authentic/tests/idp_oidc/test_manager.py

230 lines
8.6 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 pytest
from authentic2_idp_oidc import app_settings as oidc_app_settings
from authentic2_idp_oidc.models import OIDCClaim, OIDCClient
from tests.utils import login
@pytest.fixture
def app(app, admin):
login(app, admin)
return app
@pytest.fixture
def superuser_app(app, superuser):
login(app, superuser)
return app
def test_add_oidc_service_superuser(superuser_app):
resp = superuser_app.get('/manage/services/')
assert 'Add OIDC service' in resp.text
assert OIDCClient.objects.count() == 0
assert OIDCClaim.objects.count() == 0
resp = resp.click('Add OIDC service')
form = resp.form
form['name'] = 'Test'
form['redirect_uris'] = 'http://example.com'
form['has_api_access'] = True
form['activate_user_profiles'] = True
resp = form.submit()
assert OIDCClient.objects.count() == 1
assert OIDCClaim.objects.count() == len(oidc_app_settings.DEFAULT_MAPPINGS)
oidc_client = OIDCClient.objects.get()
assert oidc_client.has_api_access is True
assert oidc_client.activate_user_profiles is True
assert resp.location == f'/manage/services/{oidc_client.pk}/'
resp = resp.follow()
assert 'Settings' in resp.text
assert 'Delete' in resp.text
def test_add_oidc_service_admin(app):
resp = app.get('/manage/services/')
assert 'Add OIDC service' in resp.text
assert OIDCClient.objects.count() == 0
assert OIDCClaim.objects.count() == 0
resp = resp.click('Add OIDC service')
form = resp.form
form['name'] = 'Test'
form['redirect_uris'] = 'http://example.com'
assert 'has_api_access' not in form.fields
assert 'activate_user_profiles' not in form.fields
resp = form.submit()
assert OIDCClient.objects.count() == 1
assert OIDCClaim.objects.count() == len(oidc_app_settings.DEFAULT_MAPPINGS)
oidc_client = OIDCClient.objects.get()
assert oidc_client.has_api_access is False
assert oidc_client.activate_user_profiles is False
assert resp.location == f'/manage/services/{oidc_client.pk}/'
resp = resp.follow()
assert 'Settings' in resp.text
assert 'Delete' in resp.text
class TestEdit:
@pytest.fixture(autouse=True)
def oidc_client(self, db):
return OIDCClient.objects.create(name='Test', slug='test', redirect_uris='http://example.com')
def test_edit(self, app, oidc_client):
resp = app.get('/manage/services/')
resp = resp.click('Test')
resp = resp.click('Settings')
assert resp.pyquery('.service-field--value')
for value in resp.pyquery('.service-field--value'):
assert '\n' not in value.text
assert not value.text.endswith(' ')
resp = resp.click('Edit')
# check breadcrumbs
crumbs = [crumb for crumb in resp.pyquery('#breadcrumb')[0]]
assert len(crumbs) == 6
assert crumbs[0].text == 'Homepage'
assert crumbs[0].items() == [('href', '/')]
assert crumbs[1].text == 'Administration'
assert crumbs[1].items() == [('href', '/manage/')]
assert crumbs[2].text == 'Services'
assert crumbs[2].items() == [('href', '/manage/services/')]
assert crumbs[3].text == 'Test'
assert crumbs[3].items() == [('href', f'/manage/services/{oidc_client.id}/')]
assert crumbs[4].text == 'Configuration'
assert crumbs[4].items() == [('href', f'/manage/services/{oidc_client.id}/settings/')]
assert not crumbs[5].text
assert crumbs[5].items() == [('href', '#')]
form = resp.form
form['name'] = 'New Test'
form['colour'] = '#ff00ff'
resp = form.submit()
assert resp.location == '..'
resp = resp.follow()
assert 'New Test' in resp.text
assert '#ff00ff' in resp.text
def test_delete(self, app):
resp = app.get('/manage/services/')
resp = resp.click('Test')
resp = resp.click('Delete')
resp = resp.form.submit().follow()
assert OIDCClient.objects.count() == 0
def test_add_claim(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
resp = resp.click('Add claim')
form = resp.form
form['name'] = 'claim'
form['value'] = 'value'
form['scopes'] = 'profile'
resp = form.submit()
assert resp.location == f'/manage/services/{oidc_client.pk}/'
assert OIDCClaim.objects.filter(
client=oidc_client, name='claim', value='value', scopes='profile'
).exists()
def test_add_claim_mandatory_field_name(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
resp = resp.click('Add claim')
form = resp.form
form['value'] = 'value'
form['scopes'] = 'profile'
resp = form.submit()
assert len(resp.pyquery('.error')) == 1
assert 'This field is required.' in resp.pyquery('.error').text()
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
def test_add_claim_mandatory_field_value(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
resp = resp.click('Add claim')
form = resp.form
form['name'] = 'claim'
form['scopes'] = 'profile'
resp = form.submit()
assert len(resp.pyquery('.error')) == 1
assert 'This field is required.' in resp.pyquery('.error').text()
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
def test_add_claim_mandatory_field_scope(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
resp = resp.click('Add claim')
form = resp.form
form['name'] = 'claim'
form['value'] = 'value'
resp = form.submit()
assert len(resp.pyquery('.error')) == 1
assert 'This field is required.' in resp.pyquery('.error').text()
assert not OIDCClaim.objects.filter(client=oidc_client, name='claim', value='value', scopes='profile')
def test_add_claim_redundancy_error(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
OIDCClaim.objects.create(
client=oidc_client, name='yet_another_claim', value='value', scopes='profile'
)
resp = resp.click('Add claim')
form = resp.form
form['name'] = 'yet_another_claim'
form['value'] = 'value'
form['scopes'] = 'profile'
resp = form.submit()
assert len(resp.pyquery('.error')) == 1
assert 'claim name is already defined for this client' in resp.pyquery('.error').text()
assert (
OIDCClaim.objects.filter(
client=oidc_client, name='yet_another_claim', value='value', scopes='profile'
).count()
== 1
)
class TestEditClaim:
@pytest.fixture(autouse=True)
def claim(self, oidc_client):
return OIDCClaim.objects.create(client=oidc_client, name='claim', value='value', scopes='profile')
def test_edit_claim(self, app, oidc_client, claim):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
assert 'claim' in resp.text
resp = resp.click('Edit', index=1)
form = resp.form
form['value'] = 'new value'
resp = form.submit()
assert resp.location == f'/manage/services/{oidc_client.pk}/'
claim.refresh_from_db()
assert claim.value == 'new value'
def test_delete_claim(self, app, oidc_client):
resp = app.get(f'/manage/services/{oidc_client.pk}/settings/')
assert 'claim' in resp.text
resp = resp.click('Delete')
form = resp.form
resp = form.submit()
assert resp.location == f'/manage/services/{oidc_client.pk}/'
assert OIDCClaim.objects.filter(client=oidc_client).count() == 0