allow federating transient NameID using an attribute (fixes #10619)
This commit is contained in:
parent
f70986795d
commit
49a5254363
8
README
8
README
|
@ -247,6 +247,14 @@ MELLON_VERIFY_SSL_CERTIFICATE
|
|||
Verify SSL certificate when doing HTTP requests, used when resolving artifacts.
|
||||
Default is True.
|
||||
|
||||
MELLON_TRANSIENT_FEDERATION_ATTRIBUTE
|
||||
-------------------------------------
|
||||
|
||||
Name of an attribute to use in replacement of the NameID content when the NameID
|
||||
format is transient. Without it no login using a transient NameID can occur with
|
||||
the default adapter.
|
||||
Default is None.
|
||||
|
||||
Tests
|
||||
=====
|
||||
|
||||
|
|
|
@ -107,6 +107,21 @@ class DefaultAdapter(object):
|
|||
|
||||
def lookup_user(self, idp, saml_attributes):
|
||||
User = auth.get_user_model()
|
||||
transient_federation_attribute = utils.get_setting(idp, 'TRANSIENT_FEDERATION_ATTRIBUTE')
|
||||
if saml_attributes['name_id_format'] == lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT:
|
||||
if (transient_federation_attribute
|
||||
and saml_attributes.get(transient_federation_attribute)):
|
||||
name_id = saml_attributes[transient_federation_attribute]
|
||||
if not isinstance(name_id, basestring):
|
||||
if len(name_id) == 1:
|
||||
name_id = name_id[0]
|
||||
else:
|
||||
self.logger.warning('more than one value for attribute %r, cannot federate',
|
||||
transient_federation_attribute)
|
||||
return None
|
||||
else:
|
||||
return None
|
||||
else:
|
||||
name_id = saml_attributes['name_id_content']
|
||||
issuer = saml_attributes['issuer']
|
||||
try:
|
||||
|
|
|
@ -32,6 +32,7 @@ class AppSettings(object):
|
|||
'OPENED_SESSION_COOKIE_DOMAIN': None,
|
||||
'ORGANIZATION': None,
|
||||
'CONTACT_PERSONS': [],
|
||||
'TRANSIENT_FEDERATION_ATTRIBUTE': None,
|
||||
}
|
||||
|
||||
@property
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import threading
|
||||
import pytest
|
||||
import re
|
||||
import lasso
|
||||
|
||||
from django.contrib import auth
|
||||
from django.db import connection
|
||||
|
@ -14,6 +15,7 @@ idp = {
|
|||
'METADATA': file('tests/metadata.xml').read(),
|
||||
}
|
||||
saml_attributes = {
|
||||
'name_id_format': lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT,
|
||||
'name_id_content': 'x' * 32,
|
||||
'issuer': 'https://cresson.entrouvert.org/idp/saml2/metadata',
|
||||
'username': ['foobar'],
|
||||
|
@ -164,3 +166,27 @@ def test_provision_long_attribute(settings, django_user_model, caplog):
|
|||
assert 'to value %r ' % (u'y' * 30) in caplog.text()
|
||||
assert 'set field last_name' in caplog.text()
|
||||
assert 'set field email' in caplog.text()
|
||||
|
||||
|
||||
def test_lookup_user_transient_with_email(private_settings):
|
||||
private_settings.MELLON_TRANSIENT_FEDERATION_ATTRIBUTE = 'email'
|
||||
User = auth.get_user_model()
|
||||
adapter = DefaultAdapter()
|
||||
saml_attributes2 = saml_attributes.copy()
|
||||
saml_attributes2['name_id_format'] = lasso.SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT
|
||||
assert User.objects.count() == 0
|
||||
user = adapter.lookup_user(idp, saml_attributes2)
|
||||
assert user is not None
|
||||
assert user.saml_identifiers.count() == 1
|
||||
assert user.saml_identifiers.first().name_id == saml_attributes2['email'][0]
|
||||
|
||||
user2 = adapter.lookup_user(idp, saml_attributes2)
|
||||
assert user.id == user2.id
|
||||
|
||||
User.objects.all().delete()
|
||||
assert User.objects.count() == 0
|
||||
|
||||
private_settings.MELLON_PROVISION = False
|
||||
user = adapter.lookup_user(idp, saml_attributes)
|
||||
assert user is None
|
||||
assert User.objects.count() == 0
|
||||
|
|
Loading…
Reference in New Issue