o
    RDis                     @   sn  d dl Z d dlZd dlZd dlZd dlmZ d dlmZ d dlm	Z	m
Z
 d dlmZ d dlmZ d dlmZm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&m'Z' ddl(m)Z) ddlm*Z* ddl+m,Z, ddl-m.Z. e/e0Z1G dd dej2Z3G dd dej2Z4G dd dej5Z6G dd dej7Z8G dd de6Z9G d d! d!ej5Z:G d"d# d#e:Z;G d$d% d%ej5Z<G d&d' d'e<Z=G d(d) d)ej5Z>G d*d+ d+e>Z?G d,d- d-ej5Z@G d.d/ d/e@ZAd0d1 ZBd2d3 ZCd4d5 ZDd6d7 ZEd8d9 ZFd:d; ZGd<d= ZHd>d? ZId@dA ZJdBdC ZKdDdE ZLdFdG ZMdHdI ZNdS )J    N)suppress)	timedelta)	parse_qslurlparse)apps)settings)identify_hashermake_password)ImproperlyConfigured)modelsroutertransaction)reverse)timezone)gettext_lazy)jwk)base64url_encode)errors   )generate_client_idgenerate_client_secret)get_scopes_backend)oauth2_settings)jwk_from_pem)AllowedURIValidatorc                          e Zd Z fddZ  ZS )ClientSecretFieldc              	      s   t || j}t |dd}|st ||S zt|}t| d| j d| d W n" tyL   t| d| j d t|}t	|| j| | Y S w t ||S )Nhash_client_secretTz: z is already hashed with .z is not hashed; hashing it now.)
getattrattnamesuperpre_saver   loggerdebug
ValueErrorr	   setattr)selfmodel_instanceaddsecretshould_be_hashedhasherhashed_secret	__class__ O/var/www/Datamplify/venv/lib/python3.10/site-packages/oauth2_provider/models.pyr"       s   "zClientSecretField.pre_save__name__
__module____qualname__r"   __classcell__r0   r0   r.   r1   r          r   c                       r   )TokenChecksumFieldc                    s:   t |d}t|d }t|| j| t ||S )Ntokenzutf-8)	r   hashlibsha256encode	hexdigestr&   r    r!   r"   )r'   r(   r)   r9   checksumr.   r0   r1   r"   2   s   
zTokenChecksumField.pre_saver2   r0   r0   r.   r1   r8   1   r7   r8   c                   @   s  e Zd ZdZdZdZeedfeedffZdZdZ	dZ
d	Zd
Zeedfe	edfe
edfeedfeedffZdZdZdZeedfeedfeedffZejddZejddeddZejejdddejdZejdeddZejdedddZejd ed!Z ejd ed!Z!e"d"de#ded#d$Z$ej%dd%Z&ejd"dd&Z'ej%d'd%Z(ej)dd(Z*ej)dd)Z+ejd*eedd+Z,ejded,ddZ-G d-d. d.Z.d/d0 Z/e0d1d2 Z1d3d4 Z2d5d6 Z3d7d8 Z4d9d: Z5d;d< Z6d=d> Z7d?d@ Z8dAdB Z9e0dCdD Z:dES )FAbstractApplicationa  
    An Application instance represents a Client on the Authorization server.
    Usually an Application is created manually by client's developers after
    logging in on an Authorization Server.

    Fields:

    * :attr:`client_id` The client identifier issued to the client during the
                        registration process as described in :rfc:`2.2`
    * :attr:`user` ref to a Django user
    * :attr:`redirect_uris` The list of allowed redirect uri. The string
                            consists of valid URLs separated by space
    * :attr:`post_logout_redirect_uris` The list of allowed redirect uris after
                                        an RP initiated logout. The string
                                        consists of valid URLs separated by space
    * :attr:`client_type` Client type as described in :rfc:`2.1`
    * :attr:`authorization_grant_type` Authorization flows available to the
                                       Application
    * :attr:`client_secret` Confidential secret issued to the client during
                            the registration process as described in :rfc:`2.2`
    * :attr:`name` Friendly name for the Application
    confidentialpublicConfidentialPubliczauthorization-codeimplicitpasswordzclient-credentialszopenid-hybridzAuthorization codeImplicitzResource owner password-basedzClient credentialszOpenID connect hybrid RS256HS256zNo OIDC supportzRSA with SHA-2 256zHMAC with SHA-2 256Tprimary_keyd   )
