+
    ig^                         ^ RI t ^ RIt^ RIHtHt ^ RIHt ^ RIHtHtH	t	H
t
HtHt ^ RIHtHtHtHt ^ RIt ! R R4      tR tR# )	    N)datetime	timedelta)	lru_cache)requestrender_templateredirecturl_forjsonifysession)get_ModuleID
get_RoleIDget_permiso.get_CompanyID_DivisionID_DepartamentID_Profilec                      a  ] tR t^t o Rt. ROtR tR tR tRR lt	]
! ^dR7      R 4       tR	 tR
 tR tR tR tRR ltRtV tR# )AccessControllerz5Controlador de acceso con logging profesional y cachec                    \         P                  ! R R4      V n        V P                  4       V n        V P                  R8X  d
   RV n        R# ^<V n        R# )	FLASK_ENVdevelopment
productioni,  N)osgetenvenv_setup_loggerloggercache_duration)selfs   &]C:\Users\victor.barrera\Documents\proyectos\elepV3\Elep\src\App\Security_Module\UserAccess.py__init__AccessController.__init__   s>    99[-8((*%)XX%=c2    c                  a ^ RI p^ RIp^ RIo^ RIpVP                  ! R4      pVP
                  '       d   V# V P                  R8X  d   VP                  MVP                  pVP                  V4       VP                  ! R4      p VP                  P                  VP                  P                  \        4      RRR4      pVP                  ! VRR7       VP                  P                  VR	4      pVP                   ! VR
R7      p	V	P#                  V4       VP%                  V	4       VP*                  ! VP,                  R7      pVP#                  V4        ! V3R lRVP.                  4      pVP0                  R8X  d(   V P                  R8X  d   VP3                  V! 4       4       VP%                  V4       V#   \&         d   p
\)        RT
 24        Rp
?
LRp
?
ii ; i)ui   Configura el sistema de logging según el entorno (UTF-8 seguro y compatible con Windows, VSCode y Flask)Nuser_accessr   z:%(asctime)s - ACCESS_CONTROL - %(levelname)s - %(message)sz..logsT)exist_okzaccess_control.logzutf-8)encodingz$No se pudo crear el archivo de log: )streamc                   .   <a  ] tR t^Ct o V3R ltRtV tR# )5AccessController._setup_logger.<locals>.NoEmojiFilterc                ^   < SP                  R R\        VP                  4      4      Vn        R# )z[^\x00-\x7F]+ T)substrmsg)r   recordres   &&r   filter<AccessController._setup_logger.<locals>.NoEmojiFilter.filterD   s#    VV$4b#fjj/J
r     N)__name__
__module____qualname____firstlineno__r0   __static_attributes____classdictcell__)__classdict__r/   s   @r   NoEmojiFilterr(   C   s      r    r:   ntr   )r   loggingr/   sys	getLoggerhandlersr   INFODEBUGsetLevel	Formatterpathjoindirname__file__makedirsFileHandlersetFormatter
addHandler	ExceptionprintStreamHandlerstdoutFiltername	addFilter)r   r   r<   r=   r   level	formatterlog_dirlog_filefile_handlereconsole_handlerr:   r/   s   &            @r   r   AccessController._setup_logger   s{   ""=1 ???M !%L 8gmm %%H
	
		>ggll277??8#<dD&QGKK$/ww||G-ABH"..x'JL%%i0l+
 "//szzB$$Y/	GNN 	 77d?txx=8%%mo6/*)  	>8<==	>s   B!F7 7GGGc                   . p. pV'       g   VP                  R4       MV^ ,          f   VP                  R4       V'       g   VP                  R4       MV^ ,          f   VP                  R4       V'       g   VP                  R4       WE3# )z5Valida la integridad de los datos de la base de datosu    Datos del módulo no encontradosz$ModuloID es NULL en la base de datoszPerfil de usuario no encontradozCompanyID del usuario es NULLzUserID no proporcionado)append)r   user_idmodule_dataprofile_dataerrorswarningss   &&&&  r   _validate_database_integrity-AccessController._validate_database_integrityQ   sy     MM<=1~%DE MM;<A& ?@ MM34r    Nc                :   RVRVRVRVR\         P                  ! 4       P                  4       RV P                  /pV'       d   WWR&   V'       d   \	        V4      VR&   VR	8X  dq   R
V RV RV 2pRV RV RV 2p	V P
                  P                  V4       V P                  R8X  d-   V'       d#   RV 2p
V P
                  P                  V
4       R# R# R# VR8X  d^   RV RV RV 2pRV RV RV 2p	V P
                  P                  V4       V'       d#   RV 2pV P
                  P                  V4       R# R# VR8X  d^   RV RV RV 2pRV RV RV 2p	V P
                  P                  V4       V'       d#   RV 2pV P
                  P                  V4       R# R# R# )u6   Registra intentos de acceso con información detalladar]   rutastepresult	timestampr   dataerrorSUCCESSu   ✅ ACCESO CONCEDIDO | User: 	 | Ruta: u    | Método: zACCESO CONCEDIDO | User: r   z   Datos utilizados: DENIEDu   🚫 ACCESO DENEGADO | User: z | Paso fallido: zACCESO DENEGADO | User: z   Datos del fallo: ERRORu!   ❌ ERROR EN VALIDACIÓN | User: z	 | Paso:    ERROR EN VALIDACIÓN | User: z
   Error: N)
