From deb8c9c1f07ae528f1c40816195e2cb03b7e956c Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 25 Feb 2025 12:57:09 +0100 Subject: [PATCH 1/7] [ADD] fastapi_encrypted_errors --- fastapi_encrypted_errors/README.rst | 99 ++++ fastapi_encrypted_errors/__init__.py | 3 + fastapi_encrypted_errors/__manifest__.py | 25 + .../fastapi_dispatcher.py | 35 ++ fastapi_encrypted_errors/models/__init__.py | 1 + .../models/fastapi_endpoint.py | 47 ++ .../readme/CONTRIBUTORS.rst | 3 + .../readme/DESCRIPTION.rst | 3 + fastapi_encrypted_errors/readme/USAGE.rst | 7 + .../security/ir.model.access.csv | 2 + .../static/description/index.html | 439 ++++++++++++++++++ fastapi_encrypted_errors/tests/__init__.py | 1 + .../tests/test_fastapi_encrypted_errors.py | 74 +++ .../views/fastapi_endpoint_views.xml | 31 ++ fastapi_encrypted_errors/wizards/__init__.py | 1 + .../wizards/wizard_fastapi_decrypt_errors.py | 40 ++ .../wizard_fastapi_decrypt_errors_views.xml | 47 ++ 17 files changed, 858 insertions(+) create mode 100644 fastapi_encrypted_errors/README.rst create mode 100644 fastapi_encrypted_errors/__init__.py create mode 100644 fastapi_encrypted_errors/__manifest__.py create mode 100644 fastapi_encrypted_errors/fastapi_dispatcher.py create mode 100644 fastapi_encrypted_errors/models/__init__.py create mode 100644 fastapi_encrypted_errors/models/fastapi_endpoint.py create mode 100644 fastapi_encrypted_errors/readme/CONTRIBUTORS.rst create mode 100644 fastapi_encrypted_errors/readme/DESCRIPTION.rst create mode 100644 fastapi_encrypted_errors/readme/USAGE.rst create mode 100644 fastapi_encrypted_errors/security/ir.model.access.csv create mode 100644 fastapi_encrypted_errors/static/description/index.html create mode 100644 fastapi_encrypted_errors/tests/__init__.py create mode 100644 fastapi_encrypted_errors/tests/test_fastapi_encrypted_errors.py create mode 100644 fastapi_encrypted_errors/views/fastapi_endpoint_views.xml create mode 100644 fastapi_encrypted_errors/wizards/__init__.py create mode 100644 fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors.py create mode 100644 fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml diff --git a/fastapi_encrypted_errors/README.rst b/fastapi_encrypted_errors/README.rst new file mode 100644 index 000000000..7027f164e --- /dev/null +++ b/fastapi_encrypted_errors/README.rst @@ -0,0 +1,99 @@ +======================== +FastAPI Encrypted Errors +======================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:296fbef824a5eb64e9bbaedc382ef15e41d146f0cc59d458c0d76de46a54358e + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github + :target: https://github.com/OCA/rest-framework/tree/16.0/fastapi_encrypted_errors + :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-16-0/rest-framework-16-0-fastapi_encrypted_errors + :alt: Translate me on Weblate +.. |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| + +This module adds a "ref" field in the error response of FastAPI. +This field is an AES encrypted string that contains the error message / traceback. +This encrypted string can be decrypted using the endpoint decrypt error wizard. + +**Table of contents** + +.. contents:: + :local: + +Usage +===== + +First you have to enable the encryption for an endpoint by checking the `Encrypt Errors` checkbox +in the endpoint configuration. + +To decrypt an error message, you can use the "Decrypt Error" wizard in the +FastAPI menu. + +You can regenerate a new key by clicking on the "Regenerate Key" button next to the `Errors Secret Key` field. + +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 to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* Akretion + +Contributors +~~~~~~~~~~~~ + +* `Akretion `_: + + * Florian Mounier + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-paradoxxxzero| image:: https://github.com/paradoxxxzero.png?size=40px + :target: https://github.com/paradoxxxzero + :alt: paradoxxxzero + +Current `maintainer `__: + +|maintainer-paradoxxxzero| + +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/fastapi_encrypted_errors/__init__.py b/fastapi_encrypted_errors/__init__.py new file mode 100644 index 000000000..d7f65dfa1 --- /dev/null +++ b/fastapi_encrypted_errors/__init__.py @@ -0,0 +1,3 @@ +from . import models +from . import wizards +from . import fastapi_dispatcher diff --git a/fastapi_encrypted_errors/__manifest__.py b/fastapi_encrypted_errors/__manifest__.py new file mode 100644 index 000000000..254901404 --- /dev/null +++ b/fastapi_encrypted_errors/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +{ + "name": "FastAPI Encrypted Errors", + "summary": "Adds encrypted error messages to FastAPI error responses.", + "version": "16.0.1.0.0", + "license": "AGPL-3", + "author": "Akretion,Odoo Community Association (OCA)", + "maintainers": ["paradoxxxzero"], + "website": "https://github.com/OCA/rest-framework", + "depends": [ + "fastapi", + ], + "data": [ + "security/ir.model.access.csv", + "views/fastapi_endpoint_views.xml", + "wizards/wizard_fastapi_decrypt_errors_views.xml", + ], + "demo": [], + "external_dependencies": { + "python": ["cryptography"], + }, +} diff --git a/fastapi_encrypted_errors/fastapi_dispatcher.py b/fastapi_encrypted_errors/fastapi_dispatcher.py new file mode 100644 index 000000000..a3f0524a2 --- /dev/null +++ b/fastapi_encrypted_errors/fastapi_dispatcher.py @@ -0,0 +1,35 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +from odoo.http import _dispatchers + +from odoo.addons.fastapi.error_handlers import convert_exception_to_status_body +from odoo.addons.fastapi.fastapi_dispatcher import ( + FastApiDispatcher as BaseFastApiDispatcher, +) + + +# Inherit from last registered fastapi dispatcher +# This handles multiple overload of dispatchers +class FastApiDispatcher(_dispatchers.get("fastapi", BaseFastApiDispatcher)): + routing_type = "fastapi" + + def handle_error(self, exc): + environ = self._get_environ() + root_path = "/" + environ["PATH_INFO"].split("/")[1] + fastapi_endpoint = ( + self.request.env["fastapi.endpoint"] + .sudo() + .search([("root_path", "=", root_path)]) + ) + if fastapi_endpoint.encrypt_errors: + headers = getattr(exc, "headers", None) + status_code, body = convert_exception_to_status_body(exc) + if body: + body["ref"] = fastapi_endpoint._encrypt_error(exc) + return self.request.make_json_response( + body, status=status_code, headers=headers + ) + + return super().handle_error(exc) diff --git a/fastapi_encrypted_errors/models/__init__.py b/fastapi_encrypted_errors/models/__init__.py new file mode 100644 index 000000000..b825fab92 --- /dev/null +++ b/fastapi_encrypted_errors/models/__init__.py @@ -0,0 +1 @@ +from . import fastapi_endpoint diff --git a/fastapi_encrypted_errors/models/fastapi_endpoint.py b/fastapi_encrypted_errors/models/fastapi_endpoint.py new file mode 100644 index 000000000..add3ca2ec --- /dev/null +++ b/fastapi_encrypted_errors/models/fastapi_endpoint.py @@ -0,0 +1,47 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import traceback +import zlib + +from cryptography.fernet import Fernet + +from odoo import fields, models + + +class FastapiEndpoint(models.Model): + _inherit = "fastapi.endpoint" + + encrypt_errors = fields.Boolean( + help="Encrypt errors before sending them to the client.", + ) + encrypted_errors_secret_key = fields.Char( + help="The secret key used to encrypt errors before sending them to the client.", + default=lambda _: Fernet.generate_key(), + readonly=True, + ) + + def action_generate_encrypted_errors_secret_key(self): + for record in self: + record.encrypted_errors_secret_key = Fernet.generate_key() + + def _encrypt_error(self, exc): + self.ensure_one() + if not self.encrypt_errors or not self.encrypted_errors_secret_key: + return + + # Get full traceback + error = "".join(traceback.format_exception(exc)) + # zlib compression works quite well on tracebacks + error = zlib.compress(error.encode("utf-8")) + f = Fernet(self.encrypted_errors_secret_key) + return f.encrypt(error) + + def _decrypt_error(self, error): + self.ensure_one() + if not self.encrypt_errors or not self.encrypted_errors_secret_key: + return + + f = Fernet(self.encrypted_errors_secret_key) + error = f.decrypt(error) + return zlib.decompress(error).decode("utf-8") diff --git a/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst b/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..a4d0ad922 --- /dev/null +++ b/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst @@ -0,0 +1,3 @@ +* `Akretion `_: + + * Florian Mounier diff --git a/fastapi_encrypted_errors/readme/DESCRIPTION.rst b/fastapi_encrypted_errors/readme/DESCRIPTION.rst new file mode 100644 index 000000000..3ea245c61 --- /dev/null +++ b/fastapi_encrypted_errors/readme/DESCRIPTION.rst @@ -0,0 +1,3 @@ +This module adds a "ref" field in the error response of FastAPI. +This field is an AES encrypted string that contains the error message / traceback. +This encrypted string can be decrypted using the endpoint decrypt error wizard. diff --git a/fastapi_encrypted_errors/readme/USAGE.rst b/fastapi_encrypted_errors/readme/USAGE.rst new file mode 100644 index 000000000..041077d9b --- /dev/null +++ b/fastapi_encrypted_errors/readme/USAGE.rst @@ -0,0 +1,7 @@ +First you have to enable the encryption for an endpoint by checking the `Encrypt Errors` checkbox +in the endpoint configuration. + +To decrypt an error message, you can use the "Decrypt Error" wizard in the +FastAPI menu. + +You can regenerate a new key by clicking on the "Regenerate Key" button next to the `Errors Secret Key` field. diff --git a/fastapi_encrypted_errors/security/ir.model.access.csv b/fastapi_encrypted_errors/security/ir.model.access.csv new file mode 100644 index 000000000..d102f0c82 --- /dev/null +++ b/fastapi_encrypted_errors/security/ir.model.access.csv @@ -0,0 +1,2 @@ +id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink +access_fastapi_wizard_auth_partner_impersonate,wizard_fastapi_decrypt_errors,model_wizard_fastapi_decrypt_errors,fastapi.group_fastapi_manager,1,1,1,1 diff --git a/fastapi_encrypted_errors/static/description/index.html b/fastapi_encrypted_errors/static/description/index.html new file mode 100644 index 000000000..0ffce082e --- /dev/null +++ b/fastapi_encrypted_errors/static/description/index.html @@ -0,0 +1,439 @@ + + + + + +FastAPI Encrypted Errors + + + +
+

