Ë
    «ïiè  ã                  ó¤   — d Z ddlmZ ddlmZmZmZ ddlmZmZ ddl	m
Z
 ddlmZ ddlmZ  ee«      Zdd„Zdd	„Zdd
„Zdd„Zdd„Zdd„Zdd„Zy)uv  
services/auth_service.py â€” Authentication & Access Key management
==================================================================
Backed by PostgreSQL (`participant` table). All DB I/O goes through
`services.participant_repo`.

JWT payload fields:
    sub   â†’ candidate_id   (participant.id / participant_id)
    name  â†’ candidate name
    stage â†’ current_stage
é    )Úannotations)ÚdatetimeÚ	timedeltaÚtimezone)ÚJWTErrorÚjwt)Úsettings)Úparticipant_repo)Ú
get_loggerc                óF  — t        j                  t        j                  «      t	        t
        j                  ¬«      z   }t        | «      |t        |«      t        |j                  «       «      dœ}t        j                  |t
        j                  t
        j                  ¬«      S )N)Úminutes)ÚsubÚnameÚstageÚexp)Ú	algorithm)r   Únowr   Úutcr   r	   ÚJWT_EXPIRE_MINUTESÚstrÚintÚ	timestampr   ÚencodeÚJWT_SECRET_KEYÚJWT_ALGORITHM)Úcandidate_idr   r   ÚexpireÚpayloads        úp/Users/priyanka/Documents/AI_Agent_Assessment/pepole_hub_candidate/people_hub_candidate/services/auth_service.pyÚcreate_tokenr       so   € Ü�\‰\œ(Ÿ,™,Ó'¬)¼H×<WÑ<WÔ*XÑX€Fä�\Ó"ØÜ�U“Ü�V×%Ñ%Ó'Ó(ñ	€Gô �:‰:�gœx×6Ñ6Ä(×BXÑBXÔYÐYó    c                óÆ   — 	 t        j                  | t        j                  t        j                  g¬«      S # t
        $ r }t        j                  d|«       Y d }~y d }~ww xY w)N)Ú
algorithmszJWT decode failed: %s)r   Údecoder	   r   r   r   ÚlogÚdebug)ÚtokenÚexcs     r   Údecode_tokenr)   &   sK   € ðÜ�z‰z˜%¤×!8Ñ!8Äh×F\ÑF\ÐE]Ô^Ð^øÜò Ü�	‰	Ð)¨3Ô/Üûðús   ‚47 ·	A Á AÁA c                óÈ  — | r| j                  «       st        j                  d«       yt        j                  d| j                  «       j                  «       «       	 t	        j
                  | «      }|sy	 t	        j                  |d   «       |S # t        $ r}t        j                  d|«       ‚ d}~ww xY w# t        $ r!}t        j                  d|«       Y d}~|S d}~ww xY w)z~
    Validate a candidate's access key against the participant table.
    Returns the normalized candidate dict, or None.
    u0   login attempt with empty access_key â€” rejectedNu   login attempt â†’ access_key=%sz)DB error during access_key validation: %sÚidz'touch_last_login failed (non-fatal): %s)
Ústripr%   ÚinfoÚupperr
   Úfind_by_access_keyÚ	ExceptionÚ	exceptionÚtouch_last_loginÚwarning)Úraw_keyÚ	candidater(   s      r   Úvalidate_access_keyr6   0   sÉ   € ñ
 ˜'Ÿ-™-œ/Ü�‰ÐCÔDØä‡H�HÐ.°·±³×0EÑ0EÓ0GÔHðÜ$×7Ñ7¸Ó@ˆ	ñ ØðDÜ×)Ñ)¨)°D©/Ô:ð Ðøô ò ä�‰ÐAÀ3ÔGØûðûô ò DÜ�‰Ð=¸s×CÐCàÐûðDús0   ÁB Á5B7 Â	B4ÂB/Â/B4Â7	C!Ã CÃC!c                ó,   — t        j                  | «      S )N)r
   Ú
find_by_id)r   s    r   Úget_candidater9   N   s   € Ü×&Ñ& |Ó4Ð4r!   c           
     ó  — ddl m} ddlm} |j	                  t
        j                  «      }dD ]Õ  }dD ]Î  }|j                  d«      j                  ||j	                  |«      |j	                  |«      ¬«      }	 |j                  d¬	«      5 }|j                  |t        |«      t        | «      f«       |j                  dkD  r9t        j                  d
