Move /swipe from inventory-app
This commit is contained in:
		| @@ -3,6 +3,7 @@ from datetime import date, datetime | ||||
| from sanic import Sanic | ||||
| from sanic.response import text, json | ||||
| from sanic_prometheus import monitor | ||||
| from dateutil.parser import parse | ||||
| import httpx | ||||
| from motor.motor_asyncio import AsyncIOMotorClient | ||||
| from pymongo.errors import PyMongoError | ||||
| @@ -20,7 +21,6 @@ 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"] | ||||
| SWIPE_URI = os.environ["SWIPE_URI"] | ||||
|  | ||||
| assert len(DOORBOY_SECRET_FLOOR) >= 10 | ||||
| assert len(DOORBOY_SECRET_WORKSHOP) >= 10 | ||||
| @@ -132,8 +132,9 @@ async def view_longpoll(request): | ||||
|         await response.send("data: response-generator-ended\n\n") | ||||
|         return | ||||
|  | ||||
| # Called by the door to log a card swipe. Does not decide whether the door should be opened. | ||||
| @app.post("/swipe") | ||||
| async def forward_swipe(request): | ||||
| async def swipe(request): | ||||
|     # authenticate | ||||
|     key = request.headers.get("KEY") | ||||
|     if not key or key not in [DOORBOY_SECRET_FLOOR, DOORBOY_SECRET_WORKSHOP]: | ||||
| @@ -150,41 +151,47 @@ async def forward_swipe(request): | ||||
|         print("Door", repr(data.get("door")), "not in", doors) | ||||
|         return text("Not allowed", 403) | ||||
|  | ||||
| def slack_post(msg): | ||||
|     if SLACK_DOORLOG_CALLBACK == "DEV": | ||||
|         print(f"[DEV SLACK]: {msg}")  | ||||
|         return | ||||
|  | ||||
|     try: | ||||
|         requests.post(SLACK_DOORLOG_CALLBACK, json={"text": msg }).raise_for_status() | ||||
|     except requests.exceptions.RequestException as e: | ||||
|         print(f"[SLACK]: {e}") | ||||
|  | ||||
| def approvedStr(approved: bool) -> str: | ||||
|     if approved: | ||||
|         return "Permitted" | ||||
|     timestamp = parse(data["timestamp"]) if data.get("timestamp") else datetime.now(datetime.timezone.utc) | ||||
|      | ||||
|     return "Denied" | ||||
|  | ||||
| # consumes SLACK_DOORLOG_CALLBACK and app.ctx.db | ||||
| @app.listener("after_server_start") | ||||
| async def slack_log(app, loop): | ||||
|     pipeline = [{ | ||||
|         "$match": { | ||||
|             "operationType": "insert", | ||||
|     # Update token, create if unknown | ||||
|     app.ctx.db.inventory.update_one({ | ||||
|         "component": "doorboy", | ||||
|         "type": "token", | ||||
|         "token.uid_hash": data["uid_hash"] | ||||
|     }, { | ||||
|         "$set": { | ||||
|             "last_seen": timestamp | ||||
|         }, | ||||
|         "$setOnInsert": { | ||||
|             "first_seen": timestamp, | ||||
|             "inventory": { | ||||
|                 "claimable": True, | ||||
|             } | ||||
|         } | ||||
|     }] | ||||
|     while True: | ||||
|         try: | ||||
|             async with app.ctx.db.eventlog.watch(pipeline) as stream: | ||||
|                 async for event in stream: | ||||
|                     ev = event["fullDocument"]                     | ||||
|                      | ||||
|                     msg = "%s %s access for %s via %s" % (approvedStr(ev["approved"]), ev["door"], ev["user"]["name"], ev("method")) | ||||
|                     slack_post(msg) | ||||
|          | ||||
|         except PyMongoError as e: | ||||
|             print(e) | ||||
|     }, upsert=True) | ||||
|      | ||||
|     token = app.ctx.db.inventory.find_one({ | ||||
|         "component": "doorboy", | ||||
|         "type": "token", | ||||
|         "token.uid_hash": data["uid_hash"] | ||||
|     }) | ||||
|      | ||||
|     event_swipe = { | ||||
|         "component": "doorboy", | ||||
|         "method": "token", | ||||
|         "timestamp": timestamp, | ||||
|         "door": data["door"], | ||||
|         "event": "card-swiped", | ||||
|         "approved": data["approved"], | ||||
|         "uid_hash":  data["uid_hash"], | ||||
|         "user": { | ||||
|             "id": token.get("inventory", {}).get("owner", {}).get("username", ""), | ||||
|             "name": token.get("inventory", {}).get("owner", {}).get("display_name", "Unclaimed Token") | ||||
|         } | ||||
|     } | ||||
|     app.ctx.db.eventlog.insert_one(event_swipe) | ||||
|  | ||||
|     return text("ok") | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     app.run(debug=False, host="0.0.0.0", port=5000, single_process=True, access_log=True) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user