FastAPI Encrypted Errors

+ + +

Beta License: AGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runboat

+

This module adds a “ref” field in the error response of FastAPI. +This field is an AES encrypted string that contains the error message / traceback. +This encrypted string can be decrypted using the endpoint decrypt error wizard.

+

Table of contents

+ +
+

Usage

+

First you have to enable the encryption for an endpoint by checking the Encrypt Errors checkbox +in the endpoint configuration.

+

To decrypt an error message, you can use the “Decrypt Error” wizard in the +FastAPI menu.

+

You can regenerate a new key by clicking on the “Regenerate Key” button next to the Errors Secret Key field.

+
+
+

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 to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • Akretion
  • +
+
+
+

Contributors

+ +
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

paradoxxxzero

+

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/fastapi_encrypted_errors/tests/__init__.py b/fastapi_encrypted_errors/tests/__init__.py new file mode 100644 index 000000000..8fe3d60a6 --- /dev/null +++ b/fastapi_encrypted_errors/tests/__init__.py @@ -0,0 +1 @@ +from . import test_fastapi_encrypted_errors diff --git a/fastapi_encrypted_errors/tests/test_fastapi_encrypted_errors.py b/fastapi_encrypted_errors/tests/test_fastapi_encrypted_errors.py new file mode 100644 index 000000000..8aa1174f7 --- /dev/null +++ b/fastapi_encrypted_errors/tests/test_fastapi_encrypted_errors.py @@ -0,0 +1,74 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). + +import os +import unittest + +from odoo.tests.common import HttpCase + +from odoo.addons.fastapi.schemas import DemoExceptionType + +from fastapi import status + + +@unittest.skipIf(os.getenv("SKIP_HTTP_CASE"), "FastAPIEncryptedErrorsCase skipped") +class FastAPIEncryptedErrorsCase(HttpCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.fastapi_demo_app = cls.env.ref("fastapi.fastapi_endpoint_demo") + cls.fastapi_demo_app._handle_registry_sync() + cls.fastapi_demo_app.write({"encrypt_errors": True}) + lang = ( + cls.env["res.lang"] + .with_context(active_test=False) + .search([("code", "=", "fr_BE")]) + ) + lang.active = True + + def test_encrypted_errors_in_response(self): + route = ( + "/fastapi_demo/demo/exception?" + f"exception_type={DemoExceptionType.user_error.value}" + "&error_message=User Error" + ) + response = self.url_open(route, timeout=200) + + self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST) + res = response.json() + self.assertEqual(res["detail"], "User Error") + self.assertIn("ref", res) + + route = ( + "/fastapi_demo/demo/exception?" + f"exception_type={DemoExceptionType.bare_exception.value}" + "&error_message=Internal Server Error" + ) + response = self.url_open(route, timeout=200) + self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + res = response.json() + self.assertEqual(res["detail"], "Internal Server Error") + self.assertIn("ref", res) + + def test_encrypted_errors_decrypt(self): + route = ( + "/fastapi_demo/demo/exception?" + f"exception_type={DemoExceptionType.bare_exception.value}" + "&error_message=Internal Server Error" + ) + response = self.url_open(route, timeout=200) + self.assertEqual(response.status_code, status.HTTP_500_INTERNAL_SERVER_ERROR) + res = response.json() + self.assertEqual(res["detail"], "Internal Server Error") + self.assertIn("ref", res) + ref = res["ref"] + self.assertNotIn("Traceback (most recent call last)", ref) + self.assertNotIn("NotImplementedError: Internal Server Error", ref) + + wizard = self.env["wizard.fastapi.decrypt.errors"].create({"error": ref}) + wizard.action_decrypt_error() + self.assertIn("Traceback (most recent call last)", wizard.decrypted_error) + self.assertIn( + "NotImplementedError: Internal Server Error", wizard.decrypted_error + ) diff --git a/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml b/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml new file mode 100644 index 000000000..fce00f36f --- /dev/null +++ b/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml @@ -0,0 +1,31 @@ + + + + + + fastapi.endpoint + + + + +
+
+
+
+
+
diff --git a/fastapi_encrypted_errors/wizards/__init__.py b/fastapi_encrypted_errors/wizards/__init__.py new file mode 100644 index 000000000..a160dabbb --- /dev/null +++ b/fastapi_encrypted_errors/wizards/__init__.py @@ -0,0 +1 @@ +from . import wizard_fastapi_decrypt_errors diff --git a/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors.py b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors.py new file mode 100644 index 000000000..d19bd6d3a --- /dev/null +++ b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors.py @@ -0,0 +1,40 @@ +# Copyright 2024 Akretion (http://www.akretion.com). +# @author Florian Mounier +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl). +import traceback + +from odoo import fields, models + + +class WizardFastapiDecryptErrors(models.TransientModel): + _name = "wizard.fastapi.decrypt.errors" + _description = "Wizard to decrypt FastAPI errors" + + error = fields.Text(required=True) + fastapi_endpoint_id = fields.Many2one( + "fastapi.endpoint", + string="FastAPI Endpoint", + required=True, + default=lambda self: self.env["fastapi.endpoint"].search([], limit=1), + ) + decrypted_error = fields.Text(readonly=True) + + def action_decrypt_error(self): + self.ensure_one() + try: + error = self.fastapi_endpoint_id._decrypt_error(self.error.encode("utf-8")) + except Exception: + self.decrypted_error = ( + "Error while decrypting error: \n\n" + traceback.format_exc() + ) + else: + self.decrypted_error = error + + return { + "type": "ir.actions.act_window", + "res_model": "wizard.fastapi.decrypt.errors", + "view_mode": "form", + "view_type": "form", + "res_id": self.id, + "target": "new", + } diff --git a/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml new file mode 100644 index 000000000..62b8a803d --- /dev/null +++ b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml @@ -0,0 +1,47 @@ + + + + + wizard.fastapi.decrypt.errors + +
+ + + + + +
+
+ +
+
+
+ + + Decrypt Error + wizard.fastapi.decrypt.errors + ir.actions.act_window + form + new + + + + + +
From 347d14694e72631e280af5b14f22deb9d2188240 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Tue, 3 Jun 2025 13:40:57 +0000 Subject: [PATCH 2/7] [UPD] Update fastapi_encrypted_errors.pot --- .../i18n/fastapi_encrypted_errors.pot | 113 ++++++++++++++++++ 1 file changed, 113 insertions(+) create mode 100644 fastapi_encrypted_errors/i18n/fastapi_encrypted_errors.pot diff --git a/fastapi_encrypted_errors/i18n/fastapi_encrypted_errors.pot b/fastapi_encrypted_errors/i18n/fastapi_encrypted_errors.pot new file mode 100644 index 000000000..c15568724 --- /dev/null +++ b/fastapi_encrypted_errors/i18n/fastapi_encrypted_errors.pot @@ -0,0 +1,113 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fastapi_encrypted_errors +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Close" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_uid +msgid "Created by" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_date +msgid "Created on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.actions.act_window,name:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_action_decrypt_error +#: model:ir.ui.menu,name:fastapi_encrypted_errors.menu_fastapi_decrypt_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Decrypt Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__decrypted_error +msgid "Decrypted Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__display_name +msgid "Display Name" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors +msgid "Encrypt Errors" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors +msgid "Encrypt errors before sending them to the client." +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key +msgid "Encrypted Errors Secret Key" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__error +msgid "Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model,name:fastapi_encrypted_errors.model_fastapi_endpoint +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__fastapi_endpoint_id +msgid "FastAPI Endpoint" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.fastapi_endpoint_form_view +msgid "Generate Secret Key" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__id +msgid "ID" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Label" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors____last_update +msgid "Last Modified on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_date +msgid "Last Updated on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key +msgid "" +"The secret key used to encrypt errors before sending them to the client." +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model,name:fastapi_encrypted_errors.model_wizard_fastapi_decrypt_errors +msgid "Wizard to decrypt FastAPI errors" +msgstr "" From 54c2edaff33882d3b90d5d8cf86f5c624550485a Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 3 Jun 2025 13:43:46 +0000 Subject: [PATCH 3/7] [BOT] post-merge updates --- fastapi_encrypted_errors/README.rst | 8 +++-- fastapi_encrypted_errors/__manifest__.py | 2 +- .../static/description/icon.png | Bin 0 -> 10254 bytes .../static/description/index.html | 28 +++++++++++------- 4 files changed, 24 insertions(+), 14 deletions(-) create mode 100644 fastapi_encrypted_errors/static/description/icon.png diff --git a/fastapi_encrypted_errors/README.rst b/fastapi_encrypted_errors/README.rst index 7027f164e..2688aba39 100644 --- a/fastapi_encrypted_errors/README.rst +++ b/fastapi_encrypted_errors/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ======================== FastAPI Encrypted Errors ======================== @@ -7,13 +11,13 @@ FastAPI Encrypted Errors !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:296fbef824a5eb64e9bbaedc382ef15e41d146f0cc59d458c0d76de46a54358e + !! source digest: sha256:15dc8276c61dfb1e08999782de2a451f1d9531ada4979f1d4e02ae39e873406c !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github diff --git a/fastapi_encrypted_errors/__manifest__.py b/fastapi_encrypted_errors/__manifest__.py index 254901404..c0a5ca515 100644 --- a/fastapi_encrypted_errors/__manifest__.py +++ b/fastapi_encrypted_errors/__manifest__.py @@ -5,7 +5,7 @@ { "name": "FastAPI Encrypted Errors", "summary": "Adds encrypted error messages to FastAPI error responses.", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "license": "AGPL-3", "author": "Akretion,Odoo Community Association (OCA)", "maintainers": ["paradoxxxzero"], diff --git a/fastapi_encrypted_errors/static/description/icon.png b/fastapi_encrypted_errors/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..1dcc49c24f364e9adf0afbc6fc0bac6dbecdeb11 GIT binary patch literal 10254 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 -FastAPI Encrypted Errors +README.rst -
-

