§
    g‰¬j�3  ã            	      óØ  — d Z ddlmZ ddlZddlZddlmZ ddlmZm	Z	m
Z
mZmZmZmZ ddlmZ ddlmZmZ ddlmZmZ dd	lmZ dd
lmZ  ej        d¦  «        Z eddg¬¦  «        Z e¦   «         Z ed¬¦  «        Z ee¦  «        fdId„Z dJd„Z! G d„ de¦  «        Z" G d„ de¦  «        Z# G d„ d e¦  «        Z$ G d!„ d"e¦  «        Z%e &                    d#¦  «        dKd'„¦   «         Z'e &                    d(¦  «        dLd*„¦   «         Z(e &                    d+¦  «         e	e ¦  «        fdMd-„¦   «         Z)e *                    d.¦  «        dNdOd2„¦   «         Z+e *                    d3¦  «        dNdPd4„¦   «         Z,e *                    d5¦  «         ed6d7¬8¦  «        dfdQd<„¦   «         Z-e *                    d=¦  «         e	e ¦  «        fdRd>„¦   «         Z.e *                    d? e	 e!d@dAg¦  «        ¦  «        g¬B¦  «        dSdD„¦   «         Z/e &                    d? e	 e!d@dAg¦  «        ¦  «        g¬B¦  «        dTdE„¦   «         Z0e 1                    dF e	 e!d@g¦  «        ¦  «        g¬B¦  «        dUdH„¦   «         Z2dS )VzDAuthentication & User Account API router for Google OAuth 2.0 & JWT.é    )ÚannotationsN)ÚAny)Ú	APIRouterÚDependsÚHTTPExceptionÚQueryÚRequestÚResponseÚSecurity)Újsonable_encoder)ÚHTMLResponseÚRedirectResponse)ÚHTTPAuthorizationCredentialsÚ
HTTPBearer)Ú	BaseModel)ÚAuthServicezdscons.auth.routerz/v1/authzAuthentication & User Accounts)ÚprefixÚtagsF)Ú
auto_errorÚrequestr	   Úcredentialsú#HTTPAuthorizationCredentials | NoneÚreturnúdict[str, Any]c                ó¤  — d}|r|j         r|j         }nÓ| j                             d¦  «        r| j                             d¦  «        }nž| j                             d¦  «        r| j                             d¦  «        }ni| j                             d¦  «        r| j                             d¦  «        }n4| j                             d¦  «        r| j                             d¦  «        }|st	          dd¬¦  «        ‚|d	k    r8t          t          j        d
d¦  «        dk    rt	          dd¬¦  «        ‚ddddddœS t                               |¦  «        S )zCDependency checking Bearer JWT from header, query param, or cookie.NÚtokenÚdscons_jwt_tokenÚdscons_tokenÚaccess_tokené‘  uR   YÃªu cáº§u xÃ¡c thá»±c. Vui lÃ²ng Ä‘Äƒng nháº­p hoáº·c truyá»�n Token xÃ¡c thá»±c.©Ústatus_codeÚdetailzdev-test-tokenÚapp_envÚdevelopmentÚ
productionuO   MÃ£ xÃ¡c thá»±c khÃ´ng há»£p lá»‡ trÃªn mÃ´i trÆ°á»�ng váº­n hÃ nh thá»±c táº¿.zusr-admin-01zadmin@dscons.vnÚ
superadminu   Ban GiÃ¡m Ä�á»‘c DSCons)ÚsubÚuser_idÚemailÚroleÚ	full_name)	r   Úquery_paramsÚgetÚcookiesr   ÚgetattrÚauth_serviceÚsettingsÚdecode_jwt_token)r   r   r   s      ú8C:\Projects\DSCons\app\modules\auth\presentation\auth.pyÚget_current_userr5   "   sƒ  € ð
 €EØð 	4�{Ô.ð 	4ØÔ'ˆˆØ	Ô	×	!Ò	! 'Ñ	*Ô	*ð 4ØÔ$×(Ò(¨Ñ1Ô1ˆˆØ	Œ×	Ò	Ð/Ñ	0Ô	0ð 4Ø”×#Ò#Ð$6Ñ7Ô7ˆˆØ	Œ×	Ò	˜^Ñ	,Ô	,ð 4Ø”×#Ò# NÑ3Ô3ˆˆØ	Œ×	Ò	˜^Ñ	,Ô	,ð 4Ø”×#Ò# NÑ3Ô3ˆàð 
ÝØØgð
ñ 
ô 
ð 	
ð Ð Ò Ð Ý•<Ô(¨)°]ÑCÔCÀ|ÒSÐSÝØØhðñ ô ð ð
 "Ø%Ø&Ø Ø2ð
ð 
ð 	
õ ×(Ò(¨Ñ/Ô/Ð/ó    Úallowed_rolesú	list[str]c                ó<   ‡ — t          t          ¦  «        fdˆ fd„}|S )z%Role-based access control dependency.Úcurrent_userr   r   c                óv   •— |                       dd¦  «        }|‰vr|dk    rt          dd‰› d|› �¬¦  «        ‚| S )Nr+   Úviewerr'   é“  uN   TÃ i khoáº£n khÃ´ng Ä‘á»§ quyá»�n háº¡n. YÃªu cáº§u má»™t trong cÃ¡c quyá»�n: u   , quyá»�n hiá»‡n táº¡i: r!   )r.   r   )r:   Ú	user_roler7   s     €r4   Úrole_checkerz"require_role.<locals>.role_checkerN   sy   ø€ ð !×$Ò$ V¨XÑ6Ô6ˆ	Ø˜MÐ)Ð)¨i¸<Ò.GÐ.GÝØð [Ðhuð  [ð  [ð  PYð  [ð  [ðñ ô ð ð Ðr6   ©r:   r   r   r   )r   r5   )r7   r?   s   ` r4   Úrequire_rolerA   K   s<   ø€ õ (/Õ/?Ñ'@Ô'@ð	ð 	ð 	ð 	ð 	ð 	ð 	ð Ðr6   c                  ó2   — e Zd ZU ded<   ded<   dZded<   dS )ÚEmailLoginRequestÚstrr*   ÚpasswordNú
str | Noner,   )Ú__name__Ú
__module__Ú__qualname__Ú__annotations__r,   © r6   r4   rC   rC   _   s5   € € € € € € Ø€J€J�JØ€M€M�MØ €IÐ Ð Ð Ñ Ð Ð r6   rC   c                  óN   — e Zd ZU ded<   ded<   dZded<   dZded<   dZded	<   dS )
ÚCreateUserRequestrD   r*   rE   NrF   r,   r<   r+   Úlinked_employee_id)rG   rH   rI   rJ   r,   r+   rN   rK   r6   r4   rM   rM   e   sX   € € € € € € Ø€J€J�JØ€M€M�MØ €IÐ Ð Ð Ñ Ø€DÐÐÐÑØ%)ÐÐ)Ð)Ð)Ñ)Ð)Ð)r6   rM   c                  ó$   — e Zd ZU ded<   ded<   dS )ÚChangePasswordRequestrD   Úold_passwordÚnew_passwordN©rG   rH   rI   rJ   rK   r6   r4   rP   rP   m   s*   € € € € € € ØÐÐÑØÐÐÑÐÐr6   rP   c                  ó   — e Zd ZU ded<   dS )ÚUpdateUserRoleRequestrD   r+   NrS   rK   r6   r4   rU   rU   r   s   € € € € € € Ø€I€I�I€I€Ir6   rU   z/loginÚreqÚresponser
   c           	     óÄ   — t                                | j        | j        | j        ¬¦  «        }|                     d¦  «        }|r|                     d|ddddd¬	¦  «         |S )
