
    CEiiN                        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+y))*    )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j6                  d        Zy)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.
    Nc                 T   t         | _        d | _        i | _        t        | _        t        | _        d | _        t        | _
        t        | _        d| _        d | _        d | _        d | _        t"        | _        d | _        d | _        d | _        t,        | _        || j1                  ||       y y )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      L/var/www/html/venv/lib/python3.12/site-packages/flask_login/login_manager.py__init__zLoginManager.__init__1   s     1
 
 &(" + '=# ! &5" /G+
 #* "&%)"&*#(" $!%-?*?MM#45     c                 `    ddl }|j                  dt        d       | j                  ||       y)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   s4    
 	8	 	 	
 	c01rE   c                 x    | |_         |j                  | j                         |r|j                  t               yy)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|   s7     !$667 !!"9: !rE   c                 L   t        j                  t        j                                | j                  r| j	                         S t
        j                  | j                  v r| j                  t
        j                     }n| j                  }|st        d       | j                  r^| j                  1t        | j                  | j                        | j                         n!t        | j                  | j                         t        j                  }|j                  dt               rYt#        |      }| j%                         t&        d<   t)        |t
        j*                        t&        d<   t-        |      }t/        |      S 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.
          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   sA   2 	{>>@A%%--// : ::33G4E4EFJJ#J%%1**4+=+=>!88
 d((43N3NO##::,.BC)*5I!??AGEN-iEGFO)*5L %% **w{{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| j	                         S | j
                  st        d       | j                  r^| j                  1t        | j                  | j                        | j                         n!t        | j                  | j                         t        j                  }|j                  dt              rmt        | j
                        }| j                         t         d<   t#        |t$        j&                        t         d<   t)        | j
                        }t+        |      S | 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   rU   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  s1   ( 	 ? ? AB&&..00  #J%%%%1**4+E+EF!@@
 ..!@@
 ##::,.BC)$*;*;<I!??AGEN-iEGFO)$*;*;<L
 %% ))I))gkkJL%%rE   c                 L    ddl }|j                  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  s2     	>	 	 	
 !)rE   c                 >    || j                         }|t        _        y)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                 6   | j                   | j                  t        d      t        j                  t        j                                | j                         r| j                         S d}t        j                  d      }|| j                   | j                  |      }|t
        j                  }|j                  dt              }|j                  dt              }|t        j                  v xr t        j                  d      dk7  }|r%t        j                  |   }| j!                  |      }nX| j                  r| j#                  t              }n6|t        j$                  v r$t        j$                  |   }| j'                  |      }| 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  si    &4+A+A+I!  	;::<= **,99;; ++j)4#6#6#B&&w/D < ''F **%;[IK **%79IJKw.V7;;{3Kw3V   5;;FC''33G</ 5226:55d;;rE   c                    t        j                         }| j                         }t        j                         }|j                  j                  d| j                        }|r|dvry|r||j                  dd       k7  r||dk(  s|j                  r.|j                  d      durd|d<   t        j                  |       y|dk(  r8t        D ]  }|j                  |d         d|d	<   t        j                  |       y
y)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--/zz~~2D4K4KLt#66 ETXXeT22w$..88H%U2%*DN!&&s+!% &AHHQ%& %,[!!&&s+rE   c                     t        |      }|`|t        d<   dt        d<   d }| j                  r| j                  |      }|-t        j                         }t        j                  ||       |S y )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  sp    '")GJ %GHD""**73!557',,St<rE   c                     | j                   rB| j                  |      }|/t        j                         }ddlm} |j                  ||       |S y )Nr   )_user_loaded_from_headerr   )r;   r   r\   signalsr   r[   )r@   r   ry   rA   r   s        rC   r   z#LoginManager._load_user_from_header  sM      ((0D!557=(--c-=rE   c                     | j                   r@| j                  |      }|-t        j                         }t        j                  ||       |S y )Nr   )r<   r   r\   r   r[   )r@   r   ry   rA   s       rC   r   z$LoginManager._load_user_from_request  sG    !!))'2D!557(--c=rE   c                    dt         vr(t        j                  j                  d      r	dt         d<   dt         v rLt        j                  dd       }|dk(  rdt         v r| j                  |       |S |dk(  r| j                  |       |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6IE!jG&;  *  g%""8,rE   c           
         t         j                  }|j                  dt              }|j                  d      }|j                  dd      }|j                  dt              }|j                  dt
              }|j                  dt              }dt        v rt        t        d   	      }	n|j                  d
t              }	t        t        t        d               }
t        |	t              rt        |		      }		 t        j                         |	z   }|j%                  ||
||||||       y # t         $ r}t#        d|	       |d }~ww xY w)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45zz0#64mD::8/J::8/J') 1D)EFHzz"<oNH S!456h$ 2H	oo'(2G 	 	 		
  	!!)
, 	s   6D' '	E0D??Ec                     t         j                  }|j                  dt              }|j                  d      }|j                  dd      }|j	                  |||       y )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  sS    ##jj!7E45zz0#6{6ErE   c                     ddl }|j                  dt        d       t               r t        j
                  j                  dd      S y)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  sJ     	  	 	
 %%))*:EBBrE   c                 b    ddl }|j                  dt        d       |t        j                  d<   y)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  s8     	  	 	
 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    :6x2;$8&t
" # #
% & &2&h.(<T8
"(
TF    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8rE   