[IMP] runbot: handle exceptions in web_search_read

This commit is contained in:
Christophe Monniez 2024-02-29 16:15:11 +01:00
parent e4c5e64574
commit 376b23e122

View File

@ -2,16 +2,40 @@ import json
import logging import logging
import time import time
from functools import wraps
from odoo import http from odoo import http
from odoo.http import request from odoo.http import request
from odoo.exceptions import AccessError, AccessDenied, UserError
from odoo.tools import consteq from odoo.tools import consteq
_logger = logging.getLogger(__name__) _logger = logging.getLogger(__name__)
def to_json(fn):
@wraps(fn)
def decorator(*args, **kwargs):
headers = [('Content-Type', 'application/json'),
('Cache-Control', 'no-store')]
try:
return request.make_response(json.dumps(fn(*args, **kwargs), indent=4, default=str), headers)
except AccessError:
response = request.make_response(json.dumps('unauthorized'), headers)
response.status = 401
return response
except AccessDenied as e:
response = request.make_response(json.dumps(e.args[0]), headers)
response.status = 403
return response
except UserError as e:
response = request.make_response(json.dumps(e.args[0]), headers)
response.status = 400
return response
return decorator
class RunbotController(http.Controller): class RunbotController(http.Controller):
@http.route('/runbot/api/web_search_read', type='http', auth='public', csrf=False) @http.route('/runbot/api/web_search_read', type='http', auth='public', csrf=False)
@to_json
def api_web_search_read(self, uid=None, token=None, model=None, specification=None, id=None, ids=None, domain=None, limit=200, offset=0, order=None): def api_web_search_read(self, uid=None, token=None, model=None, specification=None, id=None, ids=None, domain=None, limit=200, offset=0, order=None):
""" """
model: the model to read model: the model to read
@ -43,13 +67,19 @@ class RunbotController(http.Controller):
).json() ).json()
""" """
user = request.env['res.users'].sudo().browse(int(uid)) user = request.env['res.users'].sudo().browse(int(uid))
if not user or not token or len(token) < 32 or not consteq(user.runbot_api_token, token): try:
assert user.active # handle unexisting user, accessing a field raises a user error
except UserError:
time.sleep(1) time.sleep(1)
return json.dumps({'error': 'Invalid user or token'}) raise AccessDenied(message={'error': 'Unauthorized'})
if not user or not user.runbot_api_token or not token or len(token) < 32 or not consteq(user.runbot_api_token, token):
time.sleep(1)
raise AccessDenied(message={'error': 'Invalid user or token'})
request.env.cache.clear() request.env.cache.clear()
limit = max(min(2000, limit), 1) limit = max(min(2000, limit), 1)
if not model.startswith('runbot.'): if not model.startswith('runbot.'):
return json.dumps({'error': 'Invalid model'}) raise UserError({'error': 'Invalid model'})
if id: if id:
ids = [id] ids = [id]
if ids: if ids:
@ -57,13 +87,13 @@ class RunbotController(http.Controller):
else: else:
domain = json.loads(domain) domain = json.loads(domain)
if not domain: if not domain:
return json.dumps({'error': 'Invalid domain'}) raise UserError({'error': 'Invalid domain'})
specification = json.loads(specification) specification = json.loads(specification)
try: try:
user_env = request.env(user=user) user_env = request.env(user=user)
result = user_env[model].web_search_read(domain, specification, limit=limit, offset=offset, order=order) result = user_env[model].web_search_read(domain, specification, limit=limit, offset=offset, order=order)
return json.dumps(result) return result
except Exception: except Exception:
_logger.exception('Something went wrong reading %s %s %s', model, specification, domain) _logger.exception('Something went wrong reading %s %s %s', model, specification, domain)
return json.dumps({'error': 'Something went wrong'}) raise UserError({'error': 'Something went wrong'})