Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[12.0][BKP] webservice #1072

Closed
wants to merge 50 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
50 commits
Select commit Hold shift + click to select a range
2b7b9e1
[ADD] webservice
etobella Dec 10, 2020
c15b000
[UPD] Update webservice.pot
oca-travis Mar 15, 2021
c24eb28
[UPD] README.rst
OCA-git-bot Mar 15, 2021
5fc5c89
[MIG] webservice: Migration to 14.0
etobella May 6, 2021
60ff486
[UPD] Update webservice.pot
oca-travis May 14, 2021
4aa4c06
[UPD] README.rst
OCA-git-bot May 14, 2021
63d03a2
Added translation using Weblate (French)
Yvesldff Jun 17, 2021
bef283e
Translated using Weblate (French)
Yvesldff Jun 17, 2021
cae28a0
[FIX] webservice: server.env.mixin needs to be inherited
LoisRForgeFlow Jun 21, 2021
4c1a2e2
[UPD] Update webservice.pot
oca-travis Jul 30, 2021
ce36170
webservice 14.0.1.0.1
OCA-git-bot Jul 30, 2021
1b1a2c7
Update translation files
oca-transbot Jul 30, 2021
d57460c
[MIG] webservice: Migration to 15.0
JasminSForgeFlow Feb 15, 2022
612c38b
[UPD] Update webservice.pot
Feb 16, 2022
8846bc6
[UPD] README.rst
OCA-git-bot Feb 16, 2022
52439f3
[UPD] Update webservice.pot
Apr 7, 2022
9135903
Update translation files
oca-transbot Apr 8, 2022
36758ce
webservice: move to web-api
simahawk Aug 10, 2022
7ba80fe
[UPD] README.rst
OCA-git-bot Aug 10, 2022
c4b0554
[MIG] webservice: Migration to 16.0
EvaSForgeFlow Jul 10, 2023
4e87dd0
webservice: improve call
simahawk Aug 27, 2022
4de8413
webservice: add api key and public auth support
simahawk Sep 1, 2022
bbd6a94
[UPD] Update webservice.pot
Jul 25, 2023
5299a84
[UPD] README.rst
OCA-git-bot Jul 25, 2023
2f9a029
Update translation files
weblate Jul 25, 2023
1eb4f6d
[UPD] README.rst
OCA-git-bot Sep 3, 2023
05c4b8d
Added translation using Weblate (Italian)
mymage Nov 27, 2023
27fc21e
Translated using Weblate (Italian)
mymage Nov 27, 2023
7b328e5
Translated using Weblate (Italian)
mymage Nov 28, 2023
487a6e6
Translated using Weblate (Italian)
mymage Jan 5, 2024
f0b8841
[IMP] webservice: multi-company
JordiMForgeFlow Feb 2, 2024
c189546
[UPD] Update webservice.pot
Feb 5, 2024
cc0abd9
[BOT] post-merge updates
OCA-git-bot Feb 5, 2024
3c58e02
Update translation files
weblate Feb 5, 2024
06dc428
Translated using Weblate (Italian)
mymage Feb 8, 2024
fd2f936
[IMP] webservice: combine the url with collection's url
gurneyalex Feb 28, 2024
c9103e1
[BOT] post-merge updates
OCA-git-bot Apr 8, 2024
4145adb
Translated using Weblate (Italian)
mymage May 13, 2024
d62ea44
[UPD] Update webservice.pot
May 14, 2024
8c01bc6
[BOT] post-merge updates
OCA-git-bot May 14, 2024
d94e219
Update translation files
weblate May 14, 2024
dc156bf
Translated using Weblate (Italian)
mymage May 23, 2024
0d1795e
[FIX] webservice: WARNING message in logs
gurneyalex May 31, 2024
b4b5a0f
[BOT] post-merge updates
OCA-git-bot Sep 16, 2024
06bfa6b
Translated using Weblate (Italian)
mymage Oct 29, 2024
3fea612
[IMP] webservice: allow to return response object on http calls
JordiMForgeFlow Jun 21, 2024
6e6d054
[IMP]webservice: black, isort, prettier
GuillemCForgeFlow Nov 7, 2024
aebcbd4
[BKP][ADD]webservice
GuillemCForgeFlow Oct 31, 2024
7337138
[IMP] webservice: pre-commit stuff
JordiMForgeFlow Nov 22, 2024
d878682
[MIG] webservice: Migration to V12
JordiMForgeFlow Nov 22, 2024
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
1 change: 1 addition & 0 deletions setup/webservice/odoo/addons/webservice
6 changes: 6 additions & 0 deletions setup/webservice/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import setuptools

