Mark-Lasfar commited on
Commit
09451d2
·
1 Parent(s): fb023ba

Update backend and server frontend for OAuth JSON response, client-side navigation, and add .gitignore

Browse files
Files changed (2) hide show
  1. api/auth.py +45 -42
  2. main.py +3 -5
api/auth.py CHANGED
@@ -3,12 +3,11 @@
3
 
4
  from fastapi_users import FastAPIUsers
5
  from fastapi_users.authentication import CookieTransport, JWTStrategy, AuthenticationBackend
6
- from fastapi_users.router.oauth import get_oauth_router
7
  from httpx_oauth.clients.google import GoogleOAuth2
8
  from httpx_oauth.clients.github import GitHubOAuth2
9
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
10
  from fastapi import Depends, Request, FastAPI, Response
11
- from fastapi.responses import RedirectResponse , JSONResponse
12
  from sqlalchemy.ext.asyncio import AsyncSession
13
  from sqlalchemy import select
14
  from fastapi_users.models import UP
@@ -55,8 +54,10 @@ GITHUB_REDIRECT_URL = os.getenv("GITHUB_REDIRECT_URL", "https://mgzon-mgzon-app.
55
 
56
  google_oauth_client = GoogleOAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
57
  github_oauth_client = GitHubOAuth2(GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET)
 
 
58
 
59
- # مدير المستخدمين
60
  class UserManager(IntegerIDMixin, BaseUserManager[User, int]):
61
  reset_password_token_secret = SECRET
62
  verification_token_secret = SECRET
@@ -144,27 +145,6 @@ class UserManager(IntegerIDMixin, BaseUserManager[User, int]):
144
  async def get_user_manager(user_db: CustomSQLAlchemyUserDatabase = Depends(get_user_db)):
145
  yield UserManager(user_db)
146
 
147
- # تعديل الـ OAuth Routers لتضمين redirect مخصص
148
- google_oauth_router = get_oauth_router(
149
- google_oauth_client,
150
- auth_backend,
151
- get_user_manager,
152
- state_secret=SECRET,
153
- associate_by_email=True,
154
- redirect_url=GOOGLE_REDIRECT_URL,
155
- )
156
-
157
- github_oauth_client._access_token_url = "https://github.com/login/oauth/access_token"
158
- github_oauth_client._access_token_params = {"headers": {"Accept": "application/json"}}
159
- github_oauth_router = get_oauth_router(
160
- github_oauth_client,
161
- auth_backend,
162
- get_user_manager,
163
- state_secret=SECRET,
164
- associate_by_email=True,
165
- redirect_url=GITHUB_REDIRECT_URL,
166
- )
167
-
168
  fastapi_users = FastAPIUsers[User, int](
169
  get_user_db,
170
  [auth_backend],
@@ -172,9 +152,40 @@ fastapi_users = FastAPIUsers[User, int](
172
 
173
  current_active_user = fastapi_users.current_user(active=True, optional=True)
174
 
175
- # إضافة route مخصص للتعامل مع الـ callback
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
176
 
177
- # تعديل الـ OAuth Callback لـ Google
178
  async def custom_oauth_callback(
179
  code: str,
180
  user_manager: UserManager = Depends(get_user_manager),
@@ -184,12 +195,10 @@ async def custom_oauth_callback(
184
  ):
185
  logger.debug(f"Processing Google callback with code: {code}")
186
  try:
187
- # جلب access token من Google
188
  token_data = await oauth_client.get_access_token(code, redirect_url)
189
  access_token = token_data["access_token"]
190
  user_info = await oauth_client.get_user_info(access_token)
191
 
192
- # استدعاء oauth_callback من UserManager
193
  user = await user_manager.oauth_callback(
194
  oauth_name="google",
195
  access_token=access_token,
@@ -201,22 +210,19 @@ async def custom_oauth_callback(
201
  is_verified_by_default=True,
202
  )
203
 
204
- # إنشاء JWT token
205
  jwt_strategy = get_jwt_strategy()
206
  token = await jwt_strategy.write(user)
207
 
208
- # تعيين الـ token في الكوكيز
209
  cookie_transport.set_cookie(response, token)
210
 
211
- # رجع JSON بدل redirect
212
  return JSONResponse(content={
213
  "message": "Google login successful",
214
  "access_token": token
215
  }, status_code=200)
216
  except Exception as e:
217
  logger.error(f"Error in Google OAuth callback: {str(e)}")
218
- raise HTTPException(status_code=400, detail=str(e))
219
- # تعديل الـ OAuth Callback لـ GitHub
220
  async def custom_github_oauth_callback(
221
  code: str,
222
  user_manager: UserManager = Depends(get_user_manager),
@@ -226,12 +232,10 @@ async def custom_github_oauth_callback(
226
  ):
227
  logger.debug(f"Processing GitHub callback with code: {code}")
228
  try:
229
- # جلب access token من GitHub
230
  token_data = await oauth_client.get_access_token(code, redirect_url)
231
  access_token = token_data["access_token"]
232
  user_info = await oauth_client.get_user_info(access_token)
233
 
234
- # استدعاء oauth_callback من UserManager
235
  user = await user_manager.oauth_callback(
236
  oauth_name="github",
237
  access_token=access_token,
@@ -243,22 +247,20 @@ async def custom_github_oauth_callback(
243
  is_verified_by_default=True,
244
  )
245
 
246
- # إنشاء JWT token
247
  jwt_strategy = get_jwt_strategy()
248
  token = await jwt_strategy.write(user)
249
 
250
- # تعيين الـ token في الكوكيز
251
  cookie_transport.set_cookie(response, token)
252
 
253
- # رجع JSON بدل redirect
254
  return JSONResponse(content={
255
  "message": "GitHub login successful",
256
  "access_token": token
257
  }, status_code=200)
258
  except Exception as e:
259
  logger.error(f"Error in GitHub OAuth callback: {str(e)}")
260
- raise HTTPException(status_code=400, detail=str(e))
261
- # تضمين الراوترات داخل التطبيق
 
262
  def get_auth_router(app: FastAPI):
263
  app.include_router(fastapi_users.get_auth_router(auth_backend), prefix="/auth/jwt", tags=["auth"])
264
  app.include_router(fastapi_users.get_register_router(UserRead, UserCreate), prefix="/auth", tags=["auth"])
@@ -266,7 +268,8 @@ def get_auth_router(app: FastAPI):
266
  app.include_router(fastapi_users.get_verify_router(UserRead), prefix="/auth", tags=["auth"])
267
  app.include_router(fastapi_users.get_users_router(UserRead, UserUpdate), prefix="/users", tags=["users"])
268
 
269
- # إضافة الـ custom callback routes
 
270
  app.get("/auth/google/callback")(custom_oauth_callback)
 
271
  app.get("/auth/github/callback")(custom_github_oauth_callback)
272
-
 
3
 
4
  from fastapi_users import FastAPIUsers
5
  from fastapi_users.authentication import CookieTransport, JWTStrategy, AuthenticationBackend
 
6
  from httpx_oauth.clients.google import GoogleOAuth2
7
  from httpx_oauth.clients.github import GitHubOAuth2
8
  from fastapi_users.manager import BaseUserManager, IntegerIDMixin
9
  from fastapi import Depends, Request, FastAPI, Response
10
+ from fastapi.responses import JSONResponse
11
  from sqlalchemy.ext.asyncio import AsyncSession
12
  from sqlalchemy import select
13
  from fastapi_users.models import UP
 
54
 
55
  google_oauth_client = GoogleOAuth2(GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET)
56
  github_oauth_client = GitHubOAuth2(GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET)
57
+ github_oauth_client._access_token_url = "https://github.com/login/oauth/access_token"
58
+ github_oauth_client._access_token_params = {"headers": {"Accept": "application/json"}}
59
 
60
+ # مدير المستخدمين (بدون تغيير)
61
  class UserManager(IntegerIDMixin, BaseUserManager[User, int]):
62
  reset_password_token_secret = SECRET
63
  verification_token_secret = SECRET
 
145
  async def get_user_manager(user_db: CustomSQLAlchemyUserDatabase = Depends(get_user_db)):
146
  yield UserManager(user_db)
147
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
148
  fastapi_users = FastAPIUsers[User, int](
149
  get_user_db,
150
  [auth_backend],
 
152
 
153
  current_active_user = fastapi_users.current_user(active=True, optional=True)
154
 
155
+ # --- إضافة custom authorize endpoints (يرجع JSON مع authorization_url) ---
156
+
157
+ # Custom Google Authorize
158
+ async def custom_google_authorize(
159
+ state: Optional[str] = None,
160
+ oauth_client=Depends(lambda: google_oauth_client),
161
+ ):
162
+ logger.debug("Generating Google authorization URL")
163
+ state_data = secrets.token_urlsafe(32) if state is None else state
164
+ authorization_url = await oauth_client.get_authorization_url(
165
+ redirect_uri=GOOGLE_REDIRECT_URL,
166
+ state=state_data,
167
+ )
168
+ return JSONResponse(content={
169
+ "authorization_url": authorization_url
170
+ }, status_code=200)
171
+
172
+ # Custom GitHub Authorize
173
+ async def custom_github_authorize(
174
+ state: Optional[str] = None,
175
+ oauth_client=Depends(lambda: github_oauth_client),
176
+ ):
177
+ logger.debug("Generating GitHub authorization URL")
178
+ state_data = secrets.token_urlsafe(32) if state is None else state
179
+ authorization_url = await oauth_client.get_authorization_url(
180
+ redirect_uri=GITHUB_REDIRECT_URL,
181
+ state=state_data,
182
+ )
183
+ return JSONResponse(content={
184
+ "authorization_url": authorization_url
185
+ }, status_code=200)
186
+
187
+ # --- Custom Callback endpoints (بدون تغيير، يرجع JSON مع token) ---
188
 
 
189
  async def custom_oauth_callback(
190
  code: str,
191
  user_manager: UserManager = Depends(get_user_manager),
 
195
  ):
196
  logger.debug(f"Processing Google callback with code: {code}")
197
  try:
 
198
  token_data = await oauth_client.get_access_token(code, redirect_url)
199
  access_token = token_data["access_token"]
200
  user_info = await oauth_client.get_user_info(access_token)
201
 
 
202
  user = await user_manager.oauth_callback(
203
  oauth_name="google",
204
  access_token=access_token,
 
210
  is_verified_by_default=True,
211
  )
212
 
 
213
  jwt_strategy = get_jwt_strategy()
214
  token = await jwt_strategy.write(user)
215
 
 
216
  cookie_transport.set_cookie(response, token)
217
 
 
218
  return JSONResponse(content={
219
  "message": "Google login successful",
220
  "access_token": token
221
  }, status_code=200)
222
  except Exception as e:
223
  logger.error(f"Error in Google OAuth callback: {str(e)}")
224
+ return JSONResponse(content={"detail": str(e)}, status_code=400)
225
+
226
  async def custom_github_oauth_callback(
227
  code: str,
228
  user_manager: UserManager = Depends(get_user_manager),
 
232
  ):
233
  logger.debug(f"Processing GitHub callback with code: {code}")
234
  try:
 
235
  token_data = await oauth_client.get_access_token(code, redirect_url)
236
  access_token = token_data["access_token"]
237
  user_info = await oauth_client.get_user_info(access_token)
238
 
 
239
  user = await user_manager.oauth_callback(
240
  oauth_name="github",
241
  access_token=access_token,
 
247
  is_verified_by_default=True,
248
  )
249
 
 
250
  jwt_strategy = get_jwt_strategy()
251
  token = await jwt_strategy.write(user)
252
 
 
253
  cookie_transport.set_cookie(response, token)
254
 
 
255
  return JSONResponse(content={
256
  "message": "GitHub login successful",
257
  "access_token": token
258
  }, status_code=200)
259
  except Exception as e:
260
  logger.error(f"Error in GitHub OAuth callback: {str(e)}")
261
+ return JSONResponse(content={"detail": str(e)}, status_code=400)
262
+
263
+ # تضمين الراوترات داخل التطبيق (بدون OAuth routers هنا، هنضيفهم يدويًا)
264
  def get_auth_router(app: FastAPI):
265
  app.include_router(fastapi_users.get_auth_router(auth_backend), prefix="/auth/jwt", tags=["auth"])
266
  app.include_router(fastapi_users.get_register_router(UserRead, UserCreate), prefix="/auth", tags=["auth"])
 
268
  app.include_router(fastapi_users.get_verify_router(UserRead), prefix="/auth", tags=["auth"])
269
  app.include_router(fastapi_users.get_users_router(UserRead, UserUpdate), prefix="/users", tags=["users"])
270
 
271
+ # إضافة الـ custom OAuth endpoints يدويًا (authorize + callback)
272
+ app.get("/auth/google/authorize")(custom_google_authorize)
273
  app.get("/auth/google/callback")(custom_oauth_callback)
274
+ app.get("/auth/github/authorize")(custom_github_authorize)
275
  app.get("/auth/github/callback")(custom_github_oauth_callback)
 
main.py CHANGED
@@ -13,7 +13,7 @@ from starlette.middleware.sessions import SessionMiddleware
13
  from fastapi.openapi.docs import get_swagger_ui_html
14
  from fastapi.middleware.cors import CORSMiddleware
15
  from api.endpoints import router as api_router
16
- from api.auth import fastapi_users, auth_backend, current_active_user, get_auth_router , google_oauth_router, github_oauth_router
17
  from api.database import User, Conversation, get_db, init_db
18
  from api.models import UserRead, UserCreate, UserUpdate
19
  from motor.motor_asyncio import AsyncIOMotorClient
@@ -141,10 +141,8 @@ logger.debug("CORS middleware configured with allowed origins")
141
 
142
  # Include routers
143
  app.include_router(api_router)
144
- app.include_router(google_oauth_router, prefix="/auth", tags=["auth"]) # إضافة Google OAuth router
145
- app.include_router(github_oauth_router, prefix="/auth", tags=["auth"]) # إضافة GitHub OAuth router
146
- get_auth_router(app) # الراوترات الأخرى (JWT, register, etc.)
147
- logger.debug("API, Google OAuth, GitHub OAuth, and auth routers included")
148
 
149
  # Add logout endpoint
150
  @app.post("/logout")
 
13
  from fastapi.openapi.docs import get_swagger_ui_html
14
  from fastapi.middleware.cors import CORSMiddleware
15
  from api.endpoints import router as api_router
16
+ from api.auth import fastapi_users, auth_backend, current_active_user, get_auth_router # أزل أي ذكر لـ google_oauth_router, github_oauth_router
17
  from api.database import User, Conversation, get_db, init_db
18
  from api.models import UserRead, UserCreate, UserUpdate
19
  from motor.motor_asyncio import AsyncIOMotorClient
 
141
 
142
  # Include routers
143
  app.include_router(api_router)
144
+ get_auth_router(app) # يضيف الـ custom OAuth endpoints + JWT + register
145
+ logger.debug("API and auth routers included")
 
 
146
 
147
  # Add logout endpoint
148
  @app.post("/logout")