Ë
    0]jl[  ã                   óÖ  — d dl 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
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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  d dl!m"Z"  ee#«      Z$	 d dl%Z&dZ'defd„Z)d=de
e   de
e*   fd„Z+d=de
e   de
e   fd„Z,dede-fd„Z.d=de
e   de fd„Z/d=de
e-   de0fd„Z1	 d=dede
e0   de-fd„Z2	 d=dede
e3   de
e-   fd„Z4dede-fd„Z5dede-fd „Z6dede-fd!„Z7	 d=d"eee"f   de
e0   deee-ee-   f      fd#„Z8	 d=de-d$e-d%e-d"eee"f   de
e0   dee0   fd&„Z9d'ee0   dee-   fd(„Z:	 d=d"eee"f   de
e0   dee-   fd)„Z;de-d$e-d%e-d*e-dede-fd+„Z<d,e0de0fd-„Z=d>d.ee   d/e*de-fd0„Z>dede*fd1„Z?de-fd2„Z@	 	 d?ded3e
e   de
e0   defd4„ZAd$e-de3fd5„ZBd$e-de3fd6„ZCdefd7„ZDdede3fd8„ZEdede3fd9„ZF	 d=dede
e0   de3fd:„ZGde	fd;„ZHdede-fd<„ZIy# e($ r dZ'Y �Œuw xY w)@é    )Ú	timedeltaÚdatetime)Úsha256)Ú	getLogger)ÚTemplate)ÚCallableÚOptionalÚTypeÚUnionÚList)Ú	urlencode)Ú	BaseCacheÚcaches)ÚHttpRequestÚHttpResponseÚJsonResponseÚ	QueryDict)ÚredirectÚrender)Úforce_bytes)Úimport_string)Úsettings)Ú
AccessBaseNTFÚreturnc                  ó2   — t         t        t        dd«         S )zy
    Get the cache instance Axes is configured to use with ``settings.AXES_CACHE`` and use ``'default'`` if not set.
    Ú
AXES_CACHEÚdefault)r   Úgetattrr   © ó    úC/var/www/zogu/zoguvenv/lib/python3.12/site-packages/axes/helpers.pyÚ	get_cacher"      s   € ô
 ”'œ( L°)Ó<Ñ=Ð=r    Úrequestc                 óP   — t        | «      }|€yt        |j                  «       «      S )a©  
    Return the cache timeout interpreted from settings.AXES_COOLOFF_TIME.

    The cache timeout can be either None if not configured or integer of seconds if configured.

    Notice that the settings.AXES_COOLOFF_TIME can be None, timedelta, float, integer, callable, or str path,
    and this function offers a unified _integer or None_ representation of that configuration
    for use with the Django cache backends.
    N)Úget_cool_offÚintÚtotal_seconds)r#   Úcool_offs     r!   Úget_cache_timeoutr)   #   s+   € ô ˜GÓ$€HØÐØÜˆx×%Ñ%Ó'Ó(Ð(r    c                 ó  — t         j                  }t        |t        «      rt	        |¬«      S t        |t
        «      rt	        |dz  ¬«      S t        |t        «      rt        |«      } || «      S t        |«      r || «      S |S )a  
    Return the login cool off time interpreted from settings.AXES_COOLOFF_TIME.

    The return value is either None or timedelta.

    Notice that the settings.AXES_COOLOFF_TIME is either None, timedelta, integer/float of hours,
    a path to a callable or a callable taking 1 argument (the request). This function
    offers a unified _timedelta or None_ representation of that configuration for use with the
    Axes internal implementations.

    :exception TypeError: if settings.AXES_COOLOFF_TIME is of wrong type.
    )Úhoursé<   )Úminutes)	r   ÚAXES_COOLOFF_TIMEÚ
isinstancer&   r   ÚfloatÚstrr   Úcallable)r#   r(   Úcool_off_funcs      r!   r%   r%   4   st   € ô ×)Ñ)€Hä�(œCÔ Ü˜xÔ(Ð(Ü�(œEÔ"Ü ¨B¡Ô/Ð/Ü�(œCÔ Ü% hÓ/ˆÙ˜WÓ%Ð%Ü�ÔÙ˜Ó Ð à€Or    Údeltac                 óð   — | j                  «       }t        |d«      \  }}t        |d«      \  }}t        |d«      \  }}|r|d›d�nd}dj                  d„ |dg|dg|d	gfD «       «      }|rd
|› d|› �S d
|› �S )zh
    Return datetime.timedelta translated to ISO 8601 formatted duration for use in e.g. cool offs.
    r,   é   ú.0fÚDÚ c              3   ó4   K  — | ]  \  }}|r	|d ›|› �–— Œ y­w)r7   Nr   )Ú.0ÚvalueÚ