max_lengthuniquedefaultdb_index%(app_label)s_%(class)s)related_namenullblank	on_deletez"Allowed URIs list, space separated)rT   	help_textz.Allowed Post Logout URIs list, space separated)rT   rV   rO       )rM   choices   z4Hashed on Save. Copy it now if this is a new secret.)rM   rT   rO   rP   rV   )rO   )rM   rT   Fauto_now_addauto_now   )rM   rX   rO   rT   z4Allowed origins list to enable CORS, space separatedc                   @      e Zd ZdZdS )zAbstractApplication.MetaTNr3   r4   r5   abstractr0   r0   r0   r1   Meta       rb   c                 C   s   | j p| jS N)name	client_idr'   r0   r0   r1   __str__      zAbstractApplication.__str__c                 C   s<   | j r| j  }t|dkr| j  dS t J d)zP
        Returns the default redirect_uri, *if* only one is registered.
        r   r   FzIf you are using implicit, authorization_code or all-in-one grant_type, you must define redirect_uris field in your Application model)redirect_urissplitlenpopr   MissingRedirectURIError)r'   urisr0   r0   r1   default_redirect_uri   s   
z(AbstractApplication.default_redirect_uric                 C      t || j S )z{
        Checks if given url is one of the items in :attr:`redirect_uris` string

        :param uri: Url to check
        )redirect_to_uri_allowedrj   rk   r'   urir0   r0   r1   redirect_uri_allowed      z(AbstractApplication.redirect_uri_allowedc                 C   rq   )z
        Checks if given URI is one of the items in :attr:`post_logout_redirect_uris` string

        :param uri: URI to check
        )rr   post_logout_redirect_urisrk   rs   r0   r0   r1    post_logout_redirect_uri_allowed   rv   z4AbstractApplication.post_logout_redirect_uri_allowedc                 C   s   | j o
t|| j  S )z
        Checks if given origin is one of the items in :attr:`allowed_origins` string

        :param origin: Origin to check
        )allowed_originsis_origin_allowedrk   )r'   originr0   r0   r1   origin_allowed   s   z"AbstractApplication.origin_allowedc           	      C   s  ddl m} tjtjtjf}tjtjf}| j  }t	dd | 
 D }|r:t|dddd}|D ]}|| q2n| j|v rJ|tdj| jd	| j  }|rbttjd
}|D ]}|| q[| jtjkrqtjsq|td| jtjkrt| j|v | jtjkfr|tdd S d S )Nr   )ValidationErrorc                 s   s    | ]}|  V  qd S rd   )lower).0sr0   r0   r1   	<genexpr>   s    z,AbstractApplication.clean.<locals>.<genexpr>zredirect uriT)re   
allow_pathallow_queryz:redirect_uris cannot be empty with grant_type {grant_type})
grant_typezallowed origin6You must set OIDC_RSA_PRIVATE_KEY to use RSA algorithmz2You cannot use HS256 with public grants or clients)django.core.exceptionsr}   r?   GRANT_AUTHORIZATION_CODEGRANT_IMPLICITGRANT_OPENID_HYBRIDrj   striprk   setget_allowed_schemesr   authorization_grant_type_formatry   r   ALLOWED_SCHEMES	algorithmRS256_ALGORITHMOIDC_RSA_PRIVATE_KEYHS256_ALGORITHManyclient_typeApplicationCLIENT_PUBLIC)	r'   r}   grant_typeshs_forbidden_grant_typesrj   allowed_schemes	validatorrt   ry   r0   r0   r1   clean   sP   



