o
    i0+                     @   s
  d 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mZ ddlZddlZddlZddlZddlZddlZeeZG dd	 d	e
ZG d
d de
Zdd ZdefddZdedefddZdededefddZdedefddZ dCdedede!fd d!Z"d"ee d#ede!fd$d%Z#dCd#edede$fd&d'Z%d(ede!fd)d*Z&d(ede!fd+d,Z'd-ede!fd.d/Z(dede!fd0d1Z)dedefd2d3Z*dede!fd4d5Z+dedefd6d7Z,d8Z-d9Z.d:Z/defd;d<Z0d=ee d>ee de!fd?d@Z1G dAdB dBe
Z2dS )Dz
Security Utilities

Provides security-related utilities:
- Rate limiting
- Input validation
- Security headers
- CORS configuration
    )RequestHTTPExceptionstatus)CORSMiddleware)TrustedHostMiddleware)BaseHTTPMiddleware)DictOptionalNc                       6   e Zd ZdZd	def fddZdefddZ  ZS )
RateLimitMiddlewarez`
    Simple rate limiting middleware.

    Limits requests per IP address to prevent abuse.
    <   requests_per_minutec                    s   t  | || _i | _d S N)super__init__r   requests)selfappr   	__class__ ?/lsinfo/ai/hellotax_ai/base_platform/app/core/security_utils.pyr       s   
zRateLimitMiddleware.__init__requestc                    s   |j r|j jnd}|jjdv r||I dH S t  || jvr%g | j|<  fdd| j| D | j|< t| j| | jkrMt	d|  t
tjdd| j|   ||I dH }|S )	z=
        Check rate limit before processing request.
        unknown)/health/metricsNc                    s   g | ]
} | d k r|qS r   r   ).0req_timecurrent_timer   r   
<listcomp>8   s
    z0RateLimitMiddleware.dispatch.<locals>.<listcomp>zRate limit exceeded for IP: z*Too many requests. Please try again later.status_codedetail)clienthosturlpathtimer   lenr   loggerwarningr   r   HTTP_429_TOO_MANY_REQUESTSappend)r   r   	call_next	client_ipresponser   r   r   dispatch%   s&   


zRateLimitMiddleware.dispatchr   )	__name__
__module____qualname____doc__intr   r   r2   __classcell__r   r   r   r   r      s    r   c                   @   s   e Zd ZdZdefddZdS )SecurityHeadersMiddlewarez0
    Add security headers to all responses.
    r   c                    sZ   ||I dH }d|j d< d|j d< d|j d< d|j d	< d
|j d< d|j d< d|j d< |S )z3
        Add security headers to response.
        NnosniffzX-Content-Type-OptionsDENYzX-Frame-Optionsz1; mode=blockzX-XSS-Protectionz#max-age=31536000; includeSubDomainszStrict-Transport-Securityzdefault-src 'self'zContent-Security-Policyzstrict-origin-when-cross-originzReferrer-Policyz(geolocation=(), microphone=(), camera=()zPermissions-Policy)headers)r   r   r/   r1   r   r   r   r2   R   s   






z"SecurityHeadersMiddleware.dispatchN)r3   r4   r5   r6   r   r2   r   r   r   r   r9   M   s    r9   c                 C   s$   | j tg ddg dg dd dS )z^
    Configure CORS middleware.

    In production, restrict origins to specific domains.
    )zhttp://localhost:8888zhttp://localhost:8889zhttp://localhost:3000zhttp://127.0.0.1:8888zhttp://127.0.0.1:8889zhttp://127.0.0.1:3000T)GETPOSTPUTDELETEPATCH)AuthorizationzContent-TypeAcceptzAccept-LanguageX-CSRF-TokenzX-Request-ID)allow_originsallow_credentialsallow_methodsallow_headersN)add_middlewarer   )r   r   r   r   configure_corsd   s   	
rJ   allowed_hostsc                 C   s   | j t|d dS )zO
    Configure trusted host middleware.

    Prevents host header attacks.
    )rK   N)rI   r   )r   rK   r   r   r   configure_trusted_hosts   s   
rL   datareturnc                 C   s   t |   S )zQ
    Hash sensitive data for storage.

    Uses SHA-256 for one-way hashing.
    )hashlibsha256encode	hexdigest)rM   r   r   r   hash_sensitive_data   s   rS   value
max_length
field_namec                 C   s(   t | |krttj| d| ddS )zC
    Validate input length to prevent buffer overflow attacks.
    z exceeds maximum length of r"   N)r*   r   r   HTTP_400_BAD_REQUEST)rT   rU   rV   r   r   r   validate_input_length   s   rX   filenamec                 C   s`   |  dd dd} tdd| } |  dd} |  dd} | d} t| d	kr.| d
