From 9600be1046c8b1d8834b50012c4be245b4d8cd83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Thu, 15 Jun 2023 17:54:57 +0200 Subject: [PATCH 01/14] [ADD] fastapi_auth_jwt, fastapi_auth_jwt_demo --- fastapi_auth_jwt_demo/README.rst | 0 fastapi_auth_jwt_demo/__init__.py | 2 + fastapi_auth_jwt_demo/__manifest__.py | 16 ++ .../demo/fastapi_endpoint.xml | 9 ++ fastapi_auth_jwt_demo/models/__init__.py | 1 + .../models/fastapi_endpoint.py | 24 +++ fastapi_auth_jwt_demo/readme/DESCRIPTION.rst | 4 + fastapi_auth_jwt_demo/routers/__init__.py | 1 + .../routers/auth_jwt_demo_api.py | 112 ++++++++++++++ fastapi_auth_jwt_demo/tests/__init__.py | 1 + .../tests/test_fastapi_auth_jwt_demo.py | 139 ++++++++++++++++++ 11 files changed, 309 insertions(+) create mode 100644 fastapi_auth_jwt_demo/README.rst create mode 100644 fastapi_auth_jwt_demo/__init__.py create mode 100644 fastapi_auth_jwt_demo/__manifest__.py create mode 100644 fastapi_auth_jwt_demo/demo/fastapi_endpoint.xml create mode 100644 fastapi_auth_jwt_demo/models/__init__.py create mode 100644 fastapi_auth_jwt_demo/models/fastapi_endpoint.py create mode 100644 fastapi_auth_jwt_demo/readme/DESCRIPTION.rst create mode 100644 fastapi_auth_jwt_demo/routers/__init__.py create mode 100644 fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py create mode 100644 fastapi_auth_jwt_demo/tests/__init__.py create mode 100644 fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py diff --git a/fastapi_auth_jwt_demo/README.rst b/fastapi_auth_jwt_demo/README.rst new file mode 100644 index 000000000..e69de29bb diff --git a/fastapi_auth_jwt_demo/__init__.py b/fastapi_auth_jwt_demo/__init__.py new file mode 100644 index 000000000..9ef814457 --- /dev/null +++ b/fastapi_auth_jwt_demo/__init__.py @@ -0,0 +1,2 @@ +from . import models +from . import routers diff --git a/fastapi_auth_jwt_demo/__manifest__.py b/fastapi_auth_jwt_demo/__manifest__.py new file mode 100644 index 000000000..2d3b9161b --- /dev/null +++ b/fastapi_auth_jwt_demo/__manifest__.py @@ -0,0 +1,16 @@ +# Copyright 2023 ACSONE SA/NV +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +{ + "name": "FastAPI Auth JWT Test", + "summary": """ + Test/demo module for fastapi_auth_jwt.""", + "version": "16.0.1.0.0", + "license": "LGPL-3", + "author": "ACSONE SA/NV,Odoo Community Association (OCA)", + "maintainers": ["sbidoul"], + "website": "https://github.com/OCA/rest-framework", + "depends": ["fastapi_auth_jwt", "auth_jwt_demo"], + "data": [], + "demo": ["demo/fastapi_endpoint.xml"], +} diff --git a/fastapi_auth_jwt_demo/demo/fastapi_endpoint.xml b/fastapi_auth_jwt_demo/demo/fastapi_endpoint.xml new file mode 100644 index 000000000..187a26317 --- /dev/null +++ b/fastapi_auth_jwt_demo/demo/fastapi_endpoint.xml @@ -0,0 +1,9 @@ + + + + Auth JWT Fastapi Demo Endpoint + auth_jwt_demo + /fastapi_auth_jwt_demo + + + diff --git a/fastapi_auth_jwt_demo/models/__init__.py b/fastapi_auth_jwt_demo/models/__init__.py new file mode 100644 index 000000000..146cb46ba --- /dev/null +++ b/fastapi_auth_jwt_demo/models/__init__.py @@ -0,0 +1 @@ +from .fastapi_endpoint import FastapiEndpoint, auth_jwt_demo_api_router diff --git a/fastapi_auth_jwt_demo/models/fastapi_endpoint.py b/fastapi_auth_jwt_demo/models/fastapi_endpoint.py new file mode 100644 index 000000000..73b26531a --- /dev/null +++ b/fastapi_auth_jwt_demo/models/fastapi_endpoint.py @@ -0,0 +1,24 @@ +# Copyright 2023 ACSONE SA/NV +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from odoo import api, fields, models + +from ..routers.auth_jwt_demo_api import router as auth_jwt_demo_api_router + +APP_NAME = "auth_jwt_demo" + + +class FastapiEndpoint(models.Model): + + _inherit = "fastapi.endpoint" + + app: str = fields.Selection( + selection_add=[(APP_NAME, "Auth JWT Demo Endpoint")], + ondelete={APP_NAME: "cascade"}, + ) + + @api.model + def _get_fastapi_routers(self): + if self.app == APP_NAME: + return [auth_jwt_demo_api_router] + return super()._get_fastapi_routers() diff --git a/fastapi_auth_jwt_demo/readme/DESCRIPTION.rst b/fastapi_auth_jwt_demo/readme/DESCRIPTION.rst new file mode 100644 index 000000000..c5bcd9cc5 --- /dev/null +++ b/fastapi_auth_jwt_demo/readme/DESCRIPTION.rst @@ -0,0 +1,4 @@ +Tests and demo routes for ``fastapi_auth_jwt``. + +The tests and routes are almost identical to those in ``auth_jwt_demo``, and +the JWT validators used are those from ``auth_jwt_demo``. diff --git a/fastapi_auth_jwt_demo/routers/__init__.py b/fastapi_auth_jwt_demo/routers/__init__.py new file mode 100644 index 000000000..e47979680 --- /dev/null +++ b/fastapi_auth_jwt_demo/routers/__init__.py @@ -0,0 +1 @@ +from .auth_jwt_demo_api import router diff --git a/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py b/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py new file mode 100644 index 000000000..dc30488ba --- /dev/null +++ b/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py @@ -0,0 +1,112 @@ +# Copyright 2023 ACSONE SA/NV +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +from typing import Annotated, Union + +from odoo.addons.base.models.res_partner import Partner +from odoo.addons.fastapi_auth_jwt.dependencies import AuthJwtPartner + +from fastapi import APIRouter, Depends +from pydantic import BaseModel + + +class TestData(BaseModel): + name: Union[str, None] + email: Union[str, None] + uid: int + + +router = APIRouter() + + +@router.get("/whoami", response_model=TestData) +def whoami( + partner: Annotated[ + Partner, + Depends(AuthJwtPartner(validator_name="demo")), + ], +) -> TestData: + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + + +@router.get("/whoami-public-or-jwt", response_model=TestData) +def whoami_public_or_jwt( + partner: Annotated[ + Partner, + Depends(AuthJwtPartner(validator_name="demo", allow_unauthenticated=True)), + ], +): + if partner: + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + return TestData(uid=partner.env.uid) + + +@router.get("/cookie/whoami", response_model=TestData) +def whoami_cookie( + partner: Annotated[ + Partner, + Depends(AuthJwtPartner(validator_name="demo_cookie")), + ], +): + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + + +@router.get("/cookie/whoami-public-or-jwt", response_model=TestData) +def whoami_cookie_public_or_jwt( + partner: Annotated[ + Partner, + Depends( + AuthJwtPartner(validator_name="demo_cookie", allow_unauthenticated=True) + ), + ], +): + if partner: + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + return TestData(uid=partner.env.uid) + + +@router.get("/keycloak/whoami", response_model=TestData) +def whoami_keycloak( + partner: Annotated[ + Partner, Depends(AuthJwtPartner(validator_name="demo_keycloak")) + ], +): + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + + +@router.get("/keycloak/whoami-public-or-jwt", response_model=TestData) +def whoami_keycloak_public_or_jwt( + partner: Annotated[ + Partner, + Depends( + AuthJwtPartner(validator_name="demo_keycloak", allow_unauthenticated=True) + ), + ], +): + if partner: + return TestData( + name=partner.name, + email=partner.email, + uid=partner.env.uid, + ) + return TestData(uid=partner.env.uid) diff --git a/fastapi_auth_jwt_demo/tests/__init__.py b/fastapi_auth_jwt_demo/tests/__init__.py new file mode 100644 index 000000000..e6f1ca6df --- /dev/null +++ b/fastapi_auth_jwt_demo/tests/__init__.py @@ -0,0 +1 @@ +from . import test_fastapi_auth_jwt_demo diff --git a/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py b/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py new file mode 100644 index 000000000..d00ee566a --- /dev/null +++ b/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py @@ -0,0 +1,139 @@ +# Copyright 2023 ACSONE SA/NV +# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). + +import time + +import jwt + +from odoo import tests + + +@tests.tagged("post_install", "-at_install") +class TestEndToEnd(tests.HttpCase): + def _get_token(self, aud=None, email=None): + validator = self.env["auth.jwt.validator"].search([("name", "=", "demo")]) + payload = { + "aud": aud or validator.audience, + "iss": validator.issuer, + "exp": time.time() + 60, + } + if email: + payload["email"] = email + access_token = jwt.encode( + payload, key=validator.secret_key, algorithm=validator.secret_algorithm + ) + return "Bearer " + access_token + + def test_whoami(self): + """A end-to-end test with positive authentication and partner retrieval.""" + partner = self.env["res.users"].search([("email", "!=", False)])[0] + token = self._get_token(email=partner.email) + resp = self.url_open( + "/fastapi_auth_jwt_demo/whoami", headers={"Authorization": token} + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + # Try again in a user session, it works because fastapi ignores the Odoo session. + self.authenticate("demo", "demo") + resp = self.url_open( + "/fastapi_auth_jwt_demo/whoami", headers={"Authorization": token} + ) + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + + def test_whoami_cookie(self): + """A end-to-end test with positive authentication and cookie.""" + partner = self.env["res.users"].search([("email", "!=", False)])[0] + token = self._get_token(email=partner.email) + resp = self.url_open( + "/fastapi_auth_jwt_demo/cookie/whoami", headers={"Authorization": token} + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + cookie = resp.cookies.get("demo_auth") + self.assertTrue(cookie) + # Try again with the cookie. + resp = self.url_open( + "/fastapi_auth_jwt_demo/cookie/whoami", + headers={"Cookie": f"demo_auth={cookie}"}, + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + cookie = resp.cookies.get("demo_auth") + self.assertTrue(cookie) + + def test_forbidden(self): + """A end-to-end test with negative authentication.""" + token = self._get_token(aud="invalid") + resp = self.url_open( + "/fastapi_auth_jwt_demo/whoami", headers={"Authorization": token} + ) + self.assertEqual(resp.status_code, 401) + + def test_public(self): + """A end-to-end test for anonymous/public access.""" + resp = self.url_open("/fastapi_auth_jwt_demo/whoami-public-or-jwt") + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.json()["uid"], self.ref("base.public_user")) + # now try with a token + partner = self.env["res.users"].search([("email", "!=", False)], limit=1) + token = self._get_token(email=partner.email) + resp = self.url_open( + "/fastapi_auth_jwt_demo/whoami-public-or-jwt", + headers={"Authorization": token}, + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + + def test_public_cookie_mode(self): + """A end-to-end test for anonymous/public access with cookie.""" + resp = self.url_open("/fastapi_auth_jwt_demo/cookie/whoami-public-or-jwt") + self.assertEqual(resp.status_code, 200, resp.text) + self.assertEqual(resp.json()["uid"], self.ref("base.public_user")) + # now try with a token + partner = self.env["res.users"].search([("email", "!=", False)], limit=1) + token = self._get_token(email=partner.email) + resp = self.url_open( + "/fastapi_auth_jwt_demo/cookie/whoami-public-or-jwt", + headers={"Authorization": token}, + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + # now try with the cookie + cookie = resp.cookies.get("demo_auth") + self.assertTrue(cookie) + partner = self.env["res.users"].search([("email", "!=", False)], limit=1) + token = self._get_token(email=partner.email) + resp = self.url_open( + "/fastapi_auth_jwt_demo/cookie/whoami-public-or-jwt", + headers={"Cookie": f"demo_auth={cookie}"}, + ) + resp.raise_for_status() + whoami = resp.json() + self.assertEqual(whoami.get("name"), partner.name) + self.assertEqual(whoami.get("email"), partner.email) + self.assertEqual(whoami.get("uid"), self.env.ref("base.user_demo").id) + cookie = resp.cookies.get("demo_auth") + self.assertTrue(cookie) + + def test_public_keyloak(self): + """A end-to-end test for anonymous/public access.""" + resp = self.url_open("/fastapi_auth_jwt_demo/keycloak/whoami-public-or-jwt") + self.assertEqual(resp.status_code, 200) + self.assertEqual(resp.json()["uid"], self.ref("base.public_user")) From 6b0d25f433de8e4609a0219d003bc57241e53d14 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Bidoul?= Date: Fri, 16 Jun 2023 18:22:07 +0200 Subject: [PATCH 02/14] [FIX] fast_api_auth_jwt_demo: sync registry before tests --- fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py b/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py index d00ee566a..9d29e693c 100644 --- a/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py +++ b/fastapi_auth_jwt_demo/tests/test_fastapi_auth_jwt_demo.py @@ -10,6 +10,13 @@ @tests.tagged("post_install", "-at_install") class TestEndToEnd(tests.HttpCase): + @classmethod + def setUpClass(cls): + super().setUpClass() + cls.env.ref( + "fastapi_auth_jwt_demo.fastapi_endpoint_auth_jwt_demo" + )._handle_registry_sync() + def _get_token(self, aud=None, email=None): validator = self.env["auth.jwt.validator"].search([("name", "=", "demo")]) payload = { From fb7d1d1f71eda22c73e966490b82e8d5d99a155c Mon Sep 17 00:00:00 2001 From: oca-ci Date: Mon, 26 Jun 2023 16:35:44 +0000 Subject: [PATCH 03/14] [UPD] Update fastapi_auth_jwt_demo.pot --- .../i18n/fastapi_auth_jwt_demo.pot | 29 +++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 fastapi_auth_jwt_demo/i18n/fastapi_auth_jwt_demo.pot diff --git a/fastapi_auth_jwt_demo/i18n/fastapi_auth_jwt_demo.pot b/fastapi_auth_jwt_demo/i18n/fastapi_auth_jwt_demo.pot new file mode 100644 index 000000000..050e15217 --- /dev/null +++ b/fastapi_auth_jwt_demo/i18n/fastapi_auth_jwt_demo.pot @@ -0,0 +1,29 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * fastapi_auth_jwt_demo +# +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_auth_jwt_demo +#: model:ir.model.fields,field_description:fastapi_auth_jwt_demo.field_fastapi_endpoint__app +msgid "App" +msgstr "" + +#. module: fastapi_auth_jwt_demo +#: model:ir.model.fields.selection,name:fastapi_auth_jwt_demo.selection__fastapi_endpoint__app__auth_jwt_demo +msgid "Auth JWT Demo Endpoint" +msgstr "" + +#. module: fastapi_auth_jwt_demo +#: model:ir.model,name:fastapi_auth_jwt_demo.model_fastapi_endpoint +msgid "FastAPI Endpoint" +msgstr "" From f71a7b581368047eb4fb3bc1ad45773e3a7a70d9 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 26 Jun 2023 16:38:51 +0000 Subject: [PATCH 04/14] [UPD] README.rst --- fastapi_auth_jwt_demo/README.rst | 79 ++++ .../static/description/index.html | 416 ++++++++++++++++++ 2 files changed, 495 insertions(+) create mode 100644 fastapi_auth_jwt_demo/static/description/index.html diff --git a/fastapi_auth_jwt_demo/README.rst b/fastapi_auth_jwt_demo/README.rst index e69de29bb..9af773839 100644 --- a/fastapi_auth_jwt_demo/README.rst +++ b/fastapi_auth_jwt_demo/README.rst @@ -0,0 +1,79 @@ +===================== +FastAPI Auth JWT Test +===================== + +.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |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-LGPL--3-blue.png + :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/16.0/fastapi_auth_jwt_demo + :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_auth_jwt_demo + :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/16.0 + :alt: Try me on Runbot + +|badge1| |badge2| |badge3| |badge4| |badge5| + +Tests and demo routes for ``fastapi_auth_jwt``. + +The tests and routes are almost identical to those in ``auth_jwt_demo``, and +the JWT validators used are those from ``auth_jwt_demo``. + +**Table of contents** + +.. contents:: + :local: + +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 `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* ACSONE SA/NV + +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-sbidoul| image:: https://github.com/sbidoul.png?size=40px + :target: https://github.com/sbidoul + :alt: sbidoul + +Current `maintainer `__: + +|maintainer-sbidoul| + +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_auth_jwt_demo/static/description/index.html b/fastapi_auth_jwt_demo/static/description/index.html new file mode 100644 index 000000000..b906169e3 --- /dev/null +++ b/fastapi_auth_jwt_demo/static/description/index.html @@ -0,0 +1,416 @@ + + + + + + +FastAPI Auth JWT Test + + + +
+