zAbstractApplication.cleanc                 C   s   t dt| jgdS )Nzoauth2_provider:detail)args)r   strpkrg   r0   r0   r1   get_absolute_url   s   z$AbstractApplication.get_absolute_urlc                 C   s   t jS )z
        Returns the list of redirect schemes allowed by the Application.
        By default, returns `ALLOWED_REDIRECT_URI_SCHEMES`.
        )r   ALLOWED_REDIRECT_URI_SCHEMESrg   r0   r0   r1   r      s   z'AbstractApplication.get_allowed_schemesc                 G   s
   | j |v S rd   )r   )r'   r   r0   r0   r1   allows_grant_type     
z%AbstractApplication.allows_grant_typec                 C   s   dS )z
        Determines whether the application can be used.

        :param request: The oauthlib.common.Request being processed.
        Tr0   )r'   requestr0   r0   r1   	is_usable  s   zAbstractApplication.is_usablec                 C   sL   | j tjkrtjstdttjS | j tjkr"tj	dt
| jdS td)Nr   oct)ktykz/This application does not support signed tokens)r   r?   r   r   r   r
   r   r   r   JWKr   client_secretrg   r0   r0   r1   jwk_key  s   
zAbstractApplication.jwk_keyN);r3   r4   r5   __doc__CLIENT_CONFIDENTIALr   r   CLIENT_TYPESr   r   GRANT_PASSWORDGRANT_CLIENT_CREDENTIALSr   GRANT_TYPESNO_ALGORITHMr   r   ALGORITHM_TYPESr   BigAutoFieldid	CharFieldr   rf   
ForeignKeyr   AUTH_USER_MODELCASCADEuser	TextFieldrj   rw   r   r   r   r   r   BooleanFieldr   re   skip_authorizationDateTimeFieldcreatedupdatedr   ry   rb   rh   propertyrp   ru   rx   r|   r   r   r   r   r   r   r0   r0   r0   r1   r?   9   s    










1r?   c                   @   s   e Zd Zdd ZdS )ApplicationManagerc                 C   s   | j |dS )Nrf   )get)r'   rf   r0   r0   r1   get_by_natural_key  ri   z%ApplicationManager.get_by_natural_keyN)r3   r4   r5   r   r0   r0   r0   r1   r     s    r   c                   @   s,   e Zd Ze ZG dd dejZdd ZdS )r   c                   @   r_   )zApplication.Meta!OAUTH2_PROVIDER_APPLICATION_MODELNr3   r4   r5   	swappabler0   r0   r0   r1   rb     rc   rb   c                 C   s   | j fS rd   r   rg   r0   r0   r1   natural_key"  s   zApplication.natural_keyN)r3   r4   r5   r   objectsr?   rb   r   r0   r0   r0   r1   r     s    r   c                   @   s   e Zd ZdZdZdZedfedffZejddZ	ej
ejejddZejddd	Zej
ejejd
Ze Ze ZejddZejddZejddZejddddZejdddedZejddddZejddZdd Zdd Z dd Z!G dd dZ"dS )AbstractGranta  
    A Grant instance represents a token with a short lifetime that can
    be swapped for an access token, as described in :rfc:`4.1.2`

    Fields:

    * :attr:`user` The Django user who requested the grant
    * :attr:`code` The authorization code generated by the authorization server
    * :attr:`application` Application instance this grant was asked for
    * :attr:`expires` Expire time in seconds, defaults to
                      :data:`settings.AUTHORIZATION_CODE_EXPIRE_SECONDS`
    * :attr:`redirect_uri` Self explained
    * :attr:`scope` Required scopes, optional
    * :attr:`code_challenge` PKCE code challenge
    * :attr:`code_challenge_method` PKCE code challenge transform algorithm
    plainS256TrJ   rQ   rU   rR   rY   )rM   rN   rU   rT   rZ   r\      rG   )rM   rT   rO   
   )rM   rT   rO   rX   c                 C      | j sdS t | j kS z@
        Check token expiration with timezone awareness
        Texpiresr   nowrg   r0   r0   r1   
