U
    ÓZjiN  ã                   @   sÎ  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 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 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 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 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' dd%l"m(Z) dd&l"m*Z* G d'd(„ d(ƒZ+d)S )*é    )Údatetime)Ú	timedelta)Úabort)Úcurrent_app)Úflash)Úg)Úhas_app_context)Úredirect)Úrequest)Úsessioné   )ÚAUTH_HEADER_NAME)ÚCOOKIE_DURATION)ÚCOOKIE_HTTPONLY)ÚCOOKIE_NAME)ÚCOOKIE_SAMESITE)ÚCOOKIE_SECURE)ÚID_ATTRIBUTE)ÚLOGIN_MESSAGE)ÚLOGIN_MESSAGE_CATEGORY)ÚREFRESH_MESSAGE)ÚREFRESH_MESSAGE_CATEGORY)ÚSESSION_KEYS)ÚUSE_SESSION_FOR_NEXT)ÚAnonymousUserMixin)Úsession_protected)Úuser_accessed)Úuser_loaded_from_cookie)Úuser_loaded_from_request)Úuser_needs_refresh)Úuser_unauthorized)Ú_create_identifier)Ú_user_context_processor)Údecode_cookie)Úencode_cookie)Úexpand_login_view)Ú	login_url)Úmake_next_paramc                   @   sâ   e Zd ZdZd1dd„Zd2dd„Zd3dd	„Zd
d„ Zdd„ Ze	dd„ ƒZ
dd„ Ze	dd„ ƒZdd„ Zdd„ Zdd„ Zdd„ Zd4dd„Zdd„ Zd d!„ Zd"d#„ Zd$d%„ Zd&d'„ Zd(d)„ Zd*d+„ Zd,d-„ Ze	d.d/„ ƒZejd0d/„ ƒZdS )5ÚLoginManagerzûThis object is used to hold the settings used for logging in. Instances
    of :class:`LoginManager` are *not* bound to specific apps, so you can
    create one in the main body of your code and then bind it to your
    app in a factory function.
    NTc                 C   s~   t | _d | _i | _t| _t| _d | _t	| _
t| _d| _d | _d | _d | _t| _d | _d | _d | _t| _|d k	rz|  ||¡ d S )NÚbasic)r   Úanonymous_userÚ
login_viewÚblueprint_login_viewsr   Úlogin_messager   Úlogin_message_categoryÚrefresh_viewr   Úneeds_refresh_messager   Úneeds_refresh_message_categoryÚsession_protectionÚlocalize_callbackÚunauthorized_callbackÚneeds_refresh_callbackr   Zid_attributeÚ_user_callbackÚ_header_callbackÚ_request_callbackr!   Ú_session_identifier_generatorÚinit_app©ÚselfÚappÚadd_context_processor© r?   ú\/var/www/html/TRUCKING_PROJECT/venv/lib/python3.8/site-packages/flask_login/login_manager.pyÚ__init__1   s&    zLoginManager.__init__c                 C   s(   ddl }|jdtdd� |  ||¡ dS )zl
        This method has been deprecated. Please use
        :meth:`LoginManager.init_app` instead.
        r   NzY'setup_app' is deprecated and will be removed in Flask-Login 0.7. Use 'init_app' instead.é   ©Ú
stacklevel)ÚwarningsÚwarnÚDeprecationWarningr:   )r<   r=   r>   rE   r?   r?   r@   Ú	setup_appm   s    üzLoginManager.setup_appc                 C   s$   | |_ | | j¡ |r | t¡ dS )aç  
        Configures an application. This registers an `after_request` call, and
        attaches this `LoginManager` to it as `app.login_manager`.

        :param app: The :class:`flask.Flask` object to configure.
        :type app: :class:`flask.Flask`
        :param add_context_processor: Whether to add a context processor to
            the app that adds a `current_user` variable to the template.
            Defaults to ``True``.
        :type add_context_processor: bool
        N)Zlogin_managerZafter_requestÚ_update_remember_cookieZcontext_processorr"   r;   r?   r?   r@   r:   |   s    zLoginManager.init_appc                 C   sÖ   t  t ¡ ¡ | jr|  ¡ S tj| jkr6| jtj }n| j}|sHt	dƒ | j
