Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
93 changes: 93 additions & 0 deletions fastapi_user_manager/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
=====================
Fastapi users manager
=====================

..
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! This file is generated by oca-gen-addon-readme !!
!! changes will be overwritten. !!
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
!! source digest: sha256:b556ef5339d8c458cb1a9be08deb285d62c9d8ec9423d6f91110e67b1fafe3d0
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

.. |badge1| image:: https://img.shields.io/badge/maturity-Alpha-red.png
:target: https://odoo-community.org/page/development-status
:alt: Alpha
.. |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/18.0/fastapi_user_manager
: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-18-0/rest-framework-18-0-fastapi_user_manager
: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=18.0
:alt: Try me on Runboat

|badge1| |badge2| |badge3| |badge4| |badge5|

This module add an api for manage user records.

.. IMPORTANT::
This is an alpha version, the data model and design can change at any time without warning.
Only for development or testing purpose, do not use in production.
`More details on development status <https://odoo-community.org/page/development-status>`_

**Table of contents**

.. contents::
:local:

Usage
=====



Changelog
=========



Bug Tracker
===========

Bugs are tracked on `GitHub Issues <https://github.com/OCA/rest-framework/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 <https://github.com/OCA/rest-framework/issues/new?body=module:%20fastapi_user_manager%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.

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

Credits
=======

Authors
-------

* Akretion

Contributors
------------

- Akretion:

- Thomas BONNERUE <thomas.bonnerue@akretion.com>

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.

This module is part of the `OCA/rest-framework <https://github.com/OCA/rest-framework/tree/18.0/fastapi_user_manager>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
3 changes: 3 additions & 0 deletions fastapi_user_manager/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
from . import models
from . import schemas
from . import routers
23 changes: 23 additions & 0 deletions fastapi_user_manager/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
{
"name": "Fastapi users manager",
"summary": "api for managing users in your database",
"version": "18.0.1.0.0",
"development_status": "Alpha",
"category": "Tools",
"website": "https://github.com/OCA/rest-framework",
"author": " Akretion, Odoo Community Association (OCA)",
"license": "AGPL-3",
"external_dependencies": {
"python": [],
},
"depends": [
"fastapi",
"pydantic",
],
"demo": ["demo/fastapi_endpoint_demo.xml"],
"data": [
"views/res_users_view.xml",
"views/fastapi_endpoint_view.xml",
"data/endpoint.xml",
],
}
9 changes: 9 additions & 0 deletions fastapi_user_manager/data/endpoint.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<odoo noupdate="1">
<record id="user_manager_endpoint" model="fastapi.endpoint">
<field name="name">User Manager</field>
<field name="app">user_manager</field>
<field name="description">Allow to add, update, delete odoo users from external system</field>
<field name="root_path">/user</field>
<field name="auth_method">http_basic</field>
</record>
</odoo>
58 changes: 58 additions & 0 deletions fastapi_user_manager/demo/fastapi_endpoint_demo.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8" ?>
<!-- Copyright 2022 ACSONE SA/NV
License LGPL-3.0 or later (http://www.gnu.org/licenses/LGPL). -->
<odoo>
<!-- This is the user that will be used to run the demo app -->
<record
id="my_demo_app_user_user"
model="res.users"
context="{'no_reset_password': True, 'no_reset_password': True}"
>
<field name="name">My Demo Endpoint User User</field>
<field name="login">my_demo_app_user_user</field>
<field name="groups_id" eval="[(6, 0, [])]" />
</record>

<!-- This is the group that will be used to run the demo app
This group will only depend on the "group_fastapi_endpoint_runner" group
that provides the minimal access rights to retrieve the user running the
endpoint handlers and performs authentication.
-->
<record id="my_demo_app_group" model="res.groups">
<field name="name">My Demo Endpoint Group User</field>
<field name="users" eval="[(4, ref('my_demo_app_user_user'))]" />
<field name="implied_ids" eval="[(4, ref('group_fastapi_endpoint_runner'))]" />
</record>

<!-- This is the endpoint that will be used to run the demo app
This endpoint will be registered on the "/fastapi_demo" path
-->

<record model="fastapi.endpoint" id="fastapi_endpoint_demo_user">
<field name="name">Fastapi Demo Endpoint user</field>
<field
name="description"
><![CDATA[
# A Dummy FastApi Demo

This demo endpoint has been created by inhering from "fastapi.endpoint", registering
a new app into the app selection field and implementing the `_get_fastapi_routers`
methods. See documentation to learn more about how to create a new app.
]]></field>
<field name="app">user_manager</field>
<field name="root_path">/fastapi_user</field>
<field name="demo_auth_method">http_basic</field>
<field name="user_id" ref="my_demo_app_user_user" />
</record>

<!-- <record id="fastapi_endpoint_multislash_demo" model="fastapi.endpoint"> -->
<!-- <field name="name">Fastapi Multi-Slash Demo Endpoint</field> -->
<!-- <field name="description"> -->
<!-- Like the other demo endpoint but with multi-slash -->
<!-- </field> -->
<!-- <field name="app">demo</field> -->
<!-- <field name="root_path">/fastapi/demo-multi</field> -->
<!-- <field name="demo_auth_method">http_basic</field> -->
<!-- <field name="user_id" ref="my_demo_app_user" /> -->
<!-- </record> -->
</odoo>
1 change: 1 addition & 0 deletions fastapi_user_manager/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import fastapi_endpoint, res_users
106 changes: 106 additions & 0 deletions fastapi_user_manager/models/fastapi_endpoint.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# licenec

from typing import Annotated

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 odoo.addons.fastapi.dependencies import (
authenticated_partner_from_basic_auth_user,
authenticated_partner_impl,
odoo_env,
)

from fastapi import Depends, HTTPException, status
from fastapi.security import APIKeyHeader

from ..routers.user import user_router


class FastapiEndpoint(models.Model):
_inherit = "fastapi.endpoint"

app: str = fields.Selection(
selection_add=[("user_manager", "User manager")],
ondelete={"user_manager": "cascade"},
)

auth_method = fields.Selection(
selection=[("api_key", "Api key"), ("http_basic", "HTTP Basic")],
string="Authenciation method for user manager",
)

@api.onchange("app")
def _compute_description(self):
if self.app == "user_manager":
self.description = """Api for user manager.
data are list of two fiels.
The fields are 'login': 'str' and 'misc': {vals}
[{'login': 'one', 'misc': {'active': 0, 'name': 'One'},
{'login': 'two', 'misc':
{'email': 'example@ex.com', 'roles': ['Admin', 'tech']}}
"""

def _get_fastapi_routers(self):
if self.app == "user_manager":
return [user_router]
return super()._get_fastapi_routers()

@api.constrains("app", "auth_method")
def _valdiate_demo_auth_method(self):
for rec in self:
if rec.app == "user_manager" and not rec.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("auth_method")
return fields

def _get_app(self):
app = super()._get_app()
if self.app == "user_manager":
# Here we add the overrides to the authenticated_partner_impl method
# according to the authentication method configured on the demo app
if self.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 api_key_based_authenticated_partner_impl(
api_key: Annotated[
str,
Depends(
APIKeyHeader(name="api-key", description="Api key to be log to the partner")
),
],
env: Annotated[Environment, Depends(odoo_env)],
) -> Partner:
partner = (
env["res.users"]
.sudo()
.search([("api_key_user", "=", api_key)], limit=1)
.partner_id
)
if not partner:
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED, detail="Incorrect API Key"
)
return partner
7 changes: 7 additions & 0 deletions fastapi_user_manager/models/res_users.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from odoo import fields, models


class ResUsers(models.Model):
_inherit = "res.users"

api_key_user = fields.Char(help="Api for user crud operations")
3 changes: 3 additions & 0 deletions fastapi_user_manager/pyproject.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[build-system]
requires = ["whool"]
build-backend = "whool.buildapi"
2 changes: 2 additions & 0 deletions fastapi_user_manager/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Akretion:
- Thomas BONNERUE \<thomas.bonnerue@akretion.com\>
1 change: 1 addition & 0 deletions fastapi_user_manager/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
This module add an api for manage user records.
1 change: 1 addition & 0 deletions fastapi_user_manager/readme/HISTORY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions fastapi_user_manager/readme/USAGE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

1 change: 1 addition & 0 deletions fastapi_user_manager/routers/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import user
Loading
Loading