designators      r!   ú	<genexpr>z'get_cool_off_iso8601.<locals>.<genexpr>]   s*   è ø€ ò áˆE�:Ùð �ˆ+�j�\Ô"ñùs   ‚ÚHÚMÚSÚPÚT)r'   ÚdivmodÚjoin)r4   Úsecondsr-   r+   ÚdaysÚdays_strÚtime_strs          r!   Úget_cool_off_iso8601rJ   Q   s¦   € ð
 ×!Ñ!Ó#€GÜ˜g rÓ*Ñ€GˆWÜ˜G RÓ(�N€Eˆ7Ü˜ Ó#�K€Dˆ%á!%�$�s�˜1‰~¨2€Hà�w‰wñ à#(¨# ,°¸#°ÀÈ#ÀÐ!Oôó €Hñ Ø�8�*˜A˜h˜ZÐ(Ð(Øˆxˆjˆ>Ðr    c                 ó†   — t        | «      }|€t        d«      ‚| j                  }|€t        j                  «       |z   S ||z   S )zG
    Get threshold for fetching access attempts from the database.
    zTCool off threshold can not be calculated with settings.AXES_COOLOFF_TIME set to None)r%   Ú	TypeErrorÚaxes_attempt_timer   Únow)r#   r(   Úattempt_times      r!   Úget_attempt_expirationrP   h   sS   € ô
 ˜GÓ$€HØÐÜØbó
ð 	
ð ×,Ñ,€LØÐÜ�|‰|‹~ Ñ(Ð(Ø˜(Ñ"Ð"r    Úusernamec                 óL   — t         j                  | i}|j                  |«       |S )a  
    Calculate credentials for Axes to use internally from given username and kwargs.

    Axes will set the username value into the key defined with ``settings.AXES_USERNAME_FORM_FIELD``
    and update the credentials dictionary with the kwargs given on top of that.
    )r   ÚAXES_USERNAME_FORM_FIELDÚupdate)rQ   ÚkwargsÚcredentialss      r!   Úget_credentialsrW   y   s(   € ô ×4Ñ4°hÐ?€KØ×Ñ�vÔØÐr    rV   c                 óB  — t         j                  r�t        j                  d«       t	        t         j                  «      rt        j                  | |«      S t        t         j                  t        «      r  t        t         j                  «      | |«      S t        d«      ‚|r5t        j                  d«       |j                  t         j                  d«      S t        j                  d«       t        | d| j                  «      }|j                  t         j                  d«      S )aÆ  
    Resolve client username from the given request or credentials if supplied.

    The order of preference for fetching the username is as follows:

    1. If configured, use ``AXES_USERNAME_CALLABLE``, and supply ``request, credentials`` as arguments
    2. If given, use ``credentials`` and fetch username from ``AXES_USERNAME_FORM_FIELD`` (defaults to ``username``)
    3. Use request.POST and fetch username from ``AXES_USERNAME_FORM_FIELD`` (defaults to ``username``)

    :param request: incoming Django ``HttpRequest`` or similar object from authentication backend or other source
    :param credentials: incoming credentials ``dict`` or similar object from authentication backend or other source
    z5Using settings.AXES_USERNAME_CALLABLE to get usernamezHsettings.AXES_USERNAME_CALLABLE needs to be a string, callable, or None.zVUsing parameter credentials to get username with key settings.AXES_USERNAME_FORM_FIELDNzWUsing parameter request.POST to get username with key settings.AXES_USERNAME_FORM_FIELDÚdata)r   ÚAXES_USERNAME_CALLABLEÚlogÚdebugr2   r/   r1   r   rL   ÚgetrS   r   ÚPOST)r#   rV   Úrequest_datas      r!   Úget_client_usernamer`   †   så   € ô  ×&Ò&Ü�	‰	ÐIÔJä”H×3Ñ3Ô4Ü×2Ñ2Ø˜óð ô ”h×5Ñ5´sÔ;ØA”=¤×!@Ñ!@ÓAÀ'È;ÓWÐWÜØVó