is_expiredQ     zAbstractGrant.is_expiredc                 C   s
   || j kS rd   )redirect_urirs   r0   r0   r1   ru   Z  r   z"AbstractGrant.redirect_uri_allowedc                 C      | j S rd   )coderg   r0   r0   r1   rh   ]     zAbstractGrant.__str__c                   @   r_   )zAbstractGrant.MetaTNr`   r0   r0   r0   r1   rb   `  rc   rb   N)#r3   r4   r5   r   CODE_CHALLENGE_PLAINCODE_CHALLENGE_S256CODE_CHALLENGE_METHODSr   r   r   r   r   r   r   r   r   r   r   APPLICATION_MODELapplicationr   r   r   r   scoper   r   code_challengecode_challenge_methodnonceclaimsr   ru   rh   rb   r0   r0   r0   r1   r   &  s4    
	r   c                   @      e Zd ZG dd dejZdS )Grantc                   @   r_   )z
Grant.MetaOAUTH2_PROVIDER_GRANT_MODELNr   r0   r0   r0   r1   rb   e  rc   rb   N)r3   r4   r5   r   rb   r0   r0   r0   r1   r   d      r   c                   @   s  e Zd ZdZejddZejej	ej
ddddZejejejddddZe Zeddddd	Zejejej
ddd
dZejejej
dddZe ZejddZejddZejddZdddZdd Zdd Z dd Z!e"dd Z#dd Z$G dd dZ%dS )AbstractAccessTokena  
    An AccessToken instance represents the actual access token to
    access user's resources, as in :rfc:`5`.

    Fields:

    * :attr:`user` The Django user representing resources" owner
    * :attr:`source_refresh_token` If from a refresh, the consumed RefeshToken
    * :attr:`token` Access token
    * :attr:`application` Application instance
    * :attr:`expires` Date and time of token expiration, in DateTime format
    * :attr:`scope` Allowed scopes
    TrJ   rQ   rU   rT   rS   rR   refreshed_access_token@   F)rM   rT   rN   rP   access_tokenrU   rT   rS   r   rZ   r\   Nc                 C      |    o	| |S z
        Checks if the access token is valid.

        :param scopes: An iterable containing the scopes to check or None
        r   allow_scopesr'   scopesr0   r0   r1   is_valid     zAbstractAccessToken.is_validc                 C   r   r   r   rg   r0   r0   r1   r     r   zAbstractAccessToken.is_expiredc                 C   (   |sdS t | j }t |}||S z
        Check if the token allows the provided scopes

        :param scopes: An iterable containing the scopes to check
        Tr   r   rk   issubsetr'   r   provided_scopesresource_scopesr0   r0   r1   r     
   
z AbstractAccessToken.allow_scopesc                 C      |    dS )z
        Convenience method to uniform tokens" interface, for now
        simply remove this token from the database in order to revoke it.
        Ndeleterg   r0   r0   r1   revoke     zAbstractAccessToken.revokec                    *   t   }| j   fdd| D S )k
        Returns a dictionary of allowed scope names (as keys) with their descriptions (as values)
        c                       i | ]\}}| v r||qS r0   r0   r   re   desctoken_scopesr0   r1   
<dictcomp>      z.AbstractAccessToken.scopes.<locals>.<dictcomp>r   get_all_scopesr   rk   itemsr'   
all_scopesr0   r  r1   r        

