diff options
Diffstat (limited to 'backend/main.py')
| -rw-r--r-- | backend/main.py | 93 |
1 files changed, 69 insertions, 24 deletions
diff --git a/backend/main.py b/backend/main.py index ce8f103..da914df 100644 --- a/backend/main.py +++ b/backend/main.py @@ -52,7 +52,8 @@ CREATE TABLE IF NOT EXISTS timers ( duration INT NOT NULL, block INT NOT NULL, machine INT NOT NULL, - status TEXT NOT NULL CHECK(status IN ('RUNNING', 'FINISHED')) + status TEXT NOT NULL CHECK(status IN ('RUNNING', 'FINISHED')), + subscription_id TEXT NOT NULL, ); """) # block is either 1 or 2, machine (1-4), odd is dryer, even is machine. @@ -72,7 +73,7 @@ for k, v in yaml_dict["qr_uri"]["h2"].items(): qr_uri[v] = f"h1-{k}" print("config.yaml loaded, qr_uri:") -for k,v in qr_uri.items(): +for k, v in qr_uri.items(): print(k, v) @@ -97,6 +98,10 @@ class RequestData(BaseModel): machine_id: str +class InformationRequestData(BaseModel): + machine_id: str + + class BlockRequestData(BaseModel): block: int @@ -112,6 +117,20 @@ class Status(Enum): OUTOFSERVICE = 3, +URI_TO_MACHINES = { + "h0": [1, None], + "h1-dryer1": [1, 1], + "h1-washer1": [1, 2], + "h1-dryer2": [1, 3], + "h1-washer2": [1, 4], + "hf": [2, None], + "h2-dryer1": [2, 1], + "h2-washer1": [2, 2], + "h2-dryer2": [2, 3], + "h2-washer2": [2, 4], +} + + # ## global vars for user-end machine_status = [[Status.EMPTY.name, Status.EMPTY.name, Status.EMPTY.name, Status.EMPTY.name], @@ -170,7 +189,7 @@ def final_timer_finished(timer_id): cursor.execute(f"SELECT * FROM timers WHERE timer_id = '{timer_id}'") out = cursor.fetchall() - notification = Notification(app_id=ONESIGNAL_APP_ID, included_segments=['All'], contents={'en' : 'get your bloody laundry'}, headings={'en': 'laundry finished'}) + notification = Notification(app_id=ONESIGNAL_APP_ID, included_segments=['All'], contents={'en': 'get your bloody laundry'}, headings={'en': 'laundry finished'}) try: api_response = api_instance.create_notification(notification) @@ -187,6 +206,19 @@ def create_session(response: fastapi.Response): return cookie +def authenticate_block(response: fastapi.Response, machine_id: str = None, block: int = None): + if machine_id: + blk = URI_TO_MACHINES[machine_id][0] + response.set_cookie(key="auth_block", value=blk) + return blk + elif block: + blk = block + response.set_cookie(key="auth_block", value=blk) + return block + else: + return "FAIL" + + # ## beginning print("Hello, world!") @@ -195,22 +227,11 @@ restart_terminated_schedules() # ## api endpoints -# this is a constant, mapping uri keys to block-machine pair -URI_TO_MACHINES = { - "h1-dryer1": [1, 1], - "h1-washer1": [1, 2], - "h1-dryer2": [1, 3], - "h1-washer2": [1, 4], - "h2-dryer1": [2, 1], - "h2-washer1": [2, 2], - "h2-dryer2": [2, 3], - "h2-washer2": [2, 4], -} - - # --- starting new timer +# eugh. too complex. TODO: refactor perhaps +# it's so complex even the linter is complaining @app.post("/start", response_class=PlainTextResponse) -async def start_new_timer(data: RequestData, response: fastapi.Response, session_key: Annotated[str | None, fastapi.Cookie()] = None): +def start_new_timer(data: RequestData, response: fastapi.Response, session_key: Annotated[str | None, fastapi.Cookie()] = None, auth_block: Annotated[str | None, fastapi.Cookie()] = None): now = datetime.datetime.now() try: if not session_key: @@ -228,6 +249,13 @@ async def start_new_timer(data: RequestData, response: fastapi.Response, session response.status_code = fastapi.status.HTTP_401_UNAUTHORIZED return "invalid uri; you are unauthorised" + if auth_block: + if auth_block != block: + response.status_code = fastapi.status.HTTP_403_FORBIDDEN + return "mismatch in block authentication cookie and requested block machine. forbidden." + else: + authenticate_block(response, machine_id=data.machine_id) + try: print("session key valid", session_key) cursor.execute(f""" @@ -266,6 +294,7 @@ async def start_new_timer(data: RequestData, response: fastapi.Response, session response.status_code = fastapi.status.HTTP_500_INTERNAL_SERVER_ERROR return "something went wrong during machine_status setting somehow" + # HTTP 200 return "all good bro timer started" @@ -290,9 +319,12 @@ def check_status(response: fastapi.Response, session_key: Annotated[str | None, # --- fetch machine status for block @app.post("/status") -def get_machine_status(data: BlockRequestData, auth_block: Annotated[str | None, fastapi.Cookie()] = None): - block_idx = data.block - 1 - return [machine_status[block_idx], machine_times[block_idx], machine_durations[block_idx]] +def get_machine_status(response: fastapi.Response, auth_block: Annotated[str | None, fastapi.Cookie()] = None): + if auth_block: + return [machine_status[auth_block], machine_times[auth_block], machine_durations[auth_block]] + else: + response.status_code = fastapi.status.HTTP_401_UNAUTHORIZED + return "block cookie needed. unauthorised" # --- get laundr(y/ies) information of user @@ -345,8 +377,8 @@ def finish_laundry(data: FinishRequestData, response: fastapi.Response, session_ return "laundry finished" if session_key != row[1]: - response.status_code = fastapi.status.HTTP_401_UNAUTHORIZED - return "session key mismatch with timer id, dubious and hence unauthorised." + response.status_code = fastapi.status.HTTP_403_FORBIDDEN + return "session key mismatch with timer id, dubious!" else: response.status_code = fastapi.status.HTTP_401_UNAUTHORIZED return "you got no session key, cannot" @@ -354,5 +386,18 @@ def finish_laundry(data: FinishRequestData, response: fastapi.Response, session_ # --- get information from uri search query @app.post("/info") -def uri_to_information(data: FinishRequestData): - pass +def uri_to_information(data: InformationRequestData, response: fastapi.Response, auth_block: Annotated[str | None, fastapi.Cookie()] = None): + try: + info = URI_TO_MACHINES[data.machine_id] + except KeyError: + response.status_code = fastapi.status.HTTP_404_NOT_FOUND + return "INVALID machine ID/URI" + + if auth_block: + if auth_block != info[0]: + response.status_code = fastapi.status.HTTP_403_FORBIDDEN + return "UNAUTHORISED to view information" + else: + authenticate_block(response, block=info[0]) + + return {"block": info[0], "machine": info[1]} |
