Files
weibo_signin/backend/auth_service/app/__pycache__/main.cpython-311.pyc

285 lines
22 KiB
Plaintext
Raw Normal View History

2026-03-09 14:05:00 +08:00
<EFBFBD>
9<16>i.><00><00><><00>dZddlmZmZmZmZmZddlmZddl m
2026-03-09 14:05:00 +08:00
Z
m Z ddl m Z ddlmZmZddlZddlZddlZddlZddlmZdd lmZmZmZdd
lmZdd lmZdd lm Z m!Z!m"Z"m#Z#m$Z$m%Z%m&Z&m'Z'dd l(m)Z)ddl*m+Z+m,Z,m-Z-m.Z.m/Z/m0Z0ej1e2<65><00>Z3eddddd<13><14><00>Z4e4<65>5eddgddgdg<01><19><00>e
<EFBFBD><00>Z6ee6<65><00>ee<18><00>fde de de"fd<1D>Z7e4<65>8d<1E><00>d<1F><00><00>Z9e4<65>:d <20><00>d!<21><00><00>Z;e4<65>:d"<22><00>d#<23><00><00>Z<e4<65>=d$e&ej><00>%<25><00>ee<18><00>fd&e de fd'<27><05><00>Z?e4<65>=d(e&<26>)<29><00>ee<18><00>fd*e!de fd+<2B><05><00>Z@e4<65>=d,e#<23>)<29><00>ee<18><00>fd-e%de fd.<2E><05><00>ZAe4<65>:d/e"<22>)<29><00>ee7<65><00>fd0e"fd1<64><05><00>ZBe4<65>=d2e&<26>)<29><00>ee<18><00>fd-e'de fd3<64><05><00>ZCee6<65><00>ee<18><00>fde de defd4<64>ZDe4<65>:d5<64><00>eeD<65><00>ee<18><00>fd6ede fd7<64><05><00>ZEe4<65>Fd8<64><00>eeD<65><00>ee<18><00>fd9eGd6ede fd:<3A><05><00>ZHe4<65>=d;<3B><00>eeD<65><00>ee<18><00>fd6ede fd<<3C><05><00>ZIe4<65>:d;<3B><00>eeD<65><00>ee<18><00>fd6ede fd=<3D><05><00>ZJe4<65>Kd><3E><00>eeD<65><00>ee<18><00>fd?eGd6ede fd@<40><05><00>ZLdS)AzK
2026-03-09 14:05:00 +08:00
Weibo-HotSign Authentication Service
Main FastAPI application entry point
<EFBFBD>)<05>FastAPI<50>Depends<64> HTTPException<6F>status<75>Security)<01>CORSMiddleware)<02>
HTTPBearer<EFBFBD>HTTPAuthorizationCredentials)<01> AsyncSession)<02>select<63>funcN)<01>datetime)<03>get_db<64>User<65>
InviteCode)<01>shared_settings)<01> create_tables)<08>
UserCreate<EFBFBD> UserLogin<69> UserResponse<73>Token<65> TokenData<74>RefreshTokenRequest<73> AuthResponse<73>WxLoginRequest)<01> AuthService)<06>verify_password<72>create_access_token<65>decode_access_token<65>create_refresh_token<65>verify_refresh_token<65>revoke_refresh_token<65>$Weibo-HotSign Authentication ServicezFHandles user authentication and authorization for Weibo-HotSign system<65>1.0.0z/docsz/redoc)<05>title<6C> description<6F>version<6F>docs_url<72> redoc_urlzhttp://localhost:3000zhttp://localhost:80T<30>*)<04> allow_origins<6E>allow_credentials<6C> allow_methods<64> allow_headers<72> credentials<6C>db<64>returnc<00><00><>K<00>|j}t|<02><00>}|<03>ttjdddi<01><05><00><00>|<03>d<06><00>}|sttjdddi<01><05><00><00>t |<01><00>}|<05>|<04><00><00>d{V<00><03>}|<06>ttjd<08> <09><00><00>|j sttj
2026-03-09 14:05:00 +08:00
d
<EFBFBD> <09><00><00>tj |<06><00>S) z7
Dependency to get current user from JWT token
NzInvalid or expired tokenzWWW-Authenticate<74>Bearer)<03> status_code<64>detail<69>headers<72>subzInvalid token payload<61>User not found<6E>r4r5<00>User account is deactivated) r/rrr<00>HTTP_401_UNAUTHORIZED<45>getr<00>get_user_by_id<69>HTTP_404_NOT_FOUND<4E> is_active<76>HTTP_403_FORBIDDENr<00>from_orm)r/r0<00>token<65>payload<61>user_id<69> auth_service<63>users <20>.D:\code\weibo\backend\auth_service\app\main.py<70>get_current_userrH6s#<00><00><00><00> <18> #<23>E<EFBFBD>!<21>%<25>(<28>(<28>G<EFBFBD><0E><EFBFBD><1B><1E>4<>-<2D>'<27><18>2<>
2026-03-09 14:05:00 +08:00
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <16>k<EFBFBD>k<EFBFBD>%<25> <20> <20>G<EFBFBD> <12>
<EFBFBD><1B><1E>4<>*<2A>'<27><18>2<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <1F>r<EFBFBD>?<3F>?<3F>L<EFBFBD><1D>,<2C>,<2C>W<EFBFBD>5<>5<> 5<> 5<> 5<> 5<> 5<> 5<>D<EFBFBD> <0B>|<7C><1B><1E>1<>#<23>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<10>><3E>
<EFBFBD><1B><1E>1<>0<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
2026-03-09 16:10:29 +08:00
<18> <20><14> &<26> &<26>&<26><00>startupc<00><00>
K<00>dS)z%Initialize database tables on startupN<70>rLrIrG<00> startup_eventrM`s <00><00><00><00>
 <09>DrI<00>/c<00><00>K<00>dddd<04>S)Nr#<00>runningr$)<03>servicerr'rLrLrIrG<00>rootrRgs <00><00><00><00>:<3A><1B><1A> <06> <06>rIz/healthc<00><00>K<00>ddiS)Nr<00>healthyrLrLrIrG<00> health_checkrUos<00><00><00><00> <14>i<EFBFBD> <20> rIz/auth/register)<02>response_modelr4<00> user_datac <00><00>hK<00>t|<01><00>}|<01>tt<00><00><00>tj|jktjdk<00><00><00><00><00>d{V<00><03>}|<03><00><00>}|sttj d<03><04><00><00>|<02> |j |j<00><00><00>d{V<00><03>\}}|rttjd<05><04><00><00>|rttjd<06><04><00><00> |<02>|<00><00><00>d{V<00><03>}d|_t#|j<00><00>|_t)j<00><00>|_|<01><00><00><00>d{V<00><03>t1t#|j<00><00>|jd<08><02> <09><00>}t3t#|j<00><00><00><00><00>d{V<00><03>} t5|| d
d t7j|<07><00><00> <0C><00>S#t$r<00>t:$r0}
ttjd t#|
<EFBFBD><00><00><00><02><04><00><00>d}
~
wwxYw)zZ
Register a new user account and return tokens.
Requires a valid invite code.
FNu邀请码无效或已被使用r9z#User with this email already existszUsername already takenT<6E>r7<00>username<6D><01>data<74>bearer<65><00><05> access_token<65> refresh_token<65>
2026-03-09 16:10:29 +08:00
token_type<EFBFBD>
expires_inrFzFailed to create user: )r<00>executer r<00>where<72>code<64> invite_code<64>is_used<65>scalar_one_or_nonerr<00>HTTP_400_BAD_REQUEST<53>check_user_exists<74>emailrZ<00>HTTP_409_CONFLICT<43> create_user<65>str<74>id<69>used_byr<00>utcnow<6F>used_at<61>commitrr rrrA<00> Exception<6F>HTTP_500_INTERNAL_SERVER_ERROR) rWr0rE<00>result<6C>invite<74>
email_user<EFBFBD> username_userrFr`ra<00>es rG<00> register_userr|ss<><00><00><00><00> <1F>r<EFBFBD>?<3F>?<3F>L<EFBFBD><16>:<3A>:<3A><0E>z<EFBFBD><1A><1A> <20> <20> <16>O<EFBFBD>y<EFBFBD>4<> 4<> <16> <1E>%<25> '<27>
<EFBFBD>
<EFBFBD><06><06><06><06><06><06><06><06>F<EFBFBD> <14> &<26> &<26> (<28> (<28>F<EFBFBD> <11>
<EFBFBD><1B><1E>3<>3<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> '3<>&D<>&D<>Y<EFBFBD>_<EFBFBD>V_<56>Vh<56>&i<>&i<> i<> i<> i<> i<> i<> i<><1D>J<EFBFBD> <0A><11>
2026-03-09 14:05:00 +08:00
<EFBFBD><1B><1E>0<>8<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<15>
<EFBFBD><1B><1E>0<>+<2B>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> 
<EFBFBD>!<21>-<2D>-<2D>i<EFBFBD>8<>8<>8<>8<>8<>8<>8<>8<><04><1E><06><0E><1C>T<EFBFBD>W<EFBFBD><1C><1C><06><0E>!<21><1F>*<2A>*<2A><06><0E><10>i<EFBFBD>i<EFBFBD>k<EFBFBD>k<EFBFBD><19><19><19><19><19><19><19>+<2B><03>D<EFBFBD>G<EFBFBD> <0C> <0C>RV<52>R_<52>0`<60>0`<60>a<>a<>a<> <0C>2<>3<EFBFBD>t<EFBFBD>w<EFBFBD><<3C><<3C>@<40>@<40>@<40>@<40>@<40>@<40>@<40>@<40> <0A><1B>%<25>'<27><1F><1B><1D>&<26>t<EFBFBD>,<2C>,<2C> 
2026-03-09 16:10:29 +08:00
<EFBFBD>
<EFBFBD>
<EFBFBD>
2026-03-17 13:47:44 +08:00
<EFBFBD><EFBFBD> <19><0E><0E><0E> <0A> <14>
2026-03-09 14:05:00 +08:00
<EFBFBD>
<EFBFBD>
<EFBFBD><1B><1E>=<3D>5<>S<EFBFBD><11>V<EFBFBD>V<EFBFBD>5<>5<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
<EFBFBD><EFBFBD><EFBFBD>s<00> C#G-<00>-H1<03>+H,<03>,H1z /auth/login)rV<00>
2026-03-09 16:10:29 +08:00
login_datac <00><00>:K<00>t|<01><00>}|<02>|j<00><00><00>d{V<00><03>}|sttjd<02><03><00><00>t |j|j<00><00>sttjd<02><03><00><00>|j sttj
d<04><03><00><00>tt|j <00><00>|jd<05><02><06><00>}tt|j <00><00><00><00><00>d{V<00><03>}t!||ddt#j|<03><00><00> <09><00>S)
z?
Authenticate user and return JWT token with user info
NzInvalid email or passwordr9r:rYr[r]r^r_)r<00>get_user_by_emailrlrrr;r<00>password<72>hashed_passwordr?r@rrorprZr rrrA)r}r0rErFr`ras rG<00>
login_userr<EFBFBD><00>sI<00><00><00><00>
2026-03-09 14:05:00 +08:00
<1F>r<EFBFBD>?<3F>?<3F>L<EFBFBD><1E>/<2F>/<2F>
<EFBFBD>0@<40>A<>A<> A<> A<> A<> A<> A<> A<>D<EFBFBD> <0F>
<EFBFBD><1B><1E>4<>.<2E>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <1B>:<3A>.<2E><04>0D<30> E<> E<>
<EFBFBD><1B><1E>4<>.<2E>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <10>><3E>
<EFBFBD><1B><1E>1<>0<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> '<27>C<EFBFBD><04><07>L<EFBFBD>L<EFBFBD>d<EFBFBD>m<EFBFBD>,\<5C>,\<5C>]<5D>]<5D>]<5D>L<EFBFBD>/<2F>s<EFBFBD>4<EFBFBD>7<EFBFBD>|<7C>|<7C><<3C><<3C><<3C><<3C><<3C><<3C><<3C><<3C>M<EFBFBD> <17>!<21>#<23><1B><17> <19> "<22>4<EFBFBD> (<28> (<28>  <06> <06> <06>rIz /auth/refresh<73>bodyc<00><00> K<00>t|j<00><00><00>d{V<00><03>}|<02>ttjd<02><03><00><00>t |<01><00>}|<03>|<02><00><00>d{V<00><03>}|<04>|jsttjd<04><03><00><00>t|j<00><00><00>d{V<00><03>tt|j <00><00>|j d<05><02><06><00>}tt|j <00><00><00><00><00>d{V<00><03>}t||dd<08> <09><00>S)
2026-03-09 14:05:00 +08:00
z<EFBFBD>
Exchange a valid refresh token for a new access + refresh token pair (Token Rotation).
The old refresh token is revoked immediately.
Nz Invalid or expired refresh tokenr9zUser not found or deactivatedrYr[r]r^)r`rarbrc)r!rarrr;rr=r?r"rrorprZr r)r<>r0rDrErF<00>
new_access<EFBFBD> new_refreshs rGrara<00>s=<00><00><00><00>)<29><14>);<3B><<3C><<3C><<3C><<3C><<3C><<3C><<3C><<3C>G<EFBFBD><0E><EFBFBD><1B><1E>4<>5<>
2026-03-09 14:05:00 +08:00
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <1F>r<EFBFBD>?<3F>?<3F>L<EFBFBD><1D>,<2C>,<2C>W<EFBFBD>5<>5<> 5<> 5<> 5<> 5<> 5<> 5<>D<EFBFBD> <0B>|<7C>4<EFBFBD>><3E>|<7C><1B><1E>4<>2<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <1F>t<EFBFBD>1<>
2<EFBFBD>
2<EFBFBD>2<>2<>2<>2<>2<>2<>2<>$<24>#<23>d<EFBFBD>g<EFBFBD>,<2C>,<2C>D<EFBFBD>M<EFBFBD>*Z<>*Z<>[<5B>[<5B>[<5B>J<EFBFBD>,<2C>S<EFBFBD><14><17>\<5C>\<5C>:<3A>:<3A>:<3A>:<3A>:<3A>:<3A>:<3A>:<3A>K<EFBFBD> <10><1F>!<21><1B><17>  <06> <06> <06>rIz/auth/me<6D> current_userc<00><00>
2026-03-09 14:05:00 +08:00
K<00>|S)z&
Get current user information
rL)r<>s rG<00>get_current_user_infor<6F>s<00><00><00><00>
<18>rIz/auth/wx-loginc <00><00><>K<00>ddl}tj}tj}|r|st t
jd<03><04><00><00>|<02>d<05><06><00>4<00>d{V<00><03>}|<05>d|||j dd <09><04>
<EFBFBD><00><00>d{V<00><03>}|<06>
<00><00>}ddd<02><00><00>d{V<00><03>n#1<00>d{V<00><03>swxYwY|<07>d <0B><00>}|sN|<07>d d <0A><00>} |<07>dd<0F><00>}
t t
j d|
<EFBFBD>d| <09>d<12><05><04><00><00>|<01> tt<00><00><00>tj|k<00><00><00><00><00>d{V<00><03>} | <0B><00><00>} | r||jr|j| jkr |j| _|jr|j| jkr |j| _|<01><00><00><00>d{V<00><03>|<01>| <0C><00><00>d{V<00><03>n<>ddl} |jp d|dd<14><00><00>}d|dd<15><00><00>}tt3| <0A><00><00><00><00>||||jd<16><17><00>} |<01>| <0C><00>|<01><00><00><00>d{V<00><03>|<01>| <0C><00><00>d{V<00><03>t8<00>d|dd<19><00>d|<0F><00><04><00>| jst t
jd<1B><04><00><00>tAt3| j!<00><00>| j"d<1C><02><1D><00>}tGt3| j!<00><00><00><00><00>d{V<00><03>}tI||ddtKj&| <0C><00><00> <20><00>S)!u<>
微信小程序登录。
流程:
1. 用 code 调微信 code2Session 接口换取 openid
2. 查找是否已有该 openid 的用户
3. 没有则自动注册,有则直接登录
4. 返回 JWT token
rNu)微信小程序未配置 APPID 和 SECRETr9<00>
)<01>timeoutz,https://api.weixin.qq.com/sns/jscode2session<6F>authorization_code)<04>appid<69>secret<65>js_code<64>
grant_type)<01>params<6D>openid<69>errcode<64>unknown<77>errmsgu 未知错误u微信登录失败: z
(errcode=<3D>)<29>wx_<78><00> T)rprZ<00> wx_openid<69> wx_nickname<6D> wx_avatarr?u!微信用户自动注册: openid=<3D>z..., username=u账号已被禁用rYr[r]r^r_)'<27>httpxr<00>WX_APPID<49> WX_SECRETrrrv<00> AsyncClientr<rf<00>jsonr;rdr rrer<>ri<00>nicknamer<65><00>
avatar_urlr<EFBFBD>rt<00>refresh<73>uuidro<00>uuid4<64>add<64>logger<65>infor?r@rrprZr rrrA)r<>r0r<>r<>r<><00>client<6E>resp<73>wx_datar<61>r<>r<>rwrFr<>r<>rZr`ras rG<00>wx_loginr<6E> ss<00><00><00><00><11>L<EFBFBD>L<EFBFBD>L<EFBFBD> <1B> $<24>E<EFBFBD> <1C> &<26>F<EFBFBD> <10>
<EFBFBD><06>
<EFBFBD><1B><1E>=<3D>><3E>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <15> <20> <20><12> <20>,<2C>,<2C>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E><06><1B>Z<EFBFBD>Z<EFBFBD> :<3A><1E> <20><1F>9<EFBFBD>2<> <0E><0E> <20>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD><04><17>)<29>)<29>+<2B>+<2B><07>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E>
<1E><><EFBFBD><EFBFBD>
<1E>
<1E>
<1E>
<1E><15>[<5B>[<5B><18> "<22> "<22>F<EFBFBD> <11>
<EFBFBD><19>+<2B>+<2B>i<EFBFBD><19>3<>3<><07><18><1B><1B>X<EFBFBD>~<7E>6<>6<><06><1B><1E>4<>F<>&<26>F<>F<>G<EFBFBD>F<>F<>F<>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> <16>:<3A>:<3A>f<EFBFBD>T<EFBFBD>l<EFBFBD>l<EFBFBD>0<>0<><14><1E>6<EFBFBD>1I<31>J<>J<>K<>K<> K<> K<> K<> K<> K<> K<>F<EFBFBD> <11> $<24> $<24> &<26> &<26>D<EFBFBD> <0B>_<01> <0F>=<3D> -<2D>T<EFBFBD>]<5D>d<EFBFBD>.><3E>><3E>><3E>#<23>}<7D>D<EFBFBD> <1C> <0F>?<3F> -<2D>t<EFBFBD><EFBFBD>$<24>.<2E>@<40>@<40>!<21>_<EFBFBD>D<EFBFBD>N<EFBFBD><10>i<EFBFBD>i<EFBFBD>k<EFBFBD>k<EFBFBD><19><19><19><19><19><19><19><10>j<EFBFBD>j<EFBFBD><14><1E><1E><1E><1E><1E><1E><1E><1E><1E><1E> <14> <0B> <0B> <0B><17>=<3D>6<>$6<>&<26><12>!<21><12>*<2A>$6<>$6<><08>&<26><16><03><12><03><1B>&<26>&<26><08><13><12>4<EFBFBD>:<3A>:<3A><<3C><<3C> <20> <20><1D><1C> <20><1A>o<EFBFBD><1A> 
<EFBFBD>
<EFBFBD>
<EFBFBD><04> <0B><06><06>t<EFBFBD> <0C> <0C> <0C><10>i<EFBFBD>i<EFBFBD>k<EFBFBD>k<EFBFBD><19><19><19><19><19><19><19><10>j<EFBFBD>j<EFBFBD><14><1E><1E><1E><1E><1E><1E><1E><1E><1E><0E> <0B> <0B>]<5D><06>s<EFBFBD><02>s<EFBFBD> <0B>]<5D>]<5D>S[<5B>]<5D>]<5D>^<5E>^<5E>^<5E> <0F>><3E>
<EFBFBD><1B><1E>1<>'<27>
<EFBFBD>
<EFBFBD>
<EFBFBD>
<EFBFBD> '<27><18><14><17>\<5C>\<5C>t<EFBFBD>}<7D> =<3D> =<3D><06><06><06>L<EFBFBD>/<2F>s<EFBFBD>4<EFBFBD>7<EFBFBD>|<7C>|<7C><<3C><<3C><<3C><<3C><<3C><<3C><<3C><<3C>M<EFBFBD> <17>!<21>#<23><1B><17> <19> "<22>4<EFBFBD> (<28> (<28>  <06> <06> <06>s<00><B(<03>(
B2<07>5B2c<00><00><>K<00>t|j<00><00>}|stdd<02><03><00><00>|<02>d<04><00>}|<01>t t <00><00><00>t j|k<00><00><00><00><00>d{V<00><03>}|<04> <00><00>}|r|j
stdd<06><03><00><00>|j stdd<08><03><00><00>|S) zDependency: require admin user.i<>z Invalid tokenr9r7Nr8i<>u需要管理员权限) rr/rr<rdr rrerprir?<00>is_admin)r/r0rCrDrwrFs rG<00> require_adminr<6E>ms<><00><00><00><00>
"<22>+<2B>"9<>:<3A>:<3A>G<EFBFBD> <12>E<01><1B><03>O<EFBFBD>D<>D<>D<>D<><15>k<EFBFBD>k<EFBFBD>%<25> <20> <20>G<EFBFBD><15>:<3A>:<3A>f<EFBFBD>T<EFBFBD>l<EFBFBD>l<EFBFBD>0<>0<><14><17>G<EFBFBD>1C<31>D<>D<>E<>E<> E<> E<> E<> E<> E<> E<>F<EFBFBD> <11> $<24> $<24> &<26> &<26>D<EFBFBD> <0F>F<01>t<EFBFBD>~<7E>F<01><1B><03>4D<34>E<>E<>E<>E<> <0F>=<3D>M<01><1B><03>4K<34>L<>L<>L<>L<> <0F>KrIz /admin/users<72>adminc<00><00>(K<00>|<01>tt<00><00><00>tj<00><00><00><00><00><00><00><00>d{V<00><03>}|<02><00><00><00><00><00>}dd<03>|D<00><00>d<04>S)u管理员查看所有用户NTc
<00><><00>g|]L}t|j<00><00>|j|j|j|j|jrt|j<00><00>ndd<01><06><02>MS)N)rprZrlr?r<><00>
created_at)rorprZrlr?r<>r<>)<02>.0<EFBFBD>us rG<00>
<listcomp>z$admin_list_users.<locals>.<listcomp><3E>si<00><00>

<EFBFBD>

<EFBFBD>

<EFBFBD><12><1A>!<21>$<24>i<EFBFBD>i<EFBFBD><1D>J<EFBFBD><1A><17><1E>[<5B><1D>J<EFBFBD>34<33><<3C>I<>c<EFBFBD>!<21>,<2C>/<2F>/<2F>/<2F>T<EFBFBD>  <0E> <0E>

<EFBFBD>

<EFBFBD>

rI<00><02>successr\)rdr r<00>order_byr<79><00>desc<73>scalars<72>all)r<>r0rw<00>userss rG<00>admin_list_usersr<73>s<><00><00><00><00> <16>:<3A>:<3A>f<EFBFBD>T<EFBFBD>l<EFBFBD>l<EFBFBD>3<>3<>D<EFBFBD>O<EFBFBD>4H<34>4H<34>4J<34>4J<34>K<>K<>L<>L<> L<> L<> L<> L<> L<> L<>F<EFBFBD> <12>N<EFBFBD>N<EFBFBD> <1C> <1C> <20> <20> "<22> "<22>E<EFBFBD><17>

<EFBFBD>

<EFBFBD><1B>

<EFBFBD>

<EFBFBD>

<EFBFBD> <06> <06> rIz/admin/users/{user_id}/togglerDc<00><00><>K<00>|<02>tt<00><00><00>tj|k<00><00><00><00><00>d{V<00><03>}|<03><00><00>}|st dd<03><04><00><00>t|j<00><00>t|j<00><00>krt dd<06><04><00><00>|j |_|<02> <00><00><00>d{V<00><03>d|jd<08>S) u管理员启用/禁用用户N<E688B7><4E>u用户不存在r9<00><>u不能禁用自己T)r<>r?)
rdr rrerprirror?rt)rDr<>r0rwrFs rG<00>admin_toggle_userr<72><00>s<><00><00><00><00><16>:<3A>:<3A>f<EFBFBD>T<EFBFBD>l<EFBFBD>l<EFBFBD>0<>0<><14><17>G<EFBFBD>1C<31>D<>D<>E<>E<> E<> E<> E<> E<> E<> E<>F<EFBFBD> <11> $<24> $<24> &<26> &<26>D<EFBFBD> <0F>G<01><1B><03>4E<34>F<>F<>F<>F<>
<EFBFBD>4<EFBFBD>7<EFBFBD>|<7C>|<7C>s<EFBFBD>5<EFBFBD>8<EFBFBD>}<7D>}<7D>$<24>$<24><1B><03>4H<34>I<>I<>I<>I<><1D><1E>'<27>D<EFBFBD>N<EFBFBD>
<0C>)<29>)<29>+<2B>+<2B><15><15><15><15><15><15><15><1B>$<24>.<2E> 9<> 9<>9rIz/admin/invite-codesc<00><00><>K<00>tjd<01><00>dd<03><00><00><00>}t|t |j<00><00><00><04><00>}|<01>|<03><00>|<01><00><00><00>d{V<00><03>|<01>|<03><00><00>d{V<00><03>dt |j<00><00>|j t |j
<00><00>d<06>d<07>S)u管理员生成邀请码r<E7A081>Nr<4E>)rf<00>
created_byT)rprfr<>r<>) <0B>secrets<74> token_urlsafe<66>upperrrorpr<>rtr<>rfr<>)r<>r0rfrxs rG<00>admin_create_invite_coder<65><00>s<><00><00><00><00> <13> <20><11> #<23> #<23>C<EFBFBD>R<EFBFBD>C<EFBFBD> (<28> .<2E> .<2E> 0<> 0<>D<EFBFBD> <17>T<EFBFBD>c<EFBFBD>%<25>(<28>m<EFBFBD>m<EFBFBD> <<3C> <<3C> <<3C>F<EFBFBD><06>F<EFBFBD>F<EFBFBD>6<EFBFBD>N<EFBFBD>N<EFBFBD>N<EFBFBD>
<0C>)<29>)<29>+<2B>+<2B><15><15><15><15><15><15><15>
<0C>*<2A>*<2A>V<EFBFBD>
<1C>
<1C><1C><1C><1C><1C><1C><1C><1C><17><15>f<EFBFBD>i<EFBFBD>.<2E>.<2E><1A>K<EFBFBD><1D>f<EFBFBD>/<2F>0<>0<>
<EFBFBD>
<EFBFBD> <06> <06>rIc<00><00>(K<00>|<01>tt<00><00><00>tj<00><00><00><00><00><00><00><00>d{V<00><03>}|<02><00><00><00><00><00>}dd<03>|D<00><00>d<04>S)u管理员查看所有邀请码NTc
<00><><00>g|]b}t|j<00><00>|j|j|j|jrt|j<00><00>nd|jrt|j<00><00>ndd<01><06><02>cS)N)rprfrhrqr<>rs)rorprfrhrqr<>rs)r<><00>cs rGr<>z+admin_list_invite_codes.<locals>.<listcomp><3E>sz<00><00>

<EFBFBD>

<EFBFBD>

<EFBFBD><12><1A>!<21>$<24>i<EFBFBD>i<EFBFBD><19><06><1C>9<EFBFBD><1C>9<EFBFBD>34<33><<3C>I<>c<EFBFBD>!<21>,<2C>/<2F>/<2F>/<2F>T<EFBFBD>-.<2E>Y<EFBFBD>@<40>3<EFBFBD>q<EFBFBD>y<EFBFBD>><3E>><3E>><3E>D<EFBFBD>  <0E> <0E>

<EFBFBD>

<EFBFBD>

rIr<>)rdr rr<>r<>r<>r<>r<>)r<>r0rw<00>codess rG<00>admin_list_invite_codesr<73><00>s<><00><00><00><00> <16>:<3A>:<3A>f<EFBFBD>Z<EFBFBD>0<>0<>9<>9<>*<2A>:O<>:T<>:T<>:V<>:V<>W<>W<>X<>X<> X<> X<> X<> X<> X<> X<>F<EFBFBD> <12>N<EFBFBD>N<EFBFBD> <1C> <1C> <20> <20> "<22> "<22>E<EFBFBD><17>

<EFBFBD>

<EFBFBD><1B>

<EFBFBD>

<EFBFBD>

<EFBFBD> <06> <06> rIz/admin/invite-codes/{code_id}<7D>code_idc<00><00><>K<00>|<02>tt<00><00><00>tj|k<00><00><00><00><00>d{V<00><03>}|<03><00><00>}|st dd<03><04><00><00>|jrt dd<06><04><00><00>|<02>|<04><00><00>d{V<00><03>|<02> <00><00><00>d{V<00><03>ddiS) u$管理员删除未使用的邀请码Nr<4E>u邀请码不存在r9r<>u!已使用的邀请码不能删除r<E999A4>T)
rdr rrerprirrh<00>deletert)r<>r<>r0rwrxs rG<00>admin_delete_invite_coder<65><00>s<><00><00><00><00><16>:<3A>:<3A>f<EFBFBD>Z<EFBFBD>0<>0<>6<>6<>z<EFBFBD>}<7D><07>7O<37>P<>P<>Q<>Q<> Q<> Q<> Q<> Q<> Q<> Q<>F<EFBFBD> <13> &<26> &<26> (<28> (<28>F<EFBFBD> <11>J<01><1B><03>4H<34>I<>I<>I<>I<> <0A>~<7E>Y<01><1B><03>4W<34>X<>X<>X<>X<>
<0C>)<29>)<29>F<EFBFBD>
<1B>
<1B><1B><1B><1B><1B><1B><1B><1B>
<0C>)<29>)<29>+<2B>+<2B><15><15><15><15><15><15><15> <15>t<EFBFBD> <1C>rI)M<>__doc__<5F>fastapirrrrr<00>fastapi.middleware.corsr<00>fastapi.securityr r
2026-03-09 14:05:00 +08:00
<00>sqlalchemy.ext.asyncior <00>
sqlalchemyr r <00>sa_func<6E>uvicorn<72>os<6F>loggingr<67>r<00> shared.modelsrrr<00> shared.configr<00> auth_service.app.models.databaser<00>auth_service.app.schemas.userrrrrrrrr<00>&auth_service.app.services.auth_servicer<00>auth_service.app.utils.securityrrrr r!r"<00> getLogger<65>__name__r<5F><00>app<70>add_middleware<72>securityrH<00>on_eventrMr<rRrU<00>post<73>HTTP_201_CREATEDr|r<>rar<>r<>r<>r<><00>putror<>r<>r<>r<>r<>rLrIrG<00><module>r<>s<><00><01><04><04>
F<01>E<>E<>E<>E<>E<>E<>E<>E<>E<>E<>E<>E<>E<>2<>2<>2<>2<>2<>2<>E<>E<>E<>E<>E<>E<>E<>E<>/<2F>/<2F>/<2F>/<2F>/<2F>/<2F>.<2E>.<2E>.<2E>.<2E>.<2E>.<2E>.<2E>.<2E><0E><0E><0E><0E> <09> <09> <09> <09><0E><0E><0E><0E><0E><0E><0E><0E><1D><1D><1D><1D><1D><1D>2<>2<>2<>2<>2<>2<>2<>2<>2<>2<>)<29>)<29>)<29>)<29>)<29>)<29>:<3A>:<3A>:<3A>:<3A>:<3A>:<3A><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02>?<3F>><3E>><3E>><3E>><3E>><3E><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02><02>
2026-03-09 14:05:00 +08:00
<1B><17> <1A>8<EFBFBD> $<24> $<24><06><0E>g<EFBFBD>
2026-03-09 16:10:29 +08:00
0<EFBFBD>X<> <13> <14><16> <02><02><02><03><04><12><12><12>*<2A>,A<>B<><1A><16>%<25><16>%<25> <13><02><02><02> <16>:<3A><<3C><<3C><08>19<31><08><18>0B<30>0B<30><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>('<27>('<27>-<2D>('<27><14>('<27><12>('<27>('<27>('<27>('<27>T<05><1C><1C>i<EFBFBD><18><18> <09> <09><19><18> <09> <05><17><17><13><1C><1C><06><06><0E><1C><06><05><17><17><19><13><13>!<21>!<21><14><13>!<21><05><18><18>
<1A><<3C>V<EFBFBD>E\<5C><18>]<5D>]<5D>BI<42>'<27>&<26>/<2F>/<2F>?
<EFBFBD>?
<EFBFBD>:<3A>?
<EFBFBD><<3C>?
<EFBFBD>?
<EFBFBD>?
<EFBFBD>^<01>]<5D>?
<EFBFBD>B<05><18><18>-<2D> <0C><18>5<>5<>?F<>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>(<06>(<06><19>(<06> <0C>(<06>(<06>(<06>6<>5<>(<06>T<05><18><18>/<2F>%<25><18>0<>0<>FM<46>g<EFBFBD>f<EFBFBD>o<EFBFBD>o<EFBFBD> <06> <06>1<> <06>|<7C> <06> <06> <06>1<>0<> <06>D<05><17><17><1A>L<EFBFBD><17>1<>1<>=D<>W<EFBFBD>EU<45>=V<>=V<><18><18>l<EFBFBD><18><18><18>2<>1<><18><05><18><18>
<1A><<3C><18>8<>8<><C<>G<EFBFBD>F<EFBFBD>O<EFBFBD>O<EFBFBD>\<06>\<06><1E>\<06>\<5C>\<06>\<06>\<06>9<>8<>\<06>D19<31><08><18>0B<30>0B<30><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><10><10>-<2D><10><14><10>
<EFBFBD><10><10><10><10>$<05><17><17><1E><18><18><19>'<27>-<2D>(<28>(<28><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><06><06> <0F><06><14><06><06><06><19><18><06>.<05><17><17> (<28>)<29>)<29><1A>'<27>-<2D>(<28>(<28><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD>:<3A>:<3A> <10>:<3A> <0F>:<3A> <15>:<3A>:<3A>:<3A>*<2A>)<29>:<3A>"<05><18><18>
<1F> <20> <20><19>'<27>-<2D>(<28>(<28><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><06><06> <0F><06><14><06><06><06>!<21> <20><06>(<05><17><17> <1E><1F><1F><19>'<27>-<2D>(<28>(<28><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><06><06> <0F><06><14><06><06><06> <20><1F><06>.<05><1A><1A> +<2B>,<2C>,<2C><1A>'<27>-<2D>(<28>(<28><1E>w<EFBFBD>v<EFBFBD><EFBFBD><EFBFBD><1D><1D> <10><1D> <0F><1D> <15><1D><1D><1D>-<2D>,<2C><1D><1D>rI