authentic/tests/test_auth_saml.py

127 lines
4.2 KiB
Python

# authentic2 - versatile identity manager
# Copyright (C) 2010-2019 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published
# by the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import pytest
import lasso
from django.contrib.auth import get_user_model
from authentic2.models import Attribute
def test_providers_on_login_page(db, app, settings):
settings.A2_AUTH_SAML_ENABLE = True
PROVIDERS = [
{'METADATA': 'meta1.xml', 'ENTITY_ID': 'idp1'},
]
settings.MELLON_IDENTITY_PROVIDERS = PROVIDERS
response = app.get('/login/')
assert response.pyquery('button[name="login-saml-0"]')
assert not response.pyquery('button[name="login-saml-1"]')
PROVIDERS.append({'METADATA': 'meta1.xml', 'ENTITY_ID': 'idp1'})
response = app.get('/login/')
# two frontends should be present on login page
assert response.pyquery('button[name="login-saml-0"]')
assert response.pyquery('button[name="login-saml-1"]')
def test_provision_attributes(db, caplog, simple_role):
from authentic2_auth_saml.adapters import AuthenticAdapter
adapter = AuthenticAdapter()
User = get_user_model()
Attribute.objects.create(kind='title', name='title', label='title')
user = User.objects.create()
idp = {
'A2_ATTRIBUTE_MAPPING': [
{
'attribute': 'email',
'saml_attribute': 'mail',
'mandatory': True,
},
{
'action': 'rename',
'from': 'http://fucking/attribute/givenName',
'to': 'first_name'
},
{
'attribute': 'title',
'saml_attribute': 'title',
},
{
'attribute': 'first_name',
'saml_attribute': 'first_name',
},
{
'action': 'toggle-role',
'role': {
'name': simple_role.name,
'ou': {
'name': simple_role.ou.name,
},
},
'condition': "roles == 'A'",
}
]
}
saml_attributes = {
u'issuer': 'https://idp.com/',
u'name_id_content': 'xxx',
u'name_id_format': lasso.SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT,
u'mail': [u'john.doe@example.com'],
u'title': [u'Mr.'],
u'http://fucking/attribute/givenName': ['John'],
}
user = adapter.lookup_user(idp, saml_attributes)
user.refresh_from_db()
assert user.email == 'john.doe@example.com'
assert user.attributes.title == 'Mr.'
assert user.first_name == 'John'
assert simple_role not in user.roles.all()
user.delete()
# if a toggle-role is mandatory, failure to evaluate condition block user creation
assert idp['A2_ATTRIBUTE_MAPPING'][-1]['action'] == 'toggle-role'
idp['A2_ATTRIBUTE_MAPPING'][-1]['mandatory'] = True
assert adapter.lookup_user(idp, saml_attributes) is None
saml_attributes['roles'] = ['A']
user = adapter.lookup_user(idp, saml_attributes)
user.refresh_from_db()
assert simple_role in user.roles.all()
user.delete()
idp['A2_ATTRIBUTE_MAPPING'][-1]['condition'] = "'A' in roles__list"
user = adapter.lookup_user(idp, saml_attributes)
user.refresh_from_db()
assert simple_role in user.roles.all()
saml_attributes['roles'] = []
adapter.provision(user, idp, saml_attributes)
# condition failed, so role should be removed
assert simple_role not in user.roles.all()
user.delete()
# on missing mandatory attribute, no user is created
del saml_attributes['mail']
assert adapter.lookup_user(idp, saml_attributes) is None