from datetime import timedelta from flask_restx import Namespace, Resource, fields from flask_jwt_extended import create_access_token from common.models.user import Tenant from common.extensions import simple_encryption from flask import current_app, request auth_ns = Namespace('auth', description='Authentication related operations') token_model = auth_ns.model('Token', { 'tenant_id': fields.Integer(required=True, description='Tenant ID'), 'api_key': fields.String(required=True, description='API Key') }) token_response = auth_ns.model('TokenResponse', { 'access_token': fields.String(description='JWT access token'), 'expires_in': fields.Integer(description='Token expiration time in seconds') }) @auth_ns.route('/token') class Token(Resource): @auth_ns.expect(token_model) @auth_ns.response(200, 'Success', token_response) @auth_ns.response(400, 'Validation Error') @auth_ns.response(401, 'Unauthorized') @auth_ns.response(404, 'Tenant Not Found') def post(self): """ Get JWT token """ current_app.logger.debug(f"Token endpoint called with data: {request.json}") try: tenant_id = auth_ns.payload['tenant_id'] api_key = auth_ns.payload['api_key'] except KeyError as e: current_app.logger.error(f"Missing required field: {e}") return {'message': f"Missing required field: {e}"}, 400 current_app.logger.debug(f"Querying database for tenant: {tenant_id}") tenant = Tenant.query.get(tenant_id) if not tenant: current_app.logger.error(f"Tenant not found: {tenant_id}") return {'message': "Tenant not found"}, 404 current_app.logger.debug(f"Tenant found: {tenant.id}") try: current_app.logger.debug("Attempting to decrypt API key") decrypted_api_key = simple_encryption.decrypt_api_key(tenant.encrypted_api_key) except Exception as e: current_app.logger.error(f"Error decrypting API key: {e}") return {'message': "Internal server error"}, 500 if api_key != decrypted_api_key: current_app.logger.error(f"Invalid API key for tenant: {tenant_id}") return {'message': "Invalid API key"}, 401 # Get the JWT_ACCESS_TOKEN_EXPIRES setting from the app config expires_delta = current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', timedelta(minutes=15)) try: current_app.logger.debug(f"Creating access token for tenant: {tenant_id}") access_token = create_access_token(identity=tenant_id, expires_delta=expires_delta) current_app.logger.debug("Access token created successfully") return { 'access_token': access_token, 'expires_in': expires_delta.total_seconds() }, 200 except Exception as e: current_app.logger.error(f"Error creating access token: {e}") return {'message': "Internal server error"}, 500