o
    i>                     @   s  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
 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 d dlmZ d dlmZ d dlmZ d dlmZ ee Z!deddfddZ"deddfddZ#dede$de%ddfddZ&dej'ddddfdede(dee% d e$d!ee$ d"ee$ d#ee$ dee dee fd$d%Z)dddddddd&ej'df
ded'ee$ dee% d!ee$ d"ee$ d#ee$ d(ee$ d)ee$ d*ee$ d+e(d e$dee ddfd,d-Z*ddej'dddfded'ee$ d.ee( dee% d e$d!ee$ d"ee$ d#ee$ ddfd/d0Z+dej'fded'ee$ de(d!ee$ d e$ddfd1d2Z,ded3e$de%e$ef ddfd4d5Z-d?ded6e$d*ee$ de(fd7d8Z.d@d9d:Z/dAd6e$d<e$d*ee$ ddfd=d>Z0dS )B    )Any)Optional)Span)_asm_request_context)call_waf_callback)get_blocked)in_asm_context)APPSEC)LOGIN_EVENTS_MODE)WAF_ACTIONS)_hash_user_idN)set_user)user)core)BlockingException)
get_logger)configspanreturnc                 C   sV   ddl m} ddlm} | tj | |d|j  | tj	d d| j
jtj	< d S )Nr   SAMPLING_DECISION_TRACE_TAG_KEYSamplingMechanism-%d02)ddtrace.internal.constantsr   ddtrace.internal.samplingr   set_tag	constantsMANUAL_KEEP_KEY_set_tag_strr	   PROPAGATION_HEADERcontext_metar   r   r    r%   O/home/ubuntu/.local/lib/python3.10/site-packages/ddtrace/appsec/_trace_utils.py_asm_manual_keep   s   r'   c                 C   s:   ddl m} ddlm} | tj | |d|j  d S )Nr   r   r   r   )	r   r   r   r   r   r   r   r    AI_GUARDr$   r%   r%   r&   _aiguard_manual_keep&   s   r)   
entry_spanprefixmetadatac           
      C   s   d}|d u rd S ||dfg}|rs|  \}}}t|tr9||k r8t|D ]\}}|| d| ||d f q$n6t|tr[||k rZ| D ]\}	}|| d|	 ||d f qFnt|trf|rddnd}| | t	| |sd S d S )N      .truefalse)
pop
isinstancelist	enumerateappenddictitemsboolr    str)
r*   r+   r,   	MAX_DEPTHstackdatalevelivkr%   r%   r&   _handle_metadata/   s(   
 
 
rB   tracersuccesslogin_events_modeloginnameemailc                 C   sX  |d u rt  }|st  }r|j}|r|rdnd}	dtj|	f }
|r,|tjd n|tj	d |t
jt
jfv rG|d|
 d tj}n|}|rNtjntj}||| dtj|	f }|d urht||| |r|tj d|	 d| |t
jkr|tj| |d|
 | |r|d	|
 | |r|d
|
 | t| |S td d S )NrD   failurez%s.%sr0   %s.sdkr/   z
.usr.loginz%s.loginz%s.emailz%s.usernamezNo root span in the current execution. Skipping track_user_success_login tags. See https://docs.datadoghq.com/security_platform/application_security/setup_and_configure/?tab=set_user&code-lang=python for more information.)r   get_entry_spanr   get_span_service_entry_spanr	   USER_LOGIN_EVENT_PREFIXr    USER_LOGIN_EVENT_SUCCESS_TRACKUSER_LOGIN_EVENT_FAILURE_TRACKr
   SDKAUTO
asm_config_user_event_modeAUTO_LOGIN_EVENTS_SUCCESS_MODEAUTO_LOGIN_EVENTS_FAILURE_MODEUSER_LOGIN_EVENT_PREFIX_PUBLICrB   USER_LOGIN_USERNAMEr'   logwarning)rC   rD   r,   rE   rF   rG   rH   r   current_spansuccess_str
tag_prefixreported_modemode_tagtag_metadata_prefixr%   r%   r&   _track_user_login_commonD   sD   

