add domain tests
Signed-off-by: Marc 'risson' Schmitt <marc.schmitt@risson.space>
This commit is contained in:
parent
cdfbb48cb6
commit
35482f48d4
|
@ -1,59 +1,19 @@
|
|||
"""Test Tenant API"""
|
||||
from json import loads
|
||||
|
||||
from django.core.management import call_command
|
||||
from django.db import connection
|
||||
from django.urls import reverse
|
||||
from rest_framework.test import APILiveServerTestCase, APITestCase, APITransactionTestCase
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.tenants.tests.utils import TenantAPITestCase
|
||||
|
||||
TENANTS_API_KEY = generate_id()
|
||||
HEADERS = {"Authorization": f"Bearer {TENANTS_API_KEY}"}
|
||||
|
||||
|
||||
class TestAPI(APITransactionTestCase):
|
||||
class TestAPI(TenantAPITestCase):
|
||||
"""Test api view"""
|
||||
|
||||
def _fixture_teardown(self):
|
||||
for db_name in self._databases_names(include_mirrors=False):
|
||||
call_command(
|
||||
"flush",
|
||||
verbosity=0,
|
||||
interactive=False,
|
||||
database=db_name,
|
||||
reset_sequences=False,
|
||||
allow_cascade=True,
|
||||
inhibit_post_migrate=False,
|
||||
)
|
||||
|
||||
def setUp(self):
|
||||
call_command("migrate_schemas", schema="template", tenant=True)
|
||||
|
||||
def assertSchemaExists(self, schema_name):
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.schemata WHERE schema_name = '{schema_name}';"
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, 1)
|
||||
|
||||
cursor.execute(
|
||||
"SELECT * FROM information_schema.tables WHERE table_schema = 'template';"
|
||||
)
|
||||
expected_tables = cursor.rowcount
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.tables WHERE table_schema = '{schema_name}';"
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, expected_tables)
|
||||
|
||||
def assertSchemaDoesntExist(self, schema_name):
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.schemata WHERE schema_name = '{schema_name}';"
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, 0)
|
||||
|
||||
@CONFIG.patch("outposts.disable_embedded_outpost", True)
|
||||
@CONFIG.patch("tenants.enabled", True)
|
||||
@CONFIG.patch("tenants.api_key", TENANTS_API_KEY)
|
||||
|
|
51
authentik/tenants/tests/test_domain.py
Normal file
51
authentik/tenants/tests/test_domain.py
Normal file
|
@ -0,0 +1,51 @@
|
|||
"""Test Domain API"""
|
||||
from json import loads
|
||||
|
||||
from django.urls import reverse
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.tenants.models import Domain, Tenant
|
||||
from authentik.tenants.tests.utils import TenantAPITestCase
|
||||
|
||||
TENANTS_API_KEY = generate_id()
|
||||
HEADERS = {"Authorization": f"Bearer {TENANTS_API_KEY}"}
|
||||
|
||||
|
||||
class TestDomainAPI(TenantAPITestCase):
|
||||
def setUp(self):
|
||||
super().setUp()
|
||||
self.tenant = Tenant.objects.create(
|
||||
name=generate_id(), schema_name="t_" + generate_id().lower()
|
||||
)
|
||||
|
||||
def tearDown(self):
|
||||
self.tenant.delete()
|
||||
|
||||
@CONFIG.patch("outposts.disable_embedded_outpost", True)
|
||||
@CONFIG.patch("tenants.enabled", True)
|
||||
@CONFIG.patch("tenants.api_key", TENANTS_API_KEY)
|
||||
def test_domain(self):
|
||||
"""Test domain creation"""
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:domain-list"),
|
||||
headers=HEADERS,
|
||||
data={"tenant": self.tenant.pk, "domain": "test.domain"},
|
||||
)
|
||||
self.assertEqual(response.status_code, 201)
|
||||
body = loads(response.content.decode())
|
||||
self.assertEqual(self.tenant.domains.get(domain="test.domain").pk, body["id"])
|
||||
self.assertEqual(self.tenant.domains.get(domain="test.domain").is_primary, True)
|
||||
|
||||
response = self.client.post(
|
||||
reverse("authentik_api:domain-list"),
|
||||
headers=HEADERS,
|
||||
data={"tenant": self.tenant.pk, "domain": "newprimary.domain", "is_primary": True},
|
||||
)
|
||||
self.assertEqual(response.status_code, 201)
|
||||
self.assertEqual(
|
||||
Domain.objects.get(tenant=self.tenant, domain="newprimary.domain").is_primary, True
|
||||
)
|
||||
self.assertEqual(
|
||||
Domain.objects.get(tenant=self.tenant, domain="test.domain").is_primary, False
|
||||
)
|
50
authentik/tenants/tests/test_settings.py
Normal file
50
authentik/tenants/tests/test_settings.py
Normal file
|
@ -0,0 +1,50 @@
|
|||
"""Test Settings API"""
|
||||
from json import loads
|
||||
|
||||
from django.urls import reverse
|
||||
from django_tenants.utils import get_public_schema_name
|
||||
|
||||
from authentik.lib.config import CONFIG
|
||||
from authentik.lib.generators import generate_id
|
||||
from authentik.tenants.models import Domain, Tenant
|
||||
from authentik.tenants.tests.utils import TenantAPITestCase
|
||||
|
||||
TENANTS_API_KEY = generate_id()
|
||||
HEADERS = {"Authorization": f"Bearer {TENANTS_API_KEY}"}
|
||||
|
||||
|
||||
# class TestSettingsAPI(TenantAPITestCase):
|
||||
# def setUp(self):
|
||||
# super().setUp()
|
||||
# self.tenant_1 = Tenant.objects.get(schema_name=get_public_schema_name())
|
||||
# self.tenant_2 = Tenant.objects.create(
|
||||
# name=generate_id(), schema_name="t_" + generate_id().lower()
|
||||
# )
|
||||
#
|
||||
# @CONFIG.patch("outposts.disable_embedded_outpost", True)
|
||||
# @CONFIG.patch("tenants.enabled", True)
|
||||
# @CONFIG.patch("tenants.api_key", TENANTS_API_KEY)
|
||||
# def test_domain(self):
|
||||
# """Test domain creation"""
|
||||
# response = self.client.post(
|
||||
# reverse("authentik_api:domain-list"),
|
||||
# headers=HEADERS,
|
||||
# data={"tenant": self.tenant.pk, "domain": "test.domain"},
|
||||
# )
|
||||
# self.assertEqual(response.status_code, 201)
|
||||
# body = loads(response.content.decode())
|
||||
# self.assertEqual(self.tenant.domains.get(domain="test.domain").pk, body["id"])
|
||||
# self.assertEqual(self.tenant.domains.get(domain="test.domain").is_primary, True)
|
||||
#
|
||||
# response = self.client.post(
|
||||
# reverse("authentik_api:domain-list"),
|
||||
# headers=HEADERS,
|
||||
# data={"tenant": self.tenant.pk, "domain": "newprimary.domain", "is_primary": True},
|
||||
# )
|
||||
# self.assertEqual(response.status_code, 201)
|
||||
# self.assertEqual(
|
||||
# Domain.objects.get(tenant=self.tenant, domain="newprimary.domain").is_primary, True
|
||||
# )
|
||||
# self.assertEqual(
|
||||
# Domain.objects.get(tenant=self.tenant, domain="test.domain").is_primary, False
|
||||
# )
|
56
authentik/tenants/tests/utils.py
Normal file
56
authentik/tenants/tests/utils.py
Normal file
|
@ -0,0 +1,56 @@
|
|||
from django.core.management import call_command
|
||||
from django.db import connection, connections
|
||||
from rest_framework.test import APITransactionTestCase
|
||||
|
||||
|
||||
class TenantAPITestCase(APITransactionTestCase):
|
||||
# Overriden to force TRUNCATE CASCADE
|
||||
def _fixture_teardown(self):
|
||||
for db_name in self._databases_names(include_mirrors=False):
|
||||
call_command(
|
||||
"flush",
|
||||
verbosity=0,
|
||||
interactive=False,
|
||||
database=db_name,
|
||||
reset_sequences=False,
|
||||
allow_cascade=True,
|
||||
inhibit_post_migrate=False,
|
||||
)
|
||||
|
||||
with connections[db_name].cursor() as cursor:
|
||||
cursor.execute(
|
||||
"SELECT nspname FROM pg_catalog.pg_namespace WHERE nspname !~ 'pg_*' AND nspname != 'information_schema' AND nspname != 'public' AND nspname != 'template'"
|
||||
)
|
||||
schemas = cursor.fetchall()
|
||||
for row in schemas:
|
||||
schema = row[0]
|
||||
cursor.execute(f"DROP SCHEMA {schema}")
|
||||
|
||||
def setUp(self):
|
||||
call_command("migrate_schemas", schema="template", tenant=True)
|
||||
|
||||
def assertSchemaExists(self, schema_name):
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.schemata WHERE schema_name = %(schema_name)s",
|
||||
{"schema_name": schema_name},
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, 1)
|
||||
|
||||
cursor.execute(
|
||||
"SELECT * FROM information_schema.tables WHERE table_schema = 'template'"
|
||||
)
|
||||
expected_tables = cursor.rowcount
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.tables WHERE table_schema = %(schema_name)s",
|
||||
{"schema_name": schema_name},
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, expected_tables)
|
||||
|
||||
def assertSchemaDoesntExist(self, schema_name):
|
||||
with connection.cursor() as cursor:
|
||||
cursor.execute(
|
||||
f"SELECT * FROM information_schema.schemata WHERE schema_name = %(schema_name)s",
|
||||
{"schema_name": schema_name},
|
||||
)
|
||||
self.assertEqual(cursor.rowcount, 0)
|
|
@ -1,12 +1,16 @@
|
|||
"""API URLs"""
|
||||
from django.urls import path
|
||||
|
||||
from authentik.tenants.api import SettingsView, TenantViewSet
|
||||
from authentik.tenants.api import DomainViewSet, SettingsView, TenantViewSet
|
||||
|
||||
api_urlpatterns = [
|
||||
path("admin/settings/", SettingsView.as_view(), name="tenant_settings"),
|
||||
(
|
||||
"tenants",
|
||||
"tenants/tenants",
|
||||
TenantViewSet,
|
||||
),
|
||||
(
|
||||
"tenants/domains",
|
||||
DomainViewSet,
|
||||
),
|
||||
]
|
||||
|
|
265
schema.yml
265
schema.yml
|
@ -27839,9 +27839,221 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/tenants/:
|
||||
/tenants/domains/:
|
||||
get:
|
||||
operationId: tenants_list
|
||||
operationId: tenants_domains_list
|
||||
description: Domain ViewSet
|
||||
parameters:
|
||||
- name: ordering
|
||||
required: false
|
||||
in: query
|
||||
description: Which field to use when ordering the results.
|
||||
schema:
|
||||
type: string
|
||||
- name: page
|
||||
required: false
|
||||
in: query
|
||||
description: A page number within the paginated result set.
|
||||
schema:
|
||||
type: integer
|
||||
- name: page_size
|
||||
required: false
|
||||
in: query
|
||||
description: Number of results to return per page.
|
||||
schema:
|
||||
type: integer
|
||||
- name: search
|
||||
required: false
|
||||
in: query
|
||||
description: A search term.
|
||||
schema:
|
||||
type: string
|
||||
tags:
|
||||
- tenants
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PaginatedDomainList'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
post:
|
||||
operationId: tenants_domains_create
|
||||
description: Domain ViewSet
|
||||
tags:
|
||||
- tenants
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DomainRequest'
|
||||
required: true
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Domain'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/tenants/domains/{id}/:
|
||||
get:
|
||||
operationId: tenants_domains_retrieve
|
||||
description: Domain ViewSet
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Domain.
|
||||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Domain'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
put:
|
||||
operationId: tenants_domains_update
|
||||
description: Domain ViewSet
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Domain.
|
||||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/DomainRequest'
|
||||
required: true
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Domain'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
patch:
|
||||
operationId: tenants_domains_partial_update
|
||||
description: Domain ViewSet
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Domain.
|
||||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
requestBody:
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedDomainRequest'
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/Domain'
|
||||
description: ''
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
delete:
|
||||
operationId: tenants_domains_destroy
|
||||
description: Domain ViewSet
|
||||
parameters:
|
||||
- in: path
|
||||
name: id
|
||||
schema:
|
||||
type: integer
|
||||
description: A unique integer value identifying this Domain.
|
||||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
responses:
|
||||
'204':
|
||||
description: No response body
|
||||
'400':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/ValidationError'
|
||||
description: ''
|
||||
'403':
|
||||
content:
|
||||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/tenants/tenants/:
|
||||
get:
|
||||
operationId: tenants_tenants_list
|
||||
description: Tenant Viewset
|
||||
parameters:
|
||||
- name: ordering
|
||||
|
@ -27870,8 +28082,6 @@ paths:
|
|||
type: string
|
||||
tags:
|
||||
- tenants
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
|
@ -27892,7 +28102,7 @@ paths:
|
|||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
post:
|
||||
operationId: tenants_create
|
||||
operationId: tenants_tenants_create
|
||||
description: Tenant Viewset
|
||||
tags:
|
||||
- tenants
|
||||
|
@ -27902,8 +28112,6 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/TenantRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'201':
|
||||
content:
|
||||
|
@ -27923,9 +28131,9 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
/tenants/{tenant_uuid}/:
|
||||
/tenants/tenants/{tenant_uuid}/:
|
||||
get:
|
||||
operationId: tenants_retrieve
|
||||
operationId: tenants_tenants_retrieve
|
||||
description: Tenant Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
|
@ -27937,8 +28145,6 @@ paths:
|
|||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
|
@ -27959,7 +28165,7 @@ paths:
|
|||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
put:
|
||||
operationId: tenants_update
|
||||
operationId: tenants_tenants_update
|
||||
description: Tenant Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
|
@ -27977,8 +28183,6 @@ paths:
|
|||
schema:
|
||||
$ref: '#/components/schemas/TenantRequest'
|
||||
required: true
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
|
@ -27999,7 +28203,7 @@ paths:
|
|||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
patch:
|
||||
operationId: tenants_partial_update
|
||||
operationId: tenants_tenants_partial_update
|
||||
description: Tenant Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
|
@ -28016,8 +28220,6 @@ paths:
|
|||
application/json:
|
||||
schema:
|
||||
$ref: '#/components/schemas/PatchedTenantRequest'
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'200':
|
||||
content:
|
||||
|
@ -28038,7 +28240,7 @@ paths:
|
|||
$ref: '#/components/schemas/GenericError'
|
||||
description: ''
|
||||
delete:
|
||||
operationId: tenants_destroy
|
||||
operationId: tenants_tenants_destroy
|
||||
description: Tenant Viewset
|
||||
parameters:
|
||||
- in: path
|
||||
|
@ -28050,8 +28252,6 @@ paths:
|
|||
required: true
|
||||
tags:
|
||||
- tenants
|
||||
security:
|
||||
- authentik: []
|
||||
responses:
|
||||
'204':
|
||||
description: No response body
|
||||
|
@ -34935,6 +35135,18 @@ components:
|
|||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedDomainList:
|
||||
type: object
|
||||
properties:
|
||||
pagination:
|
||||
$ref: '#/components/schemas/Pagination'
|
||||
results:
|
||||
type: array
|
||||
items:
|
||||
$ref: '#/components/schemas/Domain'
|
||||
required:
|
||||
- pagination
|
||||
- results
|
||||
PaginatedDummyPolicyList:
|
||||
type: object
|
||||
properties:
|
||||
|
@ -36619,6 +36831,19 @@ components:
|
|||
nullable: true
|
||||
description: Certificate/Key used for authentication. Can be left empty
|
||||
for no authentication.
|
||||
PatchedDomainRequest:
|
||||
type: object
|
||||
description: Domain Serializer
|
||||
properties:
|
||||
domain:
|
||||
type: string
|
||||
minLength: 1
|
||||
maxLength: 253
|
||||
is_primary:
|
||||
type: boolean
|
||||
tenant:
|
||||
type: string
|
||||
format: uuid
|
||||
PatchedDummyPolicyRequest:
|
||||
type: object
|
||||
description: Dummy Policy Serializer
|
||||
|
|
Reference in a new issue