o
    RDi}.                     @   sj  d 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d	d
ZeeddZeeddZeeddZeeddZeeddZi dddddddd
dd
di ddd d!d"d#d$d%d&d'd(d)d*d+gd,d-d.d/d0d1d2d3d4d5i d6d5d7d
d8dd9d:d;d<d=d:d>ed?ed@edAedBedCdDdEdFdGdHdIdJdKdLdMdNi dOdPdQgdRdQgdSd:dTdUdVdUdWdUdXg dYdZd[g d\d]d^gd_d`dagdbd:dcd<ddd:ded<dfd<dgg g d
d
d
d5dhd<d:diddj
ZdkZdlZdmdn Zdodp ZG dqdr dreZG dsdt dtZeeeeeZdudv Zee d
S )waX  
This module is largely inspired by django-rest-framework settings.

Settings for the OAuth2 Provider are all namespaced in the OAUTH2_PROVIDER setting.
For example your project's `settings.py` file might look like this:

OAUTH2_PROVIDER = {
    "CLIENT_ID_GENERATOR_CLASS":
        "oauth2_provider.generators.ClientIdGenerator",
    "CLIENT_SECRET_GENERATOR_CLASS":
        "oauth2_provider.generators.ClientSecretGenerator",
}

This module provides the `oauth2_settings` object, that is used to access
OAuth2 Provider settings, checking for user settings first, then falling
back to the defaults.
    )settings)ImproperlyConfigured)setting_changed)HttpRequest)reverse)import_string)RequestOAUTH2_PROVIDERN!OAUTH2_PROVIDER_APPLICATION_MODELzoauth2_provider.Application"OAUTH2_PROVIDER_ACCESS_TOKEN_MODELzoauth2_provider.AccessTokenOAUTH2_PROVIDER_ID_TOKEN_MODELzoauth2_provider.IDTokenOAUTH2_PROVIDER_GRANT_MODELzoauth2_provider.Grant#OAUTH2_PROVIDER_REFRESH_TOKEN_MODELzoauth2_provider.RefreshTokenCLIENT_ID_GENERATOR_CLASSz,oauth2_provider.generators.ClientIdGeneratorCLIENT_SECRET_GENERATOR_CLASSz0oauth2_provider.generators.ClientSecretGeneratorCLIENT_SECRET_GENERATOR_LENGTH   ACCESS_TOKEN_GENERATORREFRESH_TOKEN_GENERATOREXTRA_SERVER_KWARGSOAUTH2_SERVER_CLASSzoauthlib.oauth2.ServerOIDC_SERVER_CLASSzoauthlib.openid.ServerOAUTH2_VALIDATOR_CLASSz1oauth2_provider.oauth2_validators.OAuth2ValidatorOAUTH2_BACKEND_CLASSz,oauth2_provider.oauth2_backends.OAuthLibCoreSCOPESzReading scopezWriting scope)readwriteDEFAULT_SCOPES__all__SCOPES_BACKEND_CLASSz%oauth2_provider.scopes.SettingsScopes
READ_SCOPEr   WRITE_SCOPEr   !AUTHORIZATION_CODE_EXPIRE_SECONDS<   ACCESS_TOKEN_EXPIRE_SECONDSi  ID_TOKEN_EXPIRE_SECONDSREFRESH_TOKEN_EXPIRE_SECONDS"REFRESH_TOKEN_GRACE_PERIOD_SECONDSREFRESH_TOKEN_REUSE_PROTECTIONFROTATE_REFRESH_TOKENTERROR_RESPONSE_WITH_SCOPESAPPLICATION_MODELACCESS_TOKEN_MODELID_TOKEN_MODELGRANT_MODELREFRESH_TOKEN_MODELAPPLICATION_ADMIN_CLASSz&oauth2_provider.admin.ApplicationAdminACCESS_TOKEN_ADMIN_CLASSz&oauth2_provider.admin.AccessTokenAdminGRANT_ADMIN_CLASSz oauth2_provider.admin.GrantAdminID_TOKEN_ADMIN_CLASSz"oauth2_provider.admin.IDTokenAdminREFRESH_TOKEN_ADMIN_CLASSz'oauth2_provider.admin.RefreshTokenAdminREQUEST_APPROVAL_PROMPTforceALLOWED_REDIRECT_URI_SCHEMEShttphttpsALLOWED_SCHEMESOIDC_ENABLEDOIDC_ISS_ENDPOINT OIDC_USERINFO_ENDPOINTOIDC_RSA_PRIVATE_KEYOIDC_RSA_PRIVATE_KEYS_INACTIVEOIDC_JWKS_MAX_AGE_SECONDSi  OIDC_RESPONSE_TYPES_SUPPORTED)codetokenid_tokenzid_token tokenz
code tokenzcode id_tokenzcode id_token tokenOIDC_SUBJECT_TYPES_SUPPORTEDpublic*OIDC_TOKEN_ENDPOINT_AUTH_METHODS_SUPPORTEDclient_secret_postclient_secret_basic OIDC_RP_INITIATED_LOGOUT_ENABLED&OIDC_RP_INITIATED_LOGOUT_ALWAYS_PROMPT-OIDC_RP_INITIATED_LOGOUT_STRICT_REDIRECT_URIS.OIDC_RP_INITIATED_LOGOUT_ACCEPT_EXPIRED_TOKENS&OIDC_RP_INITIATED_LOGOUT_DELETE_TOKENS_SCOPESUTCi'  )
_DEFAULT_SCOPES!RESOURCE_SERVER_INTROSPECTION_URLRESOURCE_SERVER_AUTH_TOKEN)RESOURCE_SERVER_INTROSPECTION_CREDENTIALS%RESOURCE_SERVER_TOKEN_CACHING_SECONDS#AUTHENTICATION_SERVER_EXP_TIME_ZONEPKCE_REQUIREDALWAYS_RELOAD_OAUTHLIB_CORECLEAR_EXPIRED_TOKENS_BATCH_SIZE#CLEAR_EXPIRED_TOKENS_BATCH_INTERVAL)
r   r   r   r   r   r   r7   rB   rF   rH   )r   r   r   r   r   r   r   r   r0   r1   r2   r3   r4   c                    sD   | du rdS t | trt|  S t | ttfr  fdd| D S | S )zm
    If the given setting is a string import notation,
    then perform the necessary import or imports.
    Nc                    s   g | ]}t | qS  )import_from_string).0itemsetting_namer\   Q/var/www/Datamplify/venv/lib/python3.10/site-packages/oauth2_provider/settings.py
<listcomp>   s    z"perform_import.<locals>.<listcomp>)
isinstancestrr]   listtuple)valra   r\   r`   rb   perform_import   s   

