core: add providers/types endpoint
This commit is contained in:
parent
e6712a50d2
commit
2b7a22a29a
|
@ -1,10 +1,21 @@
|
||||||
"""Provider API Views"""
|
"""Provider API Views"""
|
||||||
|
from django.shortcuts import reverse
|
||||||
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
from drf_yasg2.utils import swagger_auto_schema
|
||||||
|
from rest_framework.decorators import action
|
||||||
from rest_framework.fields import ReadOnlyField
|
from rest_framework.fields import ReadOnlyField
|
||||||
from rest_framework.serializers import ModelSerializer, SerializerMethodField
|
from rest_framework.request import Request
|
||||||
|
from rest_framework.response import Response
|
||||||
|
from rest_framework.serializers import (
|
||||||
|
ModelSerializer,
|
||||||
|
SerializerMethodField,
|
||||||
|
)
|
||||||
from rest_framework.viewsets import ModelViewSet
|
from rest_framework.viewsets import ModelViewSet
|
||||||
|
|
||||||
from authentik.core.api.utils import MetaNameSerializer
|
from authentik.core.api.utils import MetaNameSerializer, TypeCreateSerializer
|
||||||
from authentik.core.models import Provider
|
from authentik.core.models import Provider
|
||||||
|
from authentik.lib.templatetags.authentik_utils import verbose_name
|
||||||
|
from authentik.lib.utils.reflection import all_subclasses
|
||||||
|
|
||||||
|
|
||||||
class ProviderSerializer(ModelSerializer, MetaNameSerializer):
|
class ProviderSerializer(ModelSerializer, MetaNameSerializer):
|
||||||
|
@ -51,3 +62,27 @@ class ProviderViewSet(ModelViewSet):
|
||||||
|
|
||||||
def get_queryset(self):
|
def get_queryset(self):
|
||||||
return Provider.objects.select_subclasses()
|
return Provider.objects.select_subclasses()
|
||||||
|
|
||||||
|
@swagger_auto_schema(responses={200: TypeCreateSerializer(many=True)})
|
||||||
|
@action(detail=False)
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def types(self, request: Request) -> Response:
|
||||||
|
"""Get all creatable provider types"""
|
||||||
|
data = []
|
||||||
|
for subclass in all_subclasses(self.queryset.model):
|
||||||
|
data.append(
|
||||||
|
{
|
||||||
|
"name": verbose_name(subclass),
|
||||||
|
"description": subclass.__doc__,
|
||||||
|
"link": reverse("authentik_admin:provider-create")
|
||||||
|
+ f"?type={subclass.__name__}",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
data.append(
|
||||||
|
{
|
||||||
|
"name": _("SAML Provider from Metadata"),
|
||||||
|
"description": _("Create a SAML Provider by importing its Metadata."),
|
||||||
|
"link": reverse("authentik_admin:provider-saml-from-metadata"),
|
||||||
|
}
|
||||||
|
)
|
||||||
|
return Response(TypeCreateSerializer(data, many=True).data)
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
"""API Utilities"""
|
"""API Utilities"""
|
||||||
from django.db.models import Model
|
from django.db.models import Model
|
||||||
|
from rest_framework.fields import CharField
|
||||||
from rest_framework.serializers import Serializer, SerializerMethodField
|
from rest_framework.serializers import Serializer, SerializerMethodField
|
||||||
|
|
||||||
|
|
||||||
|
@ -22,3 +23,11 @@ class MetaNameSerializer(Serializer):
|
||||||
def get_verbose_name_plural(self, obj: Model) -> str:
|
def get_verbose_name_plural(self, obj: Model) -> str:
|
||||||
"""Return object's plural verbose_name"""
|
"""Return object's plural verbose_name"""
|
||||||
return obj._meta.verbose_name_plural
|
return obj._meta.verbose_name_plural
|
||||||
|
|
||||||
|
|
||||||
|
class TypeCreateSerializer(Serializer):
|
||||||
|
"""Types of an object that can be created"""
|
||||||
|
|
||||||
|
name = CharField(read_only=True)
|
||||||
|
description = CharField(read_only=True)
|
||||||
|
link = CharField(read_only=True)
|
||||||
|
|
60
swagger.yaml
60
swagger.yaml
|
@ -4312,6 +4312,47 @@ paths:
|
||||||
tags:
|
tags:
|
||||||
- providers
|
- providers
|
||||||
parameters: []
|
parameters: []
|
||||||
|
/providers/all/types/:
|
||||||
|
get:
|
||||||
|
operationId: providers_all_types
|
||||||
|
description: Get all creatable provider types
|
||||||
|
parameters:
|
||||||
|
- name: application__isnull
|
||||||
|
in: query
|
||||||
|
description: ''
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: ordering
|
||||||
|
in: query
|
||||||
|
description: Which field to use when ordering the results.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: search
|
||||||
|
in: query
|
||||||
|
description: A search term.
|
||||||
|
required: false
|
||||||
|
type: string
|
||||||
|
- name: page
|
||||||
|
in: query
|
||||||
|
description: A page number within the paginated result set.
|
||||||
|
required: false
|
||||||
|
type: integer
|
||||||
|
- name: page_size
|
||||||
|
in: query
|
||||||
|
description: Number of results to return per page.
|
||||||
|
required: false
|
||||||
|
type: integer
|
||||||
|
responses:
|
||||||
|
'200':
|
||||||
|
description: ''
|
||||||
|
schema:
|
||||||
|
description: ''
|
||||||
|
type: array
|
||||||
|
items:
|
||||||
|
$ref: '#/definitions/TypeCreate'
|
||||||
|
tags:
|
||||||
|
- providers
|
||||||
|
parameters: []
|
||||||
/providers/all/{id}/:
|
/providers/all/{id}/:
|
||||||
get:
|
get:
|
||||||
operationId: providers_all_read
|
operationId: providers_all_read
|
||||||
|
@ -9005,6 +9046,25 @@ definitions:
|
||||||
title: Verbose name plural
|
title: Verbose name plural
|
||||||
type: string
|
type: string
|
||||||
readOnly: true
|
readOnly: true
|
||||||
|
TypeCreate:
|
||||||
|
description: ''
|
||||||
|
type: object
|
||||||
|
properties:
|
||||||
|
name:
|
||||||
|
title: Name
|
||||||
|
type: string
|
||||||
|
readOnly: true
|
||||||
|
minLength: 1
|
||||||
|
description:
|
||||||
|
title: Description
|
||||||
|
type: string
|
||||||
|
readOnly: true
|
||||||
|
minLength: 1
|
||||||
|
link:
|
||||||
|
title: Link
|
||||||
|
type: string
|
||||||
|
readOnly: true
|
||||||
|
minLength: 1
|
||||||
OAuth2Provider:
|
OAuth2Provider:
|
||||||
description: OAuth2Provider Serializer
|
description: OAuth2Provider Serializer
|
||||||
required:
|
required:
|
||||||
|
|
|
@ -1,5 +1,11 @@
|
||||||
import { BaseInheritanceModel, DefaultClient, AKResponse, QueryArguments } from "./Client";
|
import { BaseInheritanceModel, DefaultClient, AKResponse, QueryArguments } from "./Client";
|
||||||
|
|
||||||
|
export interface TypeCreate {
|
||||||
|
name: string;
|
||||||
|
description: string;
|
||||||
|
link: string;
|
||||||
|
}
|
||||||
|
|
||||||
export class Provider implements BaseInheritanceModel {
|
export class Provider implements BaseInheritanceModel {
|
||||||
pk: number;
|
pk: number;
|
||||||
name: string;
|
name: string;
|
||||||
|
@ -24,6 +30,10 @@ export class Provider implements BaseInheritanceModel {
|
||||||
return DefaultClient.fetch<AKResponse<Provider>>(["providers", "all"], filter);
|
return DefaultClient.fetch<AKResponse<Provider>>(["providers", "all"], filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static getTypes(): Promise<TypeCreate[]> {
|
||||||
|
return DefaultClient.fetch<TypeCreate[]>(["providers", "all", "types"]);
|
||||||
|
}
|
||||||
|
|
||||||
static adminUrl(rest: string): string {
|
static adminUrl(rest: string): string {
|
||||||
return `/administration/providers/${rest}`;
|
return `/administration/providers/${rest}`;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,6 +8,7 @@ import "../../elements/buttons/ModalButton";
|
||||||
import "../../elements/buttons/SpinnerButton";
|
import "../../elements/buttons/SpinnerButton";
|
||||||
import "../../elements/buttons/Dropdown";
|
import "../../elements/buttons/Dropdown";
|
||||||
import { TableColumn } from "../../elements/table/Table";
|
import { TableColumn } from "../../elements/table/Table";
|
||||||
|
import { until } from "lit-html/directives/until";
|
||||||
|
|
||||||
@customElement("ak-provider-list")
|
@customElement("ak-provider-list")
|
||||||
export class ProviderListPage extends TablePage<Provider> {
|
export class ProviderListPage extends TablePage<Provider> {
|
||||||
|
@ -81,46 +82,18 @@ export class ProviderListPage extends TablePage<Provider> {
|
||||||
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
|
<i class="fas fa-caret-down pf-c-dropdown__toggle-icon" aria-hidden="true"></i>
|
||||||
</button>
|
</button>
|
||||||
<ul class="pf-c-dropdown__menu" hidden>
|
<ul class="pf-c-dropdown__menu" hidden>
|
||||||
<li>
|
${until(Provider.getTypes().then((types) => {
|
||||||
<ak-modal-button href="${Provider.adminUrl("/create/?type=OAuth2Provider")}">
|
return types.map((type) => {
|
||||||
<button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("OAuth2/OpenID Provider")}<br>
|
return html`<li>
|
||||||
<small>
|
<ak-modal-button href="${type.link}">
|
||||||
${gettext("OAuth2 Provider for generic OAuth and OpenID Connect Applications.")}
|
<button slot="trigger" class="pf-c-dropdown__menu-item">${type.name}<br>
|
||||||
</small>
|
<small>${type.description}</small>
|
||||||
</button>
|
</button>
|
||||||
<div slot="modal"></div>
|
<div slot="modal"></div>
|
||||||
</ak-modal-button>
|
</ak-modal-button>
|
||||||
</li>
|
</li>`;
|
||||||
<li>
|
})
|
||||||
<ak-modal-button href="${Provider.adminUrl("/create/?type=ProxyProvider")}">
|
}), html`<ak-spinner></ak-spinner>`)}
|
||||||
<button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("Proxy Provider")}<br>
|
|
||||||
<small>
|
|
||||||
${gettext("Protect applications that don't support any of the other Protocols by using a Reverse-Proxy.")}
|
|
||||||
</small>
|
|
||||||
</button>
|
|
||||||
<div slot="modal"></div>
|
|
||||||
</ak-modal-button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<ak-modal-button href="${Provider.adminUrl("/create/?type=SAMLProvider")}">
|
|
||||||
<button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("SAML Provider")}<br>
|
|
||||||
<small>
|
|
||||||
${gettext("SAML 2.0 Endpoint for applications which support SAML.")}
|
|
||||||
</small>
|
|
||||||
</button>
|
|
||||||
<div slot="modal"></div>
|
|
||||||
</ak-modal-button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<ak-modal-button href="${Provider.adminUrl("/create/saml/from-metadata/")}">
|
|
||||||
<button slot="trigger" class="pf-c-dropdown__menu-item">${gettext("SAML Provider from Metadata")}<br>
|
|
||||||
<small>
|
|
||||||
${gettext("Create a SAML Provider by importing its Metadata.")}
|
|
||||||
</small>
|
|
||||||
</button>
|
|
||||||
<div slot="modal"></div>
|
|
||||||
</ak-modal-button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
</ul>
|
||||||
</ak-dropdown>
|
</ak-dropdown>
|
||||||
${super.renderToolbar()}`;
|
${super.renderToolbar()}`;
|
||||||
|
|
Reference in New Issue