0002-auth_saml-display-xml-metadata-in-separate-view-7049.patch
src/authentic2/apps/authenticators/models.py | ||
---|---|---|
24 | 24 |
from django.db.models import Max |
25 | 25 |
from django.shortcuts import render, reverse |
26 | 26 |
from django.utils.formats import date_format |
27 |
from django.utils.html import format_html |
|
27 | 28 |
from django.utils.text import capfirst |
28 | 29 |
from django.utils.translation import gettext_lazy as _ |
29 | 30 |
from django.utils.translation import pgettext_lazy |
... | ... | |
126 | 127 |
if isinstance(value, datetime.datetime): |
127 | 128 |
value = date_format(value, 'DATETIME_FORMAT') |
128 | 129 | |
129 |
yield _('%(field)s: %(value)s') % { |
|
130 |
'field': capfirst(self._meta.get_field(field).verbose_name), |
|
131 |
'value': value, |
|
132 |
} |
|
130 |
yield format_html( |
|
131 |
_('{field}: {value}'), |
|
132 |
field=capfirst(self._meta.get_field(field).verbose_name), |
|
133 |
value=value, |
|
134 |
) |
|
133 | 135 | |
134 | 136 |
def shown(self, ctx=()): |
135 | 137 |
if not self.show_condition: |
src/authentic2_auth_saml/models.py | ||
---|---|---|
21 | 21 |
from django.contrib.postgres.fields import JSONField |
22 | 22 |
from django.core.exceptions import ValidationError |
23 | 23 |
from django.db import models |
24 |
from django.urls import reverse |
|
25 |
from django.utils.safestring import mark_safe |
|
24 | 26 |
from django.utils.translation import gettext_lazy as _ |
25 | 27 | |
26 | 28 |
from authentic2.apps.authenticators.models import ( |
... | ... | |
221 | 223 |
getattr(settings, 'MELLON_PRIVATE_KEY', '') and getattr(settings, 'MELLON_PUBLIC_KEYS', '') |
222 | 224 |
) |
223 | 225 | |
226 |
def get_metadata_display(self): |
|
227 |
if not self.metadata: |
|
228 |
return '' |
|
229 | ||
230 |
url = reverse('a2-manager-saml-authenticator-metadata', kwargs={'pk': self.pk}) |
|
231 |
return mark_safe('<a href=%s>%s</a>' % (url, _('View metadata'))) |
|
232 | ||
224 | 233 |
def login(self, request, *args, **kwargs): |
225 | 234 |
from . import views |
226 | 235 |
src/authentic2_auth_saml/urls.py | ||
---|---|---|
14 | 14 |
# You should have received a copy of the GNU Affero General Public License |
15 | 15 |
# along with this program. If not, see <http://www.gnu.org/licenses/>. |
16 | 16 | |
17 |
from django.urls import include, re_path |
|
17 |
from django.urls import include, path, re_path |
|
18 | ||
19 |
from . import views |
|
18 | 20 | |
19 | 21 |
urlpatterns = [ |
20 | 22 |
re_path( |
21 | 23 |
r'^accounts/saml/', |
22 | 24 |
include('mellon.urls'), |
23 | 25 |
kwargs={'template_base': 'authentic2/base.html', 'logout_next_url': '/logout/'}, |
24 |
) |
|
26 |
), |
|
27 |
path( |
|
28 |
'authenticators/<int:pk>/metadata.xml', |
|
29 |
views.authenticator_metadata, |
|
30 |
name='a2-manager-saml-authenticator-metadata', |
|
31 |
), |
|
25 | 32 |
] |
src/authentic2_auth_saml/views.py | ||
---|---|---|
1 |
from django.http import Http404, HttpResponse |
|
1 | 2 |
from django.shortcuts import render |
2 | 3 |
from django.template.loader import render_to_string |
4 |
from django.views.generic import DetailView |
|
3 | 5 |
from mellon.utils import get_idp |
4 | 6 | |
5 | 7 |
from authentic2.utils.misc import redirect_to_login |
6 | 8 | |
9 |
from .models import SAMLAuthenticator |
|
10 | ||
7 | 11 | |
8 | 12 |
def login(request, authenticator, *args, **kwargs): |
9 | 13 |
context = kwargs.pop('context', {}).copy() |
... | ... | |
34 | 38 |
user_saml_identifier.idp = get_idp(user_saml_identifier.issuer.entity_id) |
35 | 39 |
context['user_saml_identifiers'] = user_saml_identifiers |
36 | 40 |
return render_to_string('authentic2_auth_saml/profile.html', context, request=request) |
41 | ||
42 | ||
43 |
class SAMLAuthenticatorMetadataView(DetailView): |
|
44 |
model = SAMLAuthenticator |
|
45 | ||
46 |
def get(self, *args, **kwargs): |
|
47 |
authenticator = self.get_object() |
|
48 |
if not authenticator.metadata: |
|
49 |
raise Http404() |
|
50 | ||
51 |
return HttpResponse(authenticator.metadata, content_type='text/xml') |
|
52 | ||
53 | ||
54 |
authenticator_metadata = SAMLAuthenticatorMetadataView.as_view() |
tests/test_manager_authenticators.py | ||
---|---|---|
505 | 505 |
resp.form.submit(status=302) |
506 | 506 | |
507 | 507 | |
508 |
def test_authenticators_saml_view_metadata(app, superuser): |
|
509 |
authenticator = SAMLAuthenticator.objects.create(slug='idp1') |
|
510 | ||
511 |
resp = login(app, superuser) |
|
512 |
resp = app.get('/manage/authenticators/%s/detail/' % authenticator.pk) |
|
513 | ||
514 |
assert 'Metadata (XML):' not in resp.text |
|
515 |
assert app.get('/manage/authenticators/%s/metadata.xml' % authenticator.pk, status=404) |
|
516 | ||
517 |
authenticator.metadata = '<a><b></b></a>' |
|
518 |
authenticator.save() |
|
519 | ||
520 |
resp = app.get('/manage/authenticators/%s/detail/' % authenticator.pk) |
|
521 |
assert 'Metadata (XML):' in resp.text |
|
522 | ||
523 |
resp = resp.click('View metadata') |
|
524 |
assert resp.text == '<a><b></b></a>' |
|
525 | ||
526 | ||
508 | 527 |
def test_authenticators_saml_missing_signing_key(app, superuser, settings): |
509 | 528 |
authenticator = SAMLAuthenticator.objects.create(slug='idp1') |
510 | 529 | |
511 |
- |