r   now	isoformatr   r,   r   infodebugwarningrj   )r   r]   re   rf   rg   ri   rj   log_datafile_msgconsole_msg	debug_msgwarning_msg	error_msgs   &&&&&&&      r   _log_access_attempt$AccessController._log_access_attemptj   s    wDDf113488
 #V #E
HW Y6wiyl[_Z`aH5gYiv\Z^Y_`KKKX&xx=(T3D6:	!!), .2( x6wiyN_`d_efH4WIYtfL]^b]cdKKK) 4TF;##K0  w:7)9TFR[\`[abH9')D6QZ[_Z`aKKKh'(0	!!),  r    )maxsizec                     \        W4      #   \         d*   pT P                  P                  RT 24        Rp?R# Rp?ii ; i)zCache de permisos con TTLz"Error obteniendo permisos cached: N)r   rL   r   rj   )r   role_id	module_idrX   s   &&& r   _get_cached_permissions(AccessController._get_cached_permissions   s?    	w22 	KK B1#FG	s   
 A<Ac                   V P                   P                  R4        \        V4      pV P                   P                  RV R24       VR8X  d    V P                   P                  R4       RV3# V P                   P                  R4       RV3#   \         d+   pT P                   P	                  R	T 24       Ru R
p?# R
p?ii ; i)u   Validación 1: Superusuarioz(>>> METODO 1: VALIDACION DE SUPERUSUARIOz    Datos obtenidos: RoleID = ''SUz1    RESULTADO: ACCESO CONCEDIDO - Es SUPERUSUARIOTz1    RESULTADO: No es superusuario, continuando...Fu!       ✗ ERROR obteniendo RoleID: N)FN)r   rr   r   rL   rj   )r   r]   re   r   rX   s   &&&  r   _validate_superuser$AccessController._validate_superuser   s    CE	 )GKK>wiqIJ$  #TVW}$  #TV'>! 	KK A!EF	s$   AB -B CB<6C<Cc                    V P                   P                  R4       V P                   P                  R4       VR8X  d   V P                   P                  R4       R# V P                   P                  RV R24       R# )	u+   Validación 2: Acceso especial a index.htmlz,>>> METODO 2: VALIDACION ESPECIAL INDEX.HTMLz'    Verificando si ruta = '/index.html'/index.htmlzC    RESULTADO: ACCESO CONCEDIDO - Ruta es index.html (acceso libre)Tz    RESULTADO: Ruta 'z"' no es index.html, continuando...F)r   rr   )r   r]   re   s   &&&r   _validate_index_access'AccessController._validate_index_access   sf    GIBD= KKbdKK4TF:\]^r    c           	     
   V P                   P                  R4       VR8X  d9   V P                   P                  R4       V P                   P                  R4       R# V^ ,          e
   V^ ,          MRpV^,          e
   V^,          MRpV^,          e
   V^,          MRpV^,          e
   V^,          MRp	V^ ,          e
   V^ ,          MRp
V^,          e
   V^,          MRpV^,          e
   V^,          MRpV P                   P                  R4       V P                   P                  RV R	V R
V	 R24       V P                   P                  R4       V P                   P                  RV
 R	V R
