- First 'working' version of the Zapier plugin. Needs further debugging and needs additional functionalty (only add_document.js)

This commit is contained in:
Josako
2024-12-12 16:36:41 +01:00
parent d35ec9f5ae
commit 46c60b36a0
14 changed files with 4875 additions and 17 deletions

View File

@@ -1,10 +1,11 @@
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, verify_jwt_in_request, get_jwt
from flask_jwt_extended import create_access_token, verify_jwt_in_request, get_jwt, get_jwt_identity, jwt_required
from common.models.user import Tenant, TenantProject
from common.extensions import simple_encryption
from flask import current_app, request
from flask import current_app, jsonify, request
from functools import wraps
auth_ns = Namespace('auth', description='Authentication related operations')
@@ -36,7 +37,6 @@ class Token(Resource):
"""
Get JWT token
"""
current_app.logger.debug(f'Token Requested {auth_ns.payload}')
try:
tenant_id = int(auth_ns.payload['tenant_id'])
api_key = auth_ns.payload['api_key']
@@ -71,16 +71,19 @@ class Token(Resource):
current_app.logger.error(f"Project for given API key not found for Tenant: {tenant_id}")
return {'message': "Invalid API key"}, 401
if "DOCAPI" not in matching_project.services:
current_app.logger.error(f"Service DOCAPI not authorized for Project {matching_project.name} "
f"for Tenant: {tenant_id}")
return {'message': f"Service DOCAPI not authorized for Project {matching_project.name}"}, 403
# 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:
access_token = create_access_token(identity=tenant_id, expires_delta=expires_delta)
additional_claims = {
'services': matching_project.services,
}
access_token = create_access_token(
identity=tenant_id,
expires_delta=expires_delta,
additional_claims=additional_claims
)
current_app.logger.debug(f"Created token: {access_token}")
return {
'access_token': access_token,
'expires_in': expires_delta.total_seconds()
@@ -145,4 +148,51 @@ class TokenRefresh(Resource):
}, 200
except Exception as e:
current_app.logger.error(f"Token refresh failed: {str(e)}")
return {'message': 'Token refresh failed'}, 401
return {'message': 'Token refresh failed'}, 401
@auth_ns.route('/services')
class Services(Resource):
@jwt_required()
@auth_ns.doc(security='Bearer')
@auth_ns.response(200, 'Success', {
'services': fields.List(fields.String, description='List of allowed services for this token'),
'tenant_id': fields.Integer(description='Tenant ID associated with this token')
})
@auth_ns.response(401, 'Invalid or expired token')
def get(self):
"""
Get allowed services for the current token
"""
# Log the incoming authorization header
auth_header = request.headers.get('Authorization')
current_app.logger.debug(f"Received Authorization header: {auth_header}")
claims = get_jwt()
tenant_id = get_jwt_identity()
return {
'services': claims.get('services', []),
'tenant_id': tenant_id
}, 200
# Decorate function to check for a particular service
def requires_service(service_name):
def decorator(fn):
@wraps(fn)
def wrapper(*args, **kwargs):
# Get the JWT claims
claims = get_jwt()
services = claims.get('services', [])
if service_name not in services:
return {
'message': f'This endpoint requires the {service_name} service',
'error': 'Insufficient permissions'
}, 403
return fn(*args, **kwargs)
return wrapper
return decorator