
    uaiU              	       T    d Z ddlmZ ddlmZmZ ddlZd Zddeded	ed
e	fdZ
d ZdS )u  
app/middleware/auth.py
======================
Middleware autenticazione - decorator per proteggere endpoints.

Responsabilità:
- Estrarre JWT token da header Authorization
- Validare token con AuthService
- Passare tenant_id e user_id alla route
- Gestire errori autenticazione
    wraps)requestjsonifyNc                 <     t                      fd            }|S )aG  
    Decorator per proteggere endpoint con JWT.
    
    Come usarlo:
        @app.route('/api/v1/protected')
        @require_auth
        def protected_route(tenant_id, user_id):
            return {'tenant': tenant_id, 'user': user_id}
    
    Flow:
    1. Client invia: Authorization: Bearer <token>
    2. Decorator estrae token da header
    3. Valida token con auth_service
    4. Se valido: passa tenant_id e user_id a route
    5. Se invalido: ritorna 401 Unauthorized
    
    Nota: auth_service DEVE essere disponibile in flask.g
    (vedi app.__init__.py per setup)
    c                     t           j                            d          }|st          ddd          dfS |                                }t          |          dk    s|d         dk    rt          d	d
dd          dfS |d         }	 ddlm} |                    d          }|st          ddd          dfS |                    |          \  }}|rt          |dd          dfS |                    d          }	|                    d          }
|                    d          }|	st          ddd          dfS  | |	|
|d|S # t          $ r.}t          dt          |           dd          dfcY d }~S d }~ww xY w)NAuthorizationzMissing authorization headerMISSING_AUTH)errorcodei     r   Bearerz#Invalid authorization header formatINVALID_AUTH_FORMATzAuthorization: Bearer <token>)r   r   expected   gauth_servicezAuth service not initializedAUTH_SERVICE_ERRORi  INVALID_TOKEN	tenant_iduser_idruolozToken missing tenant_idINVALID_TOKEN_PAYLOAD)r   r   r   zAuthentication error: 
AUTH_ERROR)r   headersgetr   splitlenflaskr   validate_token	Exceptionstr)argskwargsauth_headerpartstokenr   r   payloadr   r   r   r   efs                @/var/www/enigma.pooltech.it/enigma_inventario/middleware_auth.pydecorated_functionz(require_auth.<locals>.decorated_function&   sl    o))/:: 	7&      !!##u::??eAh(22>-;    	  a'	5500L ;0       
 *88??NGU "+         K00Ikk),,GKK((E  63        1di+ +#)+ + +  	 	 	:#a&&::$          	s1   0E 9-E 'AE <E 
F #E;5F ;F r   r+   r-   s   ` r,   require_authr/      s7    ( 1XX? ? ? ? X?B     HS256r(   
jwt_secretjwt_algorithmreturnc                    	 t          j        | ||g          }|                    d          |                    d          dfS # t           j        $ r Y dS t           j        $ r}dddt          |           fcY d}~S d}~ww xY w)a  
    Utility: estrai tenant_id da token senza usare decorator.
    
    Utile per logica non-Flask (es. background jobs).
    
    Args:
        token (str): JWT token
        jwt_secret (str): Secret key
        jwt_algorithm (str): Algoritmo JWT
        
    Returns:
        tuple: (tenant_id, user_id, error)
        
    Esempio:
        >>> tenant_id, user_id, error = get_tenant_from_token(token, 'secret')
        >>> if not error:
        ...     print(f"Token for tenant {tenant_id}, user {user_id}")
    )
algorithmsr   r   N)NNzToken expiredzInvalid token: )jwtdecoder   ExpiredSignatureErrorInvalidTokenErrorr#   )r(   r2   r3   r)   r*   s        r,   get_tenant_from_tokenr;   k   s    &6*UJM?KKK{{;''Y)?)?EE$ + + +***  6 6 6T5SVV5555555556s$   AA BB%A?9B?Bc                 <     t                      fd            }|S )z
    Decorator opzionale: se token presente, valida.
    Se assente, lascia passare con tenant_id=None.
    
    Utile per endpoint pubblici che possono avere user loggato.
    
    Nota: Meno usato, ma utile per future feature.
    c                     t           j                            d          }d }d }|r|                                }t	          |          dk    r||d         dk    rp	 ddlm} |                    d          }|rJ|                    |d                   \  }}	|	s*|                    d          }|                    d	          }n#  Y nxY w 
| ||d
|S )Nr	   r   r   r   r   r   r   r   r   )r   r   )r   r   r   r   r   r    r   r!   )r$   r%   r&   r   r   r'   r   r   r)   r   r+   s             r,   r-   z)optional_auth.<locals>.decorated_function   s    o))/::	 	%%''E5zzQ58x#7#7	''''''#$55#8#8L# =)5)D)DU1X)N)N$ =(/K(@(@I&-kk)&<&<GDq$)WGGGGGs   A'C Cr   r.   s   ` r,   optional_authr>      s;     1XXH H H H XH* r0   )r1   )__doc__	functoolsr   r    r   r   r7   r/   r#   tupler;   r>    r0   r,   <module>rC      s   
 
       " " " " " " " " 



V V Vr6 6 6# 6c 6X] 6 6 6 68    r0   