ð 	
ñ Ü�	‰	Ødô	
ð �‰œx×@Ñ@À$ÓGÐGä‡I�IØaôô ˜7 F¨G¯L©LÓ9€LØ×ÑœH×=Ñ=¸tÓDÐDr    Ú
use_ipwarec                 óš  — t         j                  r‹t        j                  d«       t	        t         j                  «      rt        j                  | «      S t        t         j                  t        «      r t        t         j                  «      | «      S t        d«      ‚|€t        }|rvt        j                  d«       t        j                  j                  | t         j                  t         j                  t         j                  t         j                   ¬«      \  }}|S t        j                  d«       | j"                  j%                  dd«      S )að  
    Get client IP address as configured by the user.

    The order of preference for address resolution is as follows:

    1. If configured, use ``AXES_CLIENT_IP_CALLABLE``, and supply ``request`` as argument
    2. If available, use django-ipware package (parameters can be configured in the Axes package)
    3. Use ``request.META.get('REMOTE_ADDR', None)`` as a fallback

    :param request: incoming Django ``HttpRequest`` or similar object from authentication backend or other source
    z?Using settings.AXES_CLIENT_IP_CALLABLE to get client IP addresszIsettings.AXES_CLIENT_IP_CALLABLE needs to be a string, callable, or None.Nz,Using django-ipware to get client IP address)Úproxy_orderÚproxy_countÚproxy_trusted_ipsÚrequest_header_orderzTUsing request.META.get('REMOTE_ADDR', None) fallback method to get client IP addressÚREMOTE_ADDR)r   ÚAXES_CLIENT_IP_CALLABLEr[   r\   r2   r/   r1   r   rL   ÚIPWARE_INSTALLEDÚipwareÚipÚget_client_ipÚAXES_IPWARE_PROXY_ORDERÚAXES_IPWARE_PROXY_COUNTÚAXES_IPWARE_PROXY_TRUSTED_IPSÚ!AXES_IPWARE_META_PRECEDENCE_ORDERÚMETAr]   )r#   ra   Úclient_ip_addressÚ_s       r!   Úget_client_ip_addressrt   ±   s  € ô  ×'Ò'Ü�	‰	ÐSÔTä”H×4Ñ4Ô5Ü×3Ñ3Øóð ô ”h×6Ñ6¼Ô<ØB”=¤×!AÑ!AÓBÀ7ÓKÐKÜØWó
ð 	
ð ÐÜ%ˆ
ÙÜ�	‰	Ð@ÔAä%Ÿy™y×6Ñ6ØÜ ×8Ñ8Ü ×8Ñ8Ü&×DÑDÜ!)×!KÑ!Kð  7ó  
ÑÐ˜1ð !Ð ä‡I�IØ^ôð �<‰<×Ñ˜M¨4Ó0Ð0r    c                 ó@   — | j                   j                  dd«      d d S )NÚHTTP_USER_AGENTú	<unknown>éÿ   ©rq   r]   ©r#   s    r!   Úget_client_user_agentr{   ä   s!   € Ø�<‰<×ÑÐ-¨{Ó;¸D¸SÐAÐAr    c                 ó@   — | j                   j                  dd«      d d S )NÚ	PATH_INFOrw   rx   ry   rz   s    r!   Úget_client_path_infor~   è   s    € Ø�<‰<×Ñ˜K¨Ó5°d°sÐ;Ð;r    c                 ó@   — | j                   j                  dd«      d d S )NÚHTTP_ACCEPTrw   i  ry   rz   s    r!   Úget_client_http_acceptr�   ì   s    € Ø�<‰<×Ñ˜M¨;Ó7¸¸Ð>Ð>r    Úrequest_or_attemptc                 óN  — t        t        j                  «      rt        j                  | |«      S t        t        j                  t        «      r  t        t        j                  «      | |«      S t        t        j                  t        «      rt        j                  S t        d«      ‚)NzCsettings.AXES_LOCKOUT_PARAMETERS needs to be a callable or iterable)r2   r   ÚAXES_LOCKOUT_PARAMETERSr/   r1   r   ÚlistrL   )r‚   rV   s     r!   Úget_lockout_parametersr†   ð   sƒ   € ô ”×0Ñ0Ô1Ü×/Ñ/Ð0BÀKÓPÐPä”(×2Ñ2´CÔ8Ø>Œ}œX×=Ñ=Ó>Ø ó
ð 	
ô ”(×2Ñ2´DÔ9Ü×/Ñ/Ð/ä
ØMóð r    Ú
ip_addressÚ
user_agentc                 ól  — t        ||«      }| ||dœ}g }|D ]?  }	 t        |t        «      r|||   i}	n|D �
ci c]  }
|
||
   “Œ
 }	}