ri   c              
   C   s@   zt | W S  ty } zd| ||jj|f }t|d}~ww )zA
    Attempt to import a class from a string representation.
    z+Could not import %r for setting %r. %s: %s.N)r   ImportError	__class____name__)rh   ra   emsgr\   r\   rb   r]      s   
r]   c                   @   s   e Zd ZdZdd ZdS )_PhonyHttpRequestr8   c                 C   s   | j S )N)_schemeselfr\   r\   rb   _get_scheme   s   z_PhonyHttpRequest._get_schemeN)rl   
__module____qualname__rp   rs   r\   r\   r\   rb   ro      s    ro   c                   @   sR   e Zd ZdZdddZedd Zdd Zd	d
 Zedd Z	dd Z
dd ZdS )OAuth2ProviderSettingsz
    A settings object, that allows OAuth2 Provider settings to be accessed as properties.

    Any setting with string import paths will be automatically resolved
    and return the class, rather than the string literal.
    Nc                 C   s4   |pi | _ |pt| _|pt| _|pd| _t | _d S )Nr\   )_user_settingsDEFAULTSdefaultsIMPORT_STRINGSimport_strings	mandatoryset_cached_attrs)rr   user_settingsry   r{   r|   r\   r\   rb   __init__   s
   



zOAuth2ProviderSettings.__init__c                 C   s   t | dsttdi | _| jS )Nrw   r	   )hasattrgetattrr   rw   rq   r\   r\   rb   r      s   
z$OAuth2ProviderSettings.user_settingsc                 C   s   || j vrtd| z| j| }W n ty-   |dkr&| jr&| j d }n| j | }Y nw |r:|| jv r:t||}|dkrEt| j	 }|dkrjd| j
v rTt| j}ng }| j
D ]}|| jv rf|| qYtd| || | j| t| || |S )Nz"Invalid OAuth2Provider setting: %sr   r   rP   rR   r   z,Defined DEFAULT_SCOPES not present in SCOPES)ry   AttributeErrorr   KeyErrorr;   r{   ri   rf   r   keysr   rP   appendr   validate_settingr~   addsetattr)rr   attrrh   scoper\   r\   rb   __getattr__   s4   