FastAPI Auth JWT Test

+ + +

Beta License: LGPL-3 OCA/rest-framework Translate me on Weblate Try me on Runbot

+

Tests and demo routes for fastapi_auth_jwt.

+

The tests and routes are almost identical to those in auth_jwt_demo, and +the JWT validators used are those from auth_jwt_demo.

+

Table of contents

+ +
+

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.

+

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

+
+
+

Credits

+
+

Authors

+
    +
  • ACSONE SA/NV
  • +
+
+
+

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:

+

sbidoul

+

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.

+
+
+
+ + From 2fba8d2679750842fb76060cda6f7b2afb8d213e Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 26 Jun 2023 16:38:51 +0000 Subject: [PATCH 05/14] [ADD] icon.png --- .../static/description/icon.png | Bin 0 -> 9455 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 fastapi_auth_jwt_demo/static/description/icon.png diff --git a/fastapi_auth_jwt_demo/static/description/icon.png b/fastapi_auth_jwt_demo/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..3a0328b516c4980e8e44cdb63fd945757ddd132d GIT binary patch literal 9455 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 z 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 Xviia!U7SGha1wx#SCgwmn*{w2TRX*I literal 0 HcmV?d00001 From ba7dc7cf7869c5f11bcfecc5048d8dd618410220 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Mon, 26 Jun 2023 16:38:55 +0000 Subject: [PATCH 06/14] fastapi_auth_jwt_demo 16.0.1.0.1 --- fastapi_auth_jwt_demo/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_auth_jwt_demo/__manifest__.py b/fastapi_auth_jwt_demo/__manifest__.py index 2d3b9161b..22038ba62 100644 --- a/fastapi_auth_jwt_demo/__manifest__.py +++ b/fastapi_auth_jwt_demo/__manifest__.py @@ -5,7 +5,7 @@ "name": "FastAPI Auth JWT Test", "summary": """ Test/demo module for fastapi_auth_jwt.""", - "version": "16.0.1.0.0", + "version": "16.0.1.0.1", "license": "LGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "maintainers": ["sbidoul"], From a5df6ea4d337e81616e242d2fe493cc78d06f01c Mon Sep 17 00:00:00 2001 From: Laurent Mignon Date: Mon, 24 Jul 2023 15:51:37 +0200 Subject: [PATCH 07/14] Migration to Pydantic v2 --- fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py b/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py index dc30488ba..b08f6d380 100644 --- a/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py +++ b/fastapi_auth_jwt_demo/routers/auth_jwt_demo_api.py @@ -11,8 +11,8 @@ class TestData(BaseModel): - name: Union[str, None] - email: Union[str, None] + name: Union[str, None] = None + email: Union[str, None] = None uid: int From 4fbfa8a8d7b5ae1df5c80fdce9df34bedc4fff84 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Tue, 25 Jul 2023 16:11:24 +0000 Subject: [PATCH 08/14] fastapi_auth_jwt_demo 16.0.2.0.0 --- fastapi_auth_jwt_demo/__manifest__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fastapi_auth_jwt_demo/__manifest__.py b/fastapi_auth_jwt_demo/__manifest__.py index 22038ba62..05db5b63d 100644 --- a/fastapi_auth_jwt_demo/__manifest__.py +++ b/fastapi_auth_jwt_demo/__manifest__.py @@ -5,7 +5,7 @@ "name": "FastAPI Auth JWT Test", "summary": """ Test/demo module for fastapi_auth_jwt.""", - "version": "16.0.1.0.1", + "version": "16.0.2.0.0", "license": "LGPL-3", "author": "ACSONE SA/NV,Odoo Community Association (OCA)", "maintainers": ["sbidoul"], From 2ca2375d023e077d33ad4ee840e12705d5bf3c98 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Sun, 3 Sep 2023 10:27:12 +0000 Subject: [PATCH 09/14] [UPD] README.rst --- fastapi_auth_jwt_demo/README.rst | 15 +++++---- .../static/description/index.html | 32 ++++++++++--------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/fastapi_auth_jwt_demo/README.rst b/fastapi_auth_jwt_demo/README.rst index 9af773839..34426677e 100644 --- a/fastapi_auth_jwt_demo/README.rst +++ b/fastapi_auth_jwt_demo/README.rst @@ -2,10 +2,13 @@ FastAPI Auth JWT Test ===================== -.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:0808c6ada00df4f17e6f45cad7b22796dec0e945b1dddf2814d39a484e976b78 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status @@ -19,11 +22,11 @@ FastAPI Auth JWT Test .. |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_auth_jwt_demo :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/16.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| Tests and demo routes for ``fastapi_auth_jwt``. @@ -40,7 +43,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 smashing it by providing a detailed and welcomed +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. diff --git a/fastapi_auth_jwt_demo/static/description/index.html b/fastapi_auth_jwt_demo/static/description/index.html index b906169e3..c990532ab 100644 --- a/fastapi_auth_jwt_demo/static/description/index.html +++ b/fastapi_auth_jwt_demo/static/description/index.html @@ -1,20 +1,20 @@ - + - + FastAPI Auth JWT Test -
+
+