uW   Ä�Äƒng nháº­p báº£o máº­t báº±ng email vÃ  máº­t kháº©u vá»›i HttpOnly Cookie an toÃ n.)r*   rE   r,   r   r   TÚlaxFé€:	 ú/©ÚkeyÚvalueÚhttponlyÚsamesiteÚsecureÚmax_ageÚpath)r1   Úauthenticate_email_userr*   rE   r,   r.   Ú
set_cookie)rV   rW   Úresr   s       r4   Úemail_loginrg   y   s�   € õ ×
.Ò
.ØŒiØ”Ø”-ð /ñ ô €Cð
 �GŠG�NÑ#Ô#€EØð 	
Ø×ÒØ"ØØØØØØð 	ñ 	
ô 	
ð 	
ð €Jr6   z/logoutúdict[str, str]c                ó–   — |                       dd¬¦  «         |                       dd¬¦  «         |                       dd¬¦  «         dddœS )	u1   Ä�Äƒng xuáº¥t vÃ  xÃ³a phiÃªn cookie xÃ¡c thá»±c.r   r[   )r]   rc   r   r   Úsuccessu0   Ä�Ã£ Ä‘Äƒng xuáº¥t an toÃ n khá»�i há»‡ thá»‘ng.)ÚstatusÚmessage)Údelete_cookie)rW   s    r4   Úlogoutrn   �   s_   € ð ×ÒÐ1¸ÐÑ<Ô<Ð<Ø×Ò˜~°CÐÑ8Ô8Ð8Ø×Ò˜~°CÐÑ8Ô8Ð8ØÐ,^Ð_Ð_Ð_r6   z/change-passwordr:   c                óÊ   — |                      d¦  «        p|                      d¦  «        }|st          dd¬¦  «        ‚t                               || j        | j        ¬¦  «        S )u>   Thay Ä‘á»•i máº­t kháº©u tÃ i khoáº£n ngÆ°á»�i dÃ¹ng an toÃ n.r)   r(   r    u7   KhÃ´ng xÃ¡c Ä‘á»‹nh Ä‘Æ°á»£c danh tÃ­nh ngÆ°á»�i dÃ¹ng.r!   )r)   rQ   rR   )r.   r   r1   Úchange_user_passwordrQ   rR   )rV   r:   r)   s      r4   Úchange_passwordrq   ˜   s}   € ð
 ×Ò˜yÑ)Ô)ÐD¨\×-=Ò-=¸eÑ-DÔ-D€GØð 
