Skip to content

Commit adaf964

Browse files
authored
Merge pull request #548 from OCA/17.0
Syncing from upstream OCA/server-auth (17.0)
2 parents 45e3684 + 6b1eb73 commit adaf964

File tree

6 files changed

+95
-53
lines changed

6 files changed

+95
-53
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ addon | version | maintainers | summary
2929
[auth_jwt](auth_jwt/) | 17.0.1.0.0 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | JWT bearer token authentication.
3030
[auth_ldaps](auth_ldaps/) | 17.0.1.0.0 | | Allows to use LDAP over SSL authentication
3131
[auth_oidc](auth_oidc/) | 17.0.1.1.0 | [![sbidoul](https://github.com/sbidoul.png?size=30px)](https://github.com/sbidoul) | Allow users to login through OpenID Connect Provider
32-
[auth_saml](auth_saml/) | 17.0.1.0.0 | [![vincent-hatakeyama](https://github.com/vincent-hatakeyama.png?size=30px)](https://github.com/vincent-hatakeyama) | SAML2 Authentication
32+
[auth_saml](auth_saml/) | 17.0.1.0.1 | [![vincent-hatakeyama](https://github.com/vincent-hatakeyama.png?size=30px)](https://github.com/vincent-hatakeyama) | SAML2 Authentication
3333
[auth_session_timeout](auth_session_timeout/) | 17.0.1.0.0 | | This module disable all inactive sessions since a given delay
3434
[auth_signup_verify_email](auth_signup_verify_email/) | 17.0.1.0.0 | | Force uninvited users to use a good email for signup
3535
[auth_user_case_insensitive](auth_user_case_insensitive/) | 17.0.1.0.0 | | Makes the user login field case insensitive

auth_saml/README.rst

Lines changed: 34 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ SAML2 Authentication
77
!! This file is generated by oca-gen-addon-readme !!
88
!! changes will be overwritten. !!
99
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
10-
!! source digest: sha256:29773025a7d79e9696be8e0a1b65361642ef6bc8b6fb8f9cb13a4b4719017c71
10+
!! source digest: sha256:ffa8efafb4e4dcf93290b09d3910d691b713c29ca2ba54b6b263a9a4336a49b4
1111
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1212
1313
.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png
@@ -36,14 +36,14 @@ On) between Odoo and other applications of your ecosystem.
3636

3737
**Benefits**:
3838

39-
- Reducing the time spent typing different passwords for different
40-
accounts.
41-
- Reducing the time spent in IT support for password oversights.
42-
- Centralizing authentication systems.
43-
- Securing all input levels / exit / access to multiple systems without
44-
prompting users.
45-
- The centralization of access control information for compliance
46-
testing to different standards.
39+
- Reducing the time spent typing different passwords for different
40+
accounts.
41+
- Reducing the time spent in IT support for password oversights.
42+
- Centralizing authentication systems.
43+
- Securing all input levels / exit / access to multiple systems without
44+
prompting users.
45+
- The centralization of access control information for compliance
46+
testing to different standards.
4747

4848
**Table of contents**
4949

@@ -91,15 +91,22 @@ login screen.
9191
Known issues / Roadmap
9292
======================
9393

94-
- clean up ``auth_saml.request``
94+
- clean up ``auth_saml.request``
9595

9696
Changelog
9797
=========
9898

99-
16.0.1.0.0
99+
17.0.1.1.0
100100
----------
101101

102-
Initial migration for 16.0.
102+
When using attribute mapping, only write value that changes. No writing
103+
the value systematically avoids getting security mail on login/email
104+
when there is no real change.
105+
106+
17.0.1.0.0
107+
----------
108+
109+
Initial migration for 17.0.
103110

104111
Bug Tracker
105112
===========
@@ -122,28 +129,28 @@ Authors
122129
Contributors
123130
------------
124131

125-
- `XCG Consulting <https://xcg-consulting.fr/>`__:
132+
- `XCG Consulting <https://xcg-consulting.fr/>`__:
126133

127-
- Florent Aide <[email protected]>
128-
- Vincent Hatakeyama <[email protected]>
129-
- Alexandre Brun
130-
- Houzéfa Abbasbhay <[email protected]>
131-
- Szeka Wong <[email protected]>
134+
- Florent Aide <[email protected]>
135+
- Vincent Hatakeyama <[email protected]>
136+
- Alexandre Brun
137+
- Houzéfa Abbasbhay <[email protected]>
138+
- Szeka Wong <[email protected]>
132139

133-
- Jeremy Co Kim Len <[email protected]>
134-
- Jeffery Chen Fan <[email protected]>
135-
- Bhavesh Odedra <[email protected]>
136-
- `Tecnativa <https://www.tecnativa.com/>`__:
140+
- Jeremy Co Kim Len <[email protected]>
141+
- Jeffery Chen Fan <[email protected]>
142+
- Bhavesh Odedra <[email protected]>
143+
- `Tecnativa <https://www.tecnativa.com/>`__:
137144

138-
- Jairo Llopis
145+
- Jairo Llopis
139146

140-
- `GlodoUK <https://www.glodo.uk/>`__:
147+
- `GlodoUK <https://www.glodo.uk/>`__:
141148

142-
- Karl Southern
149+
- Karl Southern
143150

144-
- `TAKOBI <https://takobi.online/>`__:
151+
- `TAKOBI <https://takobi.online/>`__:
145152

146-
- Lorenzo Battistini
153+
- Lorenzo Battistini
147154

148155
Maintainers
149156
-----------

auth_saml/__manifest__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
{
66
"name": "SAML2 Authentication",
7-
"version": "17.0.1.0.0",
7+
"version": "17.0.1.0.1",
88
"category": "Tools",
99
"author": "XCG Consulting, Odoo Community Association (OCA)",
1010
"maintainers": ["vincent-hatakeyama"],

auth_saml/models/res_users.py

Lines changed: 29 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,20 @@ def _auth_saml_signin(self, provider: int, validation: dict, saml_response) -> s
5555
user_saml.with_env(new_env).write({"saml_access_token": saml_response})
5656

5757
if validation.get("mapped_attrs", {}):
58-
user.write(validation.get("mapped_attrs", {}))
58+
# Only write field that changes to avoid generating Security Update on users
59+
# when login/email changes (from mail module)
60+
vals = {}
61+
for key, value in validation.get("mapped_attrs", {}).items():
62+
# If the value or the field value is not a str,
63+
# avoid comparison and write anyway
64+
if (
65+
not isinstance(value, str)
66+
or not isinstance(user[key], str)
67+
or user[key] != value
68+
):
69+
vals[key] = value
70+
if vals:
71+
user.write(vals)
5972

6073
return user.login
6174

@@ -158,27 +171,31 @@ def _set_password(self):
158171
# pylint: disable=protected-access
159172
super(ResUser, non_blank_password_users)._set_password()
160173
if blank_password_users:
161-
# similar to what Odoo does in Users._set_encrypted_password
162-
self.env.cr.execute(
163-
"UPDATE res_users SET password = NULL WHERE id IN %s",
164-
(tuple(blank_password_users.ids),),
165-
)
166-
blank_password_users.invalidate_recordset(fnames=["password"])
174+
blank_password_users._set_password_blank()
167175
return
168176

177+
def _set_password_blank(self):
178+
"""Set the password to a value that prohibits logging."""
179+
# Use SQL to blank the password to avoid sending security messages (done in
180+
# mail module) to end users.
181+
_logger.debug("Removing password from %s user(s)", len(self.ids))
182+
# similar to what Odoo does in Users._set_encrypted_password
183+
self.env.cr.execute(
184+
"UPDATE res_users SET password = NULL WHERE id IN %s",
185+
(tuple(self.ids),),
186+
)
187+
self.invalidate_recordset(fnames=["password"])
188+
169189
def allow_saml_and_password_changed(self):
170190
"""Called after the parameter is changed."""
171191
if not self.allow_saml_and_password():
172192
# sudo because the user doing the parameter change might not have the right
173193
# to search or write users
174-
users_to_blank_password = self.sudo().search(
194+
blank_password_users = self.sudo().search(
175195
[
176196
"&",
177197
("saml_ids", "!=", False),
178198
("id", "not in", list(self._saml_allowed_user_ids())),
179199
]
180200
)
181-
_logger.debug(
182-
"Removing password from %s user(s)", len(users_to_blank_password)
183-
)
184-
users_to_blank_password.write({"password": False})
201+
blank_password_users._set_password_blank()

auth_saml/readme/HISTORY.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1-
## 16.0.1.0.0
1+
## 17.0.1.1.0
22

3-
Initial migration for 16.0.
3+
When using attribute mapping, only write value that changes.
4+
No writing the value systematically avoids getting security mail on login/email
5+
when there is no real change.
6+
7+
## 17.0.1.0.0
8+
9+
Initial migration for 17.0.

auth_saml/tests/test_pysaml.py

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -133,24 +133,25 @@ def test__compute_sp_metadata_url__provider_has_sp_baseurl(self):
133133
self.assertEqual(self.saml_provider.sp_metadata_url, expected_url)
134134
self.saml_provider.sp_baseurl = temp
135135

136-
def test__hook_validate_auth_response(self):
137-
# Create a fake response with attributes
138-
fake_response = DummyResponse(200, "fake_data")
139-
fake_response.set_identity(
140-
{"email": "[email protected]", "first_name": "New", "last_name": "User"}
141-
)
142-
143-
# Add attribute mappings to the provider
136+
def _add_mapping_to_provider(self):
137+
"""Add mapping to the provider"""
144138
self.saml_provider.attribute_mapping_ids = [
145-
(0, 0, {"attribute_name": "email", "field_name": "login"}),
146-
(0, 0, {"attribute_name": "first_name", "field_name": "name"}),
139+
(0, 0, {"attribute_name": "mail", "field_name": "login"}),
140+
(0, 0, {"attribute_name": "givenName", "field_name": "name"}),
147141
(
148142
0,
149143
0,
150144
{"attribute_name": "nick_name", "field_name": "name"},
151145
), # This attribute is not in attrs
152146
]
153147

148+
def test__hook_validate_auth_response(self):
149+
# Create a fake response with attributes
150+
fake_response = DummyResponse(200, "fake_data")
151+
fake_response.set_identity(
152+
{"mail": "[email protected]", "givenName": "New", "last_name": "User"}
153+
)
154+
self._add_mapping_to_provider()
154155
# Call the method
155156
result = self.saml_provider._hook_validate_auth_response(
156157
fake_response, "[email protected]"
@@ -261,6 +262,17 @@ def test_login_with_saml(self):
261262
# User should now be able to log in with the token
262263
self.authenticate(user="[email protected]", password=token)
263264

265+
def test_login_with_saml_mapping_attributes(self):
266+
"""Test login with SAML on a provider with mapping attributes"""
267+
self.assertEqual(self.user.name, "User")
268+
self.assertEqual(self.user.login, "[email protected]")
269+
self._add_mapping_to_provider()
270+
self.test_login_with_saml()
271+
# Changed due to mapping and FakeIDP returning another value
272+
self.assertEqual(self.user.name, "Test")
273+
# Not changed
274+
self.assertEqual(self.user.login, "[email protected]")
275+
264276
def test_disallow_user_password_when_changing_ir_config_parameter(self):
265277
"""Test that disabling users from having both a password and SAML ids remove
266278
users password."""

0 commit comments

Comments
 (0)