1- """TODO: Add module description."""
1+ """认证模块路由。
2+
3+ 处理用户注册、登录、获取当前用户信息以及 GitLab OAuth 绑定。
4+ """
25from datetime import timedelta , datetime
36from typing import Optional
47from fastapi import APIRouter , Depends , HTTPException , status , Request
1013from devops_collector .models .base_models import User , UserOAuthToken
1114from devops_collector .auth .database import SessionLocal
1215from devops_collector .config import Config
16+
1317router = APIRouter (prefix = '/auth' , tags = ['Authentication' ])
1418
1519def get_db ():
16- '''"""TODO: Add description.
17-
18- Args:
19- TODO
20-
21- Returns:
22- TODO
23-
24- Raises:
25- TODO
26- """'''
20+ """获取数据库会话的依赖项。"""
2721 db = SessionLocal ()
2822 try :
2923 yield db
3024 finally :
3125 db .close ()
3226
3327@router .get ('/gitlab/bind' )
34- async def bind_gitlab (request : Request , token : str = Depends (services .oauth2_scheme ), db : Session = Depends (get_db )):
28+ async def bind_gitlab (request : Request , token : str = Depends (services .oauth2_scheme ), db : Session = Depends (get_db )):
3529 """发起 GitLab OAuth 绑定。"""
3630 if not Config .GITLAB_CLIENT_ID or not Config .GITLAB_REDIRECT_URI :
3731 raise HTTPException (500 , 'GitLab OAuth not configured' )
@@ -43,24 +37,46 @@ async def bind_gitlab(request: Request, token: str=Depends(services.oauth2_schem
4337 raise HTTPException (401 , 'User not found' )
4438 except Exception :
4539 raise HTTPException (401 , 'Invalid token' )
40+
4641 state = str (current_user .global_user_id )
47- auth_url = f'{ Config .GITLAB_URL } /oauth/authorize?client_id={ Config .GITLAB_CLIENT_ID } &redirect_uri={ Config .GITLAB_REDIRECT_URI } &response_type=code&scope=api&state={ state } '
42+ auth_url = (
43+ f'{ Config .GITLAB_URL } /oauth/authorize?'
44+ f'client_id={ Config .GITLAB_CLIENT_ID } &'
45+ f'redirect_uri={ Config .GITLAB_REDIRECT_URI } &'
46+ f'response_type=code&scope=api&state={ state } '
47+ )
4848 return RedirectResponse (auth_url )
4949
5050@router .get ('/gitlab/callback' )
51- async def gitlab_callback (code : str , state : str = None , db : Session = Depends (get_db )):
51+ async def gitlab_callback (code : str , state : str = None , db : Session = Depends (get_db )):
5252 """GitLab OAuth 回调处理。"""
5353 async with httpx .AsyncClient () as client :
54- resp = await client .post (f'{ Config .GITLAB_URL } /oauth/token' , data = {'client_id' : Config .GITLAB_CLIENT_ID , 'client_secret' : Config .GITLAB_CLIENT_SECRET , 'code' : code , 'grant_type' : 'authorization_code' , 'redirect_uri' : Config .GITLAB_REDIRECT_URI })
54+ resp = await client .post (
55+ f'{ Config .GITLAB_URL } /oauth/token' ,
56+ data = {
57+ 'client_id' : Config .GITLAB_CLIENT_ID ,
58+ 'client_secret' : Config .GITLAB_CLIENT_SECRET ,
59+ 'code' : code ,
60+ 'grant_type' : 'authorization_code' ,
61+ 'redirect_uri' : Config .GITLAB_REDIRECT_URI
62+ }
63+ )
5564 if resp .status_code != 200 :
5665 raise HTTPException (400 , f'GitLab Auth Failed: { resp .text } ' )
5766 token_data = resp .json ()
67+
5868 user_id = state
5969 if not user_id :
6070 raise HTTPException (400 , 'Invalid State' )
71+
6172 token_rec = db .query (UserOAuthToken ).filter_by (user_id = user_id , provider = 'gitlab' ).first ()
6273 if not token_rec :
63- token_rec = UserOAuthToken (user_id = user_id , provider = 'gitlab' , access_token = token_data ['access_token' ], token_type = token_data .get ('token_type' , 'Bearer' ))
74+ token_rec = UserOAuthToken (
75+ user_id = user_id ,
76+ provider = 'gitlab' ,
77+ access_token = token_data ['access_token' ],
78+ token_type = token_data .get ('token_type' , 'Bearer' )
79+ )
6480 db .add (token_rec )
6581 else :
6682 token_rec .access_token = token_data ['access_token' ]
@@ -69,70 +85,46 @@ async def gitlab_callback(code: str, state: str=None, db: Session=Depends(get_db
6985 return RedirectResponse (url = '/static/iteration.html?bind_success=true' )
7086
7187@router .post ('/register' , response_model = schemas .UserResponse )
72- def register (user : schemas .UserRegisterRequest , db : Session = Depends (get_db )):
73- '''"""TODO: Add description.
74-
75- Args:
76- user: TODO
77- db: TODO
78-
79- Returns:
80- TODO
81-
82- Raises:
83- TODO
84- """'''
88+ def register (user : schemas .UserRegisterRequest , db : Session = Depends (get_db )):
89+ """注册新用户。"""
8590 db_user = services .get_user_by_email (db , email = user .email )
8691 if db_user :
8792 raise HTTPException (status_code = 400 , detail = 'Email already registered' )
8893 return services .create_user (db = db , user_data = user )
8994
9095@router .post ('/login' , response_model = schemas .Token )
91- def login_for_access_token (form_data : OAuth2PasswordRequestForm = Depends (), db : Session = Depends (get_db )):
92- '''"""TODO: Add description.
93-
94- Args:
95- form_data: TODO
96- db: TODO
97-
98- Returns:
99- TODO
100-
101- Raises:
102- TODO
103- """'''
96+ def login_for_access_token (form_data : OAuth2PasswordRequestForm = Depends (), db : Session = Depends (get_db )):
97+ """登录获取访问令牌。"""
10498 user = services .authenticate_user (db , form_data .username , form_data .password )
10599 if not user :
106- raise HTTPException (status_code = status .HTTP_401_UNAUTHORIZED , detail = 'Incorrect username or password' , headers = {'WWW-Authenticate' : 'Bearer' })
100+ raise HTTPException (
101+ status_code = status .HTTP_401_UNAUTHORIZED ,
102+ detail = 'Incorrect username or password' ,
103+ headers = {'WWW-Authenticate' : 'Bearer' }
104+ )
107105 access_token_expires = timedelta (minutes = services .ACCESS_TOKEN_EXPIRE_MINUTES )
108- access_token = services .create_access_token (data = {'sub' : user .primary_email , 'user_id' : str (user .global_user_id )}, expires_delta = access_token_expires )
106+ access_token = services .create_access_token (
107+ data = {'sub' : user .primary_email , 'user_id' : str (user .global_user_id )},
108+ expires_delta = access_token_expires
109+ )
109110 return {'access_token' : access_token , 'token_type' : 'bearer' }
110111
111112@router .get ('/me' , response_model = schemas .UserResponse )
112- def read_users_me (token : str = Depends (services .oauth2_scheme ), db : Session = Depends (get_db )):
113- '''"""TODO: Add description.
114-
115- Args:
116- token: TODO
117- db: TODO
118-
119- Returns:
120- TODO
121-
122- Raises:
123- TODO
124- """'''
113+ def read_users_me (token : str = Depends (services .oauth2_scheme ), db : Session = Depends (get_db )):
114+ """获取当前登录用户信息。"""
125115 try :
126116 payload = services .jwt .decode (token , services .SECRET_KEY , algorithms = [services .ALGORITHM ])
127117 email : str = payload .get ('sub' )
128118 if email is None :
129119 raise HTTPException (status_code = 401 , detail = 'Invalid token' )
130120 except Exception :
131121 raise HTTPException (status_code = 401 , detail = 'Invalid token' )
122+
132123 user = services .get_user_by_email (db , email = email )
133124 if user is None :
134125 raise HTTPException (status_code = 401 , detail = 'User not found' )
135- token = db .query (UserOAuthToken ).filter_by (user_id = user .global_user_id , provider = 'gitlab' ).first ()
126+
127+ token_obj = db .query (UserOAuthToken ).filter_by (user_id = user .global_user_id , provider = 'gitlab' ).first ()
136128 resp = schemas .UserResponse .from_orm (user )
137- resp .gitlab_connected = True if token else False
129+ resp .gitlab_connected = True if token_obj else False
138130 return resp
0 commit comments