0001-authenticators-add-idp-configuration-info-for-saml-a.patch
src/authentic2/apps/authenticators/templates/authentic2/authenticators/authenticator_add_form.html | ||
---|---|---|
10 | 10 |
<form method="post" enctype="multipart/form-data"> |
11 | 11 |
{% csrf_token %} |
12 | 12 |
{{ form|with_template }} |
13 | ||
14 |
{% for authenticator in form.authenticators.values %} |
|
15 |
{% if authenticator.manager_idp_info_template_name %} |
|
16 |
<div class="infonotice {{ authenticator.type }} idp-info"> |
|
17 |
{% include authenticator.manager_idp_info_template_name %} |
|
18 |
</div> |
|
19 |
{% endif %} |
|
20 |
{% endfor %} |
|
21 | ||
13 | 22 |
<div class="buttons"> |
14 | 23 |
<button>{% trans "Add" %}</button> |
15 | 24 |
<a class="cancel" href="{% url 'a2-manager-authenticators' %}">{% trans 'Cancel' %}</a> |
... | ... | |
19 | 28 |
$('div#authenticator span.required').remove(); |
20 | 29 |
name_field = $('div#id_name_p'); |
21 | 30 |
$('select#id_authenticator').change(function() { |
31 |
$('div.idp-info').hide(); |
|
32 |
$('div.idp-info.' + this.value).show(); |
|
22 | 33 |
if(this.value == 'saml' || this.value == 'oidc') { |
23 | 34 |
name_field.show(); |
35 |
$('div#' + this.value + '-idp-info').show(); |
|
24 | 36 |
$('input#id_name').prop('required', true); |
25 | 37 |
} else { |
26 | 38 |
name_field.hide(); |
src/authentic2/apps/authenticators/templates/authentic2/authenticators/authenticator_detail.html | ||
---|---|---|
36 | 36 |
<div class="pk-tabs"> |
37 | 37 |
<div class="pk-tabs--tab-list" role="tablist"> |
38 | 38 |
<button aria-controls="panel-description" aria-selected="true" id="tab-description" role="tab" tabindex="0">{% trans "Description" %}</button> |
39 |
{% if object.manager_idp_info_template_name %} |
|
40 |
<button aria-controls="panel-config-info" aria-selected="true" id="tab-config-info" role="tab" tabindex="0">{% trans "Information for configuration" %}</button> |
|
41 |
{% endif %} |
|
39 | 42 |
{% for model in object.related_models %} |
40 | 43 |
<button aria-controls="panel-{{ model.model_name }}" aria-selected="false" id="tab-{{ model.model_name }}" role="tab" tabindex="-1">{{ model.verbose_name_plural }}</button> |
41 | 44 |
{% endfor %} |
... | ... | |
51 | 54 |
{% endfor %} |
52 | 55 |
</ul> |
53 | 56 |
</div> |
57 | ||
58 |
{% if object.manager_idp_info_template_name %} |
|
59 |
<div aria-labelledby="tab-config-info" id="panel-config-info" role="tabpanel" tabindex="0"> |
|
60 |
{% include object.manager_idp_info_template_name %} |
|
61 |
</div> |
|
62 |
{% endif %} |
|
63 | ||
54 | 64 |
{% for model, objects in object.related_models.items %} |
55 | 65 |
<div aria-labelledby="tab-{{ model.model_name }}" hidden="" id="panel-{{ model.model_name }}" role="tabpanel" tabindex="0"> |
56 | 66 |
<p>{{ model.description }}</p> |
src/authentic2/apps/authenticators/templatetags/authenticator_extras.py | ||
---|---|---|
1 |
from django import template |
|
2 | ||
3 |
from authentic2.utils.misc import make_url |
|
4 | ||
5 |
register = template.Library() |
|
6 | ||
7 | ||
8 |
@register.simple_tag(takes_context=True) |
|
9 |
def absolute_url(context, view_name, *args, **kwargs): |
|
10 |
return make_url(view_name, request=context['request'], absolute=True) |
src/authentic2_auth_oidc/models.py | ||
---|---|---|
123 | 123 | |
124 | 124 |
type = 'oidc' |
125 | 125 |
how = ['oidc'] |
126 |
manager_idp_info_template_name = 'authentic2_auth_oidc/idp_configuration_info.html' |
|
126 | 127 |
description_fields = ['show_condition', 'issuer', 'scopes', 'strategy', 'created', 'modified'] |
127 | 128 | |
128 | 129 |
class Meta: |
src/authentic2_auth_oidc/templates/authentic2_auth_oidc/idp_configuration_info.html | ||
---|---|---|
1 |
{% load i18n authenticator_extras %} |
|
2 | ||
3 |
<strong>{% trans "Configuration information for your identity provider" %}</strong> |
|
4 |
<ul> |
|
5 |
{% filter urlize %} |
|
6 |
<li>{% trans "Redirect URI (redirect_uri):" %} {% absolute_url 'oidc-login-callback' %}</li> |
|
7 |
<li>{% trans "Redirect URI after logout (post_logout_redirect_uri):" %} {% absolute_url 'auth_logout' %}</li> |
|
8 |
{% endfilter %} |
src/authentic2_auth_saml/models.py | ||
---|---|---|
177 | 177 |
type = 'saml' |
178 | 178 |
how = ['saml'] |
179 | 179 |
manager_view_template_name = 'authentic2_auth_saml/authenticator_detail.html' |
180 |
manager_idp_info_template_name = 'authentic2_auth_saml/idp_configuration_info.html' |
|
180 | 181 |
description_fields = ['show_condition', 'metadata_url', 'metadata', 'provision'] |
181 | 182 | |
182 | 183 |
class Meta: |
src/authentic2_auth_saml/templates/authentic2_auth_saml/idp_configuration_info.html | ||
---|---|---|
1 |
{% load i18n authenticator_extras %} |
|
2 | ||
3 |
<strong>{% trans "Configuration information for your identity provider" %}</strong> |
|
4 |
<ul> |
|
5 |
{% filter urlize %} |
|
6 |
<li>{% trans "Metadata URL:" %} {% absolute_url 'mellon_metadata' %}</li> |
|
7 |
{% endfilter %} |
|
8 |
{% if object and object.set_attribute_actions.all %} |
|
9 |
<li>{% trans "Expected attributes:" %} |
|
10 |
<ul> |
|
11 |
{% for attribute in object.set_attribute_actions.all %} |
|
12 |
<li>{{ attribute.saml_attribute }}{% if attribute.mandatory %} ({% trans "mandatory" %}){% endif %}</li> |
|
13 |
{% endfor %} |
|
14 |
</ul> |
|
15 |
</li> |
|
16 |
{% else %} |
|
17 |
<li>{% trans "Commonly expected attributes:" %} |
|
18 |
<ul> |
|
19 |
<li>{% trans "Email (email)" %}</li> |
|
20 |
<li>{% trans "First name (first_name)" %}</li> |
|
21 |
<li>{% trans "Last name (last_name)" %}</li> |
|
22 |
</ul> |
|
23 |
</li> |
|
24 |
{% endif %} |
|
25 |
<ul> |
tests/test_manager_authenticators.py | ||
---|---|---|
606 | 606 | |
607 | 607 |
resp = resp.click('Remove', href='samlattributelookup') |
608 | 608 |
resp = resp.form.submit().follow() |
609 |
assert 'mail' not in resp.text
|
|
609 |
assert 'Test (test)' not in resp.text
|
|
610 | 610 |
assert_event('authenticator.related_object.deletion', user=superuser, session=app.session) |
611 | 611 | |
612 | 612 | |
... | ... | |
718 | 718 | |
719 | 719 |
authenticator = SAMLAuthenticator.objects.filter(slug='test-2').get() |
720 | 720 |
assert authenticator.order == 43 |
721 | ||
722 | ||
723 |
def test_authenticators_configuration_info(app, superuser, ou1, ou2): |
|
724 |
resp = login(app, superuser, path='/manage/authenticators/') |
|
725 | ||
726 |
resp = resp.click('Add new authenticator') |
|
727 |
assert resp.text.count('infonotice') == 2 |
|
728 |
assert '<div class="infonotice saml idp-info">' in resp.text |
|
729 |
assert '<div class="infonotice oidc idp-info">' in resp.text |
|
730 |
assert resp.text.count('Configuration information for your identity provider') == 2 |
|
731 | ||
732 |
# saml |
|
733 |
assert ( |
|
734 |
'Metadata URL: <a href="http://testserver/accounts/saml/metadata/" rel="nofollow">' |
|
735 |
'http://testserver/accounts/saml/metadata/</a>' |
|
736 |
) in resp.text |
|
737 |
assert 'Commonly expected attributes:' in resp.text |
|
738 |
assert 'Email (email)' in resp.text |
|
739 | ||
740 |
authenticator = SAMLAuthenticator.objects.create(metadata='meta1.xml', slug='idp1') |
|
741 |
SetAttributeAction.objects.create( |
|
742 |
authenticator=authenticator, user_field='email', saml_attribute='mail', mandatory=True |
|
743 |
) |
|
744 |
SetAttributeAction.objects.create( |
|
745 |
authenticator=authenticator, user_field='first_name', saml_attribute='given_name' |
|
746 |
) |
|
747 | ||
748 |
resp = app.get('/manage/authenticators/%s/detail/' % authenticator.pk) |
|
749 |
assert 'Information for configuration' in resp.text |
|
750 |
assert 'Expected attributes' in resp.text |
|
751 |
assert 'mail (mandatory)' in resp.text |
|
752 |
assert 'given_name' in resp.text |
|
753 | ||
754 |
# oidc |
|
755 |
authenticator = OIDCProvider.objects.create(slug='idp2') |
|
756 |
for url in ('/manage/authenticators/add/', '/manage/authenticators/%s/detail/' % authenticator.pk): |
|
757 |
resp = app.get(url) |
|
758 |
assert ( |
|
759 |
'Redirect URI (redirect_uri): <a href="http://testserver/accounts/oidc/callback/" ' |
|
760 |
'rel="nofollow">http://testserver/accounts/oidc/callback/</a>' |
|
761 |
) in resp.text |
|
762 |
assert ( |
|
763 |
'Redirect URI after logout (post_logout_redirect_uri): <a href="http://testserver/logout/" ' |
|
764 |
'rel="nofollow">http://testserver/logout/</a>' |
|
765 |
) in resp.text |
|
721 |
- |