zAbstractAccessToken.scopesc                 C   r   rd   r9   rg   r0   r0   r1   rh     r   zAbstractAccessToken.__str__c                   @   r_   )zAbstractAccessToken.MetaTNr`   r0   r0   r0   r1   rb     rc   rb   rd   )&r3   r4   r5   r   r   r   r   r   r   r   r   r   OneToOneFieldr   REFRESH_TOKEN_MODELSET_NULLsource_refresh_tokenr   r9   r8   token_checksumID_TOKEN_MODELid_tokenr   r   r   r   r   r   r   r   r   r   r  r   r   rh   rb   r0   r0   r0   r1   r   i  sb    
	
r   c                   @   r   )AccessTokenc                   @   r_   )zAccessToken.Meta"OAUTH2_PROVIDER_ACCESS_TOKEN_MODELNr   r0   r0   r0   r1   rb     rc   rb   N)r3   r4   r5   r   rb   r0   r0   r0   r1   r    r   r  c                   @   s   e Zd ZdZejddZejej	ej
ddZejddZejejej
dZejejejddd	d
ZejddddZejddZejddZejddZdd Zdd ZG dd dZdS )AbstractRefreshTokena  
    A RefreshToken instance represents a token that can be swapped for a new
    access token when it expires.

    Fields:

    * :attr:`user` The Django user representing resources" owner
    * :attr:`token` Token value
    * :attr:`application` Application instance
    * :attr:`access_token` AccessToken instance this refresh token is
                           bounded to
    * :attr:`revoked` Timestamp of when this refresh token was revoked
    TrJ   rQ   r   rY   )rM   r   refresh_tokenr   F)rS   rT   editablerZ   r\   )rS   c              	   C   s   t  }t|}t }tj|dP |j j| j	dd}|s(	 W d   dS t
|d } t|j |jj| jd  W d   n1 sHw   Y  d| _t | _|   W d   dS 1 sdw   Y  dS )zQ
        Mark this refresh token revoked and revoke related access token
        )usingT)r   revoked__isnullNr   )r   )get_access_token_modelr   db_for_writeget_refresh_token_modelr   atomicr   select_for_updatefilterr   listr   DoesNotExistr   access_token_idr  r   r   r   revokedsave)r'   access_token_modelaccess_token_databaserefresh_token_modelr9   r0   r0   r1   r    s    


"zAbstractRefreshToken.revokec                 C   r   rd   r  rg   r0   r0   r1   rh     r   zAbstractRefreshToken.__str__c                   @   s   e Zd ZdZdZdS )zAbstractRefreshToken.MetaT)r9   r/  N)r3   r4   r5   ra   unique_togetherr0   r0   r0   r1   rb     s    rb   N)r3   r4   r5   r   r   r   r   r   r   r   r   r   r   r9   r   r   r   r  ACCESS_TOKEN_MODELr  r   	UUIDFieldtoken_familyr   r   r   r/  r  rh   rb   r0   r0   r0   r1   r!    s,    
r!  c                   @   r   )RefreshTokenc                   @   r_   )zRefreshToken.Meta#OAUTH2_PROVIDER_REFRESH_TOKEN_MODELNr   r0   r0   r0   r1   rb   !  rc   rb   N)r3   r4   r5   r!  rb   r0   r0   r0   r1   r8     r   r8  c                   @   s   e Zd ZdZejddZejej	ej
ddddZejdejdddZejejej
ddd	Ze Zejdd
ZejddZejddZdddZdd Zdd Zdd Zedd Zdd ZG dd dZ dS )AbstractIDTokena4  
    An IDToken instance represents the actual token to
    access user's resources, as in :openid:`2`.

    Fields:

    * :attr:`user` The Django user representing resources' owner
    * :attr:`jti` ID token JWT Token ID, to identify an individual token
    * :attr:`application` Application instance
    * :attr:`expires` Date and time of token expiration, in DateTime format
    * :attr:`scope` Allowed scopes
    * :attr:`created` Date and time of token creation, in DateTime format
    * :attr:`updated` Date and time of token update, in DateTime format
    TrJ   rQ   r   FzJWT Token ID)rN   rO   r#  verbose_namer   r   rZ   r\   Nc                 C   r   r   r   r   r0   r0   r1   r   J  r   zAbstractIDToken.is_validc                 C   r   r   r   rg   r0   r0   r1   r   R  r   zAbstractIDToken.is_expiredc                 C   r   r   r   r   r0   r0   r1   r   [  r  zAbstractIDToken.allow_scopesc                 C   r  )z
        Convenience method to uniform tokens' interface, for now
        simply remove this token from the database in order to revoke it.
        Nr  rg   r0   r0   r1   r  i  r  zAbstractIDToken.revokec                    r  )r	  c                    r
  r0   r0   r  r  r0   r1   r  w  r  z*AbstractIDToken.scopes.<locals>.<dictcomp>r  r  r0   r  r1   r   p  r  zAbstractIDToken.scopesc                 C   s   dj | dS )Nz$JTI: {self.jti} User: {self.user_id}rg   )r   rg   r0   r0   r1   rh   y  ri   zAbstractIDToken.__str__c                   @   r_   )zAbstractIDToken.MetaTNr`   r0   r0   r0   r1   rb   |  rc   rb   rd   )!r3   r4   r5   r   r   r   r   r   r   r   r   r   r6  uuiduuid4jtir   r   r   r   r   r   r   r   r   r   r   r   r  r   r   rh   rb   r0   r0   r0   r1   r:  %  s:    
	
