core: add API to check access to single application by slug
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
99d0d4e8de
commit
5fb07acf54
|
@ -91,6 +91,23 @@ class ApplicationViewSet(ModelViewSet):
|
||||||
applications.append(application)
|
applications.append(application)
|
||||||
return applications
|
return applications
|
||||||
|
|
||||||
|
@swagger_auto_schema(
|
||||||
|
responses={
|
||||||
|
204: "Access granted",
|
||||||
|
403: "Access denied",
|
||||||
|
}
|
||||||
|
)
|
||||||
|
@action(detail=True, methods=["GET"])
|
||||||
|
# pylint: disable=unused-argument
|
||||||
|
def check_access(self, request: Request, slug: str) -> Response:
|
||||||
|
"""Check access to a single application by slug"""
|
||||||
|
application = self.get_object()
|
||||||
|
engine = PolicyEngine(application, self.request.user, self.request)
|
||||||
|
engine.build()
|
||||||
|
if engine.passing:
|
||||||
|
return Response(status=204)
|
||||||
|
return Response(status=403)
|
||||||
|
|
||||||
@swagger_auto_schema(
|
@swagger_auto_schema(
|
||||||
manual_parameters=[
|
manual_parameters=[
|
||||||
openapi.Parameter(
|
openapi.Parameter(
|
||||||
|
|
|
@ -0,0 +1,125 @@
|
||||||
|
"""Test Applications API"""
|
||||||
|
from django.urls import reverse
|
||||||
|
from django.utils.encoding import force_str
|
||||||
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
|
from authentik.core.models import Application, User
|
||||||
|
from authentik.policies.dummy.models import DummyPolicy
|
||||||
|
from authentik.policies.models import PolicyBinding
|
||||||
|
|
||||||
|
|
||||||
|
class TestApplicationsAPI(APITestCase):
|
||||||
|
"""Test applications API"""
|
||||||
|
|
||||||
|
def setUp(self) -> None:
|
||||||
|
self.user = User.objects.get(username="akadmin")
|
||||||
|
self.allowed = Application.objects.create(name="allowed", slug="allowed")
|
||||||
|
self.denied = Application.objects.create(name="denied", slug="denied")
|
||||||
|
PolicyBinding.objects.create(
|
||||||
|
target=self.denied,
|
||||||
|
policy=DummyPolicy.objects.create(
|
||||||
|
name="deny", result=False, wait_min=1, wait_max=2
|
||||||
|
),
|
||||||
|
order=0,
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_check_access(self):
|
||||||
|
"""Test check_access operation """
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
response = self.client.get(
|
||||||
|
reverse(
|
||||||
|
"authentik_api:application-check-access",
|
||||||
|
kwargs={"slug": self.allowed.slug},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 204)
|
||||||
|
response = self.client.get(
|
||||||
|
reverse(
|
||||||
|
"authentik_api:application-check-access",
|
||||||
|
kwargs={"slug": self.denied.slug},
|
||||||
|
)
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 403)
|
||||||
|
|
||||||
|
def test_list(self):
|
||||||
|
"""Test list operation without superuser_full_list"""
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
response = self.client.get(reverse("authentik_api:application-list"))
|
||||||
|
self.assertJSONEqual(
|
||||||
|
force_str(response.content),
|
||||||
|
{
|
||||||
|
"pagination": {
|
||||||
|
"next": 0,
|
||||||
|
"previous": 0,
|
||||||
|
"count": 2,
|
||||||
|
"current": 1,
|
||||||
|
"total_pages": 1,
|
||||||
|
"start_index": 1,
|
||||||
|
"end_index": 2,
|
||||||
|
},
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"pk": str(self.allowed.pk),
|
||||||
|
"name": "allowed",
|
||||||
|
"slug": "allowed",
|
||||||
|
"provider": None,
|
||||||
|
"provider_obj": None,
|
||||||
|
"launch_url": None,
|
||||||
|
"meta_launch_url": "",
|
||||||
|
"meta_icon": None,
|
||||||
|
"meta_description": "",
|
||||||
|
"meta_publisher": "",
|
||||||
|
"policy_engine_mode": "any",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
def test_list_superuser_full_list(self):
|
||||||
|
"""Test list operation with superuser_full_list"""
|
||||||
|
self.client.force_login(self.user)
|
||||||
|
response = self.client.get(
|
||||||
|
reverse("authentik_api:application-list") + "?superuser_full_list=true"
|
||||||
|
)
|
||||||
|
self.assertJSONEqual(
|
||||||
|
force_str(response.content),
|
||||||
|
{
|
||||||
|
"pagination": {
|
||||||
|
"next": 0,
|
||||||
|
"previous": 0,
|
||||||
|
"count": 2,
|
||||||
|
"current": 1,
|
||||||
|
"total_pages": 1,
|
||||||
|
"start_index": 1,
|
||||||
|
"end_index": 2,
|
||||||
|
},
|
||||||
|
"results": [
|
||||||
|
{
|
||||||
|
"pk": str(self.allowed.pk),
|
||||||
|
"name": "allowed",
|
||||||
|
"slug": "allowed",
|
||||||
|
"provider": None,
|
||||||
|
"provider_obj": None,
|
||||||
|
"launch_url": None,
|
||||||
|
"meta_launch_url": "",
|
||||||
|
"meta_icon": None,
|
||||||
|
"meta_description": "",
|
||||||
|
"meta_publisher": "",
|
||||||
|
"policy_engine_mode": "any",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"launch_url": None,
|
||||||
|
"meta_description": "",
|
||||||
|
"meta_icon": None,
|
||||||
|
"meta_launch_url": "",
|
||||||
|
"meta_publisher": "",
|
||||||
|
"name": "denied",
|
||||||
|
"pk": str(self.denied.pk),
|
||||||
|
"policy_engine_mode": "any",
|
||||||
|
"provider": None,
|
||||||
|
"provider_obj": None,
|
||||||
|
"slug": "denied",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
27
swagger.yaml
27
swagger.yaml
|
@ -1329,6 +1329,33 @@ paths:
|
||||||
type: string
|
type: string
|
||||||
format: slug
|
format: slug
|
||||||
pattern: ^[-a-zA-Z0-9_]+$
|
pattern: ^[-a-zA-Z0-9_]+$
|
||||||
|
/core/applications/{slug}/check_access/:
|
||||||
|
get:
|
||||||
|
operationId: core_applications_check_access
|
||||||
|
description: Check access to a single application by slug
|
||||||
|
parameters: []
|
||||||
|
responses:
|
||||||
|
'204':
|
||||||
|
description: Access granted
|
||||||
|
'403':
|
||||||
|
description: Authentication credentials were invalid, absent or insufficient.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/GenericError'
|
||||||
|
'404':
|
||||||
|
description: Object does not exist or caller has insufficient permissions
|
||||||
|
to access it.
|
||||||
|
schema:
|
||||||
|
$ref: '#/definitions/APIException'
|
||||||
|
tags:
|
||||||
|
- core
|
||||||
|
parameters:
|
||||||
|
- name: slug
|
||||||
|
in: path
|
||||||
|
description: Internal application name, used in URLs.
|
||||||
|
required: true
|
||||||
|
type: string
|
||||||
|
format: slug
|
||||||
|
pattern: ^[-a-zA-Z0-9_]+$
|
||||||
/core/applications/{slug}/metrics/:
|
/core/applications/{slug}/metrics/:
|
||||||
get:
|
get:
|
||||||
operationId: core_applications_metrics
|
operationId: core_applications_metrics
|
||||||
|
|
Reference in New Issue