Base Rest

- - -Odoo Community Association - -
-

Base Rest

-

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

+

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

This addon is deprecated and not fully supported anymore from Odoo 16. Please migrate to the FastAPI migration module. See https://github.com/OCA/rest-framework/pull/291.

@@ -414,7 +409,7 @@

Base Rest

-

Configuration

+

Configuration

If an error occurs when calling a method of a service (ie missing parameter, ..) the system returns only a general description of the problem without details. This is done on purpose to ensure maximum @@ -436,7 +431,7 @@

Configuration

mode in production.

-

Usage

+

Usage

To add your own REST service you must provides at least 2 classes.

  • A Component providing the business logic of your service,
  • @@ -466,10 +461,10 @@

    Usage

    <string:_service_name>/<int:_id>/<string:method_name>
-from odoo.addons.component.core import Component
+from odoo.addons.component.core import Component
 
 
-class PingService(Component):
+class PingService(Component):
     _inherit = 'base.rest.service'
     _name = 'ping.service'
     _usage = 'ping'
@@ -477,37 +472,37 @@ 

Usage

# The following method are 'public' and can be called from the controller. - def get(self, _id, message): + def get(self, _id, message): return { 'response': 'Get called with message ' + message} - def search(self, message): + def search(self, message): return { 'response': 'Search called search with message ' + message} - def update(self, _id, message): + def update(self, _id, message): return {'response': 'PUT called with message ' + message} # pylint:disable=method-required-super - def create(self, **params): + def create(self, **params): return {'response': 'POST called with message ' + params['message']} - def delete(self, _id): + def delete(self, _id): return {'response': 'DELETE called with id %s ' % _id} # Validator - def _validator_search(self): + def _validator_search(self): return {'message': {'type': 'string'}} # Validator - def _validator_get(self): + def _validator_get(self): # no parameters by default return {} - def _validator_update(self): + def _validator_update(self): return {'message': {'type': 'string'}} - def _validator_create(self): + def _validator_create(self): return {'message': {'type': 'string'}}