|j                  |	«       ŒA |S c c}
w # t        $ rJ}|› ddj                  |j                  «       «      › �}t        j                  |«       t        |«      |‚d}~ww xY w)a<  
    Get query parameters for filtering AccessAttempt queryset.

    This method returns a dict that guarantees iteration order for keys and values,
    and can so be used in e.g. the generation of hash keys or other deterministic functions.

    Returns list of dict, every item of list are separate parameters
    )rQ   r‡   rˆ   z7 lockout parameter is not allowed. Allowed parameters: ú, N)
r†   r/   r1   ÚappendÚKeyErrorrE   Úkeysr[   Ú	exceptionÚ
ValueError)rQ   r‡   rˆ   r‚   rV   Úlockout_parametersÚparameters_dictÚfilter_kwargsÚ	parameterÚfilter_kwargÚcombined_parameterÚeÚ	error_msgs                r!   Úget_client_parametersr˜     sù   € ô 0Ð0BÀKÓPÐð Ø Ø ñ€Oð €Mà'ò /ˆ	ð	/Ü˜)¤SÔ)Ø )¨?¸9Ñ+EÐF‘ð /8ö à*ð '¨Ð8JÑ(KÑKð �ð  ð × Ñ  Õ.ð/ð& Ðùò øô ò 	/à�#ð 'Ø'+§y¡y°×1EÑ1EÓ1GÓ'HÐ&IðKð ô �M‰M˜)Ô$Ü˜YÓ'¨QÐ.ûð	/ús)   ›A ·AÁA ÁA Á 	B3Á)AB.Â.B3Úfilter_kwargs_listc                 óÚ   — g }| D ]c  }dj                  d„ |j                  «       D «       «      }t        |j                  «       «      j	                  «       }|j                  d|› �«       Œe |S )Nr9   c              3   ó&   K  — | ]	  }|sŒ|–— Œ y ­w©Nr   )r;   r<   s     r!   r>   z&make_cache_key_list.<locals>.<genexpr>6  s   è ø€ ò '
ØºŒEñ'
ùs   ‚Šzaxes-)rE   Úvaluesr   ÚencodeÚ	hexdigestr‹   )r™   Ú
cache_keysr’   Úcache_key_componentsÚcache_key_digests        r!   Úmake_cache_key_listr£   3  sz   € Ø€JØ+ò 6ˆØ!Ÿw™wñ '
Ø,×3Ñ3Ó5ô'
ó  
Ðô "Ð"6×"=Ñ"=Ó"?Ó@×JÑJÓLÐØ×Ñ˜EÐ"2Ð!3Ð4Õ5ð6ð Ðr    c                 óä   — t        | t        «      r%| j                  }| j                  }| j                  }n"t        | |«      }t        | «      }t        | «      }t        |||| |«      }t        |«      S )a  
    Build cache key name from request or AccessAttempt object.

    :param request_or_attempt: HttpRequest or AccessAttempt object
    :param credentials: credentials containing user information
    :return cache_key: Hash key that is usable for Django cache backends
    )
