Projet

Général

Profil

0001-authenticators-add-idp-configuration-info-for-saml-a.patch

Valentin Deniaud, 21 novembre 2022 18:15

Télécharger (11 ko)

Voir les différences:

Subject: [PATCH] authenticators: add idp configuration info for saml and oidc
 (#67987)

 .../authenticator_add_form.html               | 12 +++++
 .../authenticators/authenticator_detail.html  | 10 ++++
 .../authenticators/templatetags/__init__.py   |  0
 .../templatetags/authenticator_extras.py      | 10 ++++
 src/authentic2_auth_oidc/models.py            |  1 +
 .../idp_configuration_info.html               |  8 ++++
 src/authentic2_auth_saml/models.py            |  1 +
 .../idp_configuration_info.html               | 25 ++++++++++
 tests/test_manager_authenticators.py          | 47 ++++++++++++++++++-
 9 files changed, 113 insertions(+), 1 deletion(-)
 create mode 100644 src/authentic2/apps/authenticators/templatetags/__init__.py
 create mode 100644 src/authentic2/apps/authenticators/templatetags/authenticator_extras.py
 create mode 100644 src/authentic2_auth_oidc/templates/authentic2_auth_oidc/idp_configuration_info.html
 create mode 100644 src/authentic2_auth_saml/templates/authentic2_auth_saml/idp_configuration_info.html
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
-