Once you have implemented your services (ping, …), you must tell to @@ -515,9 +510,9 @@

Usage

implementing a controller that inherits from odoo.addons.base_rest.controllers.main.RestController

-from odoo.addons.base_rest.controllers import main
+from odoo.addons.base_rest.controllers import main
 
-class MyRestController(main.RestController):
+class MyRestController(main.RestController):
     _root_path = '/my_services_api/'
     _collection_name = my_module.services
 
@@ -533,7 +528,7 @@

Usage

ROOT_PATH + '<string:_service_name>/<int:_id>', ROOT_PATH + '<string:_service_name>/<int:_id>/get' ], methods=['GET'], auth="user", csrf=False) -def get(self, _service_name, _id=None, **params): +def get(self, _service_name, _id=None, **params): method_name = 'get' if _id else 'search' return self._process_method(_service_name, method_name, _id, params) @@ -543,7 +538,7 @@

Usage

ROOT_PATH + '<string:_service_name>/<int:_id>', ROOT_PATH + '<string:_service_name>/<int:_id>/<string:method_name>' ], methods=['POST'], auth="user", csrf=False) -def modify(self, _service_name, _id=None, method_name=None, **params): +def modify(self, _service_name, _id=None, method_name=None, **params): if not method_name: method_name = 'update' if _id else 'create' if method_name == 'get': @@ -555,13 +550,13 @@