V R24       WP                  9   Ed   V P                   P                  RV R24       V P                   P                  RV P                   24       V P                   P                  R4       Wz8X  dH   W8X  dB   W8X  d<   V'       d4   VR8w  d-   V	'       d%   V	R8w  d   V P                   P                  R4       R# V P                   P                  R4       V P                   P                  RWz8H   24       V P                   P                  RW8H   24       V P                   P                  RW8H   24       V P                   P                  RT;'       d    VR8g   24       V P                   P                  RT	;'       d    V	R8g   24       EMV P                   P                  RV R24       V'       d   VR8X  d|   V P                   P                  R4       Wz8X  d   V P                   P                  R4       R# V P                   P                  R4       V P                   P                  RWz8H   24       EMtV	'       d   V	R8X  d   V P                   P                  R4       Wz8X  d$   W8X  d   V P                   P                  R4       R# V P                   P                  R4       V P                   P                  RWz8H   24       V P                   P                  RW8H   24       MV P                   P                  R 4       Wz8X  d*   W8X  d$   W8X  d   V P                   P                  R!4       R# V P                   P                  R"4       V P                   P                  RWz8H   24       V P                   P                  RW8H   24       V P                   P                  RW8H   24       V P                   P                  R#4       R# )$u;   Validación 3: Acceso por departamento/división/compañíaz)>>> METODO 3: VALIDACION POR DEPARTAMENTOTz@    Restricted_Access = True - SALTANDO validacion departamentalzE    RESULTADO: Validacion departamental deshabilitada, continuando...FNz    DATOS DEL MODULO:z      Company: 'z' | Division: 'z' | Department: 'r   z    DATOS DE TU PERFIL:z%    DIVISION RESTRINGIDA detectada: 'z    Divisiones restringidas: zN    RESULTADO: Solo se permite acceso especifico (Company+Division+Department)r*   zV    RESULTADO: ACCESO CONCEDIDO - Acceso especifico completo para division restringidazY    RESULTADO: ACCESO DENEGADO - Division restringida requiere acceso especifico completoz      Company coincide: z      Division coincide: z      Department coincide: z(      Modulo tiene Division especifica: z*      Modulo tiene Department especifico: z    Division normal: 'z&' - Aplicando logica jerarquica normalzH    Modulo sin division especifica (vacio/None) - Validando solo Companyz2    RESULTADO: ACCESO CONCEDIDO - Company coincidez"    RESULTADO: Company no coincidezR    Modulo sin departamento especifico (vacio/None) - Validando Company + Divisionz>    RESULTADO: ACCESO CONCEDIDO - Company y Division coincidenz.    RESULTADO: Company o Division no coincidenzR    Modulo con departamento especifico - Validando Company + Division + DepartmentzJ    RESULTADO: ACCESO CONCEDIDO - Company, Division y Department coincidenz-    RESULTADO: No todos los valores coincidenz&    Continuando al siguiente metodo...)r   rr   RESTRICTED_DIVISIONS)r   r]   re   r^   r_   Restricted_AccessModuloIDM_CompanyIDM_DivisionIDM_DepartamentIDP_CompanyIDP_DivisionIDP_DepartamentIDs   &&&&&&       r   _validate_department_access,AccessController._validate_department_access   s    	DF$KK_aKKdf &1^%?;q>T(3A(Bk!n)4Q)C{1~,7N,F+a.D *6a)Dl1o$*6q/*E|A4-9!_-H,q/d02+K=~Ufgvfwwxyz24+K=~Ufgvfwwxyz 444KKD\NRSTUKK<T=V=V<WXYKKmo *,2!3Or$9  #y{  #|~  #;K<V;W!XY  #<\=Y<Z![\  #>?a>b!cd  #KLLoLo]imo]oKp!qr  #MoNwNwbquwbwMx!yz KK5l^Cijk  <2#5  #km-KK$$'Y[KK$$'IKKK$$'?@Z?[%\]$2(=  #uw-,2NKK$$'egKK$$'UWKK$$'?@Z?[%\]KK$$'@A]@^%_`   #uw. 0#6KK$$'qsKK$$'TVKK$$'?@Z?[%\]KK$$'@A]@^%_`KK$$'B?CeBf%ghACr    c                   V P                   P                  R4       V'       g"   V P                   P                  RV R24       R#  V P                  W44      pV P                   P                  R4       V P                   P                  RV RV R24       V P                   P                  R	V R24       Vel   \	        V4      pV P                   P                  RV 24       V^ 8  d   V P                   P                  R4       R# V P                   P                  R4        R# V P                   P                  R4       R#   \
         d*   pT P                   P                  RT 24        R