setuptools.setup(
setup_requires=['setuptools-odoo'],
odoo_addon=True,
)
1 change: 1 addition & 0 deletions test-requirements.txt
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,4 @@ invoice2data==0.3.5
freezegun
odoo_test_helper
pypdf>=3.15.0,<5.0
httpretty
87 changes: 87 additions & 0 deletions webservice/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
==========
WebService
==========

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

.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png
:target: https://odoo-community.org/page/development-status
:alt: Production/Stable
.. |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%2Fweb--api-lightgray.png?logo=github
:target: https://github.com/OCA/web-api/tree/16.0/webservice
:alt: OCA/web-api
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
:target: https://translation.odoo-community.org/projects/web-api-16-0/web-api-16-0-webservice
: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/web-api&target_branch=16.0
:alt: Try me on Runboat

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

This module creates WebService frameworks to be used globally.

The module introduces support for HTTP Request protocol. The webservice HTTP call returns by default the content of the response. A context 'content_only' can be passed to get the full response object.

**Table of contents**

.. contents::
:local:

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

Bugs are tracked on `GitHub Issues <https://github.com/OCA/web-api/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/web-api/issues/new?body=module:%20webservice%0Aversion:%2016.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
~~~~~~~

* Creu Blanca
* Camptocamp

Contributors
~~~~~~~~~~~~

* Enric Tobella <[email protected]>

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-etobella| image:: https://github.com/etobella.png?size=40px
:target: https://github.com/etobella
:alt: etobella

Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:

|maintainer-etobella|

This module is part of the `OCA/web-api <https://github.com/OCA/web-api/tree/16.0/webservice>`_ project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.
2 changes: 2 additions & 0 deletions webservice/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import components
from . import models
24 changes: 24 additions & 0 deletions webservice/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2020 Creu Blanca
# Copyright 2022 Camptocamp SA
# @author Simone Orsi <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).


{
"name": "WebService",
"summary": """
Defines webservice abstract definition to be used generally""",
"version": "12.0.1.0.0",
"license": "AGPL-3",
"development_status": "Production/Stable",
"maintainers": ["etobella"],
"author": "Creu Blanca, Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/edi",
"depends": ["component", "server_environment"],
"data": [
"security/ir.model.access.csv",
"security/ir_rule.xml",
"views/webservice_backend.xml",
],
"demo": [],
}
2 changes: 2 additions & 0 deletions webservice/components/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import base_adapter
from . import request_adapter
19 changes: 19 additions & 0 deletions webservice/components/base_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2020 Creu Blanca
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.addons.component.core import AbstractComponent


class BaseWebServiceAdapter(AbstractComponent):
_name = "base.webservice.adapter"
_collection = "webservice.backend"
_webservice_protocol = False
_usage = "webservice.request"

@classmethod
def _component_match(cls, work, usage=None, model_name=None, **kw):
"""Override to customize match.
Registry lookup filtered by usage and model_name when landing here.
Now, narrow match to `_match_attrs` attributes.
"""
return kw.get("webservice_protocol") in (None, cls._webservice_protocol)
81 changes: 81 additions & 0 deletions webservice/components/request_adapter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# Copyright 2020 Creu Blanca
# Copyright 2022 Camptocamp SA
# @author Simone Orsi <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

import requests

from odoo.addons.component.core import Component


class BaseRestRequestsAdapter(Component):
_name = "base.requests"
_webservice_protocol = "http"
_inherit = "base.webservice.adapter"