Usage

@route([ ROOT_PATH + '<string:_service_name>/<int:_id>', ], methods=['PUT'], auth="user", csrf=False) -def update(self, _service_name, _id, **params): +def update(self, _service_name, _id, **params): return self._process_method(_service_name, 'update', _id, params) @route([ ROOT_PATH + '<string:_service_name>/<int:_id>', ], methods=['DELETE'], auth="user", csrf=False) -def delete(self, _service_name, _id): +def delete(self, _service_name, _id): return self._process_method(_service_name, 'delete', _id)

As result an HTTP GET call to ‘http://my_odoo/my_services_api/ping’ will @@ -583,7 +578,7 @@

Usage

the use of a python decorator to explicitly mark a method as being available via the REST API: odoo.addons.base_rest.restapi.method.

-class PartnerNewApiService(Component):
+class PartnerNewApiService(Component):
     _inherit = "base.rest.service"
     _name = "partner.new_api.service"
     _usage = "partner"
@@ -598,10 +593,10 @@ 

Usage

output_param=restapi.CerberusValidator("_get_partner_schema"), auth="public", ) - def get(self, _id): + def get(self, _id): return {"name": self.env["res.partner"].browse(_id).name} - def _get_partner_schema(self): + def _get_partner_schema(self): return { "name": {"type": "string", "required": True} } @@ -611,7 +606,7 @@

