ó
O'—^c           @  s’  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 d	 d
 l 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 e d e j f d „  ƒ  Yƒ Z d e f d „  ƒ  YZ  d e  j! _" e d e j f d „  ƒ  Yƒ Z# e d e j f d „  ƒ  Yƒ Z$ e d e j f d „  ƒ  Yƒ Z% d „  Z& d „  Z' d S(   iÿÿÿÿ(   t   unicode_literals(   t	   timedelta(   t   reverse(   t   modelst   transaction(   t   timezone(   t   ugettext_lazy(   t   python_2_unicode_compatible(   t   ImproperlyConfiguredi   (   t   oauth2_settings(   t   AUTH_USER_MODELt	   parse_qslt   urlparset	   get_model(   t   generate_client_secrett   generate_client_id(   t   validate_urist   AbstractApplicationc        	   B  sÂ  e  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
 e e d	 ƒ f e e d
 ƒ f e	 e d ƒ f e
 e d ƒ f f Z e j d d d e d e d e ƒ Z e j e d d ƒZ e d ƒ Z e j d e d e g d e ƒ Z e j d d d e ƒ Z e j d d d e ƒ Z e j d d d e d e d e ƒ Z e j d d d e ƒ Z e j d e ƒ Z d d" d „  ƒ  YZ  e! d „  ƒ Z" d „  Z# d „  Z$ d  „  Z% d! „  Z& RS(#   uµ  
    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:`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
    u   confidentialu   publicu   Confidentialu   Publicu   authorization-codeu   implicitu   passwordu   client-credentialsu   Authorization codeu   Implicitu   Resource owner password-basedu   Client credentialst
   max_lengthid   t   uniquet   defaultt   db_indext   related_nameu   %(app_label)s_%(class)su"   Allowed URIs list, space separatedt	   help_textt
   validatorst   blanki    t   choicesiÿ   t   Metac           B  s   e  Z e Z RS(    (   t   __name__t
   __module__t   Truet   abstract(    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyR   H   s   c         C  s5   |  j  r |  j  j ƒ  j d ƒ St s1 t d ƒ ‚ d S(   uz   
        Returns the default redirect_uri extracting the first item from
        the :attr:`redirect_uris` string
        i    u„   If you are using implicit, authorization_codeor all-in-one grant_type, you must define redirect_uris field in your Application modelN(   t   redirect_urist   splitt   popt   Falset   AssertionError(   t   self(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   default_redirect_uriK   s    	c         C  s¬   x¥ |  j  j ƒ  D]” } t | ƒ } t | ƒ } | j | j k r | j | j k r | j | j k r t t | j ƒ ƒ } t t | j ƒ ƒ } | j	 | ƒ r¤ t
 Sq q Wt S(   u{   
        Checks if given url is one of the items in :attr:`redirect_uris` string

        :param uri: Url to check
        (   R    R!   R   t   schemet   netloct   patht   setR   t   queryt   issubsetR   R#   (   R%   t   urit   allowed_urit   parsed_allowed_urit
   parsed_urit   aqs_sett   uqs_set(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   redirect_uri_allowedX   s    c         C  s`   d d l  m } |  j r\ |  j t j t j f k r\ t d ƒ } | | j |  j ƒ ƒ ‚ n  d  S(   Niÿÿÿÿ(   t   ValidationErroru4   Redirect_uris could not be empty with {0} grant_type(	   t   django.core.exceptionsR4   R    t   authorization_grant_typeR   t   GRANT_AUTHORIZATION_CODEt   GRANT_IMPLICITt   _t   format(   R%   R4   t   error(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   cleann   s    
c         C  s   t  d d t |  j ƒ g ƒS(   Nu   oauth2_provider:detailt   args(   R   t   strt   id(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   get_absolute_urlw   s    c         C  s   |  j  p |  j S(   N(   t   namet	   client_id(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   __str__z   s    (    ('   R   R   t   __doc__t   CLIENT_CONFIDENTIALt   CLIENT_PUBLICR9   t   CLIENT_TYPESR7   R8   t   GRANT_PASSWORDt   GRANT_CLIENT_CREDENTIALSt   GRANT_TYPESR   t	   CharFieldR   R   RB   t
   ForeignKeyR
   t   userR   t	   TextFieldR   R    t   client_typeR6   R   t   client_secretRA   t   BooleanFieldR#   t   skip_authorizationR   t   propertyR&   R3   R<   R@   RC   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyR      s@   					t   Applicationc           B  s   e  Z RS(    (   R   R   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRT   ~   s   u!   OAUTH2_PROVIDER_APPLICATION_MODELt   Grantc           B  s’   e  Z d  Z e j e ƒ Z e j d d d e ƒ Z	 e j e
 j ƒ Z e j ƒ  Z e j d d ƒ Z e j d e ƒ Z d „  Z d „  Z d „  Z RS(   uI  
    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
    R   iÿ   R   R   c         C  s    |  j  s t St j ƒ  |  j  k S(   u@   
        Check token expiration with timezone awareness
        (   t   expiresR   R   t   now(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt
   is_expiredœ   s    	c         C  s   | |  j  k S(   N(   t   redirect_uri(   R%   R-   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyR3   ¥   s    c         C  s   |  j  S(   N(   t   code(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRC   ¨   s    (   R   R   RD   R   RL   R
   RM   RK   R   RZ   R	   t   APPLICATION_MODELt   applicationt   DateTimeFieldRV   RY   RN   t   scopeRX   R3   RC   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRU   …   s   			t   AccessTokenc           B  s°   e  Z d  Z e j e d e d e ƒZ e j d d d e ƒ Z	 e j e
 j ƒ Z e j ƒ  Z e j d e ƒ Z d d „ Z d „  Z d „  Z d	 „  Z e d
 „  ƒ Z d „  Z RS(   u‚  
    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:`token` Access token
    * :attr:`application` Application instance
    * :attr:`expires` Date and time of token expiration, in DateTime format
    * :attr:`scope` Allowed scopes
    R   t   nullR   iÿ   R   c         C  s   |  j  ƒ  o |  j | ƒ S(   u   
        Checks if the access token is valid.

        :param scopes: An iterable containing the scopes to check or None
        (   RX   t   allow_scopes(   R%   t   scopes(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   is_validÀ   s    c         C  s    |  j  s t St j ƒ  |  j  k S(   u@   
        Check token expiration with timezone awareness
        (   RV   R   R   RW   (   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRX   È   s    	c         C  s8   | s
 t  St |  j j ƒ  ƒ } t | ƒ } | j | ƒ S(   u‚   
        Check if the token allows the provided scopes

        :param scopes: An iterable containing the scopes to check
        (   R   R*   R^   R!   R,   (   R%   Rb   t   provided_scopest   resource_scopes(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRa   Ñ   s
    c         C  s   |  j  ƒ  d S(   u”   
        Convenience method to uniform tokens' interface, for now
        simply remove this token from the database in order to revoke it.
        N(   t   delete(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   revokeß   s    c           s   ‡  f d †  t  j j ƒ  Dƒ S(   uk   
        Returns a dictionary of allowed scope names (as keys) with their descriptions (as values)
        c           s4   i  |  ]* \ } } | ˆ  j  j ƒ  k r | | “ q S(    (   R^   R!   (   t   .0RA   t   desc(   R%   (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pys
   <dictcomp>ë   s   	 (   R	   t   SCOPESt   items(   R%   (    (   R%   s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRb   æ   s    c         C  s   |  j  S(   N(   t   token(   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRC   í   s    N(   R   R   RD   R   RL   R
   R   RM   RK   Rl   R	   R[   R\   R]   RV   RN   R^   t   NoneRc   RX   Ra   Rg   RS   Rb   RC   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyR_   ¬   s   				t   RefreshTokenc           B  sn   e  Z d  Z e j e ƒ Z e j d d d e ƒ Z	 e j e
 j ƒ Z e j e d d ƒZ d „  Z d „  Z RS(   u~  
    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
    R   iÿ   R   R   u   refresh_tokenc         C  s-   t  j j d |  j j ƒ j ƒ  |  j ƒ  d S(   uK   
        Delete this refresh token along with related access token
        R?   N(   R_   t   objectst   gett   access_tokenR?   Rg   Rf   (   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRg     s    c         C  s   |  j  S(   N(   Rl   (   R%   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRC     s    (   R   R   RD   R   RL   R
   RM   RK   R   Rl   R	   R[   R\   t   OneToOneFieldR_   Rq   Rg   RC   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyRn   ñ   s   		c          C  s‚   y t  j j d ƒ \ }  } Wn# t k
 rA d } t | ƒ ‚ n Xt |  | ƒ } | d k r~ d } t | j t  j ƒ ƒ ‚ n  | S(   u>    Return the Application model that is active in this project. u   .u<   APPLICATION_MODEL must be of the form 'app_label.model_name'uA   APPLICATION_MODEL refers to model {0} that has not been installedN(   R	   R[   R!   t
   ValueErrorR   R   Rm   R:   (   t	   app_labelt
   model_namet   et	   app_model(    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   get_application_model  s    c       	   C  sê   t  j ƒ  }  d  } t j } | ry t | t ƒ sl y t d | ƒ } Wql t k
 rh d } t | ƒ ‚ ql Xn  |  | } n  t	 j
 ƒ  _ | r¨ t j j d | ƒ j ƒ  n  t j j d t d |  ƒ j ƒ  t j j d |  ƒ j ƒ  Wd  QXd  S(   Nt   secondsuB   REFRESH_TOKEN_EXPIRE_SECONDS must be either a timedelta or secondst   access_token__expires__ltt   refresh_token__isnullt   expires__lt(   R   RW   Rm   R	   t   REFRESH_TOKEN_EXPIRE_SECONDSt
   isinstanceR   t	   TypeErrorR   R   t   atomicRn   Ro   t   filterRf   R_   R   RU   (   RW   t   refresh_expire_atR}   Rv   (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   clear_expired  s     	N((   t
   __future__R    t   datetimeR   t   django.core.urlresolversR   t	   django.dbR   R   t   django.utilsR   t   django.utils.translationR   R9   t   django.utils.encodingR   R5   R   t   settingsR	   t   compatR
   R   R   R   t
   generatorsR   R   R   R   t   ModelR   RT   t   _metat	   swappableRU   R_   Rn   Rx   Rƒ   (    (    (    s8   /tmp/pip-unpacked-wheel-ndW12l/oauth2_provider/models.pyt   <module>   s.   "j&D	