import json import logging from functools import wraps from odoo import http import werkzeug _logger = logging.getLogger(__name__) class ApiException(Exception): INVALID_REQUEST = "invalid_request" def __init__(self, message, code=None): super(Exception, self).__init__(message) self.code = code if code else self.INVALID_REQUEST def resource(path, method, auth="user"): assert auth in ["user", "client"] def endpoint_decorator(func): @http.route( path, auth="public", type="http", methods=[method, "OPTIONS"], csrf=False ) @wraps(func) def func_wrapper(self, req, **query): cors_headers = { "Access-Control-Allow-Origin": "*", "Access-Control-Allow-Headers": "Origin, X-Requested-With, Content-Type, Accept, X-Debug-Mode, Authorization", "Access-Control-Max-Age": 60 * 60 * 24, } if req.httprequest.method == "OPTIONS": return http.Response(status=200, headers=cors_headers) try: access_token = None if "Authorization" in req.httprequest.headers: authorization_header = req.httprequest.headers["Authorization"] if authorization_header[:7] == "Bearer ": access_token = authorization_header.split(" ", 1)[1] if access_token is None: access_token = query.get("access_token") if not access_token: raise ApiException( "access_token param is missing", "invalid_request", ) if auth == "user": token = ( req.env["galicea_openid_connect.access_token"] .sudo() .search([("token", "=", access_token)]) ) if not token: raise ApiException( "access_token is invalid", "invalid_request", ) req.uid = token.user_id.id elif auth == "client": token = ( req.env["galicea_openid_connect.client_access_token"] .sudo() .search([("token", "=", access_token)]) ) if not token: raise ApiException( "access_token is invalid", "invalid_request", ) req.uid = token.client_id.system_user_id.id ctx = req.context.copy() ctx.update({"client_id": token.client_id.id}) req.context = ctx response = func(self, req, **query) return werkzeug.Response( response=json.dumps(response), headers=cors_headers, status=200 ) except ApiException as e: error_message = "error: {0}".format(e) return werkzeug.Response( response=json.dumps( {"error": e.code, "error_message": error_message} ), status=400, headers=cors_headers, ) except: _logger.exception("Unexpected exception while processing API request") return werkzeug.Response( response=json.dumps( { "error": "server_error", "error_message": "Unexpected server error", } ), headers=cors_headers, status=500, ) return func_wrapper return endpoint_decorator