Usage

output_param=restapi.CerberusListValidator("_get_partner_schema"), auth="public", ) - def list(self): + def list(self): partners = self.env["res.partner"].search([]) return [{"name": p.name} for p in partners]
@@ -620,28 +615,28 @@

Usage

For example, base_rest_datamodel allows you to use Datamodel object instance into your services.

-from marshmallow import fields
+from marshmallow import fields
 
-from odoo.addons.base_rest import restapi
-from odoo.addons.component.core import Component
-from odoo.addons.datamodel.core import Datamodel
+from odoo.addons.base_rest import restapi
+from odoo.addons.component.core import Component
+from odoo.addons.datamodel.core import Datamodel
 
 
-class PartnerSearchParam(Datamodel):
+class PartnerSearchParam(Datamodel):
     _name = "partner.search.param"
 
     id = fields.Integer(required=False, allow_none=False)
     name = fields.String(required=False, allow_none=False)
 
 
-class PartnerShortInfo(Datamodel):
+class PartnerShortInfo(Datamodel):
     _name = "partner.short.info"
 
     id = fields.Integer(required=True, allow_none=False)
     name = fields.String(required=True, allow_none=False)
 
 
-class PartnerNewApiService(Component):
+class PartnerNewApiService(Component):
     _inherit = "base.rest.service"
     _name = "partner.new_api.service"
     _usage = "partner"
