You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
3.0 KiB

  1. # -*- coding: utf-8 -*-
  2. import json
  3. import logging
  4. from functools import wraps
  5. from odoo import http
  6. import werkzeug
  7. _logger = logging.getLogger(__name__)
  8. class ApiException(Exception):
  9. INVALID_REQUEST = 'invalid_request'
  10. def __init__(self, message, code=None):
  11. super(Exception, self).__init__(message)
  12. self.code = code if code else self.INVALID_REQUEST
  13. def resource(path, method, auth='user'):
  14. assert auth in ['user', 'client']
  15. def endpoint_decorator(func):
  16. @http.route(path, auth='public', type='http', methods=[method], csrf=False)
  17. @wraps(func)
  18. def func_wrapper(self, req, **query):
  19. try:
  20. access_token = None
  21. if 'Authorization' in req.httprequest.headers:
  22. authorization_header = req.httprequest.headers['Authorization']
  23. if authorization_header[:7] == 'Bearer ':
  24. access_token = authorization_header.split(' ', 1)[1]
  25. if access_token is None:
  26. access_token = query.get('access_token')
  27. if not access_token:
  28. raise ApiException(
  29. 'access_token param is missing',
  30. 'invalid_request',
  31. )
  32. if auth == 'user':
  33. token = req.env['galicea_openid_connect.access_token'].sudo().search(
  34. [('token', '=', access_token)]
  35. )
  36. if not token:
  37. raise ApiException(
  38. 'access_token is invalid',
  39. 'invalid_request',
  40. )
  41. req.uid = token.user_id.id
  42. elif auth == 'client':
  43. token = req.env['galicea_openid_connect.client_access_token'].sudo().search(
  44. [('token', '=', access_token)]
  45. )
  46. if not token:
  47. raise ApiException(
  48. 'access_token is invalid',
  49. 'invalid_request',
  50. )
  51. req.uid = token.client_id.system_user_id.id
  52. ctx = req.context.copy()
  53. ctx.update({'client_id': token.client_id.id})
  54. req.context = ctx
  55. response = func(self, req, **query)
  56. return json.dumps(response)
  57. except ApiException as e:
  58. return werkzeug.Response(
  59. response=json.dumps({'error': e.code, 'error_message': e.message}),
  60. status=400,
  61. )
  62. except:
  63. _logger.exception('Unexpected exception while processing API request')
  64. return werkzeug.Response(
  65. response=json.dumps({
  66. 'error': 'server_error',
  67. 'error_message': 'Unexpected server error',
  68. }),
  69. status=500,
  70. )
  71. return func_wrapper
  72. return endpoint_decorator