Skip to content

Commit 02262c0

Browse files
[MIG] auth_saml: Migration to 19.0
1 parent ddc1c48 commit 02262c0

12 files changed

Lines changed: 141 additions & 118 deletions

File tree

auth_saml/README.rst

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,13 @@ SAML2 Authentication
2121
:target: http://www.gnu.org/licenses/agpl-3.0-standalone.html
2222
:alt: License: AGPL-3
2323
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--auth-lightgray.png?logo=github
24-
:target: https://github.com/OCA/server-auth/tree/18.0/auth_saml
24+
:target: https://github.com/OCA/server-auth/tree/19.0/auth_saml
2525
:alt: OCA/server-auth
2626
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png
27-
:target: https://translation.odoo-community.org/projects/server-auth-18-0/server-auth-18-0-auth_saml
27+
:target: https://translation.odoo-community.org/projects/server-auth-19-0/server-auth-19-0-auth_saml
2828
:alt: Translate me on Weblate
2929
.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png
30-
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=18.0
30+
:target: https://runboat.odoo-community.org/builds?repo=OCA/server-auth&target_branch=19.0
3131
:alt: Try me on Runboat
3232

3333
|badge1| |badge2| |badge3| |badge4| |badge5|
@@ -133,7 +133,7 @@ Bug Tracker
133133
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-auth/issues>`_.
134134
In case of trouble, please check there if your issue has already been reported.
135135
If you spotted it first, help us to smash it by providing a detailed and welcomed
136-
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20auth_saml%0Aversion:%2018.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
136+
`feedback <https://github.com/OCA/server-auth/issues/new?body=module:%20auth_saml%0Aversion:%2019.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_.
137137

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

@@ -192,6 +192,6 @@ Current `maintainer <https://odoo-community.org/page/maintainer-role>`__:
192192

193193
|maintainer-vincent-hatakeyama|
194194

195-
This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/18.0/auth_saml>`_ project on GitHub.
195+
This module is part of the `OCA/server-auth <https://github.com/OCA/server-auth/tree/19.0/auth_saml>`_ project on GitHub.
196196

197197
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

auth_saml/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
from . import controllers, models
1+
from . import controllers, models, wizards

auth_saml/__manifest__.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,18 @@
11
# Copyright (C) 2020 GlodoUK <https://www.glodo.uk/>
2-
# Copyright (C) 2010-2016, 2022 XCG Consulting <http://odoo.consulting>
2+
# Copyright (C) 2010-2016, 2022 XCG Consulting <https://orbeet.io/>
33
# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
44