FastAPI Encrypted Errors

+
+ + +Odoo Community Association + +
+

FastAPI Encrypted Errors

-

Beta License: AGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runboat

This module adds a “ref” field in the error response of FastAPI. This field is an AES encrypted string that contains the error message / traceback. This encrypted string can be decrypted using the endpoint decrypt error wizard.

@@ -387,7 +392,7 @@

FastAPI Encrypted Errors

-

Usage

+

Usage

First you have to enable the encryption for an endpoint by checking the Encrypt Errors checkbox in the endpoint configuration.

To decrypt an error message, you can use the “Decrypt Error” wizard in the @@ -395,7 +400,7 @@

Usage

You can regenerate a new key by clicking on the “Regenerate Key” button next to the Errors Secret Key field.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed @@ -403,15 +408,15 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -435,5 +440,6 @@

Maintainers

+
From 1aa0d004bafdd871466a8fafe1a731c6b649d311 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 09:40:11 +0000 Subject: [PATCH 4/7] Added translation using Weblate (Italian) --- fastapi_encrypted_errors/i18n/it.po | 114 ++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 fastapi_encrypted_errors/i18n/it.po diff --git a/fastapi_encrypted_errors/i18n/it.po b/fastapi_encrypted_errors/i18n/it.po new file mode 100644 index 000000000..a1fd0db53 --- /dev/null +++ b/fastapi_encrypted_errors/i18n/it.po @@ -0,0 +1,114 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fastapi_encrypted_errors +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Close" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_uid +msgid "Created by" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_date +msgid "Created on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.actions.act_window,name:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_action_decrypt_error +#: model:ir.ui.menu,name:fastapi_encrypted_errors.menu_fastapi_decrypt_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Decrypt Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__decrypted_error +msgid "Decrypted Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__display_name +msgid "Display Name" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors +msgid "Encrypt Errors" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors +msgid "Encrypt errors before sending them to the client." +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key +msgid "Encrypted Errors Secret Key" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__error +msgid "Error" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model,name:fastapi_encrypted_errors.model_fastapi_endpoint +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__fastapi_endpoint_id +msgid "FastAPI Endpoint" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.fastapi_endpoint_form_view +msgid "Generate Secret Key" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__id +msgid "ID" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form +msgid "Label" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors____last_update +msgid "Last Modified on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_uid +msgid "Last Updated by" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_date +msgid "Last Updated on" +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key +msgid "" +"The secret key used to encrypt errors before sending them to the client." +msgstr "" + +#. module: fastapi_encrypted_errors +#: model:ir.model,name:fastapi_encrypted_errors.model_wizard_fastapi_decrypt_errors +msgid "Wizard to decrypt FastAPI errors" +msgstr "" From f99d14e8b85c8e672b4a9a78e17524b2cd253ea9 Mon Sep 17 00:00:00 2001 From: mymage Date: Wed, 4 Jun 2025 14:07:22 +0000 Subject: [PATCH 5/7] Translated using Weblate (Italian) Currently translated at 100.0% (19 of 19 strings) Translation: rest-framework-16.0/rest-framework-16.0-fastapi_encrypted_errors Translate-URL: https://translation.odoo-community.org/projects/rest-framework-16-0/rest-framework-16-0-fastapi_encrypted_errors/it/ --- fastapi_encrypted_errors/i18n/it.po | 42 ++++++++++++++++------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/fastapi_encrypted_errors/i18n/it.po b/fastapi_encrypted_errors/i18n/it.po index a1fd0db53..1dea61661 100644 --- a/fastapi_encrypted_errors/i18n/it.po +++ b/fastapi_encrypted_errors/i18n/it.po @@ -6,109 +6,113 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 16.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2025-06-04 16:26+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.10.4\n" #. module: fastapi_encrypted_errors #: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form msgid "Close" -msgstr "" +msgstr "Chiudi" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_uid msgid "Created by" -msgstr "" +msgstr "Creato da" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__create_date msgid "Created on" -msgstr "" +msgstr "Creato il" #. module: fastapi_encrypted_errors #: model:ir.actions.act_window,name:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_action_decrypt_error #: model:ir.ui.menu,name:fastapi_encrypted_errors.menu_fastapi_decrypt_errors #: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form msgid "Decrypt Error" -msgstr "" +msgstr "Decifra errore" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__decrypted_error msgid "Decrypted Error" -msgstr "" +msgstr "Errore decifrato" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__display_name msgid "Display Name" -msgstr "" +msgstr "Nome visualizzato" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors msgid "Encrypt Errors" -msgstr "" +msgstr "Errori cifrati" #. module: fastapi_encrypted_errors #: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypt_errors msgid "Encrypt errors before sending them to the client." -msgstr "" +msgstr "Cifra gli errori prima di inviarli al client." #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key msgid "Encrypted Errors Secret Key" -msgstr "" +msgstr "Chiave segreta errori cifrati" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__error msgid "Error" -msgstr "" +msgstr "Errore" #. module: fastapi_encrypted_errors #: model:ir.model,name:fastapi_encrypted_errors.model_fastapi_endpoint #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__fastapi_endpoint_id msgid "FastAPI Endpoint" -msgstr "" +msgstr "Endpoint FastAPI" #. module: fastapi_encrypted_errors #: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.fastapi_endpoint_form_view msgid "Generate Secret Key" -msgstr "" +msgstr "Genera chiave segreta" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__id msgid "ID" -msgstr "" +msgstr "ID" #. module: fastapi_encrypted_errors #: model_terms:ir.ui.view,arch_db:fastapi_encrypted_errors.wizard_fastapi_decrypt_errors_view_form msgid "Label" -msgstr "" +msgstr "Etichetta" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors____last_update msgid "Last Modified on" -msgstr "" +msgstr "Ultima modifica il" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_uid msgid "Last Updated by" -msgstr "" +msgstr "Ultimo aggiornamento di" #. module: fastapi_encrypted_errors #: model:ir.model.fields,field_description:fastapi_encrypted_errors.field_wizard_fastapi_decrypt_errors__write_date msgid "Last Updated on" -msgstr "" +msgstr "Ultimo aggiornamento il" #. module: fastapi_encrypted_errors #: model:ir.model.fields,help:fastapi_encrypted_errors.field_fastapi_endpoint__encrypted_errors_secret_key msgid "" "The secret key used to encrypt errors before sending them to the client." msgstr "" +"La chiave segreta utilizzata per cifrare gli errori prima di inviarli al " +"client." #. module: fastapi_encrypted_errors #: model:ir.model,name:fastapi_encrypted_errors.model_wizard_fastapi_decrypt_errors msgid "Wizard to decrypt FastAPI errors" -msgstr "" +msgstr "Procedura guidata per decifrare gli errori FastAPI" From 3daa80680e7b7a957036f11fdcab86c01b0bf679 Mon Sep 17 00:00:00 2001 From: Florian Mounier Date: Tue, 13 Jan 2026 15:01:38 +0100 Subject: [PATCH 6/7] [IMP] fastapi_encrypted_errors: pre-commit auto fixes --- fastapi_encrypted_errors/README.rst | 44 ++++++++--------- fastapi_encrypted_errors/pyproject.toml | 3 ++ .../readme/CONTRIBUTORS.md | 2 + .../readme/CONTRIBUTORS.rst | 3 -- .../readme/DESCRIPTION.md | 4 ++ .../readme/DESCRIPTION.rst | 3 -- .../readme/{USAGE.rst => USAGE.md} | 11 +++-- .../static/description/index.html | 48 +++++++++---------- .../views/fastapi_endpoint_views.xml | 1 - .../wizard_fastapi_decrypt_errors_views.xml | 3 -- 10 files changed, 58 insertions(+), 64 deletions(-) create mode 100644 fastapi_encrypted_errors/pyproject.toml create mode 100644 fastapi_encrypted_errors/readme/CONTRIBUTORS.md delete mode 100644 fastapi_encrypted_errors/readme/CONTRIBUTORS.rst create mode 100644 fastapi_encrypted_errors/readme/DESCRIPTION.md delete mode 100644 fastapi_encrypted_errors/readme/DESCRIPTION.rst rename fastapi_encrypted_errors/readme/{USAGE.rst => USAGE.md} (58%) diff --git a/fastapi_encrypted_errors/README.rst b/fastapi_encrypted_errors/README.rst index 2688aba39..271670f83 100644 --- a/fastapi_encrypted_errors/README.rst +++ b/fastapi_encrypted_errors/README.rst @@ -1,7 +1,3 @@ -.. image:: https://odoo-community.org/readme-banner-image - :target: https://odoo-community.org/get-involved?utm_source=readme - :alt: Odoo Community Association - ======================== FastAPI Encrypted Errors ======================== @@ -17,24 +13,25 @@ FastAPI Encrypted Errors .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Frest--framework-lightgray.png?logo=github - :target: https://github.com/OCA/rest-framework/tree/16.0/fastapi_encrypted_errors + :target: https://github.com/OCA/rest-framework/tree/18.0/fastapi_encrypted_errors :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-16-0/rest-framework-16-0-fastapi_encrypted_errors + :target: https://translation.odoo-community.org/projects/rest-framework-18-0/rest-framework-18-0-fastapi_encrypted_errors :alt: Translate me on Weblate .. |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 + :target: https://runboat.odoo-community.org/builds?repo=OCA/rest-framework&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| -This module adds a "ref" field in the error response of FastAPI. -This field is an AES encrypted string that contains the error message / traceback. -This encrypted string can be decrypted using the endpoint decrypt error wizard. +This module adds a "ref" field in the error response of FastAPI. This +field is an AES encrypted string that contains the error message / +traceback. This encrypted string can be decrypted using the endpoint +decrypt error wizard. **Table of contents** @@ -44,13 +41,14 @@ This encrypted string can be decrypted using the endpoint decrypt error wizard. Usage ===== -First you have to enable the encryption for an endpoint by checking the `Encrypt Errors` checkbox -in the endpoint configuration. +First you have to enable the encryption for an endpoint by checking the +Encrypt Errors checkbox in the endpoint configuration. -To decrypt an error message, you can use the "Decrypt Error" wizard in the -FastAPI menu. +To decrypt an error message, you can use the "Decrypt Error" wizard in +the FastAPI menu. -You can regenerate a new key by clicking on the "Regenerate Key" button next to the `Errors Secret Key` field. +You can regenerate a new key by clicking on the "Regenerate Key" button +next to the Errors Secret Key field. Bug Tracker =========== @@ -58,7 +56,7 @@ 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 to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -66,19 +64,19 @@ Credits ======= Authors -~~~~~~~ +------- * Akretion Contributors -~~~~~~~~~~~~ +------------ -* `Akretion `_: +- `Akretion `__: - * Florian Mounier + - Florian Mounier Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -98,6 +96,6 @@ Current `maintainer `__: |maintainer-paradoxxxzero| -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/fastapi_encrypted_errors/pyproject.toml b/fastapi_encrypted_errors/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/fastapi_encrypted_errors/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/fastapi_encrypted_errors/readme/CONTRIBUTORS.md b/fastapi_encrypted_errors/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..3b52e04e6 --- /dev/null +++ b/fastapi_encrypted_errors/readme/CONTRIBUTORS.md @@ -0,0 +1,2 @@ +- [Akretion](https://www.akretion.com): + - Florian Mounier diff --git a/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst b/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst deleted file mode 100644 index a4d0ad922..000000000 --- a/fastapi_encrypted_errors/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1,3 +0,0 @@ -* `Akretion `_: - - * Florian Mounier diff --git a/fastapi_encrypted_errors/readme/DESCRIPTION.md b/fastapi_encrypted_errors/readme/DESCRIPTION.md new file mode 100644 index 000000000..a296a0446 --- /dev/null +++ b/fastapi_encrypted_errors/readme/DESCRIPTION.md @@ -0,0 +1,4 @@ +This module adds a "ref" field in the error response of FastAPI. This +field is an AES encrypted string that contains the error message / +traceback. This encrypted string can be decrypted using the endpoint +decrypt error wizard. diff --git a/fastapi_encrypted_errors/readme/DESCRIPTION.rst b/fastapi_encrypted_errors/readme/DESCRIPTION.rst deleted file mode 100644 index 3ea245c61..000000000 --- a/fastapi_encrypted_errors/readme/DESCRIPTION.rst +++ /dev/null @@ -1,3 +0,0 @@ -This module adds a "ref" field in the error response of FastAPI. -This field is an AES encrypted string that contains the error message / traceback. -This encrypted string can be decrypted using the endpoint decrypt error wizard. diff --git a/fastapi_encrypted_errors/readme/USAGE.rst b/fastapi_encrypted_errors/readme/USAGE.md similarity index 58% rename from fastapi_encrypted_errors/readme/USAGE.rst rename to fastapi_encrypted_errors/readme/USAGE.md index 041077d9b..ad5af09f2 100644 --- a/fastapi_encrypted_errors/readme/USAGE.rst +++ b/fastapi_encrypted_errors/readme/USAGE.md @@ -1,7 +1,8 @@ -First you have to enable the encryption for an endpoint by checking the `Encrypt Errors` checkbox -in the endpoint configuration. +First you have to enable the encryption for an endpoint by checking the +Encrypt Errors checkbox in the endpoint configuration. -To decrypt an error message, you can use the "Decrypt Error" wizard in the -FastAPI menu. +To decrypt an error message, you can use the "Decrypt Error" wizard in +the FastAPI menu. -You can regenerate a new key by clicking on the "Regenerate Key" button next to the `Errors Secret Key` field. +You can regenerate a new key by clicking on the "Regenerate Key" button +next to the Errors Secret Key field. diff --git a/fastapi_encrypted_errors/static/description/index.html b/fastapi_encrypted_errors/static/description/index.html index 77532340a..6f0ff11fe 100644 --- a/fastapi_encrypted_errors/static/description/index.html +++ b/fastapi_encrypted_errors/static/description/index.html @@ -3,7 +3,7 @@ -README.rst +FastAPI Encrypted Errors -
+
+