r€| jdk	rpt|  | j
¡| jd� nt| j
| jd� tj}| dt¡rÀt|ƒ}|  ¡ td< t|tjƒtd< t|ƒ}nt|tjd�}t|ƒS )a¿  
        This is called when the user is required to log in. If you register a
        callback with :meth:`LoginManager.unauthorized_handler`, then it will
        be called. Otherwise, it will take the following actions:

            - Flash :attr:`LoginManager.login_message` to the user.

            - If the app is using blueprints find the login view for
              the current blueprint using `blueprint_login_views`. If the app
              is not using blueprints or the login view for the current
              blueprint is not specified use the value of `login_view`.

            - Redirect the user to the login view. (The page they were
              attempting to access will be passed in the ``next`` query
              string variable, so you can redirect there if present instead
              of the homepage. Alternatively, it will be added to the session
              as ``next`` if USE_SESSION_FOR_NEXT is set.)

        If :attr:`LoginManager.login_view` is not defined, then it will simply
        raise a HTTP 401 (Unauthorized) error instead.

        This should be returned from a view or before/after_request function,
        otherwise the redirect will have no effect.
        é‘  N©Úcategoryr   Ú_idÚnext©Znext_url)r    Úsendr   Ú_get_current_objectr4   r
   Ú	blueprintr,   r+   r   r-   r3   r   r.   ÚconfigÚgetr   r%   r9   r   r'   ÚurlÚmake_login_urlr	   )r<   r+   rS   r&   Úredirect_urlr?   r?   r@   ÚunauthorizedŽ   s.    

þ
zLoginManager.unauthorizedc                 C   s   || _ | jS )a>  
        This sets the callback for reloading a user from the session. The
        function you set should take a user ID (a ``str``) and return a
        user object, or ``None`` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        )r6   Úuser_callback©r<   Úcallbackr?   r?   r@   Úuser_loaderÈ   s    	zLoginManager.user_loaderc                 C   s   | j S )z;Gets the user_loader callback set by user_loader decorator.)r6   ©r<   r?   r?   r@   rY   Ô   s    zLoginManager.user_callbackc                 C   s   || _ | jS )a=  
        This sets the callback for loading a user from a Flask request.
        The function you set should take Flask request object and
        return a user object, or `None` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        )r8   Úrequest_callbackrZ   r?   r?   r@   Úrequest_loaderÙ   s    	zLoginManager.request_loaderc                 C   s   | j S )zAGets the request_loader callback set by request_loader decorator.)r8   r]   r?   r?   r@   r^   å   s    zLoginManager.request_callbackc                 C   s
   || _ |S )ab  
        This will set the callback for the `unauthorized` method, which among
        other things is used by `login_required`. It takes no arguments, and
        should return a response to be sent to the user instead of their
        normal view.

        :param callback: The callback for unauthorized users.
        :type callback: callable
        )r4   rZ   r?   r?   r@   Úunauthorized_handlerê   s    
z!LoginManager.unauthorized_handlerc                 C   s
   || _ |S )ai  
        This will set the callback for the `needs_refresh` method, which among
        other things is used by `fresh_login_required`. It takes no arguments,
        and should return a response to be sent to the user instead of their
        normal view.

        :param callback: The callback for unauthorized users.
        :type callback: callable
        )r5   rZ   r?   r?   r@   Úneeds_refresh_handler÷   s    
