From 2f5cb3032a33ead58353c1a7a6af17303b960577 Mon Sep 17 00:00:00 2001
From: GotthardG <51994228+GotthardG@users.noreply.github.com>
Date: Thu, 27 Feb 2025 10:45:16 +0100
Subject: [PATCH] Add development-only user simulation using local file

This change introduces a fallback mechanism for development environments, allowing authentication to simulate a user from a local file named "user" when not found in the mock database. The file must include a username on the first line and a space-delimited list of pgroups on the second line. This enhancement helps streamline development workflows while maintaining error handling for missing or malformed files.
---
 backend/app/routers/auth.py | 43 +++++++++++++++++++++----------------
 1 file changed, 25 insertions(+), 18 deletions(-)

diff --git a/backend/app/routers/auth.py b/backend/app/routers/auth.py
index d3e2aa8..9172cde 100644
--- a/backend/app/routers/auth.py
+++ b/backend/app/routers/auth.py
@@ -77,19 +77,20 @@ async def get_current_user(token: str = Depends(oauth2_scheme)) -> loginData:
 
 @router.post("/token/login", response_model=loginToken)
 async def login(form_data: OAuth2PasswordRequestForm = Depends()):
+    # Attempt to find the user in the normal DB
     user = mock_users_db.get(form_data.username)
-    if user is None or user["password"] != form_data.password:
-        raise HTTPException(
-            status_code=status.HTTP_401_UNAUTHORIZED,
-            detail="Incorrect username or password",
-            headers={"WWW-Authenticate": "Bearer"},
-        )
+    if user is not None:
+        # Verify password as usual for known users
+        if user["password"] != form_data.password:
+            raise HTTPException(
+                status_code=status.HTTP_401_UNAUTHORIZED,
+                detail="Incorrect username or password",
+                headers={"WWW-Authenticate": "Bearer"},
+            )
     else:
-        # For development only: if the user is not in the mock db,
-        # then simulate authentication.
-        # Read the pgroups from the local file called "user" that lives only on
-        # your machine.
-        file_path = "user"  # Adjust path as needed
+        # For development: use the local user file.
+        # Any password is accepted for the file-based user.
+        file_path = "user"  # Adjust path if your file is somewhere else.
         if not os.path.exists(file_path):
             raise HTTPException(
                 status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
@@ -100,24 +101,30 @@ async def login(form_data: OAuth2PasswordRequestForm = Depends()):
             if len(lines) < 2:
                 raise HTTPException(
                     status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
-                    detail="User file must have at least two lines: "
-                    "a username on the first and the list of pgroups on the second",
+                    detail="User file must have at least two lines:"
+                    " one for username and one for pgroups",
                 )
-            # The first line of the file is the username
             file_username = lines[0].strip()
-            # The second line is the list of pgroups (space-delimited)
+            # If desired, you can check if the provided username matches the one in
+            # your file:
+            if form_data.username != file_username:
+                raise HTTPException(
+                    status_code=status.HTTP_401_UNAUTHORIZED,
+                    detail="Username not found",
+                    headers={"WWW-Authenticate": "Bearer"},
+                )
+            # Second line: pgroups are assumed to be space-delimited.
             pgroups = lines[1].strip().split()
 
         user = {
             "username": file_username,
             "pgroups": pgroups,
         }
+        # Note: Any provided password is accepted for the user defined in the file.
 
-    # Create token
+    # Create access token from the user details
     access_token = create_access_token(
         data={"sub": user["username"], "pgroups": user["pgroups"]}
-        # data = {"sub": user["username"], "pgroups": user["pgroups"],
-        # "role": user["role"]}
     )
     return loginToken(access_token=access_token, token_type="bearer")
 
-- 
GitLab