
    _i,P                        d dl mZmZmZmZmZmZmZmZ d dl	m
Z
mZmZmZ d dlZd dlZd dlZd dlZd dlZd dlZd dlmZmZmZ d dlmZ d dlmZmZmZ d dlmZmZm Z m!Z! d dl"m#Z#  ed	e$d
          Z%dZ&d Z'd Z(d Z)d9dZ*d Z+d Z,e%-                    dddg           e!j.        d          d                         Z/e%-                    dddg           e!j.        d          d                         Z0e%-                    ddg          ed                         Z1e%-                    d          ed                          Z2e%-                    d!dg          ed"                         Z3e%-                    d#dg          ed$                         Z4e%-                    d%ddg          ed&                         Z5e%-                    d'ddg          ed(                         Z6e%-                    d)ddg           e!j.        d*          d+                         Z7e%-                    d,ddg          d-             Z8d dl9Z9d d.l:m;Z; d/Z<h d0Z=d1Z>d2 Z?e%-                    d3dg          ed4                         Z@e%-                    d5dg          ed6                         ZAe%-                    d7dg          ed8                         ZBdS ):    )	Blueprintrender_templaterequestredirecturl_forflashcurrent_appsession)
login_userlogout_userlogin_requiredcurrent_userN)datetimetimezone	timedelta)Message)URLSafeTimedSerializerSignatureExpiredBadSignature)dbbcryptmaillimiter)Userauthz../templates)template_folderz<$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LewY5jtRPPbkEfLGuc                     t          |           dk     rdS t          j        d|           sdS t          j        d|           sdS t          j        d|           sdS t          j        d	|           sd
S dS )N   )Fu6   Le mot de passe doit contenir au moins 12 caractères.z[A-Z])FzMajuscule requise.z[a-z])FzMinuscule requise.z\d)FzChiffre requis.z[!@#$%^&*(),.?":{}|<>])Fu   Caractère spécial requis.)TOK)lenresearch)passwords    2/var/www/html/MCyber-Diagnostic/blueprints/auth.pyvalidate_password_strengthr%      s    
8}}r"a"a9Xx((L1L1L9Xx((L1L1L9UH%%F.F.F9.99fBfBf:    c                 4    d}t          j        ||           d uS )Nz0^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$)r!   match)emailpatterns     r$   validate_email_formatr+   &   s    AG8GU##4//r&   c                     t          t          j        d                   }|                    dt	          |           id          S )N
SECRET_KEYuser_id2fa-verification)salt)r   r	   configdumpsstr)r.   ss     r$   create_2fa_tokenr5   .   s9    {1,?@@A77Is7||,3E7FFFr&   ,  c                     t          t          j        d                   }	 |                    | d|          }|                    d          S # t
          t          f$ r Y d S w xY w)Nr-   r/   )r0   max_ager.   )r   r	   r1   loadsgetr   r   )tokenr8   r4   datas       r$   verify_2fa_tokenr=   2   sm    {1,?@@Awwu#5wwGGxx	"""l+   tts   ,A A#"A#c                 p   |                      t          t          j        d                             }t	          d| j        g          }t          d|d          }d| d	|_        t          j	        |           d S # t          $ r-}t          j                            d
|            Y d }~d S d }~ww xY w)Nr-   
secret_keyu0   Réinitialisation de mot de passe - MCyber Audit
recipientszauth.reset_passwordT)r;   	_externalu?   Bonjour,

Cliquez ici pour réinitialiser votre mot de passe :
z!

