- Created a new eveai_chat plugin to support the new dynamic possibilities of the Specialists. Currently only supports standard Rag retrievers (i.e. no extra arguments).

This commit is contained in:
Josako
2024-11-26 13:35:29 +01:00
parent 7702a6dfcc
commit 07d89d204f
42 changed files with 1771 additions and 989 deletions

View File

@@ -5,10 +5,12 @@ from flask_jwt_extended import get_jwt_identity, verify_jwt_in_request
from sqlalchemy.exc import SQLAlchemyError
from werkzeug.exceptions import HTTPException
from common.extensions import db, api_rest, jwt, minio_client, simple_encryption
from common.extensions import db, api_rest, jwt, minio_client, simple_encryption, cors
import os
import logging.config
from common.models.user import TenantDomain
from common.utils.cors_utils import get_allowed_origins
from common.utils.database import Database
from config.logging_config import LOGGING
from .api.document_api import document_ns
@@ -54,7 +56,32 @@ def create_app(config_file=None):
register_error_handlers(app)
@app.before_request
def before_request():
def check_cors():
if request.method == 'OPTIONS':
app.logger.debug("Handling OPTIONS request")
return '', 200 # Allow OPTIONS to pass through
origin = request.headers.get('Origin')
if not origin:
return # Not a CORS request
# Get tenant ID from request
if verify_jwt_in_request():
tenant_id = get_jwt_identity()
if not tenant_id:
return
else:
return
# Check if origin is allowed for this tenant
allowed_origins = get_allowed_origins(tenant_id)
if origin not in allowed_origins:
app.logger.warning(f'Origin {origin} not allowed for tenant {tenant_id}')
return {'error': 'Origin not allowed'}, 403
@app.before_request
def set_tenant_schema():
# Check if this a health check request
if request.path.startswith('/_healthz') or request.path.startswith('/healthz'):
pass
@@ -83,6 +110,17 @@ def register_extensions(app):
jwt.init_app(app)
minio_client.init_app(app)
simple_encryption.init_app(app)
cors.init_app(app, resources={
r"/api/v1/*": {
"origins": "*",
"methods": ["GET", "POST", "PUT", "OPTIONS"],
"allow_headers": ["Content-Type", "Authorization", "X-Requested-With"],
"expose_headers": ["Content-Length", "Content-Range"],
"supports_credentials": True,
"max_age": 1728000, # 20 days
"allow_credentials": True
}
})
def register_namespaces(app):

View File

@@ -1,7 +1,7 @@
from datetime import timedelta
from datetime import timedelta, datetime as dt, timezone as tz
from flask_restx import Namespace, Resource, fields
from flask_jwt_extended import create_access_token
from flask_jwt_extended import create_access_token, verify_jwt_in_request, get_jwt
from common.models.user import Tenant, TenantProject
from common.extensions import simple_encryption
from flask import current_app, request
@@ -18,6 +18,12 @@ token_response = auth_ns.model('TokenResponse', {
'expires_in': fields.Integer(description='Token expiration time in seconds')
})
token_verification = auth_ns.model('TokenVerification', {
'is_valid': fields.Boolean(description='Token validity status'),
'expires_in': fields.Integer(description='Seconds until token expiration'),
'tenant_id': fields.Integer(description='Tenant ID from token')
})
@auth_ns.route('/token')
class Token(Resource):
@@ -82,3 +88,61 @@ class Token(Resource):
except Exception as e:
current_app.logger.error(f"Error creating access token: {e}")
return {'message': "Internal server error"}, 500
@auth_ns.route('/verify')
class TokenVerification(Resource):
@auth_ns.doc('verify_token')
@auth_ns.response(200, 'Token verification result', token_verification)
@auth_ns.response(401, 'Invalid token')
def get(self):
"""Verify a token's validity and get expiration information"""
try:
verify_jwt_in_request()
jwt_data = get_jwt()
# Get expiration timestamp from token
exp_timestamp = jwt_data['exp']
current_timestamp = dt.now().timestamp()
return {
'is_valid': True,
'expires_in': int(exp_timestamp - current_timestamp),
'tenant_id': jwt_data['sub'] # tenant_id is stored in 'sub' claim
}, 200
except Exception as e:
current_app.logger.error(f"Token verification failed: {str(e)}")
return {
'is_valid': False,
'message': 'Invalid token'
}, 401
@auth_ns.route('/refresh')
class TokenRefresh(Resource):
@auth_ns.doc('refresh_token')
@auth_ns.response(200, 'New token', token_response)
@auth_ns.response(401, 'Invalid token')
def post(self):
"""Get a new token before the current one expires"""
try:
verify_jwt_in_request()
jwt_data = get_jwt()
tenant_id = jwt_data['sub']
# Optional: Add additional verification here if needed
# Create new token
expires_delta = current_app.config.get('JWT_ACCESS_TOKEN_EXPIRES', timedelta(minutes=15))
new_token = create_access_token(
identity=tenant_id,
expires_delta=expires_delta
)
return {
'access_token': new_token,
'expires_in': int(expires_delta.total_seconds())
}, 200
except Exception as e:
current_app.logger.error(f"Token refresh failed: {str(e)}")
return {'message': 'Token refresh failed'}, 401