move /cards from inventory-app
This commit is contained in:
		| @@ -1,8 +1,7 @@ | ||||
| #!/usr/bin/env python3 | ||||
| from datetime import date, datetime | ||||
| from sanic import Sanic | ||||
| from sanic.response import text, json | ||||
| from sanic_prometheus import monitor | ||||
| from typing import List | ||||
|  | ||||
| from dateutil.parser import parse | ||||
| import httpx | ||||
| from functools import wraps | ||||
| @@ -10,6 +9,7 @@ from motor.motor_asyncio import AsyncIOMotorClient | ||||
| from pymongo.errors import PyMongoError | ||||
| import os | ||||
| from .slack import add_slack_routes | ||||
| from .users import users_with_group | ||||
|  | ||||
| app = Sanic(__name__) | ||||
| add_slack_routes(app) | ||||
| @@ -21,7 +21,6 @@ FLOOR_ACCESS_GROUP = os.environ["FLOOR_ACCESS_GROUP"] | ||||
| WORKSHOP_ACCESS_GROUP = os.environ["WORKSHOP_ACCESS_GROUP"] | ||||
| MONGO_URI = os.environ["MONGO_URI"] | ||||
| INVENTORY_API_KEY = os.environ["INVENTORY_API_KEY"] # asshole forwards to inventory-app, instead of using mongo directly | ||||
| CARD_URI = os.environ["CARD_URI"] | ||||
|  | ||||
| assert len(DOORBOY_SECRET_FLOOR) >= 10 | ||||
| assert len(DOORBOY_SECRET_WORKSHOP) >= 10 | ||||
| @@ -48,29 +47,29 @@ def authenticate_door(wrapped): | ||||
| @app.route("/allowed") | ||||
| @authenticate_door | ||||
| async def view_doorboy_uids(request): | ||||
|     users = List[str] | ||||
|      | ||||
|     # authorize | ||||
|     key = request.headers.get("KEY") | ||||
|     groups = [] | ||||
|     if key == DOORBOY_SECRET_FLOOR: | ||||
|         groups.append(FLOOR_ACCESS_GROUP) | ||||
|     if key == DOORBOY_SECRET_WORKSHOP: | ||||
|         groups.append(WORKSHOP_ACCESS_GROUP) | ||||
|     if not groups: | ||||
|         return "fail", 500 | ||||
|     async with httpx.AsyncClient() as client: | ||||
|         r = await client.post(CARD_URI, json={ | ||||
|             "groups": groups | ||||
|         }, headers={ | ||||
|             "Content-Type": "application/json", | ||||
|             "Authorization": f"Basic {INVENTORY_API_KEY}" | ||||
|         }) | ||||
|     j = r.json() | ||||
|     allowed_uids = [] | ||||
|     for obj in j: | ||||
|         allowed_uids.append({ | ||||
|             "token": obj["token"] | ||||
|         }) | ||||
|     return json({"allowed_uids": allowed_uids}) | ||||
|         users = users_with_group(FLOOR_ACCESS_GROUP) | ||||
|     elif key == DOORBOY_SECRET_WORKSHOP: | ||||
|         users = users_with_group(WORKSHOP_ACCESS_GROUP) | ||||
|     else: | ||||
|         print("WARN: unknown door token in /allowed") | ||||
|         return "unknown doorboy secret token", 403 | ||||
|      | ||||
|     flt = { | ||||
|         "token.uid_hash": {"$exists": True}, | ||||
|         "inventory.owner.username": {"$in": users} | ||||
|     } | ||||
|     prj = { | ||||
|         "token.uid_hash": True | ||||
|     } | ||||
|     tokens = await app.ctx.db.inventory.find(flt, prj) | ||||
|      | ||||
|     print(f"delegating {len(tokens)} doorkey tokens") | ||||
|     return json({"allowed_uids": tokens}) | ||||
|  | ||||
| def datetime_to_json_formatting(o): | ||||
|     if isinstance(o, (date, datetime)): | ||||
| @@ -153,7 +152,7 @@ async def swipe(request): | ||||
|     if key == DOORBOY_SECRET_WORKSHOP: | ||||
|         doors.add("workshopdoor") | ||||
|     if data.get("door") not in doors: | ||||
|         print("Door", repr(data.get("door")), "not in", doors) | ||||
|         print("WARN: Door", repr(data.get("door")), "not in", doors) | ||||
|         return text("Not allowed", 403) | ||||
|  | ||||
|     timestamp = parse(data["timestamp"]) if data.get("timestamp") else datetime.now(datetime.timezone.utc) | ||||
|   | ||||
							
								
								
									
										22
									
								
								app/users.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								app/users.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,22 @@ | ||||
|  | ||||
| from typing import List | ||||
| from kubernetes import client, config | ||||
| import os | ||||
|  | ||||
| OIDC_USERS_NAMESPACE = os.getenv("OIDC_USERS_NAMESPACE") | ||||
|  | ||||
| def users_with_group(group: str) -> List[str]: | ||||
|     config.load_incluster_config() | ||||
|     api_instance = client.CustomObjectsApi() | ||||
|      | ||||
|     users = List[str] | ||||
|      | ||||
|     ret = api_instance.list_namespaced_custom_object("codemowers.cloud", "v1beta1", OIDC_USERS_NAMESPACE, "oidcusers") | ||||
|     for item in ret["items"]: | ||||
|         if group not in item.get("status", {}).get("groups", []): | ||||
|             continue | ||||
|          | ||||
|         users.append(item['metadata']['name']) | ||||
|      | ||||
|     print(f"INFO: {len(users)} users in group {group}") | ||||
|     return users | ||||
| @@ -24,12 +24,10 @@ services: | ||||
|   doorboy_proxy: | ||||
|     network_mode: host | ||||
|     environment: | ||||
|       INVENTORY_API_KEY: "sptWL6XFxl4b8" | ||||
|       DOORBOY_SECRET_FLOOR: "0123456789" | ||||
|       DOORBOY_SECRET_WORKSHOP: "9999999999" | ||||
|       FLOOR_ACCESS_GROUP: "k-space:floor" | ||||
|       WORKSHOP_ACCESS_GROUP: "k-space:workshop" | ||||
|       CARD_URI: "https://inventory-app-72zn4.codemowers.ee/cards" | ||||
|       SLACK_DOORLOG_CALLBACK: DEV | ||||
|     env_file: .env | ||||
|     build: | ||||
|   | ||||
| @@ -5,3 +5,4 @@ python_dateutil==2.9.0 | ||||
| Requests==2.32.4 | ||||
| sanic==25.3.0 | ||||
| sanic_prometheus==0.2.1 | ||||
| kubernetes | ||||
|   | ||||
		Reference in New Issue
	
	Block a user