
    '[fiN                        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(          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                       e Zd ZdZddZddZddZd Zd Ze	d	             Z
d
 Ze	d             Zd Zd Zd Zd ZddZd Zd Zd Zd Zd Zd Zd Zd Ze	d             Zej        d             ZdS )LoginManagerzThis 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                 n   t           | _        d | _        i | _        t          | _        t          | _        d | _        t          | _
        t          | _        d| _        d | _        d | _        d | _        t"          | _        d | _        d | _        d | _        t,          | _        ||                     ||           d S 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   id_attribute_user_callback_header_callback_request_callbackr"   _session_identifier_generatorinit_appselfappadd_context_processors      M/var/www/piapp/venv/lib/python3.11/site-packages/flask_login/login_manager.py__init__zLoginManager.__init__1   s     1
 
 &(" + '=# ! &5" /G+
 #* "&%)"&*#(" $!%-?*?MM#455555 ?    c                 t    ddl }|                    dt          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@   rA   rB   rJ   s       rC   	setup_appzLoginManager.setup_appm   sP    
 	8	 	 	
 	
 	
 	c011111rE   c                     | |_         |                    | j                   |r|                    t                     dS 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)login_managerafter_request_update_remember_cookiecontext_processorr#   r?   s      rC   r>   zLoginManager.init_app|   sP     !$6777  	;!!"9:::::	; 	;rE   c                    t          j        t          j                               | j        r|                                 S t
          j        | j        v r| j        t
          j                 }n| j        }|st          d           | j
        rQ| j        /t          |                     | j
                  | j                   nt          | j
        | j                   t          j        }|                    dt                     r]t#          |          }|                                 t&          d<   t)          |t
          j                  t&          d<   t-          |          }nt-          |t
          j                  }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next_url)r!   sendr   _get_current_objectr7   r   	blueprintr/   r.   r   r0   r6   r   r1   configgetr   r&   r=   r   r(   urlmake_login_urlr
   )r@   r.   r^   r'   redirect_urls        rC   unauthorizedzLoginManager.unauthorized   sg   2 	{>@@AAA% 	0--/// :::3G4EFJJJ 	#JJJ 	P%1**4+=>>!8    
 d(43NOOOO#::,.BCC 	L)*55I!??AAGEN-iEEGFO)*55LL)*w{KKKL%%%rE   c                     || _         | 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
        )r:   user_callbackr@   callbacks     rC   user_loaderzLoginManager.user_loader   s     '!!rE   c                     | j         S )z;Gets the user_loader callback set by user_loader decorator.)r:   r@   s    rC   re   zLoginManager.user_callback   s     ""rE   c                     || _         | 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
        )r<   request_callbackrf   s     rC   request_loaderzLoginManager.request_loader   s     "*$$rE   c                     | j         S )zAGets the request_loader callback set by request_loader decorator.)r<   rj   s    rC   rl   zLoginManager.request_callback   s     %%rE   c                     || _         |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
        )r7   rf   s     rC   unauthorized_handlerz!LoginManager.unauthorized_handler   s     &."rE   c                     || _         |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
        )r8   rf   s     rC   needs_refresh_handlerz"LoginManager.needs_refresh_handler   s     '/#rE   c                    t          j        t          j                               | j        r|                                 S | j        st          d           | j        rQ| j        /t          |                     | j                  | j
                   nt          | j        | j
                   t          j        }|                    dt                    rgt          | j                  }|                                 t           d<   t#          |t$          j                  t           d<   t)          | j                  }n"| j        }t)          |t$          j                  }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.
        rT   NrU   r   rW   rX   rY   )r    r[   r   r\   r8   r2   r   r3   r6   r   r4   r^   r_   r   r&   r=   r   r(   r   r`   ra   r
   )r@   r^   r'   rb   s       rC   needs_refreshzLoginManager.needs_refresh  sY   ( 	 ? A ABBB& 	1..000  	#JJJ% 
	%1**4+EFF!@    
 .!@   
 #::,.BCC 	K)$*;<<I!??AAGEN-iEEGFO)$*;<<LL)I))gkJJJL%%%rE   c                 V    ddl }|                    dt          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.rG   rH   )rJ   rK   rL   r;   )r@   rg   rJ   s      rC   header_loaderzLoginManager.header_loader8  sB     	>	 	 	
 	
 	
 !)rE   c                 J    ||                                  }|t          _        dS )z!Store the given user as ctx.user.N)r-   r   _login_user)r@   users     rC   !_update_request_context_with_userz.LoginManager._update_request_context_with_userO  s%     <&&((DrE   c                 >   | j         | j        t          d          t          j        t          j                               |                                 r|                                 S d}t          j
        d          }|| j         |                      |          }|t
          j        }|
                    dt                    }|
                    dt                    }|t          j        v ot          j
        d          dk    }|r(t          j        |         }|                     |          }nW| j        r|                     t                    }n5|t          j        v 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)r:   r<   	Exceptionr   r[   r   r\   _session_protection_failedrz   r   r_   r^   r   r   r   cookies_load_user_from_remember_cookie_load_user_from_requestheaders_load_user_from_header)	r@   ry   user_idr^   cookie_nameheader_name
has_cookiecookieheaders	            rC   
_load_userzLoginManager._load_userW  s    &4+A+I!   	;:<<=== **,, 	<99;;; +j))4#6#B&&w//D < 'F **%;[IIK **%79IJJKw.V7;{3K3Kw3V   ; 5;;FCC' ;33G<<// 5226::55d;;;rE   c                    t          j                    }|                                 }t          j                    }|j                            d| j                  }|r|dvrdS |r||                    dd           k    r|dk    s|j        r2|                    d          durd|d<   t          j	        |           dS |dk    r;t          D ]}|                    |d            d|d	<   t          j	        |           d
S dS )NSESSION_PROTECTION)r,   strongFrW   r,   _freshr   r   r~   T)r   r\   r=   r   r^   r_   r5   	permanentr   r[   r   pop)r@   sessidentrA   modeks         rC   r   z'LoginManager._session_protection_failed  s   *,,2244-//z~~2D4KLL 	t#6665  	ETXXeT2222w$.88H%%U22%*DN!&s+++u!!% & &AHHQ%%%%$+[!!&s+++turE   c                     t          |          }|_|t          d<   dt          d<   d }| j        r|                     |          }|+t          j                    }t          j        ||           |S d S )Nr|   Fr   ry   )r$   r   r:   r   r\   r   r[   )r@   r   r   ry   rA   s        rC   r   z,LoginManager._load_user_from_remember_cookie  s    ''")GJ %GHD" 4**733!577',St<<<<trE   c                     | j         rI|                      |          }|2t          j                    }ddlm} |                    ||           |S d S )Nr   )_user_loaded_from_headerr   )r;   r   r\   signalsr   r[   )r@   r   ry   rA   r   s        rC   r   z#LoginManager._load_user_from_header  si      	((00D!577======(--c-===trE   c                     | j         rB|                      |          }|+t          j                    }t          j        ||           |S d S )Nr   )r<   r   r\   r   r[   )r@   r   ry   rA   s       rC   r   z$LoginManager._load_user_from_request  sT    ! 	))'22D!577(-c====trE   c                 &   dt           vr)t          j                            d          r
dt           d<   dt           v rUt          j        dd           }|dk    rdt           v r|                     |           n|dk    r|                     |           |S )Nr~   $REMEMBER_COOKIE_REFRESH_EACH_REQUESTsetr|   r   )r   r   r^   r_   r   _set_cookie_clear_cookie)r@   response	operations      rC   rQ   z$LoginManager._update_remember_cookie  s    g%%+*<*@*@2+
 +
% $)GK '!!K66IE!!jG&;&;  ****g%%""8,,,rE   c           
         t           j        }|                    dt                    }|                    d          }|                    dd          }|                    dt                    }|                    dt
                    }|                    dt                    }dt          v rt          t          d         	          }	n|                    d
t                    }	t          t          t          d                             }
t          |	t                    rt          |		          }		 t          j                    |	z   }n%# t           $ r}t#          d|	           |d }~ww xY w|                    ||
||||||           d S )Nr}   REMEMBER_COOKIE_DOMAINREMEMBER_COOKIE_PATH/REMEMBER_COOKIE_SECUREREMEMBER_COOKIE_HTTPONLYREMEMBER_COOKIE_SAMESITE_remember_seconds)secondsREMEMBER_COOKIE_DURATIONr|   zDREMEMBER_COOKIE_DURATION must be a datetime.timedelta, instead got: )valueexpiresdomainpathsecurehttponlysamesite)r   r^   r_   r   r   r   r   r   r   r   r%   str
isinstanceintr   utcnow	TypeErrorr   
set_cookie)r@   r   r^   r   r   r   r   r   r   durationdatar   es                rC   r   zLoginManager._set_cookie  s   #jj!7EE455zz0#664mDD::8/JJ::8/JJ')) 1D)EFFFHHzz"<oNNH S!45566h$$ 	3 222H	o''(2GG 	 	 	,!), ,  	 	 	 		
 		
 		
 		
 		
s   1E 
E*E%%E*c                     t           j        }|                    dt                    }|                    d          }|                    dd          }|                    |||           d S )Nr}   r   r   r   )r   r   )r   r^   r_   r   delete_cookie)r@   r   r^   r   r   r   s         rC   r   zLoginManager._clear_cookie  se    #jj!7EE455zz0#66{6EEEEErE   c                     ddl }|                    dt          d           t                      r t          j                            dd          S dS )z:Legacy property, use app.config['LOGIN_DISABLED'] instead.r   Nu'_login_disabled' is deprecated and will be removed in Flask-Login 0.7. Use 'LOGIN_DISABLED' in 'app.config' instead.rG   rH   LOGIN_DISABLEDF)rJ   rK   rL   r	   r   r^   r_   )r@   rJ   s     rC   _login_disabledzLoginManager._login_disabled  se     	  	 	
 	
 	
  	C%))*:EBBBurE   c                 f    ddl }|                    dt          d           |t          j        d<   dS )zALegacy property setter, use app.config['LOGIN_DISABLED'] instead.r   Nr   rG   rH   r   )rJ   rK   rL   r   r^   )r@   newvaluerJ   s      rC   r   zLoginManager._login_disabled  sK     	  	 	
 	
 	
 08+,,,rE   )NT)T)N)__name__
__module____qualname____doc__rD   rM   r>   rc   rh   propertyre   rm   rl   rp   rr   rt   rv   rz   r   r   r   r   r   rQ   r   r   r   setter rE   rC   r*   r*   *   s        :6 :6 :6 :6x2 2 2 2; ; ; ;$8& 8& 8&t
" 
" 
" # # X#
% 
% 
% & & X&    2& 2& 2&h  .   (< (< (<T  8  
 
 
    "(
 (
 (
TF F F   X  8 8 8 8 8rE   r*   N),r   r   flaskr   r   r   r   r	   r
   r   r   r^   r   r   r   r   r   r   r   r   r   r   r   r   r   mixinsr   r   r   r   r   r   r    r!   utilsr"   r#   r$   r%   r&   r'   ra   r(   r*   r   rE   rC   <module>r      s                                       ! ! ! ! ! !                   $ $ $ $ $ $ # # # # # # # # # # # #       # # # # # # ! ! ! ! ! !             ! ! ! ! ! ! * * * * * * # # # # # # , , , , , ,             ( ( ( ( ( ( & & & & & & & & & & & & " " " " " " , , , , , , - - - - - - ' ' ' ' ' ' & & & & & & % % % % % % * * * * * *                         $ $ $ $ $ $ . . . . . . " " " " " "u8 u8 u8 u8 u8 u8 u8 u8 u8 u8rE   