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
4 changes: 2 additions & 2 deletions webservice/__manifest__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,13 @@
{
"name": "WebService",
"summary": """Defines webservice abstract definition to be used generally""",
"version": "18.0.1.1.0",
"version": "18.0.1.1.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"],
"depends": ["component"],
"external_dependencies": {"python": ["requests-oauthlib", "oauthlib", "responses"]},
"data": [
"security/ir.model.access.csv",
Expand Down
32 changes: 1 addition & 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 @@ -145,33 +145,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
60 changes: 0 additions & 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 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 @@ -23,17 +18,6 @@ class TestWebServiceOauth2BackendApplication(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_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 @@ -172,18 +156,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 @@ -246,38 +218,6 @@ def test_fetch_token_from_auth(self):
)
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/18.0.1.1.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()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the case that the module is not added, can you provide the uninstall hook to pass all data?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The uninstall hook is here: b175404

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

in the migration should be there if the other module is not installed (it does not exist)

in some cases that could happen if you only add the modules

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you mean?
In general we should have two cases:

  1. webservice is already installed in the database (meaning current database version of the module depends on server_environment): then webservice upgrade will remove the dependency and upgrade hook will install webservice_server_env.
  2. webservice is not installed and this is a brand new installation: if server_environment is installed then webservice_server_env will be auto installed, because of auto_install key in manifest.
    In both cases if you decide to uninstall server_environment and webservice_server_env the uninstall hook will make the fields regular for the webservice.

Can you pls describe the case I need to handle?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, there is a 3rd case (and it happened to me with fs_storage).

You have server_environment and webservice installed. On the update, you don't know that you need the new module, and you don't add it (I use doodba, and I specify exactly the modules I need). On the update, the if is false, as the module is not found, then, you loose all data, leaving your instance without the credentials.

We have 2 options:

1- raise an exception if the module is not found
2- Make it in a way that the module restores data in case the module is not found.

@yankinmax yankinmax Aug 19, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You have server_environment and webservice installed. On the update, you don't know that you need the new module, and you don't add it

I thought it's actually covered by Odoo with auto_install: if you potentially specify the list of modules to install, the web-api submodule is present on a branch revision (or even aggregated one is built on top of the branch revision), so you definitely have in the code source the webservice_server_env, then even if you don't force it in the list it should be auto installed.
Am I not right?

@ivantodorovich @simahawk @gurneyalex WDYT?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, but that implies that the module is there. A lot of people is adding the whole branch of modules of the OCA repository, but that is not mandatory. That happened to me, with a system that uses git-aggregate and a process to get only the necessary modules. That could happen to if you use PyPi too. Doing this kind of activities (limiting the modules) allows us to be sure that the modules in the instance are compatible and allows us to make some tests on the instance before pushing it.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ok, I see....but I still can't get what kind of uninstall hook I need to add. Can you pls suggest the pseudo-code idea?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Something like this:

https://github.com/OCA/web-api/pull/146/changes#diff-477d83525842ed4ad9af6ca90b3a4d7c434ed43d33a48065d35662c006445572

Another option is to raise an Exception, this way this problem is avoided.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@etobella WDYT:

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/18.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-18-0/web-api-18-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=18.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:%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
-------

* 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/18.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": "18.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
41 changes: 41 additions & 0 deletions webservice_server_env/models/webservice_backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# 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).

from odoo import models


class WebserviceBackend(models.Model):
_name = "webservice.backend"
_inherit = ["webservice.backend", "server.env.techname.mixin", "server.env.mixin"]

@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
3 changes: 3 additions & 0 deletions webservice_server_env/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 webservice_server_env/readme/CONTRIBUTORS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
- Enric Tobella \<<etobella@creublanca.es>\>
- Daniel Reis \<<dreis@opensourceintegrators.com>\>
2 changes: 2 additions & 0 deletions webservice_server_env/readme/DESCRIPTION.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Glue module to make Server Environment features available for the
Webservice addon.
Binary file added webservice_server_env/static/description/icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading