mirror of
https://github.com/bringout/oca-technical.git
synced 2026-04-18 13:32:01 +02:00
105 lines
3.4 KiB
Python
105 lines
3.4 KiB
Python
# Copyright 2022 ACSONE SA/NV
|
|
# License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL).
|
|
from typing import Annotated, Any, List
|
|
|
|
from odoo import _, api, fields, models
|
|
from odoo.api import Environment
|
|
from odoo.exceptions import ValidationError
|
|
|
|
from odoo.addons.base.models.res_partner import Partner
|
|
|
|
from fastapi import APIRouter, Depends, HTTPException, status
|
|
from fastapi.security import APIKeyHeader
|
|
|
|
from ..dependencies import (
|
|
authenticated_partner_from_basic_auth_user,
|
|
authenticated_partner_impl,
|
|
odoo_env,
|
|
)
|
|
from ..routers import demo_router, demo_router_doc
|
|
|
|
|
|
class FastapiEndpoint(models.Model):
|
|
|
|
_inherit = "fastapi.endpoint"
|
|
|
|
app: str = fields.Selection(
|
|
selection_add=[("demo", "Demo Endpoint")], ondelete={"demo": "cascade"}
|
|
)
|
|
demo_auth_method = fields.Selection(
|
|
selection=[("api_key", "Api Key"), ("http_basic", "HTTP Basic")],
|
|
string="Authenciation method",
|
|
)
|
|
|
|
def _get_fastapi_routers(self) -> List[APIRouter]:
|
|
if self.app == "demo":
|
|
return [demo_router]
|
|
return super()._get_fastapi_routers()
|
|
|
|
@api.constrains("app", "demo_auth_method")
|
|
def _valdiate_demo_auth_method(self):
|
|
for rec in self:
|
|
if rec.app == "demo" and not rec.demo_auth_method:
|
|
raise ValidationError(
|
|
_(
|
|
"The authentication method is required for app %(app)s",
|
|
app=rec.app,
|
|
)
|
|
)
|
|
|
|
@api.model
|
|
def _fastapi_app_fields(self) -> List[str]:
|
|
fields = super()._fastapi_app_fields()
|
|
fields.append("demo_auth_method")
|
|
return fields
|
|
|
|
def _get_app(self):
|
|
app = super()._get_app()
|
|
if self.app == "demo":
|
|
# Here we add the overrides to the authenticated_partner_impl method
|
|
# according to the authentication method configured on the demo app
|
|
if self.demo_auth_method == "http_basic":
|
|
authenticated_partner_impl_override = (
|
|
authenticated_partner_from_basic_auth_user
|
|
)
|
|
else:
|
|
authenticated_partner_impl_override = (
|
|
api_key_based_authenticated_partner_impl
|
|
)
|
|
app.dependency_overrides[
|
|
authenticated_partner_impl
|
|
] = authenticated_partner_impl_override
|
|
return app
|
|
|
|
def _prepare_fastapi_app_params(self) -> dict[str, Any]:
|
|
params = super()._prepare_fastapi_app_params()
|
|
if self.app == "demo":
|
|
tags_metadata = params.get("openapi_tags", []) or []
|
|
tags_metadata.append({"name": "demo", "description": demo_router_doc})
|
|
params["openapi_tags"] = tags_metadata
|
|
return params
|
|
|
|
|
|
def api_key_based_authenticated_partner_impl(
|
|
api_key: Annotated[
|
|
str,
|
|
Depends(
|
|
APIKeyHeader(
|
|
name="api-key",
|
|
description="In this demo, you can use a user's login as api key.",
|
|
)
|
|
),
|
|
],
|
|
env: Annotated[Environment, Depends(odoo_env)],
|
|
) -> Partner:
|
|
"""A dummy implementation that look for a user with the same login
|
|
as the provided api key
|
|
"""
|
|
partner = (
|
|
env["res.users"].sudo().search([("login", "=", api_key)], limit=1).partner_id
|
|
)
|
|
if not partner:
|
|
raise HTTPException(
|
|
status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect API Key"
|
|
)
|
|
return partner
|