z"LoginManager.needs_refresh_handlerc                 C   sÂ   t  t ¡ ¡ | jr|  ¡ S | js*tdƒ | jrb| jdk	rRt	|  | j¡| j
d� nt	| j| j
d� tj}| dt¡r¦t| jƒ}|  ¡ td< t|tjƒtd< t| jƒ}n| j}t|tjd�}t|ƒS )a€  
        This is called when the user is logged in, but they need to be
        reauthenticated because their session is stale. If you register a
        callback with `needs_refresh_handler`, then it will be called.
        Otherwise, it will take the following actions:

            - Flash :attr:`LoginManager.needs_refresh_message` to the user.

            - Redirect the user to :attr:`LoginManager.refresh_view`. (The page
              they were attempting to access will be passed in the ``next``
              query string variable, so you can redirect there if present
              instead of the homepage.)

        If :attr:`LoginManager.refresh_view` is not defined, then it will
        simply raise a HTTP 401 (Unauthorized) error instead.

        This should be returned from a view or before/after_request function,
        otherwise the redirect will have no effect.
        rJ   NrK   r   rM   rN   rO   )r   rP   r   rQ   r5   r/   r   r0   r3   r   r1   rS   rT   r   r%   r9   r   r'   r
   rU   rV   r	   )r<   rS   r&   rW   r?   r?   r@   Úneeds_refresh  s0    

þþ
zLoginManager.needs_refreshc                 C   s"   ddl }|jdtdd� || _|S )a«  
        This function has been deprecated. Please use
        :meth:`LoginManager.request_loader` instead.

        This sets the callback for loading a user from a header value.
        The function you set should take an authentication token and
        return a user object, or `None` if the user does not exist.

        :param callback: The callback for retrieving a user object.
        :type callback: callable
        r   Nzc'header_loader' is deprecated and will be removed in Flask-Login 0.7. Use 'request_loader' instead.rB   rC   )rE   rF   rG   r7   )r<   r[   rE   r?   r?   r@   Úheader_loader8  s    üzLoginManager.header_loaderc                 C   s   |dkr|   ¡ }|t_dS )z!Store the given user as ctx.user.N)r*   r   Z_login_user)r<   Úuserr?   r?   r@   Ú!_update_request_context_with_userO  s    z.LoginManager._update_request_context_with_userc           	      C   sö   | j dkr| jdkrtdƒ‚t t ¡ ¡ |  ¡ r:|  ¡ S d}t	 
d¡}|dk	rd| j dk	rd|   |¡}|dkrìtj}| 
dt¡}| 
dt¡}|tjko t	 
d¡dk}|r¼tj| }|  |¡}n0| jrÎ|  t¡}n|tjkrìtj| }|  |¡}|  |¡S )z;Loads user from session or remember_me cookie as applicableNznMissing user_loader or request_loader. Refer to http://flask-login.readthedocs.io/#how-it-works for more info.Ú_user_idÚREMEMBER_COOKIE_NAMEr   Ú	_rememberÚclear)r6   r8   Ú	Exceptionr   rP   r   rQ   Ú_session_protection_failedre   r   rT   rS   r   r   r
   ÚcookiesÚ_load_user_from_remember_cookieÚ_load_user_from_requestÚheadersÚ_load_user_from_header)	r<   rd   Úuser_idrS   Úcookie_nameÚheader_nameZ
has_cookieÚcookieÚheaderr?   r?   r@   Ú
_load_userW  s4    ÿ

ÿ



zLoginManager._load_userc                 C   s¶   t  ¡ }|  ¡ }t ¡ }|j d| j¡}|r4|dkr8dS |r²|| dd ¡kr²|dksZ|jr~| d¡dk	rpd|d< t 	|¡ dS |dkr²t
D ]}| |d ¡ qŠd|d	< t 	|¡ d
S dS )NZSESSION_PROTECTION)r)   ÚstrongFrM   r)   Ú_freshrw   ri   rh   T)r   rQ   r9   r   rS   rT   r2   Z	permanentr   rP   r   Úpop)r<   ÚsessÚidentr=   ÚmodeÚkr?   r?   r@   rk   �  s&    

z'LoginManager._session_protection_failedc                 C   sZ   t |ƒ}|d k	rV|td< dtd< d }| jr4|  |¡}|d k	rVt ¡ }tj||d� |S d S )Nrf   Frx   ©rd   )r#   r   r6   r   rQ   r   rP   )r<   rt   rq   rd   r=   r?   r?   r@   rm   �  s    
z,LoginManager._load_user_from_remember_cookiec                 C   sB   | j r>|   |¡}|d k	r>t ¡ }ddlm} |j||d� |S d S )Nr   )Ú_user_loaded_from_headerr~   )r7   r   rQ   Úsignalsr   rP   )r<   ru   rd   r=   r   r?   r?   r@   rp   «  s    
z#LoginManager._load_user_from_headerc                 C   s6   | j r2|   |¡}|d k	r2t ¡ }tj||d� |S d S )Nr~   )r8   r   rQ   r   rP   )r<   r
   rd   r=   r?   r?   r@   rn   ·  s    