ra   Fuser_idscoperole
session_id	propagatec                 C   sZ  |
t jkr|
ntj}|t jkrdS |}|}|t jkr*d }}|du r$dntt|}tdd||
||||}|s9dS |t jkrGt	|trGt|}|
tj| |rk|
t jkr_|
tjt| n|
tj dt| td|ppd||||||	|dd
 t r|rt|nd||d}|r||d< t|dd	}|rtd
d |jD rtt dS dS dS )ax  
    Add a new login success tracking event. The parameters after metadata (name, email,
    scope, role, session_id, propagate) will be passed to the `set_user` function that will be called
    by this one, see:
    https://docs.datadoghq.com/logs/log_configuration/attributes_naming_convention/#user-related-attributes
    https://docs.datadoghq.com/security_platform/application_security/setup_and_configure/?tab=set_tag&code-lang=python

    :param tracer: tracer instance to use
    :param user_id: a string with the UserId
    :param metadata: a dictionary with additional metadata information to be stored with the event
    NTz.success.usr.id F)	may_block)REQUEST_USER_IDREQUEST_USERNAMELOGIN_SUCCESSREQUEST_SESSION_IDcustom_data
force_sentc                 s        | ]}|t jt jfv V  qd S Nr   BLOCK_ACTIONREDIRECT_ACTION.0actionr%   r%   r&   	<genexpr>       z1track_user_login_success_event.<locals>.<genexpr>)r
   rR   rS   rT   DISABLEDANONr   r:   ra   r3   r    r	   !AUTO_LOGIN_EVENTS_COLLECTION_MODErQ   USER_LOGIN_USERIDrW   r   r   r   anyactionsr   r   )rC   rb   r,   rF   rG   rH   rc   rd   re   rf   rE   r   	real_modeinitial_logininitial_user_idrn   resr%   r%   r&   track_user_login_success_event   sD   


 
r   existsc                 C   s  |t jkr|ntj}|t jkrdS |t jkrt|trt|}t	dd|||}	|	s+dS |durA|r3dnd}
|	
dtjtjf |
 |rm|t jkrQt|trQt|}|t jkr_|	
tjt| |	
dtjtjf t| |	
tj| |t jt jfv r|r|	
dtj | |r|	
dtj | |r|	
dtj | t rd	di}|r||d
< t|d}|rtdd |jD rtt dS dS dS )aZ  
    Add a new login failure tracking event.
    :param tracer: tracer instance to use
    :param user_id: a string with the UserId if exists=True or the username if not
    :param exists: a boolean indicating if the user exists in the system
    :param metadata: a dictionary with additional metadata information to be stored with the event
    NFr0   r1   z%s.failure.%sz%s.failure.loginz%s.failure.emailz%s.failure.usernameLOGIN_FAILURErj   )rn   c                 s   rp   rq   rr   ru   r%   r%   r&   rx      ry   z1track_user_login_failure_event.<locals>.<genexpr>)r
   rR   rS   rT   rz   r{   r3   r:   r   ra   r    r	   rW   r   EXISTSrQ   r}   IDr|   r   r   r~   r   r   r   )rC   rb   r   r,   rE   rF   rG   rH   r   r   
exists_strrn   r   r%   r%   r&   track_user_login_failure_event   sD   



