allow federating transient NameID using an attribute (fixes #10619)

This commit is contained in:
Benjamin Dauvergne 2016-04-11 19:20:05 +02:00
parent f70986795d
commit 49a5254363
4 changed files with 51 additions and 1 deletions

8
README
View File

@ -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
=====

View File

@ -107,7 +107,22 @@ class DefaultAdapter(object):
def lookup_user(self, idp, saml_attributes):
User = auth.get_user_model()
name_id = saml_attributes['name_id_content']
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:
return User.objects.get(saml_identifiers__name_id=name_id,

View File

@ -32,6 +32,7 @@ class AppSettings(object):
'OPENED_SESSION_COOKIE_DOMAIN': None,
'ORGANIZATION': None,
'CONTACT_PERSONS': [],
'TRANSIENT_FEDERATION_ATTRIBUTE': None,
}
@property

View File

@ -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