diff --git a/authentik/core/api/sources.py b/authentik/core/api/sources.py index 73bf16b76..e4f8feb38 100644 --- a/authentik/core/api/sources.py +++ b/authentik/core/api/sources.py @@ -74,6 +74,8 @@ class SourceViewSet( for subclass in all_subclasses(self.queryset.model): subclass: Source component = "" + if len(subclass.__subclasses__()) > 0: + continue if subclass._meta.abstract: component = subclass.__bases__[0]().component else: diff --git a/authentik/sources/oauth/api/source.py b/authentik/sources/oauth/api/source.py index 2c37008f2..0beafb976 100644 --- a/authentik/sources/oauth/api/source.py +++ b/authentik/sources/oauth/api/source.py @@ -1,6 +1,7 @@ """OAuth Source Serializer""" from django.urls.base import reverse_lazy -from drf_spectacular.utils import extend_schema, extend_schema_field +from drf_spectacular.types import OpenApiTypes +from drf_spectacular.utils import OpenApiParameter, extend_schema, extend_schema_field from rest_framework.decorators import action from rest_framework.fields import BooleanField, CharField, SerializerMethodField from rest_framework.request import Request @@ -12,7 +13,7 @@ from authentik.core.api.sources import SourceSerializer from authentik.core.api.used_by import UsedByMixin from authentik.core.api.utils import PassiveSerializer from authentik.sources.oauth.models import OAuthSource -from authentik.sources.oauth.types.manager import MANAGER +from authentik.sources.oauth.types.manager import MANAGER, SourceType class SourceTypeSerializer(PassiveSerializer): @@ -100,11 +101,26 @@ class OAuthSourceViewSet(UsedByMixin, ModelViewSet): ] ordering = ["name"] - @extend_schema(responses={200: SourceTypeSerializer(many=True)}) + @extend_schema( + responses={200: SourceTypeSerializer(many=True)}, + parameters=[ + OpenApiParameter( + name="name", + location=OpenApiParameter.QUERY, + type=OpenApiTypes.STR, + ) + ], + ) @action(detail=False, pagination_class=None, filter_backends=[]) def source_types(self, request: Request) -> Response: - """Get all creatable source types""" + """Get all creatable source types. If ?name is set, only returns the type for . + If isn't found, returns the default type.""" data = [] - for source_type in MANAGER.get(): - data.append(SourceTypeSerializer(source_type).data) + if "name" in request.query_params: + source_type = MANAGER.find_type(request.query_params.get("name")) + if source_type.__class__ != SourceType: + data.append(SourceTypeSerializer(source_type).data) + else: + for source_type in MANAGER.get(): + data.append(SourceTypeSerializer(source_type).data) return Response(data) diff --git a/authentik/sources/oauth/migrations/0005_update_provider_type_names.py b/authentik/sources/oauth/migrations/0005_update_provider_type_names.py new file mode 100644 index 000000000..a699effa7 --- /dev/null +++ b/authentik/sources/oauth/migrations/0005_update_provider_type_names.py @@ -0,0 +1,33 @@ +# Generated by Django 3.2.5 on 2021-08-21 13:41 +from django.apps.registry import Apps +from django.db import migrations +from django.db.backends.base.schema import BaseDatabaseSchemaEditor + + +def update_provider_types(apps: Apps, schema_editor: BaseDatabaseSchemaEditor): + OAuthSource = apps.get_model("authentik_sources_oauth", "oauthsource") + + db_alias = schema_editor.connection.alias + + for source in OAuthSource.objects.using(db_alias).all(): + changed = False + if source.provider_type == "azure-ad": + source.provider_type = "azuread" + changed = True + if source.provider_type == "openid-connect": + source.provider_type = "openidconnect" + changed = True + + if changed: + source.save() + + +class Migration(migrations.Migration): + + dependencies = [ + ("authentik_sources_oauth", "0004_auto_20210417_1900"), + ] + + operations = [ + migrations.RunPython(update_provider_types), + ] diff --git a/authentik/sources/oauth/types/azure_ad.py b/authentik/sources/oauth/types/azure_ad.py index 2893aabdf..329f1dd79 100644 --- a/authentik/sources/oauth/types/azure_ad.py +++ b/authentik/sources/oauth/types/azure_ad.py @@ -75,7 +75,7 @@ class AzureADType(SourceType): callback_view = AzureADOAuthCallback redirect_view = AzureADOAuthRedirect name = "Azure AD" - slug = "azure-ad" + slug = "azuread" urls_customizable = True diff --git a/authentik/sources/oauth/types/oidc.py b/authentik/sources/oauth/types/oidc.py index 01fae8dcd..309dbeb95 100644 --- a/authentik/sources/oauth/types/oidc.py +++ b/authentik/sources/oauth/types/oidc.py @@ -40,6 +40,6 @@ class OpenIDConnectType(SourceType): callback_view = OpenIDConnectOAuth2Callback redirect_view = OpenIDConnectOAuthRedirect name = "OpenID Connect" - slug = "openid-connect" + slug = "openidconnect" urls_customizable = True diff --git a/schema.yml b/schema.yml index 026aea14b..240308250 100644 --- a/schema.yml +++ b/schema.yml @@ -13178,7 +13178,14 @@ paths: /api/v2beta/sources/oauth/source_types/: get: operationId: sources_oauth_source_types_list - description: Get all creatable source types + description: |- + Get all creatable source types. If ?name is set, only returns the type for . + If isn't found, returns the default type. + parameters: + - in: query + name: name + schema: + type: string tags: - sources security: diff --git a/web/src/pages/sources/oauth/OAuthSourceForm.ts b/web/src/pages/sources/oauth/OAuthSourceForm.ts index 0e4a9dc07..367ffa87b 100644 --- a/web/src/pages/sources/oauth/OAuthSourceForm.ts +++ b/web/src/pages/sources/oauth/OAuthSourceForm.ts @@ -5,6 +5,7 @@ import { UserMatchingModeEnum, OAuthSourceRequest, FlowsInstancesListDesignationEnum, + SourceType, } from "authentik-api"; import { t } from "@lingui/macro"; import { customElement, property } from "lit-element"; @@ -25,19 +26,28 @@ export class OAuthSourceForm extends ModelForm { slug: pk, }) .then((source) => { - this.showUrlOptions = first(source.type?.urlsCustomizable, false); + this.providerType = source.type; return source; }); } + _modelName?: string; + @property() - modelName?: string; + set modelName(v: string | undefined) { + this._modelName = v; + new SourcesApi(DEFAULT_CONFIG).sourcesOauthSourceTypesList({ + name: v?.replace("oauthsource", ""), + }).then((type) => { + this.providerType = type[0]; + }); + } + get modelName(): string|undefined { + return this._modelName; + } - @property({ type: Boolean }) - showUrlOptions = false; - - @property({ type: Boolean }) - showRequestTokenURL = false; + @property({ attribute: false }) + providerType?: SourceType; getSuccessMessage(): string { if (this.instance) { @@ -61,7 +71,7 @@ export class OAuthSourceForm extends ModelForm { }; renderUrlOptions(): TemplateResult { - if (!this.showUrlOptions) { + if (!this.providerType?.urlsCustomizable) { return html``; } return html` @@ -74,7 +84,7 @@ export class OAuthSourceForm extends ModelForm { > @@ -89,7 +99,7 @@ export class OAuthSourceForm extends ModelForm { > @@ -104,7 +114,7 @@ export class OAuthSourceForm extends ModelForm { > @@ -112,7 +122,7 @@ export class OAuthSourceForm extends ModelForm { ${t`URL used by authentik to get user information.`}

- ${this.showRequestTokenURL + ${this.providerType.requestTokenUrl ? html` { > - - -
${this.renderUrlOptions()}