diff options
| -rw-r--r-- | backend/authentication/backend.py | 7 | ||||
| -rw-r--r-- | backend/authentication/user.py | 3 | ||||
| -rw-r--r-- | backend/models/form.py | 4 | ||||
| -rw-r--r-- | backend/route_manager.py | 35 | 
4 files changed, 25 insertions, 24 deletions
| diff --git a/backend/authentication/backend.py b/backend/authentication/backend.py index e4699bd..f1d2ece 100644 --- a/backend/authentication/backend.py +++ b/backend/authentication/backend.py @@ -1,6 +1,5 @@  import jwt  import typing as t -from abc import ABC  from starlette import authentication  from starlette.requests import Request @@ -10,7 +9,7 @@ from backend import constants  from .user import User -class JWTAuthenticationBackend(authentication.AuthenticationBackend, ABC): +class JWTAuthenticationBackend(authentication.AuthenticationBackend):      """Custom Starlette authentication backend for JWT."""      @staticmethod @@ -35,7 +34,7 @@ class JWTAuthenticationBackend(authentication.AuthenticationBackend, ABC):      ) -> t.Optional[tuple[authentication.AuthCredentials, authentication.BaseUser]]:          """Handles JWT authentication process."""          if "Authorization" not in request.headers: -            return +            return None          auth = request.headers["Authorization"]          token = self.get_token_from_header(auth) @@ -47,7 +46,7 @@ class JWTAuthenticationBackend(authentication.AuthenticationBackend, ABC):          scopes = ["authenticated"] -        if payload.get("admin", False) is True: +        if payload.get("admin") is True:              scopes.append("admin")          return authentication.AuthCredentials(scopes), User(token, payload) diff --git a/backend/authentication/user.py b/backend/authentication/user.py index 3bed0a1..722c348 100644 --- a/backend/authentication/user.py +++ b/backend/authentication/user.py @@ -1,10 +1,9 @@  import typing as t -from abc import ABC  from starlette.authentication import BaseUser -class User(BaseUser, ABC): +class User(BaseUser):      """Starlette BaseUser implementation for JWT authentication."""      def __init__(self, token: str, payload: dict[str, t.Any]) -> None: diff --git a/backend/models/form.py b/backend/models/form.py index 21cc549..cb58065 100644 --- a/backend/models/form.py +++ b/backend/models/form.py @@ -25,8 +25,8 @@ class Form(BaseModel):          """Validates is all features in allowed list."""          # Uppercase everything to avoid mixed case in DB          value = [v.upper() for v in value] -        allowed_values = list(v.value for v in FormFeatures.__members__.values()) -        if not all(v in allowed_values for v in value): +        allowed_values = [v.value for v in FormFeatures.__members__.values()] +        if any(v not in allowed_values for v in value):              raise ValueError("Form features list contains one or more invalid values.")          if FormFeatures.COLLECT_EMAIL in value and FormFeatures.REQUIRES_LOGIN not in value:  # noqa diff --git a/backend/route_manager.py b/backend/route_manager.py index 7427298..437cbf6 100644 --- a/backend/route_manager.py +++ b/backend/route_manager.py @@ -4,6 +4,8 @@ Module to dynamically generate a Starlette routing map based on a directory tree  import importlib  import inspect +import typing as t +  from pathlib import Path  from starlette.routing import Route as StarletteRoute, BaseRoute, Mount @@ -26,6 +28,10 @@ def construct_route_map_from_dict(route_dict: dict) -> list[BaseRoute]:      return route_map +def is_route_class(member: t.Any) -> bool: +    return inspect.isclass(member) and issubclass(member, Route) and member != Route + +  def create_route_map() -> list[BaseRoute]:      routes_directory = Path("backend") / "routes" @@ -37,24 +43,21 @@ def create_route_map() -> list[BaseRoute]:          route = importlib.import_module(import_name)          for _member_name, member in inspect.getmembers(route): -            if inspect.isclass(member): -                if issubclass(member, Route) and member != Route: -                    member.check_parameters() +            if is_route_class(member): +                member.check_parameters() -                    levels = str(file.parent).split("/")[2:] +                levels = str(file.parent).split("/")[2:] -                    current_level = None -                    for level in levels: -                        if current_level is None: -                            current_level = route_dict[f"/{level}"] -                        else: -                            current_level = current_level[f"/{level}"] - -                    if current_level is not None: -                        current_level[member.path] = member +                current_level = None +                for level in levels: +                    if current_level is None: +                        current_level = route_dict[f"/{level}"]                      else: -                        route_dict[member.path] = member +                        current_level = current_level[f"/{level}"] -    route_map = construct_route_map_from_dict(route_dict.to_dict()) +                if current_level is not None: +                    current_level[member.path] = member +                else: +                    route_dict[member.path] = member -    return route_map +    return construct_route_map_from_dict(route_dict.to_dict()) | 