p?R# R
p?ii ; i)u$   Validación 4: Permisos específicosz1>>> METODO 4: VALIDACION POR PERMISOS ESPECIFICOSzRoleID no definido para UserID=u-   , no se pueden validar permisos específicos.Fz    DATOS DE PERMISOS:z      Tu RoleID: 'z' | ModuloID: 'r   z"      Valor de permiso obtenido: 'Nz#      Permiso convertido a entero: z-    RESULTADO: ACCESO CONCEDIDO - Permiso > 0Tz9    RESULTADO: ACCESO DENEGADO - Permiso = 0 (sin acceso)z>    RESULTADO: ACCESO DENEGADO - No se encontro permiso (NULL)u#       ✗ ERROR obteniendo permisos: )r   rr   rt   r   intrL   rj   )r   r]   re   r   r   
permissionpermission_levelrX   s   &&&&&   r   _validate_permission_access,AccessController._validate_permission_access  sF   LNKK"A'Jw xy	55gIJKK57KK1'/)TUVWKKA*QOP%#&z?   #FGWFX!YZ#a'KK$$'TVKK$$'`b    #ac 	KK CA3GH	s%   B<D? D? "D? ?E3
E..E3c                
   V P                  W4      w  rxV'       d   RRV3# V P                  W4      '       d   RRV3# V P                  WW4V4      '       d   RRV3# V'       d   V P                  WW4      '       d   RRV3# RRV3# )ut   
Ejecuta los 4 métodos de validación en cascada.
Retorna:
    (resultado: bool, metodo: str, role_id: str | None)
TzMETODO 1 - SUPERUSUARIOzMETODO 2 - INDEX.HTMLzMETODO 3 - DEPARTAMENTOzMETODO 4 - PERMISOS ESPECIFICOSFNINGUNO)r   r   r   r   )	r   UserIDre   r^   r_   r   r   is_superuserr   s	   &&&&&&&  r   _validate_access_cascade)AccessController._validate_access_cascade>  s     !% 8 8 F2G;; &&v440'99 ++F+Ufgg2G;; t77gXX:GCC i((r    c           	         V'       d+   \         P                  ! 4       V,
          P                  4       M^ pV P                  P	                  RV RV RVR R24       VR8X  d$   \
        P                  ! RR4      p\        WR	7      # \        V4      # )
zFRenderiza el template exitosamente con manejo especial para index.htmlzRENDERIZANDO TEMPLATE | User: rl   z | Tiempo ejecucion: .3fsr   emailUsuario)
user_email)r   rp   total_secondsr   rr   r   getr   )r   re   r]   
start_timeexecution_timer   s   &&&&  r   _render_success_template)AccessController._render_success_templateY  s    JT(,,.:5DDFZ[,WIYtf E!!/ 4A7	

 =  Wi8J"4??t$$r    )r   r   r   )CLIEEXTERNOSPROVEEDORES)NN)N)r3   r4   r5   r6   __doc__r   r   r   rb   r{   r   r   r   r   r   r   r   r   r7   r8   )r9   s   @r   r   r      sf     ? ?F
3j 2+-Z s *
ZxB)6% %r    r   c                	   ^ RI HpHp ^ RIHpHpHpHp ^ RIHp	 ^ RI	p
V	P                  ! 4       p\        4       p V '       g;   VP                  P                  R4       VP                  ! 4        V! V! R4      4      # V'       g"   RpVP                  WRR	VR
7       V! RVR7      # VP                  P!                  R4       VP                  P!                  RV  RV RV 24       VP                  P!                  R4        V! V4      pT! T 4      pTP)                  YT4      w  ppT F!  pTP                  P                  RT 24       K#  	  T'       d   T	P                  ! 4       T,
          P%                  4       pRRP+                  T4       2pTP                  YRR	TR
7       TP                  P'                  RT  RT RTR RT 24       T! RRR7      # T'       d   T^ ,          e
   T^ ,          MRpTP-                  YTTTT4      w  pppT	P                  ! 4       T,
          P%                  4       pT'       dV   TP                  P!                  RT RT  RT;'       g    R  R!T;'       g    R  RT R"TR R#24       TP/                  YT4      # T'       d/   R$T^ ,           R%T^,           R&T^,           RT;'       g    R  2pMR'pT'       d,   R(T^ ,           R)T^,           R%T^,           R&T^,           2pMR*pTP                  P                  R+T  RT;'       g    R  RT R"TR R#2	4       TP                  P                  R,T R-T 24       TP                  YR.R	R/T R0T R12R
7       T! RR2R7      #   \"         dv    T	P                  ! 4       T,
          P%                  4       pRT 2pTP                  YRR	TR
7       TP                  P'                  RT  RT RTR RT 24       T! RRR7      u # i ; i  \0         d   pT	P                  ! 4       T,
          P%                  4       pTP                  P'                  R3T  RT RTR R4\3        T4       24       TP4                  R58X  d.   TP                  P'                  R6T
P6                  ! 4        24       TP                  YR7R	\3        T4      R
7       T! RR8\3        T4       2R7      u Rp?# Rp?ii ; i)9zs
Valida el acceso del usuario a la ruta solicitada.
Aplica validaciones en cascada y maneja errores de integridad.
)r   r   )r   r   r   r	   )r   Nu?   Intento de acceso sin UserID en sesión - Redirigiendo al loginloginzRuta no proporcionadaINPUT_VALIDATIONrn   )rj   zSecurity/AccessDened.html)messagez&=== INICIANDO VALIDACION DE ACCESO ===zUser: rl   z | Restricted: z&=== VALIDANDO 4 METODOS EN CASCADA ===u%   No se encontró el módulo en la BD: DB_INTEGRITYro   u    | Tiempo ejecución: r   zs | u3   El módulo no está registrado en la base de datos.z	WARNING: zErrores de integridad en BD: z; z"Error al validar datos de usuario.zACCESO FINAL CONCEDIDO POR: z	 | User: z
 | RoleID=zN/Az | ModuloID=z | Tiempo: r   z