r   c                 C   s  t  }|r|r
dnd}|tj| |r>|tjkr#t|tr#t	|}|t
jt| |tjt| |tjt| |r`|tjkrNt|trNt	|}|tjt| |tjt| t| |tjkrt|dtj d d S |dtj t| d S td d S )Nr0   r1   rJ   z%s.auto.modezNo root span in the current execution. Skipping track_user_signup tags. See https://docs.datadoghq.com/security_platform/application_security/setup_and_configure/?tab=set_user&code-lang=python for more information.)r   rK   r    r	   USER_SIGNUP_EVENTr
   r{   r3   r:   r   r   r   USER_SIGNUP_EVENT_USERIDr}   USER_SIGNUP_EVENT_USERNAMErX   r'   rQ   USER_SIGNUP_EVENT_MODErY   rZ   )rC   rb   rD   rF   rE   r   r\   r%   r%   r&   track_user_signup_event   s0   
r   
event_namec                 C   s|   |s	t d dS |st d dS t }|st d dS |dtj|f d |r8t|tj d| | t| dS )z
    Add a new custom tracking event.

    :param tracer: tracer instance to use
    :param event_name: the name of the custom event
    :param metadata: a dictionary with additional metadata information to be stored with the event
    zDEmpty event name given to track_custom_event. Skipping setting tags.NzBEmpty metadata given to track_custom_event. Skipping setting tags.zNo root span in the current execution. Skipping track_custom_event tags. See https://docs.datadoghq.com/security_platform/application_security/setup_and_configure/?tab=set_user&code-lang=python for more information.z%s.%s.trackr0   r/   )	rY   rZ   r   rK   r    r	   CUSTOM_EVENT_PREFIXrB   r'   )rC   r   r,   r   r%   r%   r&   track_custom_event  s    	

r   useridc                 C   sb   t js
td dS t rdS i }|durt||d< |dur%t||d< tj|dd tt S )z
    Return true if the specified User ID should be blocked.

    :param tracer: tracer instance to use
    :param userid: the ID of the user as registered by `set_user`
    zmOne click blocking of user ids is disabled. To use this feature please enable Application Security MonitoringFTNri   rl   rm   )	rS   _asm_enabledrY   rZ   r   r:   r   r   r9   )rC   r   re   rn   r%   r%   r&   should_block_user:  s   
r   c                   C   s    t js
td dS t  dS )at  
    Block the current request and return a 403 Unauthorized response. If the response
    has already been started to be sent this could not work. The behaviour of this function
    could be different among frameworks, but it usually involves raising some kind of internal Exception,
    meaning that if you capture the exception the request blocking could not work.
    z_block_request() is disabled. To use this feature please enable, Application Security MonitoringN)rS   r   rY   rZ   r   block_requestr%   r%   r%   r&   r   U  s   
r   sdkmodec                 C   s   t jr|tjkrtd dS |tjkrt j}t	 }|rO|
tj| | rO|tjkr1tt| } |
tj| |tjkrF|
tjt|  |
tjt|  td| |r[t  dS dS )aj  
    Check if the specified User ID should be blocked and if positive
    block the current request using `block_request`.

    This should only be called with set_user from the sdk API

    :param userid: the ID of the user as registered by `set_user`
    :param mode: the mode of the login event ("sdk" by default, "auto" to simulate auto instrumentation)
    z1should_block_user call requires ASM to be enabledN)rS   r   r
   rz   rY   rZ   rR   rT   r   rK   r    r	   r|   r{   r   r:   rQ   r}   r   r   r   r   )r   r   re   r*   r%   r%   r&   block_request_if_user_blockedc  s$   




r   rq   )r   N)r   N)1typingr   r   ddtrace._trace.spanr   ddtrace.appsecr   #ddtrace.appsec._asm_request_contextr   r   r   ddtrace.appsec._constantsr	   r
   r   ddtrace.appsec._utilsr   ddtrace.constantsr   )ddtrace.contrib.internal.trace_utils_baser   ddtrace.extr   ddtrace.internalr   ddtrace.internal._exceptionsr   ddtrace.internal.loggerr   ddtrace.internal.settings.asmr   rS   __name__rY   r'   r)   r:   r7   rB   rQ   r9   ra   r   r   r   r   r   r   r   r%   r%   r%   r&   <module>   s    		
?	

@	
9
"' !
$