Merge lp:~roadmr/canonical-identity-provider/saml-extra-attribute-substitutions into lp:canonical-identity-provider/release

Proposed by Daniel Manrique
Status: Merged
Approved by: Daniel Manrique
Approved revision: no longer in the source branch.
Merge reported by: Otto Co-Pilot
Merged at revision: not available
Proposed branch: lp:~roadmr/canonical-identity-provider/saml-extra-attribute-substitutions
Merge into: lp:canonical-identity-provider/release
Diff against target: 50 lines (+34/-0)
2 files modified
src/ubuntu_sso_saml/processors.py (+8/-0)
src/ubuntu_sso_saml/tests/test_processors.py (+26/-0)
To merge this branch: bzr merge lp:~roadmr/canonical-identity-provider/saml-extra-attribute-substitutions
Reviewer Review Type Date Requested Status
Maximiliano Bertacchini Approve
Review via email: mp+362265@code.launchpad.net

Commit message

Add two new substitutions to be used in SAML attribute values.

"displayname" is normally the users' Full Name in SSO.
"email" is the e-mail address.

These enable reporting richer SAML attributes to SPs who can then create nicer-looking
local identities.

Additionally, the existence of the e-mail attribute/substitution might allow
for full compliance with the SAML 8.3 "persistent" policy, though this would
require additional implementation work.

Description of the change

Add two new substitutions to be used in SAML attribute values.

These were requested by Canonical's support group because they need a presentable "full name" to create end-user-visible accounts (and their rationale is that e.g. showing "John Peterson" to a user is fine, but "lordofallthatisunholyandfun" might not be - and the latter is the best we can do currently, since we only support substitutions for "subject" (which is usually the e-mail) and "personname" (which is the username)).

The new substitutions:

"displayname" is the users' Full Name in SSO.
"email" is the e-mail address.

These enable reporting richer SAML attributes to SPs who can then create nicer-looking
local identities.

Additionally, the existence of the e-mail attribute/substitution might allow
for full compliance with the SAML 8.3 "persistent" policy, though this would
require additional implementation work. With a separate substitution for e-mail, we could send a truly persistent identifier as the SAML subject's NameID, like the OpenID; and then, send the e-mail as a custom attribute.

To post a comment you must log in.
Revision history for this message
Maximiliano Bertacchini (maxiberta) wrote :

Looks good to me. +1

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 2019-01-18 17:46:34 +0000
3+++ src/ubuntu_sso_saml/processors.py 2019-01-25 21:10:18 +0000
4@@ -461,4 +461,12 @@
5 request = self._django_request
6 attributes[key] = request.build_absolute_uri(
7 request.user.get_absolute_url())
8+ elif value == '{{displayname}}':
9+ displayname = self._django_request.user.displayname
10+ if displayname:
11+ attributes[key] = displayname
12+ elif value == '{{email}}':
13+ email = self._subject
14+ if email:
15+ attributes[key] = email
16 return attributes
17
18=== modified file 'src/ubuntu_sso_saml/tests/test_processors.py'
19--- src/ubuntu_sso_saml/tests/test_processors.py 2019-01-18 17:46:34 +0000
20+++ src/ubuntu_sso_saml/tests/test_processors.py 2019-01-25 21:10:18 +0000
21@@ -1799,3 +1799,29 @@
22 '{}</saml:AttributeValue></saml:Attribute>'.format(
23 openid_url))
24 self.assertIn(expected, samlresponse)
25+
26+ def test_email_as_attribute(self):
27+ self.setup_saml_sp(attributes=json.dumps({
28+ 'email-from-attrib': '{{email}}',
29+ }))
30+ email = self.setup_saml_emails()
31+
32+ samlresponse = self.do_saml_request()
33+ expected = ('<saml:Attribute Name="email-from-attrib">'
34+ '<saml:AttributeValue>'
35+ '{}</saml:AttributeValue></saml:Attribute>'.format(
36+ email))
37+ self.assertIn(expected, samlresponse)
38+
39+ def test_displayname_as_attribute(self):
40+ self.setup_saml_sp(attributes=json.dumps({
41+ 'fullname': '{{displayname}}',
42+ }))
43+ displayname = self.account.displayname
44+
45+ samlresponse = self.do_saml_request()
46+ expected = ('<saml:Attribute Name="fullname">'
47+ '<saml:AttributeValue>'
48+ '{}</saml:AttributeValue></saml:Attribute>'.format(
49+ displayname))
50+ self.assertIn(expected, samlresponse)