Ce lien expire dans 30 minutes.zErreur mail reset: )get_reset_tokenr3   r	   r1   r   r)   r   bodyr   send	Exceptionloggererror)userr;   msg	reset_urles        r$   send_reset_emailrN   >   s      C0B<0P,Q,Q RRE
DRVR\Q]
^
^
^C-UdKKKI GV_  G  G  GCH	3NNN;-334M!4M4MNNNNNNNNNNs   (A> >
B5"B00B5c                 F   	 t          d| j        g          }dt          j        t          j                                      d           d|_        t          j	        |           d S # t          $ r-}t          j                            d|            Y d }~d S d }~ww xY w)Nu$   Mot de passe modifié - MCyber AuditrA   u1   Bonjour,

Votre mot de passe a été modifié le u   %d/%m/%Y à %H:%Mz UTC.zErreur mail notif pass: )r   r)   r   nowr   utcstrftimerE   r   rF   rG   r	   rH   rI   )rJ   rK   rM   s      r$   "send_password_changed_notificationrS   F   s    T<$*VVV IV^VbIcIcIlIl  nA  JB  JB  I  I  I	#SSS;-334Rq4R4RSSSSSSSSSSs   A%A) )
B 3"BB z/loginGETPOST)methodsz5 per minutec                     t           j        rt          t          d                    S t          j        dk    r0t          j                            dd                                          	                                } t          j                            dd          }| r|st          dd           t          d          S t          j                            | 	                                          }|rt!          j        |j        |          }nt!          j        t&          |           d
}|r|r|j        st          dd           t          d          S |j        r:t-          |j                  }|t0          d<   t          t          d                    S t3          |d           t4          j                            d|j                    ddlm}  ||j        |j                   t          t          j                             d          pt          d                    S t4          j        !                    d|             ddlm"}  || d           t          dd           t          d          S )Nmain.dashboardrU   r)    r#   zEmail et mot de passe requis.dangerz
login.htmlr)   Fu   Compte désactivé.	2fa_tokenzauth.verify_2faTrememberu   ✅ Login: r   )log_auth_successnextu   ❌ Login fail: )log_auth_failedzIdentifiants invalideszEmail ou mot de passe invalide.)#r   is_authenticatedr   r   r   methodformr:   striplowerr   r   r   query	filter_byfirstr   check_password_hashr#   DUMMY_PASSWORD_HASHis_active_accounttwo_factor_enabledr5   idr
   r   r	   rH   infor)   services.logger_servicer_   argswarningra   )r)   r#   rJ   is_validr;   r_   ra   s          r$   loginrt   Q   sm    $ 3 011222~  "--3355;;==<##J33 	1H 	118<<<"<000z##%#006688  	F6t}hOO&':HEEEH 	?H 	?) 5+X666&|444 & <(11',$(9 : :;;;td++++##$>$*$>$>??? A@@@@@TWdj111GL,,V44Q@P8Q8QRRR&&'A%'A'ABBB @?????OE#;<<<3X>>><(((r&   z/verify-2faz15 per 5 minutesc                  6   t          j        d          } | st          t          d                    S t	          |           }|sAt          j        dd            t          dd           t          t          d                    S t          j                            |          }|st          t          d                    S t          j
        dk    r9t          j                            dd                                          }t          j        |j                  }|                    |d	          rit#          |d
           t          j        dd            t$          j                            d|j                    t          t          d                    S |j        rV	 t/          j        |j                  }t3          |          D ]\  }}t5          j        ||          r|                    |           t/          j        |          |_        t:          j                                          t#          |d
           t          j        dd            t$          j                            d|j                    t          dt?          |           dd           t          t          d                    c S n9# t@          $ r,}t$          j        !                    d|            Y d }~nd }~ww xY wt          dd           tE          d          S )Nr\   
auth.loginu   Session expirée.rr   rU   otprY      valid_windowTr]   u   ✅ 2FA TOTP OK: rX   u   ✅ 2FA RECOVERY OK: u+   Code de secours utilisé. Il vous en reste .u$   Erreur vérification codes secours: zCode invalide.rZ   zverify_2fa.html)#r
   r:   r   r   r=   popr   r   rg   r   rc   rd   re   pyotpTOTPtwo_factor_secretverifyr   r	   rH   ro   r)   two_factor_recovery_codesjsonr9   	enumerater   rj   r2   r   commitr    rG   rI   r   )	r;   r.   rJ   
code_inputtotprecovery_codesidxhashed_coderM   s	            r$   
verify_2far      s    K$$E8',"7"7888u%%G /K&&&!9-----...:>>'""D7!6!6777~\%%eR006688
 z$011;;z;22 	7td++++KT***##$D