ÝØÐ$]ð
ñ 
ô 
ð 	
õ ×,Ò,ØØÔ%ØÔ%ð -ñ ô ð r6   z/google/loginÚredirect_urirF   r   c                óZ   — t                                | ¬¦  «        }t          |d¬¦  «        S )uP   Chuyá»ƒn hÆ°á»›ng trá»±c tiáº¿p tá»›i mÃ n hÃ¬nh Ä‘Äƒng nháº­p Google OAuth 2.0.©rr   i3  )Úurlr"   )r1   Úget_google_auth_urlr   )rr   Ú	login_urls     r4   Úredirect_to_google_loginrx   ©   s-   € õ ×0Ò0¸lÐ0ÑKÔK€IÝ 	°sÐ;Ñ;Ô;Ð;r6   z/google/login-urlc                ó<   — dt                                | ¬¦  «        iS )ub   Láº¥y Ä‘Æ°á»�ng dáº«n URL chuyá»ƒn hÆ°á»›ng ngÆ°á»�i dÃ¹ng Ä‘áº¿n mÃ n hÃ¬nh Ä‘Äƒng nháº­p Google.rw   rt   )r1   rv   rt   s    r4   Úget_google_login_urlrz   °   s    € ð �×9Ò9À|Ð9ÑTÔTÐUÐUr6   z/google/callback.zAuthorization code from Google)ÚdescriptionÚcoderD   r   c              ƒ  óˆ  K  — 	 t                                | |¬¦  «        ƒ d{V —†}n># t          $ r1}|j        dk    rt	          d|j        › d�d¬¦  «        cY d}~S |‚d}~ww xY wt          j        t          |d         ¦  «        d¬	¦  «        }t	          d
|d          	                    dd¦  «        › d|d         d         › d|d         d         › d|d         d          
                    ¦   «         › d|d         dd…         › d|d         › d|d         › d|› d�¦  «        }|                     d|d         ddddd¬¦  «         |S ) ua   Callback endpoint tiáº¿p nháº­n authorization code tá»« Google sau khi ngÆ°á»�i dÃ¹ng Ä‘á»“ng Ã½.)r|   rr   Nr=   uÌ  
                <!DOCTYPE html>
                <html lang="vi">
                <head>
                    <meta charset="UTF-8">
                    <title>Tá»« chá»‘i truy cáº­p - DSCons ERP</title>
                    <style>
                        body { font-family: 'Segoe UI', -apple-system, BlinkMacSystemFont, sans-serif; background: #0b0f19; color: #f8fafc; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
                        .card { background: #131b2e; padding: 2.5rem 2rem; border-radius: 14px; box-shadow: 0 20px 40px rgba(0,0,0,0.6); text-align: center; max-width: 480px; border: 1px solid #dc2626; }
                        .icon { font-size: 3rem; margin-bottom: 1rem; color: #ef4444; }
                        h2 { color: #f87171; margin-top: 0; font-size: 1.4rem; }
                        .desc { color: #cbd5e1; font-size: 0.95rem; line-height: 1.5; margin: 1rem 0 1.5rem 0; background: rgba(239, 68, 68, 0.1); padding: 12px 16px; border-radius: 8px; border-left: 3px solid #ef4444; text-align: left; }
                        .hint { color: #94a3b8; font-size: 0.85rem; margin-bottom: 1.5rem; }
                        .btn { background: #ef4444; color: white; border: none; padding: 10px 24px; border-radius: 8px; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; transition: background 0.2s; }
                        .btn:hover { background: #dc2626; }
                    </style>
                </head>
                <body>
                    <div class="card">
                        <div class="icon">ðŸ›¡ï¸�â›”</div>
                        <h2>TRUY Cáº¬P Bá»Š Tá»ª CHá»�I (403)</h2>
                        <div class="desc">u¦  </div>
                        <p class="hint">Há»‡ thá»‘ng ERP Ä�á»‹nh SÆ¡n Ã¡p dá»¥ng chÃ­nh sÃ¡ch Zero-Trust. Má»�i tÃ i khoáº£n truy cáº­p báº¯t buá»™c pháº£i do Ban GiÃ¡m Ä�á»‘c hoáº·c Quáº£n trá»‹ viÃªn khá»Ÿi táº¡o trÆ°á»›c.</p>
                        <a href="/v1/erp/login" class="btn">Quay láº¡i Trang Ä�Äƒng Nháº­p</a>
                    </div>
                </body>
                </html>
                )r"   ÚuserF)Úensure_asciiuã  
    <!DOCTYPE html>
    <html lang="vi">
    <head>
        <meta charset="UTF-8">
        <title>Ä�Äƒng nháº­p thÃ nh cÃ´ng - DSCons ERP</title>
        <style>
            body { font-family: 'Segoe UI', sans-serif; background: #0f172a; color: #f8fafc; display: flex; align-items: center; justify-content: center; height: 100vh; margin: 0; }
            .card { background: #1e293b; padding: 2rem; border-radius: 12px; box-shadow: 0 10px 25px rgba(0,0,0,0.5); text-align: center; max-width: 450px; border: 1px solid #334155; }
            .btn { background: #0284c7; color: white; border: none; padding: 10px 20px; border-radius: 8px; font-weight: 600; cursor: pointer; text-decoration: none; display: inline-block; margin-top: 15px; }
            .btn:hover { background: #0369a1; }
            .avatar { width: 80px; height: 80px; border-radius: 50%; border: 3px solid #0284c7; margin-bottom: 1rem; }
        </style>
    </head>
    <body>
        <div class="card">
            <img src="Ú
avatar_urlÚ u:   " class="avatar" alt="Avatar">
            <h2>Xin chÃ o, r,   z5!</h2>
            <p style="color: #94a3b8;">Email: r*   uQ   </p>
            <p><strong>Vai trÃ² ERP:</strong> <span style="color: #38bdf8;">r+   ze</span></p>
            <p style="font-size: 0.85rem; color: #64748b; word-break: break-all;">Token: r   é   u¯   ...</p>
            <a href="/dashboard" class="btn">VÃ o Báº£ng Ä�iá»�u Khiá»ƒn ERP</a>
        </div>
        <script>
            localStorage.setItem('dscons_jwt_token', 'z6');
            localStorage.setItem('dscons_token', 'zC');
            localStorage.setItem('dscons_user', JSON.stringify(z{));
            setTimeout(() => window.location.href = '/dashboard', 1200);
        </script>
    </body>
    </html>
    r   TrY   rZ   r[   r\   )r1   Úexchange_google_coder   r"   r   r#   ÚjsonÚdumpsr   r.   Úupperre   )r|   rr   ÚresultÚexcÚ	user_jsonÚresps         r4   Úgoogle_auth_callbackr‹   ¶   s#  è è € ð%Ý#×8Ò8Ø Lð 9ñ 
ô 
ð 
ð 
ð 
ð 
ð 
ð 
ˆˆøõ ð !ð !ð !ØŒ?˜cÒ!Ð!Ýðð* ,/¬:ð+ð ð ð8  ð;ñ ô ð ð ð ð ð ð ð> ˆ	øøøøðC!øøøõF ”
Õ+¨F°6¬NÑ;Ô;È%ÐPÑPÔP€IÝð ð  ˜f”~×)Ò)¨,¸Ñ;Ô;ð!ð ð" # 6œN¨;Ô7ð#ð ð$ 06°f¬~¸gÔ/Fð%ð ð& NTÐTZÌ^Ð\bÔMc×MiÒMiÑMkÔMkð'ð ð( [aÐaoÔZpÐqtÐrtÐqtÔZuð)ð ð0 8>¸nÔ7Mð1ð ð2 4:¸.Ô3Ið3ð ð4 AJð5ð ð ñ 	ô 	€Dð@ 	‡O‚OØØ�^Ô$ØØØØØð ñ ô ð ð €Ks    „"' §
A"±$AÁA"ÁAÁA"z/mec                ó   — | S )uO   Láº¥y thÃ´ng tin tÃ i khoáº£n vÃ  quyá»�n háº¡n hiá»‡n táº¡i tá»« Bearer Token.rK   )r:   s    r4   Úget_current_user_profiler�     s
   € ð
 Ðr6   z/usersr'   Údirector)Údependenciesúlist[dict[str, Any]]c                 ó4   — t                                ¦   «         S )um   Liá»‡t kÃª toÃ n bá»™ tÃ i khoáº£n ngÆ°á»�i dÃ¹ng vÃ  vai trÃ² trong há»‡ thá»‘ng (Chá»‰ Admin/GiÃ¡m Ä‘á»‘c).)r1   Ú
list_usersrK   r6   r4   r’   r’     s   € õ ×"Ò"Ñ$Ô$Ð$r6   c                ór   — t                                | j        | j        | j        | j        | j        ¬¦  «        S )uZ   Táº¡o tÃ i khoáº£n ngÆ°á»�i dÃ¹ng má»›i cÃ³ phÃ¢n quyá»�n (Chá»‰ SuperAdmin/GiÃ¡m Ä‘á»‘c).)r*   rE   r,   r+   rN   )r1   Úcreate_user_accountr*   rE   r,   r+   rN   )rV   s    r4   Úcreate_userr•   !  s;   € õ ×+Ò+ØŒiØ”Ø”-ØŒXØÔ1ð ,ñ ô ð r6   z/users/{user_id}/roler)   c                óD   — t                                | |j        ¬¦  «        S )u=   PhÃ¢n quyá»�n vai trÃ² cho ngÆ°á»�i dÃ¹ng (Chá»‰ SuperAdmin).)r)   Únew_role)r1   Úupdate_user_roler+   )r)   rV   s     r4   r˜   r˜   -  s   € õ
 ×(Ò(°À3Ä8Ð(ÑLÔLÐLr6   )r   r	   r   r   r   r   )r7   r8   )rV   rC   rW   r
   r   r   )rW   r
   r   rh   )rV   rP   r:   r   r   r   )N)rr   rF   r   r   )rr   rF   r   rh   )r|   rD   rr   rF   r   r   r@   )r   r�   )rV   rM   r   r   )r)   rD   rV   rU   r   r   )3Ú__doc__Ú
