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)
|
||||
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(
|
||||
manual_parameters=[
|
||||
openapi.Parameter(
|
||||
|
|
125
authentik/core/tests/test_applications_api.py
Normal file
125
authentik/core/tests/test_applications_api.py
Normal file
|
@ -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
|
||||
format: slug
|
||||
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/:
|
||||
get:
|
||||
operationId: core_applications_metrics
|
||||
|
|
Reference in a new issue