sources: prevent deletion of built-in source (#12914)
* web: sources: disable "delete" button for built-in source * poetry doesn't like that I use python 3.13 / implement check on backend too * fix ruff i think Signed-off-by: Dominic R <git@sdko.org> * nvm Signed-off-by: Dominic R <git@sdko.org> * reformat * check by managed attribute Signed-off-by: Jens Langhammer <jens@goauthentik.io> * like this? --------- Signed-off-by: Dominic R <git@sdko.org> Signed-off-by: Jens Langhammer <jens@goauthentik.io> Co-authored-by: Dominic R <git@sdko.org> Co-authored-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
@ -5,6 +5,7 @@ from collections.abc import Iterable
|
||||
from drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||
from rest_framework import mixins
|
||||
from rest_framework.decorators import action
|
||||
from rest_framework.exceptions import ValidationError
|
||||
from rest_framework.fields import CharField, ReadOnlyField, SerializerMethodField
|
||||
from rest_framework.parsers import MultiPartParser
|
||||
from rest_framework.request import Request
|
||||
@ -154,6 +155,17 @@ class SourceViewSet(
|
||||
matching_sources.append(source_settings.validated_data)
|
||||
return Response(matching_sources)
|
||||
|
||||
def destroy(self, request: Request, *args, **kwargs):
|
||||
"""Prevent deletion of built-in sources"""
|
||||
instance: Source = self.get_object()
|
||||
|
||||
if instance.managed == Source.MANAGED_INBUILT:
|
||||
raise ValidationError(
|
||||
{"detail": "Built-in sources cannot be deleted"}, code="protected"
|
||||
)
|
||||
|
||||
return super().destroy(request, *args, **kwargs)
|
||||
|
||||
|
||||
class UserSourceConnectionSerializer(SourceSerializer):
|
||||
"""User source connection"""
|
||||
|
||||
@ -32,5 +32,5 @@ class AuthentikCoreConfig(ManagedAppConfig):
|
||||
"name": "authentik Built-in",
|
||||
"slug": "authentik-built-in",
|
||||
},
|
||||
managed="goauthentik.io/sources/inbuilt",
|
||||
managed=Source.MANAGED_INBUILT,
|
||||
)
|
||||
|
||||
@ -678,6 +678,8 @@ class SourceGroupMatchingModes(models.TextChoices):
|
||||
class Source(ManagedModel, SerializerModel, PolicyBindingModel):
|
||||
"""Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
|
||||
|
||||
MANAGED_INBUILT = "goauthentik.io/sources/inbuilt"
|
||||
|
||||
name = models.TextField(help_text=_("Source's display Name."))
|
||||
slug = models.SlugField(help_text=_("Internal source name, used in URLs."), unique=True)
|
||||
|
||||
|
||||
@ -57,10 +57,13 @@ export class SourceListPage extends TablePage<Source> {
|
||||
}
|
||||
|
||||
renderToolbarSelected(): TemplateResult {
|
||||
const disabled = this.selectedElements.length < 1;
|
||||
const disabled =
|
||||
this.selectedElements.length < 1 ||
|
||||
this.selectedElements.some((item) => item.component === "");
|
||||
const nonBuiltInSources = this.selectedElements.filter((item) => item.component !== "");
|
||||
return html`<ak-forms-delete-bulk
|
||||
objectLabel=${msg("Source(s)")}
|
||||
.objects=${this.selectedElements}
|
||||
.objects=${nonBuiltInSources}
|
||||
.usedBy=${(item: Source) => {
|
||||
return new SourcesApi(DEFAULT_CONFIG).sourcesAllUsedByList({
|
||||
slug: item.slug,
|
||||
|
||||
Reference in New Issue
Block a user