From 5a161439d47176c9fe3503128582400046f02fd0 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Thu, 6 Oct 2022 14:01:19 +0200 Subject: [PATCH 01/15] rest_log: add sanitize params hook Provide a hook to customize stored params. At the same time, assume passwords must be always cleaned up. --- rest_log/components/service.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 7fe8ff9ea..44ded890c 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -122,6 +122,8 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): if args: params = dict(params or {}, args=args) + params = self._log_call_sanitize_params(params) + result = kw.get("result") error = kw.get("traceback") orig_exception = kw.get("orig_exception") @@ -154,6 +156,11 @@ def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): return return env["rest.log"].sudo().create(values) + def _log_call_sanitize_params(self, params): + if "password" in params: + params["password"] = "" + return params + def _db_logging_active(self, method_name): enabled = self._log_calls_in_db if not enabled: From 46979c6e3f0d512dcbbe33b918565a17ce05613b Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 22 Nov 2022 15:39:38 +0000 Subject: [PATCH 02/15] rest_log 15.0.1.0.1 --- rest_log/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_log/__manifest__.py b/rest_log/__manifest__.py index 2e6b9f263..1aebe9c26 100644 --- a/rest_log/__manifest__.py +++ b/rest_log/__manifest__.py @@ -5,7 +5,7 @@ { "name": "REST Log", "summary": "Track REST API calls into DB", - "version": "15.0.1.0.0", + "version": "15.0.1.0.1", "development_status": "Beta", "website": "https://github.com/OCA/rest-framework", "author": "Camptocamp, ACSONE, Odoo Community Association (OCA)", From 126d60d9747c5dfb9ed7e7f46b73408d89e9f2e9 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Mon, 26 Jun 2023 09:31:36 +0200 Subject: [PATCH 03/15] [16.0][MIG] - rest_log --- .pre-commit-config.yaml | 1 - rest_log/__manifest__.py | 3 +-- rest_log/tests/test_db_logging.py | 3 +-- setup/rest_log/odoo/addons/rest_log | 1 + setup/rest_log/setup.py | 6 ++++++ 5 files changed, 9 insertions(+), 5 deletions(-) create mode 120000 setup/rest_log/odoo/addons/rest_log create mode 100644 setup/rest_log/setup.py diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 1a9d88595..93a5aff40 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -4,7 +4,6 @@ exclude: | ^base_rest_auth_jwt/| ^base_rest_auth_user_service/| ^model_serializer/| - ^rest_log/| # END NOT INSTALLABLE ADDONS # Files and folders generated by bots, to avoid loops ^setup/|/static/description/index\.html$| diff --git a/rest_log/__manifest__.py b/rest_log/__manifest__.py index 1aebe9c26..36f681c4c 100644 --- a/rest_log/__manifest__.py +++ b/rest_log/__manifest__.py @@ -5,7 +5,7 @@ { "name": "REST Log", "summary": "Track REST API calls into DB", - "version": "15.0.1.0.1", + "version": "16.0.1.0.0", "development_status": "Beta", "website": "https://github.com/OCA/rest-framework", "author": "Camptocamp, ACSONE, Odoo Community Association (OCA)", @@ -20,5 +20,4 @@ "views/rest_log_views.xml", "views/menu.xml", ], - "installable": False, } diff --git a/rest_log/tests/test_db_logging.py b/rest_log/tests/test_db_logging.py index 4acc97a06..0fe575c15 100644 --- a/rest_log/tests/test_db_logging.py +++ b/rest_log/tests/test_db_logging.py @@ -2,8 +2,7 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). # from urllib.parse import urlparse import json - -import mock +from unittest import mock from odoo import exceptions from odoo.tools import mute_logger diff --git a/setup/rest_log/odoo/addons/rest_log b/setup/rest_log/odoo/addons/rest_log new file mode 120000 index 000000000..e2a9bc60f --- /dev/null +++ b/setup/rest_log/odoo/addons/rest_log @@ -0,0 +1 @@ +../../../../rest_log \ No newline at end of file diff --git a/setup/rest_log/setup.py b/setup/rest_log/setup.py new file mode 100644 index 000000000..28c57bb64 --- /dev/null +++ b/setup/rest_log/setup.py @@ -0,0 +1,6 @@ +import setuptools + +setuptools.setup( + setup_requires=['setuptools-odoo'], + odoo_addon=True, +) From abda1ab56387a1bd34538aaada56959d8dd9052a Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Fri, 11 Mar 2022 17:03:58 +0100 Subject: [PATCH 04/15] [FIX] rest_log: result is not always a json --- rest_log/components/service.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 44ded890c..a85e3c3fd 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -7,6 +7,7 @@ import traceback from werkzeug.urls import url_encode, url_join +from werkzeug.wrappers import Response from odoo import exceptions, registry from odoo.http import request @@ -125,6 +126,10 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): params = self._log_call_sanitize_params(params) result = kw.get("result") + if isinstance(result, Response): + result = {"content": "Binary response"} + else: + result = json_dump(result) error = kw.get("traceback") orig_exception = kw.get("orig_exception") exception_name = None @@ -142,7 +147,7 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): "request_method": httprequest.method, "params": json_dump(params), "headers": json_dump(headers), - "result": json_dump(result), + "result": result, "error": error, "exception_name": exception_name, "exception_message": exception_message, From cf678f7b75c47e3feebf7515f38b528055c8d291 Mon Sep 17 00:00:00 2001 From: nans Date: Thu, 7 Apr 2022 14:16:46 +0200 Subject: [PATCH 05/15] [IMP] rest_log: never crash the call because of the log --- rest_log/components/service.py | 61 +++++++++++++++++++--------------- 1 file changed, 35 insertions(+), 26 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index a85e3c3fd..a17a80671 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -4,6 +4,7 @@ # License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl.html). import json +import logging import traceback from werkzeug.urls import url_encode, url_join @@ -21,6 +22,8 @@ RESTServiceValidationErrorException, ) +_logger = logging.getLogger(__name__) + def json_dump(data): """Encode data to JSON as we like.""" @@ -38,10 +41,9 @@ def dispatch(self, method_name, *args, params=None): return self._dispatch_with_db_logging(method_name, *args, params=params) def _dispatch_with_db_logging(self, method_name, *args, params=None): - # TODO: consider refactoring thi using a savepoint as described here - # https://github.com/OCA/rest-framework/pull/106#pullrequestreview-582099258 try: - result = super().dispatch(method_name, *args, params=params) + with self.env.cr.savepoint(): + result = super().dispatch(method_name, *args, params=params) except exceptions.ValidationError as orig_exception: self._dispatch_exception( method_name, @@ -66,34 +68,41 @@ def _dispatch_with_db_logging(self, method_name, *args, params=None): *args, params=params, ) - log_entry = self._log_call_in_db( - self.env, request, method_name, *args, params=params, result=result - ) - if log_entry and isinstance(result, dict): - log_entry_url = self._get_log_entry_url(log_entry) - result["log_entry_url"] = log_entry_url + self._log_dispatch_success(method_name, result, *args, params) return result + def _log_dispatch_success(self, method_name, result, *args, params=None): + try: + with self.env.cr.savepoint(): + log_entry = self._log_call_in_db( + self.env, request, method_name, *args, params + ) + if log_entry and not isinstance(result, Response): + log_entry_url = self._get_log_entry_url(log_entry) + result["log_entry_url"] = log_entry_url + except Exception as e: + _logger.exception("Rest Log Error Creation: %s", e) + def _dispatch_exception( self, method_name, exception_klass, orig_exception, *args, params=None ): - tb = traceback.format_exc() - # TODO: how to test this? Cannot rollback nor use another cursor - self.env.cr.rollback() - with registry(self.env.cr.dbname).cursor() as cr: - env = self.env(cr=cr) - log_entry = self._log_call_in_db( - env, - request, - method_name, - *args, - params=params, - traceback=tb, - orig_exception=orig_exception, - ) - log_entry_url = self._get_log_entry_url(log_entry) - # UserError and alike have `name` attribute to store the msg - exc_msg = self._get_exception_message(orig_exception) + exc_msg, log_entry_url = None, None # in case it fails below + try: + exc_msg = self._get_exception_message(orig_exception) + tb = traceback.format_exc() + with registry(self.env.cr.dbname).cursor() as cr: + log_entry = self._log_call_in_db( + self.env(cr=cr), + request, + method_name, + *args, + params=params, + traceback=tb, + orig_exception=orig_exception, + ) + log_entry_url = self._get_log_entry_url(log_entry) + except Exception as e: + _logger.exception("Rest Log Error Creation: %s", e) raise exception_klass(exc_msg, log_entry_url) from orig_exception def _get_exception_message(self, exception): From a0d2c2b058faf96a96f4f4fe3d822eee12fad249 Mon Sep 17 00:00:00 2001 From: nans Date: Thu, 7 Apr 2022 14:38:54 +0200 Subject: [PATCH 06/15] [IMP] rest_log: do not fail logging because of non-serializable parameters --- rest_log/components/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index a17a80671..0447aeb27 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -27,7 +27,7 @@ def json_dump(data): """Encode data to JSON as we like.""" - return json.dumps(data, cls=JSONEncoder, indent=4, sort_keys=True) + return json.dumps(data, cls=JSONEncoder, indent=4, sort_keys=True, default=str) class BaseRESTService(AbstractComponent): From cb644279136056c2ef0dd5b7d168d5bc9a0a4f86 Mon Sep 17 00:00:00 2001 From: "Laurent Mignon (ACSONE)" Date: Tue, 12 Apr 2022 12:16:06 +0200 Subject: [PATCH 07/15] [FIX] rest_lot: set the right status on the log in case of error --- rest_log/components/service.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 0447aeb27..a76cd0992 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -137,7 +137,7 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): result = kw.get("result") if isinstance(result, Response): result = {"content": "Binary response"} - else: + elif result: result = json_dump(result) error = kw.get("traceback") orig_exception = kw.get("orig_exception") From 9dbfa2fbd39080a2ce8ec652827d199c9a4e591d Mon Sep 17 00:00:00 2001 From: SilvioC2C Date: Tue, 11 Oct 2022 13:23:06 +0200 Subject: [PATCH 08/15] [FIX] rest_log: fix params management --- rest_log/components/service.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index a76cd0992..2ecd1d01b 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -129,8 +129,9 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): for header_key in self._log_call_header_strip: if header_key in headers: headers[header_key] = "" + params = dict(params or {}) if args: - params = dict(params or {}, args=args) + params.update(args=args) params = self._log_call_sanitize_params(params) @@ -170,7 +171,7 @@ def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): return return env["rest.log"].sudo().create(values) - def _log_call_sanitize_params(self, params): + def _log_call_sanitize_params(self, params: dict) -> dict: if "password" in params: params["password"] = "" return params From 17c6ef29a348f14da1e11c798456da4f16943a05 Mon Sep 17 00:00:00 2001 From: SilvioC2C Date: Tue, 11 Oct 2022 13:30:27 +0200 Subject: [PATCH 09/15] [IMP] rest_log: refactor headers management --- rest_log/components/service.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 2ecd1d01b..deab92c00 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -125,10 +125,7 @@ def _log_call_header_strip(self): def _log_call_in_db_values(self, _request, *args, params=None, **kw): httprequest = _request.httprequest - headers = dict(httprequest.headers) - for header_key in self._log_call_header_strip: - if header_key in headers: - headers[header_key] = "" + headers = self._log_call_sanitize_headers(dict(httprequest.headers or [])) params = dict(params or {}) if args: params.update(args=args) @@ -176,6 +173,12 @@ def _log_call_sanitize_params(self, params: dict) -> dict: params["password"] = "" return params + def _log_call_sanitize_headers(self, headers: dict) -> dict: + for header_key in self._log_call_header_strip: + if header_key in headers: + headers[header_key] = "" + return headers + def _db_logging_active(self, method_name): enabled = self._log_calls_in_db if not enabled: From a275c693cd1ca15e60c0dd460d2b5263c2500299 Mon Sep 17 00:00:00 2001 From: SilvioC2C Date: Tue, 11 Oct 2022 13:30:49 +0200 Subject: [PATCH 10/15] [IMP] rest_log: handle odoo.http.Response objects in logs Some endpoints will not return a dict as expected by the ``_dispatch_with_db_logging`` method (and the other methods called within), but an object of type ``odoo.http.Response``. When that happens, the instance fails to handle it while creating logs (ie: tries to call ``json.dumps()`` on such object, which is not allowed). This patch should fix the issue. --- rest_log/components/service.py | 19 ++++++++---- rest_log/tests/test_db_logging.py | 49 +++++++++++++++++++++++++++++++ 2 files changed, 62 insertions(+), 6 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index deab92c00..e16166f64 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -8,10 +8,9 @@ import traceback from werkzeug.urls import url_encode, url_join -from werkzeug.wrappers import Response from odoo import exceptions, registry -from odoo.http import request +from odoo.http import Response, request from odoo.addons.base_rest.http import JSONEncoder from odoo.addons.component.core import AbstractComponent @@ -133,10 +132,18 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): params = self._log_call_sanitize_params(params) result = kw.get("result") + # NB: ``result`` might be an object of class ``odoo.http.Response``, + # for example when you try to download a file. In this case, we need to + # handle it properly, without the assumption that ``result`` is a dict. if isinstance(result, Response): - result = {"content": "Binary response"} - elif result: - result = json_dump(result) + status_code = result.status_code + result = { + "status": status_code, + "headers": self._log_call_sanitize_headers(dict(result.headers or [])), + } + state = "success" if status_code in range(200, 300) else "failed" + else: + state = "success" if result else "failed" error = kw.get("traceback") orig_exception = kw.get("orig_exception") exception_name = None @@ -158,7 +165,7 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): "error": error, "exception_name": exception_name, "exception_message": exception_message, - "state": "success" if result else "failed", + "state": state, } def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): diff --git a/rest_log/tests/test_db_logging.py b/rest_log/tests/test_db_logging.py index 0fe575c15..01c1991ae 100644 --- a/rest_log/tests/test_db_logging.py +++ b/rest_log/tests/test_db_logging.py @@ -5,6 +5,7 @@ from unittest import mock from odoo import exceptions +from odoo.http import Response from odoo.tools import mute_logger from odoo.addons.base_rest.controllers.main import _PseudoCollection @@ -229,6 +230,54 @@ def test_log_entry_severity_mapping_param_bad_values(self): expected["ValueError"] = "warning" self.assertEqual(mapping, expected) + def test_log_entry_values_success_with_response(self): + with self._get_mocked_request() as mocked_request: + res = Response( + b"A test .pdf file to download", + headers=[ + ("Content-Type", "application/pdf"), + ("X-Content-Type-Options", "nosniff"), + ("Content-Disposition", "attachment; filename*=UTF-8''test.pdf"), + ("Content-Length", 28), + ], + ) + res.status_code = 200 + entry = self.service._log_call_in_db( + self.env, mocked_request, "method", result=res + ) + self.assertEqual(entry.state, "success") + self.assertEqual( + json.loads(entry.result), + { + "headers": { + "Content-Disposition": "attachment; filename*=UTF-8''test.pdf", + "Content-Length": "28", + "Content-Type": "application/pdf", + "X-Content-Type-Options": "nosniff", + }, + "status": 200, + }, + ) + + def test_log_entry_values_failure_with_response(self): + with self._get_mocked_request() as mocked_request: + res = Response(b"", headers=[]) + res.status_code = 418 + entry = self.service._log_call_in_db( + self.env, mocked_request, "method", result=res + ) + self.assertEqual(entry.state, "failed") + self.assertEqual( + json.loads(entry.result), + { + "headers": { + "Content-Length": "0", + "Content-Type": "text/html; charset=utf-8", + }, + "status": 418, + }, + ) + class TestDBLoggingExceptionBase( TransactionRestServiceRegistryCase, TestDBLoggingMixin From b2fc4d7c83a7f25c7c22253ba3ee927c9f666f7c Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Tue, 18 Oct 2022 15:19:52 +0200 Subject: [PATCH 11/15] rest_log: add hook to customize result --- rest_log/components/service.py | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index e16166f64..253e3f1c5 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -131,19 +131,7 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): params = self._log_call_sanitize_params(params) - result = kw.get("result") - # NB: ``result`` might be an object of class ``odoo.http.Response``, - # for example when you try to download a file. In this case, we need to - # handle it properly, without the assumption that ``result`` is a dict. - if isinstance(result, Response): - status_code = result.status_code - result = { - "status": status_code, - "headers": self._log_call_sanitize_headers(dict(result.headers or [])), - } - state = "success" if status_code in range(200, 300) else "failed" - else: - state = "success" if result else "failed" + result, state = self._log_call_prepare_result(kw.get("result")) error = kw.get("traceback") orig_exception = kw.get("orig_exception") exception_name = None @@ -168,6 +156,21 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): "state": state, } + def _log_call_prepare_result(self, result): + # NB: ``result`` might be an object of class ``odoo.http.Response``, + # for example when you try to download a file. In this case, we need to + # handle it properly, without the assumption that ``result`` is a dict. + if isinstance(result, Response): + status_code = result.status_code + result = { + "status": status_code, + "headers": self._log_call_sanitize_headers(dict(result.headers or [])), + } + state = "success" if status_code in range(200, 300) else "failed" + else: + state = "success" if result else "failed" + return result, state + def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): values = self._log_call_in_db_values(_request, *args, params=params, **kw) enabled_states = self._get_matching_active_conf(method_name) From 2ddda5807a26092984a95e739db2049716ae4d82 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Tue, 18 Oct 2022 15:23:26 +0200 Subject: [PATCH 12/15] rest_log: add hook to customize error --- rest_log/components/service.py | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 253e3f1c5..67fd82210 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -128,19 +128,9 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): params = dict(params or {}) if args: params.update(args=args) - params = self._log_call_sanitize_params(params) - + error, exception_name, exception_message = self._log_call_prepare_error(**kw) result, state = self._log_call_prepare_result(kw.get("result")) - error = kw.get("traceback") - orig_exception = kw.get("orig_exception") - exception_name = None - exception_message = None - if orig_exception: - exception_name = orig_exception.__class__.__name__ - if hasattr(orig_exception, "__module__"): - exception_name = orig_exception.__module__ + "." + exception_name - exception_message = self._get_exception_message(orig_exception) collection = self.work.collection return { "collection": collection._name, @@ -171,6 +161,16 @@ def _log_call_prepare_result(self, result): state = "success" if result else "failed" return result, state + def _log_call_prepare_error(self, traceback=None, orig_exception=None, **kw): + exception_name = None + exception_message = None + if orig_exception: + exception_name = orig_exception.__class__.__name__ + if hasattr(orig_exception, "__module__"): + exception_name = orig_exception.__module__ + "." + exception_name + exception_message = self._get_exception_message(orig_exception) + return traceback, exception_name, exception_message + def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): values = self._log_call_in_db_values(_request, *args, params=params, **kw) enabled_states = self._get_matching_active_conf(method_name) From 27d62b280a7f5bf85a3b34a594d9f0763b309983 Mon Sep 17 00:00:00 2001 From: Simone Orsi Date: Tue, 18 Oct 2022 16:10:39 +0200 Subject: [PATCH 13/15] rest_log: postpone serialization of values This way we can hook an manipulate data w/out having to decode from JSON back and forth. --- rest_log/components/service.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 67fd82210..3c1751c98 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -137,8 +137,8 @@ def _log_call_in_db_values(self, _request, *args, params=None, **kw): "collection_id": collection.id, "request_url": httprequest.url, "request_method": httprequest.method, - "params": json_dump(params), - "headers": json_dump(headers), + "params": params, + "headers": headers, "result": result, "error": error, "exception_name": exception_name, @@ -171,8 +171,12 @@ def _log_call_prepare_error(self, traceback=None, orig_exception=None, **kw): exception_message = self._get_exception_message(orig_exception) return traceback, exception_name, exception_message + _log_call_in_db_keys_to_serialize = ("params", "headers", "result") + def _log_call_in_db(self, env, _request, method_name, *args, params=None, **kw): values = self._log_call_in_db_values(_request, *args, params=params, **kw) + for k in self._log_call_in_db_keys_to_serialize: + values[k] = json_dump(values[k]) enabled_states = self._get_matching_active_conf(method_name) if not values or enabled_states and values["state"] not in enabled_states: return From cb8e8c5413ecdcdb3beba382c9cfc43c9ab6e57c Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Fri, 22 Sep 2023 11:42:46 +0200 Subject: [PATCH 14/15] [FIX] - fix rest log form view --- rest_log/views/rest_log_views.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/rest_log/views/rest_log_views.xml b/rest_log/views/rest_log_views.xml index 323190cea..9528fc19d 100644 --- a/rest_log/views/rest_log_views.xml +++ b/rest_log/views/rest_log_views.xml @@ -82,6 +82,7 @@ nolabel="1" widget="ace" options="{'mode': 'python'}" + colspan="2" /> From daab30b9d82504c2e30d693e16c8f2459af33df0 Mon Sep 17 00:00:00 2001 From: sbejaoui Date: Tue, 12 Dec 2023 09:01:46 +0100 Subject: [PATCH 15/15] [FIX] rest_log: log result in case success --- rest_log/README.rst | 23 +++++---- rest_log/components/service.py | 2 +- rest_log/static/description/index.html | 66 +++++++++++++------------- rest_log/views/rest_log_views.xml | 2 +- 4 files changed, 49 insertions(+), 44 deletions(-) diff --git a/rest_log/README.rst b/rest_log/README.rst index 72a6377f5..9be31c092 100644 --- a/rest_log/README.rst +++ b/rest_log/README.rst @@ -2,10 +2,13 @@ REST Log ======== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:c4d8f6d63c3748741d5306c2b4327785eaec0a0c9770397ef4610266c515d0f2 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -14,16 +17,16 @@ REST Log :target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html :alt: License: LGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github - :target: https://github.com/OCA/rest-framework/tree/15.0/rest_log + :target: https://github.com/OCA/rest-framework/tree/16.0/rest_log :alt: OCA/rest-framework .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/rest-framework-15-0/rest-framework-15-0-rest_log + :target: https://translation.odoo-community.org/projects/rest-framework-16-0/rest-framework-16-0-rest_log :alt: Translate me on Weblate -.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png - :target: https://runbot.odoo-community.org/runbot/271/15.0 - :alt: Try me on Runbot +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&target_branch=16.0 + :alt: Try me on Runboat -|badge1| |badge2| |badge3| |badge4| |badge5| +|badge1| |badge2| |badge3| |badge4| |badge5| When exposing REST services is often useful to see what's happening especially in case of errors. @@ -90,8 +93,8 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. -If you spotted it first, help us smashing it by providing a detailed and welcomed -`feedback `_. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -140,6 +143,6 @@ Current `maintainer `__: |maintainer-simahawk| -This module is part of the `OCA/rest-framework `_ project on GitHub. +This module is part of the `OCA/rest-framework `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/rest_log/components/service.py b/rest_log/components/service.py index 3c1751c98..354bfe178 100644 --- a/rest_log/components/service.py +++ b/rest_log/components/service.py @@ -74,7 +74,7 @@ def _log_dispatch_success(self, method_name, result, *args, params=None): try: with self.env.cr.savepoint(): log_entry = self._log_call_in_db( - self.env, request, method_name, *args, params + self.env, request, method_name, *args, params, result=result ) if log_entry and not isinstance(result, Response): log_entry_url = self._get_log_entry_url(log_entry) diff --git a/rest_log/static/description/index.html b/rest_log/static/description/index.html index 9fce1a724..8cd6a83ef 100644 --- a/rest_log/static/description/index.html +++ b/rest_log/static/description/index.html @@ -1,20 +1,20 @@ - + - + REST Log