r/   r   rQ   r‡   rˆ   r`   rt   r{   r˜   r£   )r‚   rV   rQ   r‡   rˆ   r™   s         r!   Úget_client_cache_keysr¥   >  sx   € ô Ð$¤jÔ1Ø%×.Ñ.ˆØ'×2Ñ2ˆ
Ø'×2Ñ2‰
ä&Ð'9¸;ÓGˆÜ*Ð+=Ó>ˆ
Ü*Ð+=Ó>ˆ
ä.Ø�*˜jÐ*<¸kóÐô Ð1Ó2Ð2r    Ú	path_infoc                 ó  ‡— t         j                  r“t        j                  d«       t	        t         j                  «      rt        j                  | ||||«      S t        t         j                  t        «      r# t        t         j                  «      | ||||«      S t        d«      ‚i }t         j                  r| |d<   ||d<   ||d<   n(t        | |||«      }i }|D ]  }|j                  |«       Œ t        |j                  «       «      }|rt        |t        t        f«      r|d   }||d<   t!        d«      Š|j#                  «       D ��	cg c]
  \  }}	||	d	œ‘Œ }
}}	d
j%                  ˆfd„|
D «       «      }d|z   dz   }|S c c}	}w )zÐ
    Get a readable string that can be used in e.g. logging to distinguish client requests.

    Example log format would be
    ``{username: "example", ip_address: "127.0.0.1", path_info: "/example/"}``
    z=Using settings.AXES_CLIENT_STR_CALLABLE to get client string.zIsettings.AXES_CLIENT_STR_CALLABLE needs to be a string, callable or None.rQ   r‡   rˆ   r   r¦   z$key: "$value"©Úkeyr<   rŠ   c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrœ   ©Ú
substitute©r;   ÚitemÚtemplates     €r!   r>   z!get_client_str.<locals>.<genexpr>�  s   øè ø€ ÒG¸˜8×.Ñ.¨t×4ÑGùó   ƒú{ú})r   ÚAXES_CLIENT_STR_CALLABLEr[   r\   r2   r/   r1   r   rL   ÚAXES_VERBOSEr˜   rT   Úcleanse_parametersÚcopyÚtupler…   r   ÚitemsrE   )rQ   r‡   rˆ   r¦   r#   Úclient_dictÚclient_listÚclientÚkÚvr¸   Ú
client_strr¯   s               @r!   Úget_client_strr¿   Z  s‰  ø€ ô ×(Ò(Ü�	‰	ÐQÔRä”H×5Ñ5Ô6Ü×4Ñ4Ø˜* j°)¸Wóð ô ”h×7Ñ7¼Ô=ØC”=¤×!BÑ!BÓCØ˜* j°)¸Wóð ô ØWó
ð 	
ð €Kä×Òà"*ˆ�JÑØ$.ˆ�LÑ!Ø$.ˆ�LÒ!ô ,¨H°jÀ*ÈgÓVˆØˆØ!ò 	'ˆFØ×Ñ˜vÕ&ð	'ä$ [×%5Ñ%5Ó%7Ó8€Ká”Z 	¬E´4¨=Ô9Ø˜a‘Lˆ	Ø(€K�Ñô Ð(Ó)€HØ0;×0AÑ0AÓ0C×D©¨¨1�Q Ó#ÐD€EÑDØ—‘ÓGÀÔGÓG€JØ�zÑ! CÑ'€JØÐùó Es   ÅE>Úparamsc                 óÖ   — dgt         j                  z   }t         j                  r|j                  t         j                  «       |r#| j	                  «       }|D ]  }||v sŒd||<   Œ |S | S )aŠ  
    Replace sensitive parameter values in a parameter dict with
    a safe placeholder value.

    Parameters name ``'password'`` will always be cleansed.  Additionally,
    parameters named in ``settings.AXES_SENSITIVE_PARAMETERS`` and
    ``settings.AXES_PASSWORD_FORM_FIELD will be cleansed.

    This is used to prevent passwords and similar values from
    being logged in cleartext.
    Úpasswordz********************)r   ÚAXES_SENSITIVE_PARAMETERSÚAXES_PASSWORD_FORM_FIELDr‹   r¶   )rÀ   Úsensitive_parametersÚcleansedÚparams       r!   rµ   rµ   ’  sn   € ð '˜<¬(×*LÑ*LÑLÐÜ×(Ò(Ø×#Ñ#¤H×$EÑ$EÔFáØ—;‘;“=ˆØ)ò 	9ˆEØ˜Ò Ø"8�˜’ð	9ð ˆØ€Mr    ÚqueryÚ
max_lengthc                 óà   ‡— t        | j                  «       «      }t        d«      Š|j                  «       D ��cg c]
  \  }}||dœ‘Œ }}}dj	                  ˆfd„|D «       «      }|d| S c c}}w )a~  
    Turns a query dictionary into an easy-to-read list of key-value pairs.

    If a field is called either ``'password'`` or ``settings.AXES_PASSWORD_FORM_FIELD`` or if the fieldname is included
    in ``settings.AXES_SENSITIVE_PARAMETERS`` its value will be masked.

    The length of the output is limited to max_length to avoid a DoS attack via excessively large payloads.
    z$key=$valuer¨   ú
c              3   ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wrœ   r«   r­   s     €r!   r>   z get_query_str.<locals>.<genexpr>¹  s   øè ø€ ÒF¸˜(×-Ñ-¨d×3ÑFùr°   N)rµ   r¶   r   r¸   rE   )rÈ   rÉ   Ú
query_dictr¼   r½   r¸   Ú	query_strr¯   s          @r!   Úget_query_strrÏ   «  sk   ø€ ô $ E§J¡J£LÓ1€Jä˜Ó&€HØ0:×0@Ñ0@Ó0B×C©¨¨1�Q Ó#ÐC€EÑCØ—	‘	ÓFÀÔFÓF€Ià�[�jÐ!Ð!ùó Ds   ¹A*c                 óN  — t        t        j                  «      rt        j                  | |«      S t        t        j                  t        «      r  t        t        j                  «      | |«      S t        t        j                  t        «      rt        j                  S t        d«      ‚)Nz@settings.AXES_FAILURE_LIMIT needs to be a callable or an integer)r2   r   ÚAXES_FAILURE_LIMITr/   r1   r   r&   rL   )r#   rV   s     r!   Úget_failure_limitrÒ   ¾  s|   € Ü”×+Ñ+Ô,Ü×*Ñ*Ø�[ó
ð 	
ô ”(×-Ñ-¬sÔ3Ø9Œ}œX×8Ñ8Ó9¸'À;ÓOÐOÜ”(×-Ñ-¬sÔ3Ü×*Ñ*Ð*Ü
ÐVÓ
WÐWr    c                  ób   — t         j                  rt         j                  S t         j                  S rœ   )r   r.   ÚAXES_COOLOFF_MESSAGEÚAXES_PERMALOCK_MESSAGEr   r    r!   Úget_lockout_messagerÖ   Ê  s#   € Ü×!Ò!Ü×,Ñ,Ð,Ü×*Ñ*Ð*r    Úoriginal_responsec                 óâ  — t         j                  r~t        t         j                  «      r	 t        j                  | ||«      S t	        t         j                  t
        «      r$t        t         j                  «      }	  || ||«      S t        d«      ‚t         j                  }t        | |«      t        | |«      xs ddœ}t        | «      }|r|j                  t        |«      |dœ«       | j                  j                  d«      dk(  r,t        ||¬«      }t         j                   |d<   d	|d
<   d|d<   |S t         j"                  rt%        | t         j"                  ||¬«      S t         j&                  r2t         j&                  }t)        d|d   i«      }	|› d|	› �}
t+        |
«      S t-        t/        «       |¬«      S # t        $ r t        j                  | |«      cY S w xY w# t        $ r  || |«      cY S w xY w)NzGsettings.AXES_LOCKOUT_CALLABLE needs to be a string, callable, or None.r9   )Úfailure_limitrQ   )Úcooloff_timeÚcooloff_timedeltaÚHTTP_X_REQUESTED_WITHÚXMLHttpRequest)ÚstatuszAccess-Control-Allow-OriginzPOST, OPTIONSzAccess-Control-Allow-Methodsz=Origin, Content-Type, Accept, Authorization, x-requested-withzAccess-Control-Allow-HeadersrQ   ú?)r   ÚAXES_LOCKOUT_CALLABLEr2   rL   r/   r1   r   ÚAXES_HTTP_RESPONSE_CODErÒ   r`   r%   rT   rJ   rq   r]   r   ÚAXES_ALLOWED_CORS_ORIGINSÚAXES_LOCKOUT_TEMPLATEr   ÚAXES_LOCKOUT_URLr   r   r   rÖ   )r#   r×   rV   Úcallable_objrÞ   Úcontextr(   Újson_responseÚlockout_urlÚquery_stringÚurls              r!   Úget_lockout_responserë   Ð  sø  € ô
 ×%Ò%Ü”H×2Ñ2Ô3ðLÜ×5Ñ5ØÐ.°óð ô ”h×4Ñ4´cÔ:Ü(¬×)GÑ)GÓHˆLð:Ù# GÐ->ÀÓLÐLô ØUó
