remove applications api

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
This commit is contained in:
Jens Langhammer 2023-08-07 20:34:09 +02:00
parent 9ee77993a9
commit 9d3bd8418d
No known key found for this signature in database
4 changed files with 0 additions and 274 deletions

View File

@ -1,127 +0,0 @@
"""transactional application and provider creation"""
from django.apps import apps
from drf_spectacular.utils import PolymorphicProxySerializer, extend_schema, extend_schema_field
from rest_framework.exceptions import ValidationError
from rest_framework.fields import BooleanField, CharField, ChoiceField, DictField, ListField
from rest_framework.permissions import IsAdminUser
from rest_framework.request import Request
from rest_framework.response import Response
from rest_framework.views import APIView
from yaml import ScalarNode
from authentik.blueprints.v1.common import (
Blueprint,
BlueprintEntry,
BlueprintEntryDesiredState,
KeyOf,
)
from authentik.blueprints.v1.importer import Importer
from authentik.core.api.applications import ApplicationSerializer
from authentik.core.api.utils import PassiveSerializer
from authentik.core.models import Provider
from authentik.lib.utils.reflection import all_subclasses
def get_provider_serializer_mapping():
"""Get a mapping of all providers' model names and their serializers"""
mapping = {}
for model in all_subclasses(Provider):
if model._meta.abstract:
continue
mapping[f"{model._meta.app_label}.{model._meta.model_name}"] = model().serializer
return mapping
@extend_schema_field(
PolymorphicProxySerializer(
component_name="model",
serializers=get_provider_serializer_mapping,
resource_type_field_name="provider_model",
)
)
class TransactionProviderField(DictField):
"""Dictionary field which can hold provider creation data"""
class TransactionApplicationSerializer(PassiveSerializer):
"""Serializer for creating a provider and an application in one transaction"""
app = ApplicationSerializer()
provider_model = ChoiceField(choices=list(get_provider_serializer_mapping().keys()))
provider = TransactionProviderField()
_provider_model: type[Provider] = None
def validate_provider_model(self, fq_model_name: str) -> str:
"""Validate that the model exists and is a provider"""
if "." not in fq_model_name:
raise ValidationError("Invalid provider model")
try:
app, _, model_name = fq_model_name.partition(".")
model = apps.get_model(app, model_name)
if not issubclass(model, Provider):
raise ValidationError("Invalid provider model")
self._provider_model = model
except LookupError:
raise ValidationError("Invalid provider model")
return fq_model_name
class TransactionApplicationResponseSerializer(PassiveSerializer):
"""Transactional creation response"""
valid = BooleanField()
applied = BooleanField()
logs = ListField(child=CharField())
class TransactionalApplicationView(APIView):
"""Create provider and application and attach them in a single transaction"""
permission_classes = [IsAdminUser]
@extend_schema(
request=TransactionApplicationSerializer(),
responses={
200: TransactionApplicationResponseSerializer(),
},
)
def put(self, request: Request) -> Response:
"""Convert data into a blueprint, validate it and apply it"""
data = TransactionApplicationSerializer(data=request.data)
data.is_valid(raise_exception=True)
print(data.validated_data)
blueprint = Blueprint()
blueprint.entries.append(
BlueprintEntry(
model=data.validated_data["provider_model"],
state=BlueprintEntryDesiredState.MUST_CREATED,
identifiers={
"name": data.validated_data["provider"]["name"],
},
id="provider",
attrs=data.validated_data["provider"],
)
)
app_data = data.validated_data["app"]
app_data["provider"] = KeyOf(None, ScalarNode(tag="", value="provider"))
blueprint.entries.append(
BlueprintEntry(
model="authentik_core.application",
state=BlueprintEntryDesiredState.MUST_CREATED,
identifiers={
"slug": data.validated_data["app"]["slug"],
},
attrs=app_data,
)
)
importer = Importer(blueprint, {})
response = {"valid": False, "applied": False, "logs": []}
valid, logs = importer.validate()
response["logs"] = [x["event"] for x in logs]
response["valid"] = valid
if valid:
applied = importer.apply()
response["applied"] = applied
return Response(response, status=200)

View File

@ -1,45 +0,0 @@
"""Test Transactional API"""
from json import loads
from django.urls import reverse
from rest_framework.test import APITestCase
from authentik.core.models import Application
from authentik.core.tests.utils import create_test_admin_user, create_test_flow
from authentik.lib.generators import generate_id
from authentik.providers.oauth2.models import OAuth2Provider
class TestTransactionalApplicationsAPI(APITestCase):
"""Test Transactional API"""
def setUp(self) -> None:
self.user = create_test_admin_user()
def test_create_transactional(self):
"""Test transactional Application + provider creation"""
self.client.force_login(self.user)
uid = generate_id()
authorization_flow = create_test_flow()
response = self.client.put(
reverse("authentik_api:core-transactional-application"),
data={
"app": {
"name": uid,
"slug": uid,
},
"provider_model": "authentik_providers_oauth2.oauth2provider",
"provider": {
"name": uid,
"authorization_flow": str(authorization_flow.pk),
},
},
)
response_body = loads(response.content.decode())
self.assertTrue(response_body["valid"])
self.assertTrue(response_body["applied"])
provider = OAuth2Provider.objects.filter(name=uid).first()
self.assertIsNotNone(provider)
app = Application.objects.filter(slug=uid).first()
self.assertIsNotNone(app)
self.assertEqual(app.provider.pk, provider.pk)

