+
    <B.j                     z    R t ^ RIt^ RIt^ RIt^ RIt^ RIt^ RIt^ RIHt R R lt	R R lt
RR R lltR	 R
 ltR# )z9Small TOTP implementation for admin second-factor checks.Nquotec                $    V ^8  d   QhR\         /# )   returnstr)formats   "app\core\totp.py__annotate__r      s     Q Qc Q    c                     \         P                  ! \        P                  ! ^4      4      P	                  R4      P                  R4      # )z:Return a base32 secret compatible with authenticator apps.ascii=)base64	b32encodesecretstoken_bytesdecoderstrip r   r
   generate_totp_secretr      s4    G//34;;GDKKCPPr   c                H    V ^8  d   QhR\         R\         R\         R\         /# )r   secretaccount_nameissuerr   r   )r	   s   "r
   r   r      s(      3 c 3 3 r   c                 L    V R V 2pR\        V4       RV  R\        V4       R2# ):zotpauth://totp/z?secret=z&issuer=z"&algorithm=SHA1&digits=6&period=30r   )r   r   r   labels   &&& r
   build_provisioning_urir      s<    ha~&E
%,
6((5=/1S	Ur   c                H    V ^8  d   QhR\         R\         R\        R\        /# )r   r   codevalid_windowr   )r   intbool)r	   s   "r
   r   r      s(     	 	 	3 	c 	$ 	r   c                 v   VP                  4       P                  R R4      pVP                  4       '       d   \        V4      ^8w  d   R# \	        \
        P
                  ! 4       ^,          4      p\        V) V^,           4       F3  p\        P                  ! \        WV,           4      V4      '       g   K2   R# 	  R# )  FT)
stripreplaceisdigitlenr#   timerangehmaccompare_digest_totp_at)r   r!   r"   
normalizedcurrent_counteroffsets   &&&   r
   verify_totpr4      s    %%c2.J3z?a#7$))++,O|a'78x&0HI:VV 9 r   c                <    V ^8  d   QhR\         R\        R\         /# )r   r   counterr   )r   r#   )r	   s   "r
   r   r   %   s!     * *S *3 *3 *r   c                    V R ^\        V 4      ^,          ,
          ^,          ,          ,           p\        P                  ! VP                  4       4      p\        P
                  ! RV4      p\        P                  ! W4\        P                  4      P                  4       pVR,          ^,          p\        P                  ! RWVV^,            4      ^ ,          R,          p\        VR,          4      P                  ^4      # )r   z>Qz>Iii@B )r+   r   	b32decodeupperstructpackr.   newhashlibsha1digestunpackr   zfill)r   r6   padded_secretkeymsgr@   r3   r!   s   &&      r
   r0   r0   %   s    SQVq%8A$=>>M


=..0
1C
++dG
$CXXc-446FBZ$F==vvz:;A>KDti &&q))r   )   )__doc__r   r>   r.   r   r;   r,   urllib.parser   r   r   r4   r0   r   r   r
   <module>rI      s2    ?       Q
	*r   