r:  c                   @   r   )IDTokenc                   @   r_   )zIDToken.MetaOAUTH2_PROVIDER_ID_TOKEN_MODELNr   r0   r0   r0   r1   rb     rc   rb   N)r3   r4   r5   r:  rb   r0   r0   r0   r1   r?    r   r?  c                   C      t tjS )z<Return the Application model that is active in this project.)r   	get_modelr   r   r0   r0   r0   r1   get_application_model     rC  c                   C   rA  )z6Return the Grant model that is active in this project.)r   rB  r   GRANT_MODELr0   r0   r0   r1   get_grant_model  rD  rF  c                   C   rA  )z<Return the AccessToken model that is active in this project.)r   rB  r   r5  r0   r0   r0   r1   r&    rD  r&  c                   C   rA  )z8Return the IDToken model that is active in this project.)r   rB  r   r  r0   r0   r0   r1   get_id_token_model  rD  rG  c                   C   rA  )z=Return the RefreshToken model that is active in this project.)r   rB  r   r  r0   r0   r0   r1   r(    rD  r(  c                  C   
   t j} | S )zBReturn the Application admin class that is active in this project.)r   APPLICATION_ADMIN_CLASS)application_admin_classr0   r0   r1   get_application_admin_class     rK  c                  C   rH  )zBReturn the AccessToken admin class that is active in this project.)r   ACCESS_TOKEN_ADMIN_CLASS)access_token_admin_classr0   r0   r1   get_access_token_admin_class  rL  rO  c                  C   rH  )z<Return the Grant admin class that is active in this project.)r   GRANT_ADMIN_CLASS)grant_admin_classr0   r0   r1   get_grant_admin_class  rL  rR  c                  C   rH  )z>Return the IDToken admin class that is active in this project.)r   ID_TOKEN_ADMIN_CLASS)id_token_admin_classr0   r0   r1   get_id_token_admin_class  rL  rU  c                  C   rH  )zCReturn the RefreshToken admin class that is active in this project.)r   REFRESH_TOKEN_ADMIN_CLASS)refresh_token_admin_classr0   r0   r1   get_refresh_token_admin_class  rL  rX  c                  C   sr  dd } t  }d }t }t }t }t }tj}|r9t|t	s5zt	|d}W n t