CompanyID=z | DivisionID=z | DepartamentID=zPerfil de usuario no disponiblez	ModuloID=z | CompanyID=u    Datos del módulo no disponiblesu>   ACCESO FINAL DENEGADO - TODOS LOS 4 MÉTODOS FALLARON | User: u      Comparación → Usuario: u    | Módulo: ACCESS_DENIEDu8   Diferencias detectadas entre perfil y módulo (Usuario: u    vs Módulo: )u/   No tienes permisos para acceder a este módulo.u   ERROR CRÍTICO | User: zs | Error: r   zTraceback completo:
GENERALzError al verificar acceso: )&Consultas_SQL.Security.UserPasswordSQLr   r   flaskr   r   r   r	   r   	tracebackrp   r   r   rt   clearr{   rr   LookupErrorr   rj   rb   rE   r   r   rL   r,   r   
format_exc)r   re   r   r   r   r   r   r   r	   r   r   r   access_controllerrz   r^   r   r_   r`   ra   rt   r   	resultadometodor   user_cmp
module_cmprX   s   &&&                        r   check_user_accessr   h  s   
 BA!J(*FO $$,,-noMMOGG,--/I11&@RT[cl1m"#>	RR  %%&NO  %%vhiv_UfTg&hi  %%&NO	b&t,K FfM -II&_kl  G$$,,y	-BC   &llnz9HHJN7		&8I7JKI11&PW_h1i$$**/xy G&&4S%9i[J ##>+OQ Q &1[^5O;q>UY
 &7%O%O+|5F&
"	67 #,,.:5DDF$$))*6( 3HJw'7'7%&8XEVEVQVDW XF+nS%9<

 %==dJWW  a 1Q?P Q%%1!_$5Z@P@P5?QS 
 =A/}[^<L M""-a.!11B;q>BRT 
 @
$$,,
7+;+;e*<IdV;WefiVjjkm $$,,/LXJVbcmbn-op11ow!!)
-
|1F 2  #+I q  		b&llnz9HHJN?vFI11&PW_h1i$$**/xy G&&4S%9i[J ##>+`b b		bz  O #,,.:5DDF  &&%fXYtf =""0!5[QJ	

   M1$$**-B9CWCWCYBZ+[\--fIwVYZ[V\-]:)DSVH'MO 	OOs   AO: =O:  O: &AO: M7 	AO: B O: O: BO:  O: -"O: O: 'O:  O: AO: AO: 7A=O74O: 6O77O: :SCSSS)r<   r   r   r   	functoolsr   r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r2   r    r   <module>r      s<      (  O O  
U% U%n
VOr    