wu981526092 commited on
Commit
dbbc4b1
ยท
1 Parent(s): d1a53e8
Files changed (1) hide show
  1. backend/middleware/auth.py +30 -16
backend/middleware/auth.py CHANGED
@@ -7,25 +7,25 @@ Local development bypasses authentication entirely.
7
 
8
  import os
9
  import logging
10
- from typing import Optional, Dict, Any
11
  from fastapi import Request, Response, HTTPException
12
- from starlette.middleware.base import BaseHTTPMiddleware
13
  from starlette.responses import RedirectResponse, JSONResponse
 
14
  from utils.environment import should_enable_auth, get_oauth_config, is_huggingface_space
15
 
16
  logger = logging.getLogger(__name__)
17
 
18
 
19
- class ConditionalAuthMiddleware(BaseHTTPMiddleware):
20
  """
21
- Middleware that conditionally enables authentication based on deployment environment.
22
 
23
  - In HF Spaces: Full OAuth authentication required
24
  - In local development: Authentication bypassed
25
  """
26
 
27
- def __init__(self, app, excluded_paths: Optional[list] = None):
28
- super().__init__(app)
29
 
30
  # Paths that don't require authentication even in HF Spaces
31
  self.excluded_paths = excluded_paths or [
@@ -56,24 +56,33 @@ class ConditionalAuthMiddleware(BaseHTTPMiddleware):
56
  else:
57
  logger.info("๐Ÿ  Authentication middleware DISABLED (Local development)")
58
 
59
- async def dispatch(self, request: Request, call_next):
60
  """
61
- Process request through conditional authentication.
62
  """
 
 
 
 
 
 
63
  # If auth is disabled (local dev), bypass all authentication
64
  if not self.auth_enabled:
65
  logger.debug(f"๐Ÿ  Auth disabled - allowing {request.url.path}")
66
- return await call_next(request)
 
67
 
68
  # If auth is enabled but OAuth not properly configured, log warning and continue
69
  if not self.oauth_config:
70
  logger.warning("OAuth not configured properly, bypassing auth")
71
- return await call_next(request)
 
72
 
73
  # Check if path is excluded from authentication
74
  if self._is_excluded_path(request.url.path):
75
  logger.debug(f"๐Ÿšช Excluded path - allowing {request.url.path}")
76
- return await call_next(request)
 
77
 
78
  # Log the authentication check
79
  logger.info(f"๐Ÿ” Checking authentication for {request.url.path}")
@@ -88,7 +97,7 @@ class ConditionalAuthMiddleware(BaseHTTPMiddleware):
88
 
89
  # For API calls, return JSON error with login instructions
90
  if request.url.path.startswith("/api/"):
91
- return JSONResponse(
92
  status_code=401,
93
  content={
94
  "error": "Authentication required to access OpenAI-powered features",
@@ -97,13 +106,18 @@ class ConditionalAuthMiddleware(BaseHTTPMiddleware):
97
  "reason": "API access requires user authentication for security and usage tracking"
98
  }
99
  )
 
 
 
100
 
101
- # For web requests, redirect to login page
102
- return RedirectResponse(url="/auth/login-page", status_code=302)
103
 
104
  # Add user info to request state
105
- request.state.user = user
106
- return await call_next(request)
 
 
107
 
108
  def _is_excluded_path(self, path: str) -> bool:
109
  """Check if the request path should bypass authentication."""
 
7
 
8
  import os
9
  import logging
10
+ from typing import Optional, Dict, Any, Callable, Awaitable
11
  from fastapi import Request, Response, HTTPException
 
12
  from starlette.responses import RedirectResponse, JSONResponse
13
+ from starlette.types import ASGIApp, Receive, Scope, Send
14
  from utils.environment import should_enable_auth, get_oauth_config, is_huggingface_space
15
 
16
  logger = logging.getLogger(__name__)
17
 
18
 
19
+ class ConditionalAuthMiddleware:
20
  """
21
+ ASGI middleware that conditionally enables authentication based on deployment environment.
22
 
23
  - In HF Spaces: Full OAuth authentication required
24
  - In local development: Authentication bypassed
25
  """
26
 
27
+ def __init__(self, app: ASGIApp, excluded_paths: Optional[list] = None):
28
+ self.app = app
29
 
30
  # Paths that don't require authentication even in HF Spaces
31
  self.excluded_paths = excluded_paths or [
 
56
  else:
57
  logger.info("๐Ÿ  Authentication middleware DISABLED (Local development)")
58
 
59
+ async def __call__(self, scope: Scope, receive: Receive, send: Send) -> None:
60
  """
61
+ ASGI callable that processes HTTP requests.
62
  """
63
+ if scope["type"] != "http":
64
+ await self.app(scope, receive, send)
65
+ return
66
+
67
+ request = Request(scope, receive)
68
+
69
  # If auth is disabled (local dev), bypass all authentication
70
  if not self.auth_enabled:
71
  logger.debug(f"๐Ÿ  Auth disabled - allowing {request.url.path}")
72
+ await self.app(scope, receive, send)
73
+ return
74
 
75
  # If auth is enabled but OAuth not properly configured, log warning and continue
76
  if not self.oauth_config:
77
  logger.warning("OAuth not configured properly, bypassing auth")
78
+ await self.app(scope, receive, send)
79
+ return
80
 
81
  # Check if path is excluded from authentication
82
  if self._is_excluded_path(request.url.path):
83
  logger.debug(f"๐Ÿšช Excluded path - allowing {request.url.path}")
84
+ await self.app(scope, receive, send)
85
+ return
86
 
87
  # Log the authentication check
88
  logger.info(f"๐Ÿ” Checking authentication for {request.url.path}")
 
97
 
98
  # For API calls, return JSON error with login instructions
99
  if request.url.path.startswith("/api/"):
100
+ response = JSONResponse(
101
  status_code=401,
102
  content={
103
  "error": "Authentication required to access OpenAI-powered features",
 
106
  "reason": "API access requires user authentication for security and usage tracking"
107
  }
108
  )
109
+ else:
110
+ # For web requests, redirect to login page
111
+ response = RedirectResponse(url="/auth/login-page", status_code=302)
112
 
113
+ await response(scope, receive, send)
114
+ return
115
 
116
  # Add user info to request state
117
+ scope["state"] = scope.get("state", {})
118
+ scope["state"]["user"] = user
119
+
120
+ await self.app(scope, receive, send)
121
 
122
  def _is_excluded_path(self, path: str) -> bool:
123
  """Check if the request path should bypass authentication."""