y4   d}t|w || }|rjtj|d}	|j|	}
| |
|	}td| tj|d}|j|}| ||}td| ntd	| tjd
|d}|j|}| ||}td| tjd
|d}|j|}| ||}td| tj|d}|j|}| ||}td| d S )Nc           
      S   s   t j}t j}|   }}|rH| jdddd | }| }| jjjt|d	  t
| d||  d | jj|} t| |  }|s| jj| }|| }	|	S )Nr   T)flat)id__inz tokens deleted, z left)r   CLEAR_EXPIRED_TOKENS_BATCH_SIZE#CLEAR_EXPIRED_TOKENS_BATCH_INTERVALcountvalues_listmodelr   r+  r,  r  r#   r$   timesleep)
querysetqueryr[  r\  
current_nostart_noflat_querysetbatch_lengthstop_nodeletedr0   r0   r1   batch_delete  s   
	z#clear_expired.<locals>.batch_delete)secondszBREFRESH_TOKEN_EXPIRE_SECONDS must be either a timedelta or seconds)revoked__ltz!%s Revoked refresh tokens deleted)access_token__expires__ltz!%s Expired refresh tokens deletedz3refresh_expire_at is %s. No refresh tokens deleted.T)refresh_token__isnullexpires__ltz %s Expired access tokens deleted)access_token__isnullro  z%s Expired ID tokens deleted)ro  z%s Expired grant tokens deleted)r   r   r&  r(  rG  rF  r   REFRESH_TOKEN_EXPIRE_SECONDS
isinstancer   	TypeErrorr
   r   Qr   r+  r#   info)rj  r   refresh_expire_atr1  r3  id_token_modelgrant_modelrq  erevoked_queryr/  revoked_deleted_noexpired_queryexpiredexpired_deleted_noaccess_token_queryaccess_tokensaccess_tokens_delete_noid_token_query	id_tokensid_tokens_delete_nogrants_querygrantsgrants_deleted_nor0   r0   r1   clear_expired  sN   





r  c                 C   s   t | }tt|j}|D ]J}t |}|jdko!|jdv o!|jdu }|r6|j|jkr6|j|jkr6|j|jksH|j|jkrW|j|jkrW|j|jkrWtt|j}|	|rW dS qdS )a  
    Checks if a given uri can be redirected to based on the provided allowed_uris configuration.

    On top of exact matches, this function also handles loopback IPs based on RFC 8252.

    :param uri: URI to check
    :param allowed_uris: A list of URIs that are allowed
    http)z	127.0.0.1z::1NTF)
r   r   r   rc  schemehostnameportpathnetlocr   )rt   allowed_uris
parsed_uriuqs_setallowed_uriparsed_allowed_uriallowed_uri_is_loopbackaqs_setr0   r0   r1   rr     s,   


rr   c                 C   sL   t | }|jtjvrdS |D ]}t |}|j|jkr#|j|jkr# dS qdS )z
    Checks if a given origin uri is allowed based on the provided allowed_origins configuration.

    :param origin: Origin URI to check
    :param allowed_origins: A list of Origin URIs that are allowed
    FT)r   r  r   r   r  )r{   ry   parsed_originallowed_originparsed_allowed_originr0   r0   r1   rz   0  s   rz   )Or:   loggingr`  r<  
contextlibr   datetimer   urllib.parser   r   django.appsr   django.confr   django.contrib.auth.hashersr   r	   r   r
   	django.dbr   r   r   django.urlsr   django.utilsr   django.utils.translationr   r   jwcryptor   jwcrypto.commonr   oauthlib.oauth2.rfc6749r   
generatorsr   r   r   r   r   utilsr   
validatorsr   	getLoggerr3   r#   r   r   r8   Modelr?   Managerr   r   r   r   r   r  r!  r8  r:  r?  rC  rF  r&  rG  r(  rK  rO  rR  rU  rX  r  rr   rz   r0   r0   r0   r1   <module>   sf    
 _
>oC[F.