| |«       t!        j"                  | «      cddd«       c c S 	 ddd«       ŒÐ Œ× t        j)                  d|| «       t!        j"                  | «      xs i }
|
rt        |«      |
d<   |
xs dS # 1 sw Y   ŒSxY w# t$        $ r#}	t        j'                  d|||	«       Y d}	~	�ŒLd}	~	ww xY w)a  
    Move a candidate to the next interview stage.
    Currently a best-effort UPDATE on the participant table; if the
    target column doesn't exist in the schema, we return the cached
    candidate dict with `current_stage` overridden so the rest of the
    flow keeps working.
    r   )Úsql)Údatabase)Úcurrent_stager   Ústage_noÚinterview_stage)r+   Úparticipant_idr   z6UPDATE {table} SET {stage} = %s WHERE {idc}::text = %s)Útabler   ÚidcF)Ú	dict_rowsu$   advance_stage â†’ id=%s new_stage=%dNz&advance_stage attempt %s/%s failed: %sz6advance_stage could not persist new_stage=%d for id=%sr=   )Úpsycopg2r;   Úutilsr<   Ú
Identifierr	   ÚDB_TABLE_PARTICIPANTÚSQLÚformatÚ
get_cursorÚexecuter   r   Úrowcountr%   r-   r
   r8   r0   r&   r3   )r   Ú	new_stageÚ_sqlÚ_dbrA   Ú	stage_colÚid_colÚqueryÚcurr(   Úcands              r   Úadvance_stagerU   R   sT  € õ %Ý%à�O‰OœH×9Ñ9Ó:€EÛNˆ	Û>ˆFØ—H‘HØHóç‰fØØ—o‘o iÓ0Ø—O‘O FÓ+ð ó ð ðØ—^‘^¨e�^Ô4¸Ø—K‘K ¬¨I«¼¸LÓ8IÐ'JÔKØ—|‘| aÒ'ÜŸ™Ð!GÈÐW`ÔaÜ/×:Ñ:¸<ÓH÷	 5Õ4à'÷ 5øñ ?ð Oô& ‡K�KÐHÈ)ÐUaÔbÜ×&Ñ& |Ó4Ò:¸€DÙÜ # I£ˆˆ_ÑØŠ<�4Ð÷ 5Ð4ûô
 ò Ü—	‘	ÐBÀIÈvÐWZÔ[Ýûðús7   Á8EÂ
A!EÃ+	EÃ:EÅEÅEÅ	FÅ!E?Å?Fc                óT   — t         j                  j                  t        | «      d«      S )Nz/people_hub_assessment)r	   ÚSTAGE_ROUTESÚgetr   ©r   s    r   Úget_redirect_urlrZ   z   s    € Ü× Ñ ×$Ñ$¤S¨£ZÐ1IÓJÐJr!   c                óT   — t         j                  j                  t        | «      d«      S )NÚ
Assessment)r	   ÚSTAGE_NAMESrX   r   rY   s    r   Úget_stage_namer^   ~   s   € Ü×Ñ×#Ñ#¤C¨£J°Ó=Ð=r!   N)r   r   r   r   r   r   Úreturnr   )r'   r   r_   údict | None)r4   r   r_   r`   )r   r   r_   r`   )r   r   rM   r   r_   r`   )r   r   r_   r   )Ú__doc__Ú
__future__r   r   r   r   Újoser   r   Úconfigr	   Úservicesr
   Úutils.loggerr   Ú__name__r%   r    r)   r6   r9   rU   rZ   r^   © r!   r   Ú<module>ri      sQ   ðñ
õ #ç 2Ñ 2ç å Ý %Ý #á�Ó€ó
Zóóó<5ó#óPKô>r!   