0001-allow-federating-transient-NameID-using-an-attribute.patch
README | ||
---|---|---|
247 | 247 |
Verify SSL certificate when doing HTTP requests, used when resolving artifacts. |
248 | 248 |
Default is True. |
249 | 249 | |
250 |
MELLON_TRANSIENT_FEDERATION_ATTRIBUTE |
|
251 |
------------------------------------- |
|
252 | ||
253 |
Name of an attribute to use in replacement of the NameID content when the NameID |
|
254 |
format is transient. Without it no login using a transient NameID can occur with |
|
255 |
the default adapter. |
|
256 |
Default is None. |
|
257 | ||
250 | 258 |
Tests |
251 | 259 |
===== |
252 | 260 |
mellon/adapters.py | ||
---|---|---|
107 | 107 | |
108 | 108 |
def lookup_user(self, idp, saml_attributes): |
109 | 109 |
User = auth.get_user_model() |
110 |
name_id = saml_attributes['name_id_content'] |
|
110 |
transient_federation_attribute = utils.get_setting(idp, 'TRANSIENT_FEDERATION_ATTRIBUTE') |
|
111 |
if saml_attributes['name_id_format'] == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT: |
|
112 |
if (transient_federation_attribute |
|
113 |
and saml_attributes.get(transient_federation_attribute)): |
|
114 |
name_id = saml_attributes[transient_federation_attribute] |
|
115 |
if not isinstance(name_id, basestring): |
|
116 |
if len(name_id) == 1: |
|
117 |
name_id = name_id[0] |
|
118 |
else: |
|
119 |
self.logger.warning('more than one value for attribute %r, cannot federate', |
|
120 |
transient_federation_attribute) |
|
121 |
return None |
|
122 |
else: |
|
123 |
return None |
|
124 |
else: |
|
125 |
name_id = saml_attributes['name_id_content'] |
|
111 | 126 |
issuer = saml_attributes['issuer'] |
112 | 127 |
try: |
113 | 128 |
return User.objects.get(saml_identifiers__name_id=name_id, |
mellon/app_settings.py | ||
---|---|---|
32 | 32 |
'OPENED_SESSION_COOKIE_DOMAIN': None, |
33 | 33 |
'ORGANIZATION': None, |
34 | 34 |
'CONTACT_PERSONS': [], |
35 |
'TRANSIENT_FEDERATION_ATTRIBUTE': None, |
|
35 | 36 |
} |
36 | 37 | |
37 | 38 |
@property |
tests/test_default_adapter.py | ||
---|---|---|
1 | 1 |
import threading |
2 | 2 |
import pytest |
3 | 3 |
import re |
4 |
import lasso |
|
4 | 5 | |
5 | 6 |
from django.contrib import auth |
6 | 7 |
from django.db import connection |
... | ... | |
14 | 15 |
'METADATA': file('tests/metadata.xml').read(), |
15 | 16 |
} |
16 | 17 |
saml_attributes = { |
18 |
'name_id_format': lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT, |
|
17 | 19 |
'name_id_content': 'x' * 32, |
18 | 20 |
'issuer': 'https://cresson.entrouvert.org/idp/saml2/metadata', |
19 | 21 |
'username': ['foobar'], |
... | ... | |
164 | 166 |
assert 'to value %r ' % (u'y' * 30) in caplog.text() |
165 | 167 |
assert 'set field last_name' in caplog.text() |
166 | 168 |
assert 'set field email' in caplog.text() |
169 | ||
170 | ||
171 |
def test_lookup_user_transient_with_email(private_settings): |
|
172 |
private_settings.MELLON_TRANSIENT_FEDERATION_ATTRIBUTE = 'email' |
|
173 |
User = auth.get_user_model() |
|
174 |
adapter = DefaultAdapter() |
|
175 |
saml_attributes2 = saml_attributes.copy() |
|
176 |
saml_attributes2['name_id_format'] = lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT |
|
177 |
assert User.objects.count() == 0 |
|
178 |
user = adapter.lookup_user(idp, saml_attributes2) |
|
179 |
assert user is not None |
|
180 |
assert user.saml_identifiers.count() == 1 |
|
181 |
assert user.saml_identifiers.first().name_id == saml_attributes2['email'][0] |
|
182 | ||
183 |
user2 = adapter.lookup_user(idp, saml_attributes2) |
|
184 |
assert user.id == user2.id |
|
185 | ||
186 |
User.objects.all().delete() |
|
187 |
assert User.objects.count() == 0 |
|
188 | ||
189 |
private_settings.MELLON_PROVISION = False |
|
190 |
user = adapter.lookup_user(idp, saml_attributes) |
|
191 |
assert user is None |
|
192 |
assert User.objects.count() == 0 |
|
167 |
- |