View File

@ -15,7 +15,6 @@ from authentik.core.api.propertymappings import PropertyMappingViewSet
from authentik.core.api.providers import ProviderViewSet
from authentik.core.api.sources import SourceViewSet, UserSourceConnectionViewSet
from authentik.core.api.tokens import TokenViewSet
from authentik.core.api.transactional_applications import TransactionalApplicationView
from authentik.core.api.users import UserViewSet
from authentik.core.views import apps
from authentik.core.views.debug import AccessDeniedView
@ -71,11 +70,6 @@ urlpatterns = [
api_urlpatterns = [
("core/authenticated_sessions", AuthenticatedSessionViewSet),
("core/applications", ApplicationViewSet),
path(
"core/transactional/applications/",
TransactionalApplicationView.as_view(),
name="core-transactional-application",
),
("core/groups", GroupViewSet),
("core/users", UserViewSet),
("core/tokens", TokenViewSet),

View File

@ -4349,39 +4349,6 @@ paths:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/transactional/applications/:
put:
operationId: core_transactional_applications_update
description: Convert data into a blueprint, validate it and apply it
tags:
- core
requestBody:
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionApplicationRequest'
required: true
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/TransactionApplicationResponse'
description: ''
'400':
content:
application/json:
schema:
$ref: '#/components/schemas/ValidationError'
description: ''
'403':
content:
application/json:
schema:
$ref: '#/components/schemas/GenericError'
description: ''
/core/user_consent/:
get:
operationId: core_user_consent_list
@ -37593,22 +37560,6 @@ components:
description: |-
* `twilio` - Twilio
* `generic` - Generic
ProviderModelEnum:
enum:
- authentik_providers_ldap.ldapprovider
- authentik_providers_oauth2.oauth2provider
- authentik_providers_proxy.proxyprovider
- authentik_providers_radius.radiusprovider
- authentik_providers_saml.samlprovider
- authentik_providers_scim.scimprovider
type: string
description: |-
* `authentik_providers_ldap.ldapprovider` - authentik_providers_ldap.ldapprovider
* `authentik_providers_oauth2.oauth2provider` - authentik_providers_oauth2.oauth2provider
* `authentik_providers_proxy.proxyprovider` - authentik_providers_proxy.proxyprovider
* `authentik_providers_radius.radiusprovider` - authentik_providers_radius.radiusprovider
* `authentik_providers_saml.samlprovider` - authentik_providers_saml.samlprovider
* `authentik_providers_scim.scimprovider` - authentik_providers_scim.scimprovider
ProviderRequest:
type: object
description: Provider Serializer
@ -40020,36 +39971,6 @@ components:
readOnly: true
required:
- key
TransactionApplicationRequest:
type: object
description: Serializer for creating a provider and an application in one transaction
properties:
app:
$ref: '#/components/schemas/ApplicationRequest'
provider_model:
$ref: '#/components/schemas/ProviderModelEnum'
provider:
$ref: '#/components/schemas/modelRequest'
required:
- app
- provider
- provider_model
TransactionApplicationResponse:
type: object
description: Transactional creation response
properties:
valid:
type: boolean
applied:
type: boolean
logs:
type: array
items:
type: string
required:
- applied
- logs
- valid
TypeCreate:
type: object
description: Types of an object that can be created
@ -40977,23 +40898,6 @@ components:
type: integer
required:
- count
modelRequest:
oneOf:
- $ref: '#/components/schemas/LDAPProviderRequest'
- $ref: '#/components/schemas/OAuth2ProviderRequest'
- $ref: '#/components/schemas/ProxyProviderRequest'
- $ref: '#/components/schemas/RadiusProviderRequest'
- $ref: '#/components/schemas/SAMLProviderRequest'
- $ref: '#/components/schemas/SCIMProviderRequest'
discriminator:
propertyName: provider_model
mapping:
authentik_providers_ldap.ldapprovider: '#/components/schemas/LDAPProviderRequest'
authentik_providers_oauth2.oauth2provider: '#/components/schemas/OAuth2ProviderRequest'
authentik_providers_proxy.proxyprovider: '#/components/schemas/ProxyProviderRequest'
authentik_providers_radius.radiusprovider: '#/components/schemas/RadiusProviderRequest'
authentik_providers_saml.samlprovider: '#/components/schemas/SAMLProviderRequest'
authentik_providers_scim.scimprovider: '#/components/schemas/SCIMProviderRequest'
securitySchemes:
authentik:
type: apiKey