__future__r   r„   ÚloggingÚtypingr   Úfastapir   r   r   r   r	   r
   r   Úfastapi.encodersr   Úfastapi.responsesr   r   Úfastapi.securityr   r   Úpydanticr   Ú)app.modules.auth.application.auth_servicer   Ú	getLoggerÚloggerÚrouterr1   Úsecurityr5   rA   rC   rM   rP   rU   Úpostrg   rn   rq   r.   rx   rz   r‹   r�   r’   r•   Úputr˜   rK   r6   r4   ú<module>r©      sÉ  ðØ JÐ Jà "Ð "Ð "Ð "Ð "Ð "à €€€Ø €€€Ø Ð Ð Ð Ð Ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð .Ð -Ð -Ð -Ð -Ð -Ø <Ð <Ð <Ð <Ð <Ð <Ð <Ð <Ø EÐ EÐ EÐ EÐ EÐ EÐ EÐ EØ Ð Ð Ð Ð Ð à AÐ AÐ AÐ AÐ AÐ Aà	ˆÔ	Ð/Ñ	0Ô	0€Ø	ˆ˜*Ð,LÐ+MÐ	NÑ	NÔ	N€Øˆ{‰}Œ}€Øˆ: Ð'Ñ'Ô'€ð 8@°xÀÑ7IÔ7Ið&0ð &0ð &0ð &0ð &0ðRð ð ð ð(!ð !ð !ð !ð !˜	ñ !ô !ð !ð*ð *ð *ð *ð *˜	ñ *ô *ð *ðð ð ð ð ˜Iñ ô ð ð
