82 lines
3.2 KiB
Python
82 lines
3.2 KiB
Python
"""authentik SAML IDP Views"""
|
|
|
|
from django.contrib import messages
|
|
from django.contrib.auth.mixins import LoginRequiredMixin
|
|
from django.http import HttpRequest, HttpResponse
|
|
from django.shortcuts import get_object_or_404
|
|
from django.utils.translation import gettext_lazy as _
|
|
from django.views import View
|
|
from django.views.generic.edit import FormView
|
|
from structlog.stdlib import get_logger
|
|
|
|
from authentik.core.models import Application, Provider
|
|
from authentik.lib.views import bad_request_message
|
|
from authentik.providers.saml.forms import SAMLProviderImportForm
|
|
from authentik.providers.saml.models import SAMLProvider
|
|
from authentik.providers.saml.processors.metadata import MetadataProcessor
|
|
from authentik.providers.saml.processors.metadata_parser import (
|
|
ServiceProviderMetadataParser,
|
|
)
|
|
|
|
LOGGER = get_logger()
|
|
|
|
|
|
class DescriptorDownloadView(View):
|
|
"""Replies with the XML Metadata IDSSODescriptor."""
|
|
|
|
@staticmethod
|
|
def get_metadata(request: HttpRequest, provider: SAMLProvider) -> str:
|
|
"""Return rendered XML Metadata"""
|
|
return MetadataProcessor(provider, request).build_entity_descriptor()
|
|
|
|
def get(self, request: HttpRequest, application_slug: str) -> HttpResponse:
|
|
"""Replies with the XML Metadata IDSSODescriptor."""
|
|
application = get_object_or_404(Application, slug=application_slug)
|
|
provider: SAMLProvider = get_object_or_404(
|
|
SAMLProvider, pk=application.provider_id
|
|
)
|
|
try:
|
|
metadata = DescriptorDownloadView.get_metadata(request, provider)
|
|
except Provider.application.RelatedObjectDoesNotExist: # pylint: disable=no-member
|
|
return bad_request_message(
|
|
request, "Provider is not assigned to an application."
|
|
)
|
|
else:
|
|
response = HttpResponse(metadata, content_type="application/xml")
|
|
response[
|
|
"Content-Disposition"
|
|
] = f'attachment; filename="{provider.name}_authentik_meta.xml"'
|
|
return response
|
|
|
|
|
|
class MetadataImportView(LoginRequiredMixin, FormView):
|
|
"""Import Metadata from XML, and create provider"""
|
|
|
|
form_class = SAMLProviderImportForm
|
|
template_name = "providers/saml/import.html"
|
|
success_url = "/"
|
|
|
|
def dispatch(self, request, *args, **kwargs):
|
|
if not request.user.is_superuser:
|
|
return self.handle_no_permission()
|
|
return super().dispatch(request, *args, **kwargs)
|
|
|
|
def form_valid(self, form: SAMLProviderImportForm) -> HttpResponse:
|
|
try:
|
|
metadata = ServiceProviderMetadataParser().parse(
|
|
form.cleaned_data["metadata"].read().decode()
|
|
)
|
|
metadata.to_provider(
|
|
form.cleaned_data["provider_name"],
|
|
form.cleaned_data["authorization_flow"],
|
|
)
|
|
messages.success(self.request, _("Successfully created Provider"))
|
|
except ValueError as exc:
|
|
LOGGER.warning(str(exc))
|
|
messages.error(
|
|
self.request,
|
|
_("Failed to import Metadata: %(message)s" % {"message": str(exc)}),
|
|
)
|
|
return super().form_invalid(form)
|
|
return super().form_valid(form)
|