55
{
66
"name": "SAML2 Authentication",
7-
"version": "18.0.1.1.0",
7+
"version": "19.0.1.0.0",
88
"category": "Tools",
99
"author": "XCG Consulting, Odoo Community Association (OCA)",
1010
"maintainers": ["vincent-hatakeyama"],
1111
"website": "https://github.com/OCA/server-auth",
1212
"license": "AGPL-3",
1313
"depends": ["base_setup", "web"],
1414
"external_dependencies": {
15-
"python": ["pysaml2"],
15+
"python": ["pysaml2", "responses"],
1616
"bin": ["xmlsec1"],
1717
# special definition used by OCA to install packages
1818
"deb": ["xmlsec1"],

auth_saml/controllers/main.py

Lines changed: 27 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@
1212

1313
from odoo import (
1414
SUPERUSER_ID,
15-
_,
1615
api,
1716
exceptions,
1817
http,
1918
models,
2019
modules,
2120
)
22-
from odoo.http import request
21+
from odoo.http import Response, request
2322
from odoo.tools.misc import clean_context
2423

2524
from odoo.addons.web.controllers.home import Home
@@ -35,19 +34,23 @@
3534

3635
def fragment_to_query_string(func):
3736
@functools.wraps(func)
38-
def wrapper(self, **kw):
37+
def wrapper(self, *a, **kw):
38+
kw.pop("debug", False)
3939
if not kw:
40-
return """<html><head><script>
40+
return Response("""<html><head><script>
4141
var l = window.location;
4242
var q = l.hash.substring(1);
43-
var r = '/' + l.search;
43+
var r = l.pathname + l.search;
4444
if(q.length !== 0) {
4545
var s = l.search ? (l.search === '?' ? '' : '&') : '?';
4646
r = l.pathname + l.search + s + q;
4747
}
48+
if (r == l.pathname) {
49+
r = '/';
50+
}
4851
window.location = r;
49-
</script></head><body></body></html>"""
50-
return func(self, **kw)
52+
</script></head><body></body></html>""")
53+
return func(self, *a, **kw)
5154

5255
return wrapper
5356

@@ -59,7 +62,7 @@ def wrapper(self, **kw):
5962

6063
class SAMLLogin(Home):
6164
# Disable pylint self use as the method is meant to be reused in other modules
62-
def _list_saml_providers_domain(self): # pylint: disable=no-self-use
65+
def _list_saml_providers_domain(self):
6366
return []
6467

6568
def list_saml_providers(self, with_autoredirect: bool = False) -> models.Model:
@@ -131,11 +134,11 @@ def web_login(self, *args, **kw):
131134
if response.is_qweb:
132135
error = request.params.get("saml_error")
133136
if error == "no-signup":
134-
error = _("Sign up is not allowed on this database.")
137+
error = request.env._("Sign up is not allowed on this database.")
135138
elif error == "access-denied":
136-
error = _("Access Denied")
139+
error = request.env._("Access Denied")
137140
elif error == "expired":
138-
error = _(
141+
error = request.env._(
139142
"You do not have access to this database. Please contact support."
140143
)
141144
else:
@@ -179,8 +182,10 @@ def get_auth_request(self, pid):
179182
)
180183
if not redirect_url:
181184
raise Exception(
182-
"Failed to get auth request from provider. "
183-
"Either misconfigured SAML provider or unknown provider."
185+
request.env._(
186+
"Failed to get auth request from provider. "
187+
"Either misconfigured SAML provider or unknown provider."
188+
)
184189
)
185190

186191
redirect = werkzeug.utils.redirect(redirect_url, 303)
@@ -227,25 +232,28 @@ def signin(self, **kw):
227232
request.httprequest.url_root.rstrip("/"),
228233
)
229234
)
235+
# The response needs to be saved otherwise login does not work.
236+
# auth_oauth has a similar code
237+
request.env.cr.commit()
230238
action = state.get("a")
231239
menu = state.get("m")
232240
redirect = (
233241
werkzeug.urls.url_unquote_plus(state["r"]) if state.get("r") else False
234242
)
235-
url = "/web"
243+
url = "/odoo"
236244
if redirect:
237245
url = redirect
238246
elif action:
239-
url = f"/#action={action}"
247+
url = f"/odoo/action-{action}"
240248
elif menu:
241-
url = f"/#menu_id={menu}"
249+
url = f"/odoo?menu_id={menu}"
242250

243251
credentials_dict = {
244252
"login": credentials[1],
245253
"token": credentials[2],
246254
"type": "saml_token",
247255
}
248-
auth_info = request.session.authenticate(dbname, credentials_dict)
256+
auth_info = request.session.authenticate(request.env, credentials_dict)
249257
resp = request.redirect(_get_login_redirect_url(auth_info["uid"], url), 303)
250258
resp.autocorrect_location_header = False
251259
return resp
@@ -277,15 +285,15 @@ def saml_metadata(self, **kw):
277285

278286
if not dbname or not provider:
279287
_logger.debug("Metadata page asked without database name or provider id")
280-
raise request.not_found(_("Missing parameters"))
288+
raise request.not_found(request.env._("Missing parameters"))
281289

282290
provider = int(provider)
283291

284292
with modules.registry.Registry(dbname).cursor() as cr:
285293
env = api.Environment(cr, SUPERUSER_ID, {})
286294
client = env["auth.saml.provider"].sudo().browse(provider)
287295
if not client.exists():
288-
raise request.not_found(_("Unknown provider"))
296+
raise request.not_found(request.env._("Unknown provider"))
289297

