Skip to content
Open
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
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# generated from manifests external_dependencies
oauthlib
requests-oauthlib
responses
6 changes: 6 additions & 0 deletions setup/webservice_server_env/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
@@ -1 +1,2 @@
responses
odoo-addon-server_environment @ git+https://github.com/OCA/server-env.git@refs/pull/276/head#subdirectory=setup/server_environment
6 changes: 3 additions & 3 deletions webservice/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@
"name": "WebService",
"summary": """
Defines webservice abstract definition to be used generally""",
"version": "16.0.1.6.0",
"version": "16.0.1.6.1",
"license": "AGPL-3",
"development_status": "Production/Stable",
"maintainers": ["etobella"],
"author": "Creu Blanca, Camptocamp, Odoo Community Association (OCA)",
"website": "https://github.com/OCA/web-api",
"depends": ["component", "server_environment"],
"external_dependencies": {"python": ["requests-oauthlib", "oauthlib"]},
"depends": ["component"],
"external_dependencies": {"python": ["requests-oauthlib", "oauthlib", "responses"]},
"data": [
"security/ir.model.access.csv",
"security/ir_rule.xml",
Expand Down
33 changes: 2 additions & 31 deletions webservice/models/webservice_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
class WebserviceBackend(models.Model):

_name = "webservice.backend"
_inherit = ["collection.base", "server.env.techname.mixin", "server.env.mixin"]
_inherit = ["collection.base"]
_description = "WebService Backend"

name = fields.Char(required=True)
Expand Down Expand Up @@ -130,6 +130,7 @@ def _compute_redirect_url(self):
)
base_url = base_url[len("http://") :]
if not base_url.startswith("https://"):
# flake8: noqa: E231 missing whitespace after ':'
base_url = f"https://{base_url}"
for rec in self:
if rec.auth_type == "oauth2" and rec.oauth2_flow == "web_application":
Expand All @@ -146,33 +147,3 @@ def button_authorize(self):
"url": authorize_url,
"target": "self",
}

@property
def _server_env_fields(self):
base_fields = super()._server_env_fields
webservice_fields = {
"protocol": {},
"url": {},
"auth_type": {},
"username": {},
"password": {},
"api_key": {},
"api_key_header": {},
"content_type": {},
"oauth2_flow": {},
"oauth2_scope": {},
"oauth2_clientid": {},
"oauth2_client_secret": {},
"oauth2_authorization_url": {},
"oauth2_token_url": {},
"oauth2_audience": {},
}
webservice_fields.update(base_fields)
return webservice_fields

def _compute_server_env(self):
# OVERRIDE: reset ``oauth2_flow`` when ``auth_type`` is not "oauth2", even if
# defined otherwise in server env vars
res = super()._compute_server_env()
self.filtered(lambda r: r.auth_type != "oauth2").oauth2_flow = None
return res
61 changes: 1 addition & 60 deletions webservice/tests/test_oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,14 @@
# @author Alexandre Fayolle <alexandre.fayolle@camptocamp.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
import json
import os
import time
from unittest import mock
from urllib.parse import quote

import responses
from oauthlib.oauth2.rfc6749.errors import InvalidGrantError

from odoo.tests.common import Form

from odoo.addons.server_environment import server_env
from odoo.addons.server_environment.models import server_env_mixin

from .common import CommonWebService, mock_cursor


Expand All @@ -24,17 +19,6 @@ def _setup_records(cls):