d	 } | S )z>
    Sanitize filename to prevent path traversal attacks.
    /_\z	[<>:"|?*] z.. .   N)replaceresublstripr*   )rY   r   r   r   sanitize_filename   s   
re   
   sizemax_size_mbc                 C   s    | dkrdS |d d }| |kS )z5
    Check if file size is within allowed limit.
    r   Fi   r   )rg   rh   max_size_bytesr   r   r   check_file_size   s   rj   	mime_typeallowed_typesc                 C   s   | sdS | |v S )z3
    Validate MIME type against allowed types.
    Fr   )rk   rl   r   r   r   validate_mime_type   s   rm   c                 C   sP   t | j|sdd| j dS t| j|sdd| ddS t| j}d|dS )z/
    Comprehensive file upload validation.
    FzInvalid MIME type: )validerrorz*File size exceeds maximum allowed size of MBT)rn   sanitized_filename)rm   content_typerj   rg   re   rY   )filerl   rh   sanitized_namer   r   r   validate_file_upload   s   


ru   emailc                 C   s   d}t || duS )z!
    Basic email validation.
    z0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$N)rb   match)rv   patternr   r   r   validate_email   s   ry   c                 C   s   | sdS t | S )zValidate email format.F)ry   )rv   r   r   r   validate_email_format   s   rz   r'   c                    sF   | sdS g d}|    t fdd|D rdS  dp" dS )z4Validate URL format and prevent dangerous protocols.F)javascript:zfile:zdata:c                 3   s    | ]}  |V  qd S r   )
startswith)r   proto	url_lowerr   r   	<genexpr>  s    z&validate_url_format.<locals>.<genexpr>zhttp://zhttps://)loweranyr|   )r'   dangerous_protocolsr   r~   r   validate_url_format   s   r   c                    &   g d}|    t fdd|D S )ze
    Check for common SQL injection patterns.

    Returns True if suspicious patterns detected.
    )z' OR '1'='1z'; DROP TABLEz' OR 1=1zUNION SELECTz'; --z' OR 'a'='ac                 3       | ]	}|   v V  qd S r   )upperr   rx   value_upperr   r   r         z&check_sql_injection.<locals>.<genexpr>)r   r   rT   suspicious_patternsr   r   r   check_sql_injection     	r   c                 C   s$   | s| S |  dd dd ddS )z(Sanitize SQL input to prevent injection.'r]   ;z--)ra   rT   r   r   r   sanitize_sql_input  s   r   c                    r   )z[
    Check for common XSS patterns.

    Returns True if suspicious patterns detected.
    )z<scriptr{   zonerror=zonload=z<iframezeval(c                 3   r   r   )r   r   value_lowerr   r   r   2  r   zcheck_xss.<locals>.<genexpr>)r   r   r   r   r   r   	check_xss"  r   r   c                 C   s
   t | S )z#Sanitize HTML input to prevent XSS.)htmlescaper   r   r   r   sanitize_html_input5     
r       
csrf_tokenrD   c                   C   s
   t tS )zGenerate a secure CSRF token.)secrets	token_hexCSRF_TOKEN_LENGTHr   r   r   r   generate_csrf_token@  r   r   tokencookie_tokenc                 C   s   | r|sdS t | |S )z'Verify CSRF token matches cookie token.F)r   compare_digest)r   r   r   r   r   verify_csrf_tokenE  s   r   c                       r
   )
CSRFMiddlewarezz
    CSRF protection middleware.

    Validates CSRF tokens for state-changing operations (POST, PUT, DELETE, PATCH).
    Nexempt_pathsc                    s   t  | |pg d| _d S )N)r   r   z/docsz/openapi.jsonz/api/v1/auth/loginz/api/v1/auth/registerz/api/v1/agents)r   r   r   )r   r   r   r   r   r   r   S  s   zCSRFMiddleware.__init__r   c                    s   j dv r(| I dH }t jvr&t } jjdk}|jt|d|ddd |S t fdd	| jD r;| I dH S  j	
t} j
t}|rK|s`td
 j  d jj  ttjddt||sztd j  d jj  ttjdd| I dH S )z-Check CSRF token for state-changing requests.)r=   HEADOPTIONSNhttpsFlaxi  )keyrT   httponlysecuresamesitemax_agec                 3   s    | ]
} j j|V  qd S r   )r'   r(   r|   )r   r(   r   r   r   r   k  s    z*CSRFMiddleware.dispatch.<locals>.<genexpr>zCSRF token missing for  zCSRF token missingr"   zCSRF token mismatch for zCSRF token invalid)methodCSRF_COOKIE_NAMEcookiesr   r'   scheme
set_cookier   r   r<   getCSRF_HEADER_NAMEr+   r,   r(   r   r   HTTP_403_FORBIDDENr   )r   r   r/   r1   r   is_httpscsrf_cookier   r   r   r2   W  s@   


zCSRFMiddleware.dispatchr   )	r3   r4   r5   r6   listr   r   r2   r8   r   r   r   r   r   L  s    r   )rf   )3r6   fastapir   r   r   fastapi.middleware.corsr   fastapi.middleware.trustedhostr   starlette.middleware.baser   typingr   r	   r)   rO   loggingr   rb   r   	getLoggerr3   r+   r   r9   rJ   r   rL   strrS   r7   rX   re   boolrj   rm   dictru   ry   rz   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>   sH    	
4	