290298
return request.make_response(
291299
client._metadata_string(

auth_saml/models/__init__.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
from . import (
44
auth_saml_attribute_mapping,
55
auth_saml_provider,
6-
auth_saml_request,
76
ir_config_parameter,
87
res_config_settings,
98
res_users,

auth_saml/models/auth_saml_provider.py

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@
1010
import urllib
1111

1212
import requests
13-
14-
# dependency name is pysaml2 # pylint: disable=W7936
1513
import saml2
1614
import saml2.xmldsig as ds
1715
from saml2.client import Saml2Client
@@ -165,7 +163,7 @@ def _compute_sp_metadata_url(self):
165163
)
166164

167165
for record in self:
168-
if isinstance(record.id, models.NewId):
166+
if not record.id:
169167
record.sp_metadata_url = False
170168
continue
171169

@@ -335,8 +333,12 @@ def _validate_auth_response(self, token: str, base_url: str = None):
335333

336334
if not matching_value:
337335
raise Exception(
338-
f"Matching attribute {self.matching_attribute} not found "
339-
f"in user attrs: {attrs}"
336+
self.env._(
337+
"Matching attribute %(matching_attribute)s"
338+
" not found in user attrs: %(attrs)s",
339+
matching_attribute=self.matching_attribute,
340+
attrs=attrs,
341+
)
340342
)
341343

342344
if matching_value and isinstance(matching_value, list):
@@ -417,8 +419,12 @@ def action_refresh_metadata_from_url(self):
417419
document = requests.get(provider.idp_metadata_url, timeout=5)
418420
if document.status_code != 200:
419421
raise UserError(
420-
"Unable to download the metadata for "
421-
f"{provider.name}: {document.reason}"
422+
self.env._(
423+
"Unable to download the metadata for"
424+
" %(provider_name)s: %(reason)s",
425+
provider_name=provider.name,
426+
reason=document.reason,
427+
)
422428
)
423429
if document.text != provider.idp_metadata:
424430
providers_to_update[provider.id] = document.text

auth_saml/models/res_users.py

Lines changed: 16 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77

88
import passlib
99

10-
from odoo import SUPERUSER_ID, _, api, fields, models, modules, tools
10+
from odoo import SUPERUSER_ID, api, fields, models, modules, tools
1111
from odoo.exceptions import AccessDenied, ValidationError
1212

1313
from .ir_config_parameter import ALLOW_SAML_UID_AND_PASSWORD
@@ -153,21 +153,22 @@ def _set_password(self):
153153
# And also to be able to set password to a blank value
154154
if not self.allow_saml_and_password():
155155
saml_users = self.filtered(
156-
lambda user: user.sudo().saml_ids
157-
and user.id not in self._saml_allowed_user_ids()
158-
and user.password
156+
lambda user: (
157+
user.sudo().saml_ids
158+
and user.id not in self._saml_allowed_user_ids()
159+
and user.password
160+
)
159161
)
160162
if saml_users:
161163
# same error as an api.constrains because it is a constraint.
162164
# a standard constrains would require the use of SQL as the password
163165
# field is obfuscated by the base module.
164166
raise ValidationError(
165-
_(
166-
"This database disallows users to "
167-
"have both passwords and SAML IDs. "
168-
"Error for logins %s"
167+
self.env._(
168+
"This database disallows users to have both "
169+
"passwords and SAML IDs. Error for logins %s",
170+
saml_users.mapped("login"),
169171
)
170-
% saml_users.mapped("login")
171172
)
172173
# handle setting password to NULL
173174
blank_password_users = self.filtered(lambda user: user.password is False)
@@ -185,11 +186,12 @@ def _set_password_blank(self):
185186
# mail module) to end users.
186187
_logger.debug("Removing password from %s user(s)", len(self.ids))
187188
# similar to what Odoo does in Users._set_encrypted_password
188-
self.env.cr.execute(
189-
"UPDATE res_users SET password = NULL WHERE id IN %s",
190-
(tuple(self.ids),),
191-
)
192-
self.invalidate_recordset(fnames=["password"])
189+
if self:
190+
self.env.cr.execute(
191+
"UPDATE res_users SET password = NULL WHERE id IN %s",
192+
(tuple(self.ids),),
193+
)
194+
self.invalidate_recordset(fnames=["password"])
193195

194196
def allow_saml_and_password_changed(self):
195197
"""Called after the parameter is changed."""

0 commit comments

Comments
 (0)