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 drf_spectacular.utils import OpenApiResponse, extend_schema
|
||||||
from rest_framework import mixins
|
from rest_framework import mixins
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
|
from rest_framework.exceptions import ValidationError
|
||||||
from rest_framework.fields import CharField, ReadOnlyField, SerializerMethodField
|
from rest_framework.fields import CharField, ReadOnlyField, SerializerMethodField
|
||||||
from rest_framework.parsers import MultiPartParser
|
from rest_framework.parsers import MultiPartParser
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
@ -154,6 +155,17 @@ class SourceViewSet(
|
|||||||
matching_sources.append(source_settings.validated_data)
|
matching_sources.append(source_settings.validated_data)
|
||||||
return Response(matching_sources)
|
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):
|
class UserSourceConnectionSerializer(SourceSerializer):
|
||||||
"""User source connection"""
|
"""User source connection"""
|
||||||
|
|||||||
@ -32,5 +32,5 @@ class AuthentikCoreConfig(ManagedAppConfig):
|
|||||||
"name": "authentik Built-in",
|
"name": "authentik Built-in",
|
||||||
"slug": "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):
|
class Source(ManagedModel, SerializerModel, PolicyBindingModel):
|
||||||
"""Base Authentication source, i.e. an OAuth Provider, SAML Remote or LDAP Server"""
|
"""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."))
|
name = models.TextField(help_text=_("Source's display Name."))
|
||||||
slug = models.SlugField(help_text=_("Internal source name, used in URLs."), unique=True)
|
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 {
|
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
|
return html`<ak-forms-delete-bulk
|
||||||
objectLabel=${msg("Source(s)")}
|
objectLabel=${msg("Source(s)")}
|
||||||
.objects=${this.selectedElements}
|
.objects=${nonBuiltInSources}
|
||||||
.usedBy=${(item: Source) => {
|
.usedBy=${(item: Source) => {
|
||||||
return new SourcesApi(DEFAULT_CONFIG).sourcesAllUsedByList({
|
return new SourcesApi(DEFAULT_CONFIG).sourcesAllUsedByList({
|
||||||
slug: item.slug,
|
slug: item.slug,
|
||||||
|
|||||||
Reference in New Issue
Block a user