ð 	
ô ×-Ñ-€Fä*¨7°KÓ@Ü'¨°Ó=ÒCÀñ€Gô
 ˜GÓ$€HÙØ�‰ä 4Øó!ð &.ñ	ô	
ð ‡|�|×ÑÐ/Ó0Ð4DÒDÜ$ W°VÔ<ˆä×.Ñ.ð 	Ð3Ñ4ð 9HˆÐ4Ñ5àKð 	Ð4Ñ5ð Ðä×%Ò%Ü�gœx×=Ñ=¸wÈvÔVÐVä× Ò Ü×/Ñ/ˆÜ  *¨g°jÑ.AÐ!BÓCˆØ�˜Q˜|˜nÐ-ˆÜ˜‹}ÐäÔ+Ó-°fÔ=Ð=øôg ò Lä×5Ñ5°g¸{ÓKÒKðLûô ò :Ù# G¨[Ó9Ò9ð:ús#   «F4 Á:	G Æ4GÇGÇG.Ç-G.c                 óH   — t         j                  sy| t         j                  v S ©NF)r   ÚAXES_IP_WHITELIST©r‡   s    r!   Úis_ip_address_in_whitelistrð     ó#   € Ü×%Ò%Øð 	”h×0Ñ0Ð0ðr    c                 óH   — t         j                  sy| t         j                  v S rí   )r   ÚAXES_IP_BLACKLISTrï   s    r!   Úis_ip_address_in_blacklistrô     rñ   r    c                 óœ   — t         j                  rt        | j                  «      ryt         j                  rt        | j                  «      ryy)z@
    Check if the given request refers to a whitelisted IP.
    TF)r   ÚAXES_NEVER_LOCKOUT_WHITELISTrð   Úaxes_ip_addressÚAXES_ONLY_WHITELISTrz   s    r!   Ú is_client_ip_address_whitelistedrù   $  sE   € ô
 ×,Ò,Ô1KØ×Ñô2ð ä×#Ò#Ô(BØ×Ñô)ð àr    c                 ó|   — t        | j                  «      ryt        j                  rt	        | j                  «      syy)z@
    Check if the given request refers to a blacklisted IP.
    TF)rô   r÷   r   rø   rð   rz   s    r!   Ú is_client_ip_address_blacklistedrû   6  s7   € ô
 " '×"9Ñ"9Ô:Øä×#Ò#Ô,FØ×Ñô-ð àr    c                 óD   — t         j                  r| j                  dk(  ryy)z?
    Check if the given request uses a whitelisted method.
    ÚGETTF)r   ÚAXES_NEVER_LOCKOUT_GETÚmethodrz   s    r!   Úis_client_method_whitelistedr   F  s   € ô
 ×&Ò&¨7¯>©>¸UÒ+BØàr    c                 óª   — t         j                  }|€yt        |«      r	 || |«      S t        |t        «      r t        |«      | |«      S t        d«      ‚)aÏ  
    Check if the given request or credentials refer to a whitelisted username.

    This method invokes the ``settings.AXES_WHITELIST`` callable
    with ``request`` and ``credentials`` arguments.

    This function could use the following implementation for checking
    the lockout flags from a specific property in the user object:

    .. code-block: python

       username_value = get_client_username(request, credentials)
       username_field = getattr(
           get_user_model(),
           "USERNAME_FIELD",
           "username"
       )
       kwargs = {username_field: username_value}

       user_model = get_user_model()
       user = user_model.objects.get(**kwargs)
       return user.nolockout
    FzIsettings.AXES_WHITELIST_CALLABLE needs to be a string, callable, or None.)r   ÚAXES_WHITELIST_CALLABLEr2   r/   r1   r   rL   )r#   rV   Úwhitelist_callables      r!   Úis_user_attempt_whitelistedr  Q  s_   € ô6 "×9Ñ9ÐØÐ!ØÜÐ"Ô#Ù! '¨;Ó7Ð7ÜÐ$¤cÔ*Ø0Œ}Ð/Ó0°¸+ÓFÐFä