# TODO: url and url_params could come from work_ctx
def _request(self, method, url=None, url_params=None, **kwargs):
url = self._get_url(url=url, url_params=url_params)
content_only = kwargs.pop("content_only", True)
new_kwargs = kwargs.copy()
new_kwargs.update(
{
"auth": self._get_auth(**kwargs),
"headers": self._get_headers(**kwargs),
"timeout": None,
}
)
# pylint: disable=E8106
request = requests.request(method, url, **new_kwargs)
request.raise_for_status()
if content_only:
return request.content
return request

Check warning on line 33 in webservice/components/request_adapter.py

View check run for this annotation

Codecov / codecov/patch

webservice/components/request_adapter.py#L33

Added line #L33 was not covered by tests

def get(self, **kwargs):
return self._request("get", **kwargs)

def post(self, **kwargs):
return self._request("post", **kwargs)

def put(self, **kwargs):
return self._request("put", **kwargs)

def _get_auth(self, auth=False, **kwargs):
if auth:
return auth
handler = getattr(self, "_get_auth_for_" + self.collection.auth_type, None)
return handler(**kwargs) if handler else None

def _get_auth_for_user_pwd(self, **kw):
if self.collection.username and self.collection.password:
return self.collection.username, self.collection.password
return None

Check warning on line 53 in webservice/components/request_adapter.py

View check run for this annotation

Codecov / codecov/patch

webservice/components/request_adapter.py#L53

Added line #L53 was not covered by tests

def _get_headers(self, content_type=False, headers=False, **kwargs):
headers = headers or {}
result = {
"Content-Type": content_type or self.collection.content_type,
}
handler = getattr(self, "_get_headers_for_" + self.collection.auth_type, None)
if handler:
headers.update(handler(**kwargs))
result.update(headers)
return result

def _get_headers_for_api_key(self, **kw):
return {self.collection.api_key_header: self.collection.api_key}

def _get_url(self, url=None, url_params=None, **kwargs):
if not url:
url = self.collection.url
elif not url.startswith(self.collection.url):
if not url.startswith("http"):
url = f"{self.collection.url.rstrip('/')}/{url.lstrip('/')}"

Check warning on line 74 in webservice/components/request_adapter.py

View check run for this annotation

Codecov / codecov/patch

webservice/components/request_adapter.py#L74

Added line #L74 was not covered by tests
else:
# TODO: if url is given, we should validate the domain
# to avoid abusing a webservice backend for different calls.
pass

url_params = url_params or kwargs
return url.format(**url_params)
58 changes: 58 additions & 0 deletions webservice/controllers/oauth2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# Copyright 2024 Camptocamp SA
# @author Alexandre Fayolle <[email protected]>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import json
import logging

from oauthlib.oauth2.rfc6749 import errors
from werkzeug.urls import url_encode

from odoo import http
from odoo.http import request

_logger = logging.getLogger(__name__)


class OAuth2Controller(http.Controller):
@http.route(
"/webservice/<int:backend_id>/oauth2/redirect",
type="http",
auth="public",
csrf=False,
)
def redirect(self, backend_id, **params):
backend = request.env["webservice.backend"].browse(backend_id).sudo()
if backend.auth_type != "oauth2" or backend.oauth2_flow != "web_application":
_logger.error("unexpected backed config for backend %d", backend_id)
raise errors.MismatchingRedirectURIError()
expected_state = backend.oauth2_state
state = params.get("state")
if state != expected_state:
_logger.error("unexpected state: %s", state)
raise errors.MismatchingStateError()
code = params.get("code")
adapter = (
backend._get_adapter()
) # we expect an adapter that supports web_application
token = adapter._fetch_token_from_authorization(code)
backend.write({"oauth2_token": json.dumps(token), "oauth2_state": False})
# after saving the token, redirect to the backend form view
uid = request.session.uid
user = request.env["res.users"].sudo().browse(uid)
cids = request.httprequest.cookies.get("cids", str(user.company_id.id))
cids = [int(cid) for cid in cids.split(",")]
record_action = backend.get_access_action()
url_params = {
"model": backend._name,
"id": backend.id,
"active_id": backend.id,
"action": record_action.get("id"),
}
view_id = backend.get_formview_id()
if view_id:
url_params["view_id"] = view_id

if cids:
url_params["cids"] = ",".join([str(cid) for cid in cids])
url = "/web?#%s" % url_encode(url_params)
return request.redirect(url)
Loading
Loading