z$LoginManager._load_user_from_requestc                 C   sb   dt krtj d¡rdt d< dt kr^t  dd ¡}|dkrLdt krL|  |¡ n|dkr^|  |¡ |S )Nrh   Z$REMEMBER_COOKIE_REFRESH_EACH_REQUESTÚsetrf   ri   )r   r   rS   rT   ry   Ú_set_cookieÚ_clear_cookie)r<   ÚresponseZ	operationr?   r?   r@   rI   À  s    ÿ
z$LoginManager._update_remember_cookiec              
   C   sö   t j}| dt¡}| d¡}| dd¡}| dt¡}| dt¡}| dt¡}dtkrdttd d	�}	n| d
t	¡}	t
ttd ƒƒ}
t|	tƒr”t|	d	�}	zt ¡ |	 }W n2 tk
rÖ } ztd|	› �ƒ|‚W 5 d }~X Y nX |j||
||||||d� d S )Nrg   ÚREMEMBER_COOKIE_DOMAINÚREMEMBER_COOKIE_PATHú/ZREMEMBER_COOKIE_SECUREZREMEMBER_COOKIE_HTTPONLYZREMEMBER_COOKIE_SAMESITEZ_remember_seconds)ÚsecondsZREMEMBER_COOKIE_DURATIONrf   zDREMEMBER_COOKIE_DURATION must be a datetime.timedelta, instead got: )ÚvalueÚexpiresÚdomainÚpathÚsecureÚhttponlyÚsamesite)r   rS   rT   r   r   r   r   r   r   r   r$   ÚstrÚ
isinstanceÚintr   ÚutcnowÚ	TypeErrorrj   Ú
set_cookie)r<   r„   rS   rr   r‹   rŒ   r�   rŽ   r�   ÚdurationÚdatarŠ   Úer?   r?   r@   r‚   Ñ  s>    


ÿýøzLoginManager._set_cookiec                 C   s<   t j}| dt¡}| d¡}| dd¡}|j|||d� d S )Nrg   r…   r†   r‡   )r‹   rŒ   )r   rS   rT   r   Zdelete_cookie)r<   r„   rS   rr   r‹   rŒ   r?   r?   r@   rƒ   û  s
    
zLoginManager._clear_cookiec                 C   s0   ddl }|jdtdd� tƒ r,tj dd¡S dS )z:Legacy property, use app.config['LOGIN_DISABLED'] instead.r   Núu'_login_disabled' is deprecated and will be removed in Flask-Login 0.7. Use 'LOGIN_DISABLED' in 'app.config' instead.rB   rC   ÚLOGIN_DISABLEDF)rE   rF   rG   r   r   rS   rT   )r<   rE   r?   r?   r@   Ú_login_disabled  s    ûzLoginManager._login_disabledc                 C   s&   ddl }|jdtdd� |tjd< dS )zALegacy property setter, use app.config['LOGIN_DISABLED'] instead.r   Nr™   rB   rC   rš   )rE   rF   rG   r   rS   )r<   ZnewvaluerE   r?   r?   r@   r›     s    û)NT)T)T)N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rA   rH   r:   rX   r\   ÚpropertyrY   r_   r^   r`   ra   rb   rc   re   rv   rk   rm   rp   rn   rI   r‚   rƒ   r›   Úsetterr?   r?   r?   r@   r(   *   s8   
<

:

4
*	*
r(   N),r   r   Zflaskr   r   r   r   r   r	   r
   r   rS   r   r   r   r   r   r   r   r   r   r   r   r   r   Zmixinsr   r€   r   r   r   r   r   r    Úutilsr!   r"   r#   r$   r%   r&   rV   r'   r(   r?   r?   r?   r@   Ú<module>   sJ   