@@ -657,7 +652,7 @@ 

Usage

output_param=restapi.Datamodel("partner.short.info", is_list=True), auth="public", ) - def search(self, partner_search_param): + def search(self, partner_search_param): """ Search for partners :param partner_search_param: An instance of partner.search.param @@ -683,7 +678,7 @@

Usage

evaluation context.

-

Changelog

+

Changelog

-

16.0.1.0.2 (2023-10-07)

+

16.0.1.0.2 (2023-10-07)

Features

-

12.0.2.0.1

+

12.0.2.0.1

  • validator_…() methods can now return a cerberus Validator object instead of a schema dictionnary, for additional flexibility @@ -715,20 +710,20 @@

    12.0.2.0.1

-

12.0.2.0.0

+

12.0.2.0.0

  • Licence changed from AGPL-3 to LGPL-3
-

12.0.1.0.1

+

12.0.1.0.1

  • Fix issue when rendering the jsonapi documentation if no documentation is provided on a method part of the REST api.
-

12.0.1.0.0

+

12.0.1.0.0

First official version. The addon has been incubated into the Shopinvader repository from @@ -736,7 +731,7 @@

12.0.1.0.0

-

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 @@ -744,22 +739,22 @@

Bug Tracker

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

-

Credits

+

Credits

-

Authors

+

Authors

  • ACSONE SA/NV
-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -772,6 +767,5 @@

Maintainers

-
diff --git a/base_rest/static/src/js/components/swagger_ui.js b/base_rest/static/src/js/components/swagger_ui.esm.js similarity index 98% rename from base_rest/static/src/js/components/swagger_ui.js rename to base_rest/static/src/js/components/swagger_ui.esm.js index a63d1ed8a..a7f6bd5ec 100644 --- a/base_rest/static/src/js/components/swagger_ui.js +++ b/base_rest/static/src/js/components/swagger_ui.esm.js @@ -58,6 +58,7 @@ class SwaggerUI extends Component { } (function () { + // eslint-disable-next-line "use strict"; whenReady(() => { diff --git a/base_rest/views/openapi_template.xml b/base_rest/views/openapi_template.xml index de42ff5b7..3551e06bd 100644 --- a/base_rest/views/openapi_template.xml +++ b/base_rest/views/openapi_template.xml @@ -60,7 +60,7 @@