z"OAuth2ProviderSettings.__getattr__c                 C   s"   |s|| j v rtd| d S d S )Nz'OAuth2Provider setting: %s is mandatory)r|   r   )rr   r   rh   r\   r\   rb   r      s   z'OAuth2ProviderSettings.validate_settingc                    s"    fdddD }|  j |S )a  
        This is used to communicate settings to oauth server.

        Takes relevant settings and format them accordingly.
        There's also EXTRA_SERVER_KWARGS that can override every value
        and is more flexible regarding keys and acceptable values
        but doesn't have import string magic or any additional
        processing, callables have to be assigned directly.
        For the likes of signed_token_generator it means something like

        {"token_generator": signed_token_generator(privkey, **kwargs)}
        c                    s   i | ]
\}}|t  |qS r\   )r   )r^   keyvaluerq   r\   rb   
<dictcomp>  s    
z8OAuth2ProviderSettings.server_kwargs.<locals>.<dictcomp>))token_expires_inr$   )refresh_token_expires_inr&   )token_generatorr   )refresh_token_generatorr   )updater   )rr   kwargsr\   rq   rb   server_kwargs   s
   
	z$OAuth2ProviderSettings.server_kwargsc                 C   s<   | j D ]}t| | q| j   t| drt| d d S d S )Nrw   )r~   delattrclearr   )rr   r   r\   r\   rb   reload  s   


zOAuth2ProviderSettings.reloadc                 C   sv   | j r| j S t|tr|}nt|tr%t }|j|_|jddr$d|_nt	d| |
td}|dtd  S )a  
        Helper function to get the OIDC issuer URL, either from the settings
        or constructing it from the passed request.

        If only an oauthlib request is available, a dummy django request is
        built from that and used to generate the URL.
        X_DJANGO_OAUTH_TOOLKIT_SECUREFr9   z4request must be a django or oauthlib request: got %rz+oauth2_provider:oidc-connect-discovery-infoNz!/.well-known/openid-configuration)r<   rd   r   r   ro   headersMETAgetrp   	TypeErrorbuild_absolute_urir   len)rr   requestdjango_requestabs_urlr\   r\   rb   oidc_issuer  s   

z"OAuth2ProviderSettings.oidc_issuer)NNNN)rl   rt   ru   __doc__r   propertyr   r   r   r   r   r   r\   r\   r\   rb   rv      s    

*
rv   c                  O   s    |d }|dkrt   d S d S )Nsettingr	   )oauth2_settingsr   )argsr   r   r\   r\   rb   reload_oauth2_settings3  s   r   ) r   django.confr   django.core.exceptionsr   django.core.signalsr   django.httpr   django.urlsr   django.utils.module_loadingr   oauthlib.commonr   r   USER_SETTINGSr+   r,   r-   r.   r/   rx   	MANDATORYrz   ri   r]   ro   rv   r   r   connectr\   r\   r\   rb   <module>   s   	

 !"#$%&'()*+459:;<=?@R{