Skip to content
Merged
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
24 changes: 24 additions & 0 deletions webservice/models/webservice_backend.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,30 @@ def _valid_field_parameter(self, field, name):
extra_params = ("auth_type",)
return name in extra_params or super()._valid_field_parameter(field, name)

@api.onchange("auth_type")
def _onchange_auth_type(self):
# Keep `oauth2_flow` in sync in the UI as the user edits `auth_type`,
# regardless of whether `server_environment` is installed (see
# `create`/`write` below for the same guarantee on any other write).
if self.auth_type != "oauth2":
self.oauth2_flow = False

@api.model_create_multi
def create(self, vals_list):
records = super().create(vals_list)
records.filtered(
lambda r: r.auth_type != "oauth2" and r.oauth2_flow
).oauth2_flow = False
return records

def write(self, vals):
res = super().write(vals)
if "auth_type" in vals:
self.filtered(
lambda r: r.auth_type != "oauth2" and r.oauth2_flow
).oauth2_flow = False
return res

def call(self, method, *args, **kwargs):
_logger.debug("backend %s: call %s %s %s", self.name, method, args, kwargs)
response = getattr(self._get_adapter(), method)(*args, **kwargs)
Expand Down
61 changes: 61 additions & 0 deletions webservice/tests/test_oauth2.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,3 +271,64 @@ def test_oauth2_flow_compute_with_ui(self):
self.assertEqual(
ws.oauth2_flow, oauth2_flow if ws.auth_type == "oauth2" else False
)


class TestWebServiceOauth2FlowReset(CommonWebService):
"""``oauth2_flow`` must be reset on any write, not only via the UI.

This is a plain ORM-level guarantee independent of ``server_environment``
(see ``webservice_server_env`` for the extra guarantee that applies when
that module is installed).
"""

@classmethod
def _setup_records(cls):
res = super()._setup_records()
cls.url = "https://localhost.demo.odoo/"
cls.webservice = cls.env["webservice.backend"].create(
{
"name": "WebService OAuth2",
"tech_name": "test_oauth2_reset",
"auth_type": "oauth2",
"protocol": "http",
"url": cls.url,
"oauth2_flow": "backend_application",
"content_type": "application/xml",
"oauth2_clientid": "some_client_id",
"oauth2_client_secret": "shh_secret",
"oauth2_token_url": f"{cls.url}oauth2/token",
"oauth2_audience": cls.url,
}
)
return res

def test_write_resets_oauth2_flow_when_auth_type_changes(self):
self.webservice.write({"auth_type": "none"})
self.assertFalse(self.webservice.oauth2_flow)

def test_write_keeps_oauth2_flow_when_auth_type_stays_oauth2(self):
self.webservice.write({"oauth2_client_secret": "new_secret"})
self.assertEqual(self.webservice.oauth2_flow, "backend_application")

def test_create_resets_oauth2_flow_for_non_oauth2_auth_type(self):
ws = self.env["webservice.backend"].create(
{
"name": "WebService No Auth",
"tech_name": "test_oauth2_reset_create",
"auth_type": "none",
"protocol": "http",
"url": self.url,
# Inconsistent on purpose: no `create`/`write` should ever
# leave this set together with a non-oauth2 `auth_type`.
"oauth2_flow": "backend_application",
}
)
self.assertFalse(ws.oauth2_flow)

def test_onchange_resets_oauth2_flow(self):
ws = self.webservice.new(
{"auth_type": "oauth2", "oauth2_flow": "backend_application"}
)
ws.auth_type = "none"
ws._onchange_auth_type()
self.assertFalse(ws.oauth2_flow)
Loading