res = super()._setup_records()
cls.url = "https://localhost.demo.odoo/"
os.environ["SERVER_ENV_CONFIG"] = "\n".join(
[
"[webservice_backend.test_oauth2_back]",
"auth_type = oauth2",
"oauth2_flow = backend_application",
"oauth2_clientid = some_client_id",
"oauth2_client_secret = shh_secret",
f"oauth2_token_url = {cls.url}oauth2/token",
f"oauth2_audience = {cls.url}",
]
)
cls.webservice = cls.env["webservice.backend"].create(
{
"name": "WebService OAuth2",
Expand Down Expand Up @@ -151,18 +135,6 @@ class TestWebServiceOauth2WebApplication(CommonWebService):
def _setup_records(cls):
res = super()._setup_records()
cls.url = "https://localhost.demo.odoo/"
os.environ["SERVER_ENV_CONFIG"] = "\n".join(
[
"[webservice_backend.test_oauth2_web]",
"auth_type = oauth2",
"oauth2_flow = web_application",
"oauth2_clientid = some_client_id",
"oauth2_client_secret = shh_secret",
f"oauth2_token_url = {cls.url}oauth2/token",
f"oauth2_audience = {cls.url}",
f"oauth2_authorization_url = {cls.url}/authorize",
]
)
cls.webservice = cls.env["webservice.backend"].create(
{
"name": "WebService OAuth2",
Expand Down Expand Up @@ -198,6 +170,7 @@ def test_authorization_code(self):
self.assertEqual(action["target"], expected_action["target"])
self.assertTrue(
action["url"].startswith(expected_action["url"]),
# flake8: noqa: E231 missing whitespace after ':'
f"Got url:\n{action['url']}\nexpected:\n{expected_action['url']}",
)

Expand All @@ -220,38 +193,6 @@ def test_fetch_token_from_auth(self):
token = adapter._fetch_token_from_authorization(code)
self.assertEqual("cool_token", token["access_token"])

def test_oauth2_flow_compute_with_server_env(self):
"""Check the ``compute`` method when updating server envs"""
ws = self.webservice
url = self.url
for auth_type, oauth2_flow in [
(tp, fl)
for tp in ws._fields["auth_type"].get_values(ws.env)
for fl in ws._fields["oauth2_flow"].get_values(ws.env)
]:
# Update env with current ``auth_type`` and ``oauth2_flow``
with mock.patch.dict(
os.environ,
{
"SERVER_ENV_CONFIG": f"""
[webservice_backend.test_oauth2_web]
auth_type = {auth_type}
oauth2_flow = {oauth2_flow}
oauth2_clientid = some_client_id
oauth2_client_secret = shh_secret
oauth2_token_url = {url}oauth2/token
oauth2_audience = {url}
oauth2_authorization_url = {url}/authorize
""",
},
):
server_env_mixin.serv_config = server_env._load_config() # Reload vars
ws.invalidate_recordset() # Avoid reading from cache
if auth_type == "oauth2":
self.assertEqual(ws.oauth2_flow, oauth2_flow)
else:
self.assertFalse(ws.oauth2_flow)

def test_oauth2_flow_compute_with_ui(self):
"""Check the ``compute`` method when updating WS from UI"""
ws = self.webservice
Expand Down
22 changes: 22 additions & 0 deletions webservice/upgrades/16.0.1.6.1/post-update.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2026 Camptocamp SA
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl).

from openupgradelib import openupgrade

from odoo import _, exceptions


@openupgrade.migrate()
def migrate(env, version):
module = env["ir.module.module"].search([("name", "=", "webservice_server_env")])
if not module:
raise exceptions.UserError(
_(
"The 'webservice_server_env' module is not available. "
"It is required to preserve the server environment managed "
"fields of 'webservice.backend'. Make it available on the "
"addons path before upgrading 'webservice'."
)
)
if module.state == "uninstalled":
module.button_install()
87 changes: 87 additions & 0 deletions webservice_server_env/README.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
=============================
WebService Server Environment
=============================

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

.. |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_server_env
: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_server_env
: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|

Glue module to make Server Environment features available for the
Webservice addon.

**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_server_env%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 <etobella@creublanca.es>
- Daniel Reis <dreis@opensourceintegrators.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.

.. |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_server_env>`_ 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_server_env/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from . import models
from .hooks import uninstall_hook
19 changes: 19 additions & 0 deletions webservice_server_env/__manifest__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Copyright 2020 Creu Blanca
# Copyright 2022 Camptocamp SA
# @author Simone Orsi <simahawk@gmail.com>
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).


{
"name": "WebService Server Environment",
"summary": "Use Server Environment feature to manage Webservice configs",
"version": "16.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/web-api",
"depends": ["webservice", "server_environment"],
"uninstall_hook": "uninstall_hook",
"auto_install": True,
}
34 changes: 34 additions & 0 deletions webservice_server_env/hooks.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# Copyright 2025 Camptocamp SA
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).

from odoo.addons.server_environment.uninstall import restore_env_managed_columns


def uninstall_hook(env):
"""Restore database columns dropped by server.env.mixin.

When the module is uninstalled, the columns managed by the server
environment mixin must be restored and repopulated with current values,
so the database remains usable.
"""
restore_env_managed_columns(
env,
"webservice.backend",
[
"protocol",
"url",
"auth_type",
"username",
"password",
"api_key",
"api_key_header",
"content_type",
"oauth2_flow",
"oauth2_scope",
"oauth2_clientid",
"oauth2_client_secret",
"oauth2_authorization_url",
"oauth2_token_url",
"oauth2_audience",
],
)
1 change: 1 addition & 0 deletions webservice_server_env/models/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
from . import webservice_backend
Loading
Loading