ð ð ð ð ˜Iñ ô ð ð ‡‚ˆXÑÔðð ð ñ Ôðð* ‡‚ˆYÑÔð`ð `ð `ñ Ôð`ð ‡‚ÐÑ Ô à?F¸wÐGWÑ?XÔ?Xðð ð ð ñ !Ô ðð  ‡‚ˆOÑÔð<ð <ð <ð <ñ Ôð<ð ‡‚ÐÑ Ô ðVð Vð Vð Vñ !Ô ðVð
 ‡‚ÐÑÔà��cÐ'GÐHÑHÔHØ#ðVð Vð Vð Vñ  ÔðVðr ‡‚ˆEÑÔà#* 7Ð+;Ñ#<Ô#<ðð ð ð ñ Ôðð ‡‚ˆH G G¨L¨L¸,È
Ð9SÑ,TÔ,TÑ$UÔ$UÐ#V€ÑWÔWð%ð %ð %ñ XÔWð%ð
 ‡‚ˆX W W¨\¨\¸<ÈÐ:TÑ-UÔ-UÑ%VÔ%VÐ$W€ÑXÔXðð ð ñ YÔXðð ‡‚Ø¨7¨7°<°<ÀÀÑ3OÔ3OÑ+PÔ+PÐ*Qð ñ ô ðMð Mð Mñô ðMð Mð Mr6   