Ë
    LµCj¼
  ã            	       óè   — d Z ddlmZ ddlmZmZmZ ddlmZ ddl	m
Z
 ddlmZ ddlmZ ddlmZ dd	lmZ dd
lmZ  e«       Ze G d„ d«      «       Z ee«       edd¬«      fdede
dedz  defd„Zy)u7  
Dual-mode authentication for endpoints reachable both by the SaaS
customer dashboard (JWT-authenticated) and by service/integration
callers (API-key-authenticated).

/analyze is the main consumer of this â€” a logged-in customer using the
dashboard hits it with a Bearer token, while a server-to-server
integration the client sets up later can keep using an API key. Either
is accepted; the resulting AuthContext tells the route handler which
one was used and, if a user, who they are â€” so the analysis can be
correctly attributed and saved against their account.
é    )Ú	dataclass)ÚDependsÚHeaderÚRequest)Úselect)ÚAsyncSession)Údecode_token)Úget_settings)ÚAuthenticationError)ÚUser)Úget_db_sessionc                   ó\   — e Zd ZU eed<   dZedz  ed<   dZedz  ed<   ededz  fd„«       Z	y)ÚAuthContextÚ	auth_typeNÚuserÚapi_keyÚreturnc                 óJ   — | j                   r| j                   j                  S d S )N)r   Úid)Úselfs    ú?C:\Crop_Prediction\Backend\crop-ai-system\app\core\dual_auth.pyÚuser_idzAuthContext.user_id#   s   € à#Ÿyšyˆt�y‰y�|‰|Ð2¨dÐ2ó    )
Ú__name__Ú
__module__Ú__qualname__ÚstrÚ__annotations__r   r   r   Úpropertyr   © r   r   r   r      s@   … àƒNØ€Dˆ$�‰+ÓØ€GˆS�4‰ZÓàð3˜˜t™ò 3ó ñ3r   r   Nz	X-API-Key)ÚaliasÚrequestÚdbÚ	x_api_keyr   c              ƒ   óª  K  — | j                   j                  d«      }|rË|j                  «       j                  d«      r¬|dd  }t	        |d¬«      }|j                  d«      }|j                  t        t        «      j                  t        j                  |k(  «      «      ƒ d {  –—† }|j                  «       }|€t        d¬«      ‚|j                  st        d	¬«      ‚t        d
|¬«      S |rXt        j                  }	|	s)t        j                   rt        d¬«      ‚t        d|¬«      S ||	vrt        d¬«      ‚t        d|¬«      S t        d¬«      ‚7 Œ­­w)NÚAuthorizationzbearer é   Úaccess)Úexpected_typeÚsubzUser account no longer exists)Úmessagez3This account has been deactivated. Contact support.r   )r   r   z'Service misconfigured. Contact support.r   )r   r   zInvalid or missing API keyzuAuthentication required. Provide either a Bearer token (logged-in user) or an X-API-Key header (service integration).)ÚheadersÚgetÚlowerÚ
startswithr	   Úexecuter   r   Úwherer   Úscalar_one_or_noner   Ú	is_activer   ÚsettingsÚvalid_api_keys_listÚis_production)
r"   r#   r$   Úauth_headerÚtokenÚpayloadr   Úresultr   Ú
valid_keyss
             r   Úget_auth_contextr<   (   s/  è ø€ ð
 —/‘/×%Ñ% oÓ6€Ká�{×(Ñ(Ó*×5Ñ5°iÔ@Ø˜A˜B�ˆÜ˜u°HÔ=ˆØ—+‘+˜eÓ$ˆà—z‘z¤&¬£,×"4Ñ"4´T·W±WÀÑ5GÓ"HÓI×IˆØ×(Ñ(Ó*ˆàˆ<Ü%Ð.MÔNÐNØ�~Š~Ü%Ð.cÔdÐdä V°$Ô7Ð7áÜ×1Ñ1ˆ
ÙÜ×%Ò%Ü)Ð2[Ô\Ð\Ü¨¸IÔFÐFà˜JÑ&Ü%Ð.JÔKÐKÜ Y¸	ÔBÐBä
ð@ôð ð+ Jús   ‚B!EÂ#EÂ$B.E)Ú__doc__Údataclassesr   Úfastapir   r   r   Ú
sqlalchemyr   Úsqlalchemy.ext.asyncior   Úapp.core.auth_tokensr	   Úapp.core.configr
   Úapp.core.exceptionsr   Úapp.db.modelsr   Úapp.db.sessionr   r4   r   r   r<   r    r   r   ú<module>rG      s‹   ðñõ "ç ,Ñ ,Ý Ý /å -Ý (Ý 3Ý Ý )á‹>€ð ÷3ð 3ó ð3ñ ˜~Ó.Ù" 4¨{Ô;ñ$Øð$àð$ð �T‰zð$ð ô	$r   