$D$DEEEG$455666 ) 	UU!%D,J!K!K(1.(A(A C C$C1+zJJ 
C&**3///9=N9S9S6
))+++"4$7777K666#*//0T
0T0TUUUbCP^L_L_bbbdmnnn'0@(A(ABBBBB
CC  U U U"(()SPQ)S)STTTTTTTTU 	))),---s   'DK K 
K9"K44K9z/logoutc                      ddl m}   | t          j        t          j                   t                       t          j        dd            t          dd           t          t          d                    S )Nr   
log_logoutr\   u   Vous êtes déconnecté.ro   rv   )rp   r   r   rn   r)   r   r
   r|   r   r   r   r   s    r$   logoutr      so     322222J| 2333MMMKT"""	
$f---GL))***r&   z	/settingsc                       t          d          S )Nzaccount_settings.html)r    r&   r$   account_settingsr      s     2333r&   z/settings/update_profilec                  "   t           j                            dd                                          d d         } | t          _        t          j                                         t          dd           t          t          d                    S )Ncompany_namerY   d   u   Profil mis à jour.successauth.account_settings)r   rd   r:   re   r   r   r   r
   r   r   r   r   )r   s    r$   update_profiler      st     <##NB77==??EL ,LJ	
+++G344555r&   z/settings/change_passwordc                     t           j                            dd          } t           j                            dd          }t           j                            dd          }t          j        t
          j        |           s,t          dd           t          t          d                    S ||k    r,t          dd           t          t          d                    S t          |          \  }}|s,t          |d           t          t          d                    S t          j        |                              d	          t
          _        t          j                                         t!          t
                     d
dlm}  |t
          j        t
          j                   t          dd           t          t          d                    S )Ncurrent_passwordrY   new_passwordconfirm_passwordzMot de passe actuel incorrect.rZ   r   z'Les mots de passe ne correspondent pas.utf-8r   )log_password_changed   Mot de passe mis à jour.r   )r   rd   r:   r   rj   r   r#   r   r   r   r%   generate_password_hashdecoder   r
   r   rS   rp   r   rn   r)   )
current_pwnew_pw
confirm_pwrs   rK   r   s         r$   change_passwordr      s    !!"4b99J\nb11F!!"4b99J%l&;ZHH :.999 7889997BBB 788999.v66MHc :c8 788999"9&AAHHQQLJ&|444 =<<<<<,*<===	
%y111G344555r&   z/enable_2fac                  x   t           j        rt          t          d                    S t           j        s;t          j                    t           _        t          j        	                                 t          j        dk    r+t          j                            dd                                          } t          j        t           j                  }|                    | d          rd t#          d          D             }d	 |D             }t%          j        |          t           _        d
t           _        t          j        	                                 ddlm}  |t           j        t           j                   t3          dd           t5          d|          S t3          dd           t7          j        t          j                              }t=          j                    }|                     |d           t5          d|!                                "                    d          t           j                  S )Nr   rU   rw   rY   rx   ry   c                 Z    g | ](}t          j        d                                           )S )   )secrets	token_hexupper).0_s     r$   
<listcomp>zenable_2fa.<locals>.<listcomp>  s/    III!*1--3355IIIr&   
   c                 \    g | ])}t          j        |                              d           *S )r   )r   r   r   )r   codes     r$   r   zenable_2fa.<locals>.<listcomp>
  s2    fffTXF9$??FFwOOfffr&   Tr   )log_2fa_enabledu@   2FA configurée avec succès. Sauvegardez ces codes maintenant !r   zshow_recovery_codes.html)codeszCode incorrect.rZ      )scalezenable_2fa.htmlr   )qr_coder@   )#r   rm   r   r   r   r}   random_base32r   r
   r   r   rc   rd   r:   re   r~   r   ranger   r2   r   rp   r   rn   r)   r   r   pyqrcodecreateget_totp_uriioBytesIOsvggetvaluer   )r;   r   	raw_codeshashed_codesr   qrbuffers          r$   
enable_2far      s    &Yx@W8X8X/Y/Y(Y ) ).)<)>)>&

~  ++1133z,899;;u1;-- 	/IIuRyyIIIIff\efffL 6:Z5M5ML2.2L+J @?????OLO\-?@@@TV_```"#=YOOOO#X... 
244	5	5BZ\\FFF6F ,#)??#4#4#;#;G#D#D&2&DF F F Fr&   z/disable_2fac                  :   t           j        st          t          d                    S t          j        dk    rt          j        t           j        t          j	        
                    dd                    rdt           _        d t           _        t          j                                         ddlm}   | t           j        t           j                   t'          dd	           t          t          d                    S t'          d
d           t)          d          S )Nr   rU   r#   rY   Fr   log_2fa_disabledu   2FA désactivée.r   zMot de passe incorrect.rZ   zdisable_2fa.html)r   rm   r   r   r   rc   r   rj   r#   rd   r:   r   r   r
   r   rp   r   rn   r)   r   r   r   s    r$   disable_2far   $  s     * : 788999~%l&;W\=M=MjZ\=]=]^^ 	7.3L+59L2J A@@@@@\_l.@AAA%y111G$;<<===+X666-...r&   z/reset_password_requestz10 per hourc                     t           j        rt          t          d                    S t          j        dk    rt          j                            dd                                          	                                } t          j                            |                                           }|rt          |           t          dd           t          t          d                    S t!          d	          S )
NrX   rU   r)   rY   r[   u.   Si le compte existe, un email a été envoyé.ro   rv   zreset_request.html)r   rb   r   r   r   rc   rd   r:   re   rf   r   rg   rh   ri   rN   r   r   )r)   rJ   s     r$   reset_password_requestr   ?  s     $PXg>N6O6O-P-P&P~  "--3355;;==z##%#006688'!$'''>GGG--.../000r&   z/reset_password/<token>c                 x   t           j        rt          t          d                    S t	          j        | t          t          j        d                             }|s,t          dd           t          t          d                    S t          j        dk    rt          j                            dd	          }|t          j                            d
d	          k    r!t          dd           t          d|           S t          |          \  }}|s!t          |d           t          d|           S t!          j        |                              d          |_        t(          j                                         t          dd           t          t          d                    S t          d|           S )NrX   r-   r?   u   Lien invalide ou expiré.rr   zauth.reset_password_requestrU   r#   rY   r   u   Mots de passe différents.rZ   zreset_token.html)r;   r   r   r   rv   )r   rb   r   r   r   verify_reset_tokenr3   r	   r1   r   r   rc   rd   r:   r   r%   r   r   r   r#   r   r
   r   )r;   rJ   pwrs   rK   s        r$   reset_passwordr   L  s   $PXg>N6O6O-P-P&P"5S9KL9Y5Z5Z[[[D @)9555 =>>???~\j"--!!"4b9999.999"#5UCCCC2266# 	D#x   "#5UCCCC5b99@@II

)9555--...-U;;;;r&   )secure_filenamezstatic/uploads/logos>   jpgpngjpegi    c                 t    d| v o4|                      dd          d                                         t          v S )Nr{   rx   )rsplitrf   ALLOWED_LOGO_EXTENSIONS)filenames    r$   allowed_logo_filer   s  s6    (?\xsA66q9??AAE\\\r&   z/settings/upload_logoc                  	   t           j        dvr,t          dd           t          t	          d                    S dt
          j        vr,t          dd           t          t	          d                    S t
          j        d         } | j        dk    r,t          dd           t          t	          d                    S t          | j                  s,t          dd           t          t	          d                    S | 	                    d	t          j                   |                                 }| 	                    d	           |t          k    r,t          d
d           t          t	          d                    S t          j                            t           j        t$                    }t          j        |d           t           j        rt          j                            |t           j                  }	 t          j                            |          rt          j        |           n9# t.          $ r,}t           j                            d|            Y d}~nd}~ww xY wd	dl}| j                            dd          d                                         }|                                j         d| }t          j                            ||          }	 |                     |           ng# t.          $ rZ}t           j                             d| d           t          dd           t          t	          d                    cY d}~S d}~ww xY w|t           _        	 tB          j"        #                                 t           j        $                    dt           j%         d|            d	dl&m'}	  |	t           j(        t           j%                   t          dd           n# t.          $ ry}tB          j"        )                                 	 t          j        |           n#  Y nxY wt           j                             d| d           t          dd           Y d}~nd}~ww xY wt          t	          d                    S )u/   Upload logo personnalisé (managers uniquement))manageradminu0   ❌ Seuls les managers peuvent uploader un logo.rZ   r   logou    ❌ Aucun fichier sélectionné.rY   u7   ❌ Format invalide. Formats acceptés : PNG, JPG, JPEGr   u'   ❌ Fichier trop volumineux (max 2 MB).T)exist_okz%Impossible de supprimer ancien logo: Nr{   rx   zErreur sauvegarde logo: exc_infou   ❌ Erreur lors de l'upload.   🎨 z upload logo: )log_logo_uploadedu    ✅ Logo uploadé avec succès !r   zErreur DB upload logo: u$   ❌ Erreur lors de l'enregistrement.)*r   roler   r   r   r   filesr   r   seekosSEEK_ENDtellMAX_LOGO_SIZEpathjoinr	   	root_pathUPLOAD_FOLDER_LOGOSmakedirslogo_filenameexistsremoverG   rH   rr   uuidr   rf   uuid4hexsaverI   r   r
   r   ro   r)   rp   r   rn   rollback)
file	file_sizeupload_pathold_logo_pathrM   r   file_extensionunique_filename	file_pathr   s
             r$   upload_logor   v  sn     444@(KKK 788999 W]""0(;;; 788999= D}0(;;; 788999T]++ :GRRR 788999 	IIa		IIIaLLL=  7BBB 788999 ',,{46IJJKKd++++ ! T[,2LMM	Tw~~m,, )	-((( 	T 	T 	T&&'Rq'R'RSSSSSSSS	T KKK]))#q11!4::<<N)<<N<<O[/::I:		) : : :  !?A!?!?$ OOO,h777 78899999999: "1L@

 [(: [ [/ [ [\\\ 	>=====,/<+=>>>0)<<<< @ @ @

	Ii    	D  !>1!>!> NNN4h????????@ G344555sh   :3H. .
I$8"II$K3 3
M=AMMM'BO+ +
Q.5Q)P)(Q))P-+9Q))Q.z/settings/delete_logoc                     t           j        s,t          dd           t          t	          d                    S t
          j                            t          j	        t                    } t
          j                            | t           j                  }	 t
          j                            |          rt          j        |           n;# t          $ r.}t          j                            d| d           Y d}~nd}~ww xY wdt           _        dt           _        	 t"          j                                         t          j                            d	t           j         d
           t          dd           ni# t          $ r\}t"          j                                         t          j                            d| d           t          dd           Y d}~nd}~ww xY wt          t	          d                    S )u   Supprimer le logo personnaliséu   ❌ Aucun logo à supprimer.rZ   r   z!Erreur suppression fichier logo: Tr   NFu   🗑️ z supprime son logou   ✅ Logo supprimé.r   zErreur DB suppression logo: u"   ❌ Erreur lors de la suppression.)r   r   r   r   r   r   r   r   r	   r   r   r   r   rG   rH   rI   show_logo_on_reportsr   r
   r   ro   r)   r   )r   	logo_pathrM   s      r$   delete_logor     s   
 % :,h777 788999 ',,{46IJJK[,*DEEIY7>>)$$ 	!Ii    Y Y Y  !HQ!H!HSW XXXXXXXXY "&L(-L%>

 Q<+= Q Q QRRR#Y//// > > >

  !C!C!Cd SSS2H========>
 G344555s2   3C 
C?$C::C?AE7 7
GAGGz/settings/update_brandingc                     t           j        dk    st           j        dk    r1dt          j        v t           _        dt          j        v t           _        n(t           j        dk    rdt          j        v t           _        	 t          j        	                                 t          j                            dt           j         d           t          d	d
           ni# t          $ r\} t          j                                         t          j                            d|  d           t          dd           Y d} ~ nd} ~ ww xY wt%          t'          d                    S )u,   Mettre à jour les préférences white-labelr   r   	show_logoshow_company_namerJ   use_manager_brandingr   u"    modifie préférences white-labelu    ✅ Préférences mises à jour.r   zErreur update branding: Tr   u#   ❌ Erreur lors de la mise à jour.rZ   Nr   )r   r   r   rd   r   show_company_name_on_reportsr  r   r
   r   r	   rH   ro   r)   r   rG   r   rI   r   r   )rM   s    r$   update_brandingr    sA   
 I%%):g)E)E,77<,G)4G7<4W11		f	$	$,Bgl,R)?

 ^(: ^ ^ ^___0)<<<< ? ? ?

  !?A!?!?$ OOO3X>>>>>>>>?
 G344555s   ;AC 
D=!AD88D=)r6   )Cflaskr   r   r   r   r   r   r	   r
   flask_loginr   r   r   r   r}   r   r   r!   r   r   r   r   r   
flask_mailr   itsdangerousr   r   r   
extensionsr   r   r   r   modelsr   __name__r   rk   r%   r+   r5   r=   rN   rS   routelimitrt   r   r   r   r   r   r   r   r   r   r   werkzeug.utilsr   r   r   r   r   r   r   r  r   r&   r$   <module>r     s   f e e e e e e e e e e e e e e e e e e e M M M M M M M M M M M M  				  				   2 2 2 2 2 2 2 2 2 2       O O O O O O O O O O 1 0 0 0 0 0 0 0 0 0 0 0      y>BBB
 U   0 0 0G G G   O O OT T T Hufo..~0) 0)  /.0)d ME6?33!"".. .. #" 43..` Ix((+ +  )(+ K4 4  4 &996 6  :96 '&::6 6  ;:6B ME6?33(F (F  43(FT NUFO44/ /  54/2 %v??}	1 	1  @?	1 %v??< < @?<< 
			 * * * * * * - 000 ] ] ] #fX66Q6 Q6  76Q6f #fX666 6  766@ '&::6 6  ;:6 6 6r&   