Compare commits

...

3 Commits

Author SHA1 Message Date
Jens Langhammer
ab456a7f51 make URL path not clash?
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-03-24 13:38:34 +01:00
Jens Langhammer
9411d4724a fix tests
Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-03-24 13:38:16 +01:00
Jens Langhammer
74d555819a core: separate applications API
this separates the concept of "RBAC accessible application" and "Policy-accessible application"

Signed-off-by: Jens Langhammer <jens@goauthentik.io>
2026-03-24 12:38:52 +01:00
7 changed files with 71 additions and 40 deletions

View File

@@ -242,11 +242,6 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
@extend_schema(
parameters=[
OpenApiParameter(
name="superuser_full_list",
location=OpenApiParameter.QUERY,
type=OpenApiTypes.BOOL,
),
OpenApiParameter(
name="for_user",
location=OpenApiParameter.QUERY,
@@ -257,18 +252,17 @@ class ApplicationViewSet(UsedByMixin, ModelViewSet):
location=OpenApiParameter.QUERY,
type=OpenApiTypes.BOOL,
),
]
],
responses={
200: ApplicationSerializer(many=True),
},
operation_id="core_applications_accessible_list",
)
def list(self, request: Request) -> Response:
"""Custom list method that checks Policy based access instead of guardian"""
@action(methods=["GET"], detail=False, url_path="@accessible")
def accessible(self, request: Request) -> Response:
"""Get applications accessible for user"""
should_cache = request.query_params.get("search", "") == ""
superuser_full_list = (
str(request.query_params.get("superuser_full_list", "false")).lower() == "true"
)
if superuser_full_list and request.user.is_superuser:
return super().list(request)
only_with_launch_url = str(
request.query_params.get("only_with_launch_url", "false")
).lower()

View File

@@ -80,10 +80,10 @@ class TestApplicationsAPI(APITestCase):
self.assertEqual(body["passing"], False)
self.assertEqual(body["messages"], ["dummy"])
def test_list(self):
"""Test list operation without superuser_full_list"""
def test_list_accessible(self):
"""Test list operation without"""
self.client.force_login(self.user)
response = self.client.get(reverse("authentik_api:application-list"))
response = self.client.get(reverse("authentik_api:application-accessible"))
self.assertJSONEqual(
response.content.decode(),
{
@@ -136,12 +136,10 @@ class TestApplicationsAPI(APITestCase):
},
)
def test_list_superuser_full_list(self):
"""Test list operation with superuser_full_list"""
def test_list_rbac(self):
"""Test list operation"""
self.client.force_login(self.user)
response = self.client.get(
reverse("authentik_api:application-list") + "?superuser_full_list=true"
)
response = self.client.get(reverse("authentik_api:application-list"))
self.assertJSONEqual(
response.content.decode(),
{

View File

@@ -2733,12 +2733,8 @@ paths:
/core/applications/:
get:
operationId: core_applications_list
description: Custom list method that checks Policy based access instead of guardian
description: Application Viewset
parameters:
- in: query
name: for_user
schema:
type: integer
- in: query
name: group
schema:
@@ -2756,10 +2752,6 @@ paths:
schema:
type: string
- $ref: '#/components/parameters/QueryName'
- in: query
name: only_with_launch_url
schema:
type: boolean
- $ref: '#/components/parameters/QueryPaginationOrdering'
- $ref: '#/components/parameters/QueryPaginationPage'
- $ref: '#/components/parameters/QueryPaginationPageSize'
@@ -2768,10 +2760,6 @@ paths:
name: slug
schema:
type: string
- in: query
name: superuser_full_list
schema:
type: boolean
tags:
- core
security:
@@ -2977,6 +2965,59 @@ paths:
$ref: '#/components/responses/ValidationErrorResponse'
'403':
$ref: '#/components/responses/GenericErrorResponse'
/core/applications/@accessible/:
get:
operationId: core_applications_accessible_list
description: Get applications accessible for user
parameters:
- in: query
name: for_user
schema:
type: integer
- in: query
name: group
schema:
type: string
- in: query
name: meta_description
schema:
type: string
- in: query
name: meta_launch_url
schema:
type: string
- in: query
name: meta_publisher
schema:
type: string
- $ref: '#/components/parameters/QueryName'
- in: query
name: only_with_launch_url
schema:
type: boolean
- $ref: '#/components/parameters/QueryPaginationOrdering'
- $ref: '#/components/parameters/QueryPaginationPage'
- $ref: '#/components/parameters/QueryPaginationPageSize'
- $ref: '#/components/parameters/QuerySearch'
- in: query
name: slug
schema:
type: string
tags:
- core
security:
- authentik: []
responses:
'200':
content:
application/json:
schema:
$ref: '#/components/schemas/PaginatedApplicationList'
description: ''
'400':
$ref: '#/components/responses/ValidationErrorResponse'
'403':
$ref: '#/components/responses/GenericErrorResponse'
/core/authenticated_sessions/:
get:
operationId: core_authenticated_sessions_list

View File

@@ -63,7 +63,6 @@ export class ApplicationListPage extends WithBrandConfig(TablePage<Application>)
async apiEndpoint(): Promise<PaginatedResponse<Application>> {
return new CoreApi(DEFAULT_CONFIG).coreApplicationsList({
...(await this.defaultEndpointConfig()),
superuserFullList: true,
});
}

View File

@@ -161,7 +161,6 @@ export class BrandForm extends ModelForm<Brand, string> {
.fetchObjects=${async (query?: string): Promise<Application[]> => {
const args: CoreApplicationsListRequest = {
ordering: "name",
superuserFullList: true,
};
if (query !== undefined) {
args.search = query;

View File

@@ -23,7 +23,7 @@ export class UserApplicationTable extends Table<Application> {
static styles: CSSResult[] = [...super.styles, applicationListStyle];
async apiEndpoint(): Promise<PaginatedResponse<Application>> {
return new CoreApi(DEFAULT_CONFIG).coreApplicationsList({
return new CoreApi(DEFAULT_CONFIG).coreApplicationsAccessibleList({
...(await this.defaultEndpointConfig()),
forUser: this.user?.pk,
});

View File

@@ -69,7 +69,7 @@ export class LibraryPage extends AKElement {
onlyWithLaunchUrl: true,
});
const applicationListFetch = await coreApi().coreApplicationsList(applicationListParams(1));
const applicationListFetch = await coreApi().coreApplicationsAccessibleList(applicationListParams(1));
const pageCount = applicationListFetch.pagination.totalPages;
if (pageCount === 1) {
return applicationListFetch.results;
@@ -77,7 +77,7 @@ export class LibraryPage extends AKElement {
const applicationLaterPages = await Promise.allSettled(
Array.from({ length: pageCount - 1 }).map((_a, idx) =>
coreApi().coreApplicationsList(applicationListParams(idx + 2)),
coreApi().coreApplicationsAccessibleList(applicationListParams(idx + 2)),
),
);