FastAPI Encrypted Errors

- - -Odoo Community Association - -
-

FastAPI Encrypted Errors

-

Beta License: AGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runboat

-

This module adds a “ref” field in the error response of FastAPI. -This field is an AES encrypted string that contains the error message / traceback. -This encrypted string can be decrypted using the endpoint decrypt error wizard.

+

Beta License: AGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runboat

+

This module adds a “ref” field in the error response of FastAPI. This +field is an AES encrypted string that contains the error message / +traceback. This encrypted string can be decrypted using the endpoint +decrypt error wizard.

Table of contents

    @@ -392,31 +388,32 @@

    FastAPI Encrypted Errors

-

Usage

-

First you have to enable the encryption for an endpoint by checking the Encrypt Errors checkbox -in the endpoint configuration.

-

To decrypt an error message, you can use the “Decrypt Error” wizard in the -FastAPI menu.

-

You can regenerate a new key by clicking on the “Regenerate Key” button next to the Errors Secret Key field.

+

Usage

+

First you have to enable the encryption for an endpoint by checking the +Encrypt Errors checkbox in the endpoint configuration.

+

To decrypt an error message, you can use the “Decrypt Error” wizard in +the FastAPI menu.

+

You can regenerate a new key by clicking on the “Regenerate Key” button +next to the Errors Secret Key field.

-

Bug Tracker

+

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 to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • Akretion
-

Contributors

+

Contributors

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -435,11 +432,10 @@

Maintainers

promote its widespread use.

Current maintainer:

paradoxxxzero

-

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/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml b/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml index fce00f36f..925cb2059 100644 --- a/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml +++ b/fastapi_encrypted_errors/views/fastapi_endpoint_views.xml @@ -2,7 +2,6 @@ - fastapi.endpoint diff --git a/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml index 62b8a803d..6e4452fbb 100644 --- a/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml +++ b/fastapi_encrypted_errors/wizards/wizard_fastapi_decrypt_errors_views.xml @@ -1,6 +1,5 @@ - wizard.fastapi.decrypt.errors @@ -19,7 +18,6 @@ />