ØSóð r    c                 ó   ‡ — ˆ fd„}|S )a:  
    Decorator that toggles function execution based on settings.

    If the ``settings.AXES_ENABLED`` flag is set to ``False``
    the decorated function never runs and a None is returned.

    This decorator is only suitable for functions that do not
    require return values to be passed back to callers.
    c                  ó6   •— t         j                  r ‰| i |¤ŽS y rœ   )r   ÚAXES_ENABLED)ÚargsrU   Úfuncs     €r!   Úinnerztoggleable.<locals>.inner„  s!   ø€ Ü× Ò Ù˜Ð( Ñ(Ð(ð !r    r   )r	  r
  s   ` r!   Ú
toggleabler  y  s   ø€ ô)ð €Lr    c                 óÊ   — 	 | j                   }|j                  €|j                  «        t	        t        |j                  «      «      j                  «       S # t        $ r Y yw xY w)z²
    Get client session and returns the SHA256 hash of session key, forcing session creation if required.

    If no session is available on request returns an empty string.
    r9   )ÚsessionÚAttributeErrorÚsession_keyÚcreater   r   rŸ   )r#   r  s     r!   Úget_client_session_hashr  ‹  s[   € ðØ—/‘/ˆð ×ÑÐ"Ø�‰Ôä”+˜g×1Ñ1Ó2Ó3×=Ñ=Ó?Ð?øô ò áðús   ‚A Á	A"Á!A"rœ   )i   )NN)Jr   r   Úhashlibr   Úloggingr   Ústringr   Útypingr   r	   r
   r   r   Úurllib.parser   Údjango.core.cacher   r   Údjango.httpr   r   r   r   Údjango.shortcutsr   r   Údjango.utils.encodingr   Údjango.utils.module_loadingr   Ú	axes.confr   Úaxes.modelsr   Ú__name__r[   Ú	ipware.iprj   ri   ÚImportErrorr"   r&   r)   r%   r1   rJ   rP   ÚdictrW   r`   Úboolrt   r{   r~   r�   r†   r˜   r£   r¥   r¿   rµ   rÏ   rÒ   rÖ   rë   rð   rô   rù   rû   r   r  r  r  r   r    r!   ú<module>r#     sÔ  ðß (Ý Ý Ý ß 8Õ 8Ý "ç /ß JÓ Jß -Ý -Ý 5å Ý "á�Ó€ðÛàÐð
>�9ó >ñ)˜x¨Ñ4ð )ÀÈÁó )ñ"˜( ;Ñ/ð ¸8ÀIÑ;Nó ð: 	ð ¨có ñ.# H¨[Ñ$9ð #ÀXó #ñ"
˜h s™mð 
Àó 
ð 9=ñ(EØð(EØ'/°¡~ð(Eàó(EðZ "&ñ01Øð01à˜‘ð01ð ˆc�]ó01ðfB ;ð B°3ó Bð< +ð <°#ó <ð? Kð ?°Có ?ð #'ñØ˜k¨:Ð5Ñ6ðà˜$‘ðð 
ˆ%��T˜#‘Y�Ñ
Ñ óð2 #'ñ,Øð,àð,ð ð,ð ˜k¨:Ð5Ñ6ð	,ð
 ˜$‘ð,ð 
ˆ$�Zó,ð^¨D°©Jð ¸4À¹9ó ð #'ñ3Ø˜k¨:Ð5Ñ6ð3à˜$‘ð3ð 
ˆ#�Yó3ð85Øð5àð5ð ð5ð ð	5ð
 ð5ð 	ó5ðp˜tð ¨ó ñ2"˜˜i™ð "°cð "ÀSó "ð&	X˜{ð 	X¸Có 	Xð+˜Só +ð 15Ø"&ñ?>Øð?>à Ñ-ð?>ð ˜$‘ð?>ð ó	?>ðD¨3ð °4ó ð¨3ð °4ó ð¨kó ð$¨kð ¸dó ð ¨+ð ¸$ó ð 9=ñ%Øð%Ø'/°¡~ð%à	ó%ðP˜ó ð$@ [ð @°Sô @øði ò ØÓðús   Á,G ÇG(Ç'G(