Merge lp:~roadmr/canonical-identity-provider/dont-clobber-saml-attribute-email into lp:canonical-identity-provider/release

Proposed by Daniel Manrique
Status: Merged
Approved by: Daniel Manrique
Approved revision: 1733
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: lp:~roadmr/canonical-identity-provider/dont-clobber-saml-attribute-email
Merge into: lp:canonical-identity-provider/release
Diff against target: 81 lines (+31/-6)
2 files modified
src/ubuntu_sso_saml/processors.py (+11/-6)
src/ubuntu_sso_saml/tests/test_processors.py (+20/-0)
To merge this branch: bzr merge lp:~roadmr/canonical-identity-provider/dont-clobber-saml-attribute-email
Reviewer Review Type Date Requested Status
Jonathan Hartley (community) Approve
Review via email: mp+381788@code.launchpad.net

Commit message

ensure persistent id-honoring SAML peers don't mess with {{email}} attrib substitution

Description of the change

to QA:

- setup a saml config with "honor persistent id" and "don't use email as persistent id"
- add an attribute using the {{email}} substitution
- hit it form a suitably-configured RP
- ensure the attribute contains the email and not the sha256 persistent id

To post a comment you must log in.
Revision history for this message
Jonathan Hartley (tartley) wrote :

Looks good to me, but with one nitwit idea attached. My apologies.

review: Approve
Revision history for this message
Daniel Manrique (roadmr) wrote :

Thanks!

1733. By Daniel Manrique

Review comment fixes

1734. By Daniel Manrique

tweak comments

Revision history for this message
Jonathan Hartley (tartley) wrote :

Approved! Splendid.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/ubuntu_sso_saml/processors.py'
2--- src/ubuntu_sso_saml/processors.py 2020-03-26 21:49:05 +0000
3+++ src/ubuntu_sso_saml/processors.py 2020-04-08 15:21:38 +0000
4@@ -378,7 +378,8 @@
5
6 def _determine_subject(self):
7 account = self._django_request.user
8- preferred = account.preferredemail.email
9+ # By default the subject (user identifier) is the email.
10+ email = subject = account.preferredemail.email
11
12 # check if SP prefers @canonical emails
13 sp_config = get_config_from_processor(self)
14@@ -388,19 +389,23 @@
15 account,
16 honor_preferred=(
17 sp_config.honor_preferred_email))
18+ # If the peer prefers canonical emails then use that for
19+ # both subject and email.
20 if canonical_email is not None:
21- preferred = canonical_email
22- # Maybe override subject if we need to use a true persistent id
23+ email = subject = canonical_email
24 if (sp_config.honor_authnrequest_nameidpolicy_format and
25 not sp_config.send_email_as_persistent and
26 self._subject_format.split(":")[-1] == "persistent"):
27+ # If the SP config requires it, replace the subject by a
28+ # persistent identifier (but leave email alone).
29 # openid identifier is unicode (or str in py3 at some point)
30 # sha256 eats strings (or bytes in py3)
31 # so we must ENcode
32 identifier = account.openid_identifier.encode('utf-8')
33- preferred = sha256(identifier).hexdigest()
34+ subject = sha256(identifier).hexdigest()
35
36- self._subject = preferred
37+ self._email = email
38+ self._subject = subject
39
40 def _format_assertion(self):
41 sp_config = get_config_from_processor(self)
42@@ -501,7 +506,7 @@
43 if displayname:
44 attributes[key] = displayname
45 elif value == '{{email}}':
46- email = self._subject
47+ email = self._email
48 if email:
49 attributes[key] = email
50 # Convert keys and values to utf8-encoded str and return that
51
52=== modified file 'src/ubuntu_sso_saml/tests/test_processors.py'
53--- src/ubuntu_sso_saml/tests/test_processors.py 2020-03-26 21:49:05 +0000
54+++ src/ubuntu_sso_saml/tests/test_processors.py 2020-04-08 15:21:38 +0000
55@@ -1978,6 +1978,26 @@
56 email))
57 self.assertIn(expected, samlresponse)
58
59+ def test_email_as_attribute_persistent_id(self):
60+ # Ensure the email is still substituted properly in attributes
61+ # even when using persistent id
62+ self.setup_saml_sp(
63+ attributes=json.dumps({
64+ 'email-from-attrib': '{{email}}',
65+ }),
66+ honor_authnrequest_nameidpolicy_format=True,
67+ send_email_as_persistent=False
68+ )
69+ email = self.setup_saml_emails()
70+
71+ data = self.get_request_data(nameid_format="persistent")
72+ samlresponse = self.do_saml_request(data=data)
73+ expected = ('<saml:Attribute Name="email-from-attrib">'
74+ '<saml:AttributeValue>'
75+ '{}</saml:AttributeValue></saml:Attribute>'.format(
76+ email))
77+ self.assertIn(expected, samlresponse)
78+
79 def test_displayname_as_attribute(self):
80 self.setup_saml_sp(attributes=json.dumps({
81 'fullname': '{{displayname}}',