core: allow formatting strings to be used for applications' launch URLs
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
4343246a41
commit
e741caa6b3
|
@ -1,13 +1,16 @@
|
||||||
"""Application API Views"""
|
"""Application API Views"""
|
||||||
|
from typing import Optional
|
||||||
|
|
||||||
from django.core.cache import cache
|
from django.core.cache import cache
|
||||||
from django.db.models import QuerySet
|
from django.db.models import QuerySet
|
||||||
from django.http.response import HttpResponseBadRequest
|
from django.http.response import HttpResponseBadRequest
|
||||||
from django.shortcuts import get_object_or_404
|
from django.shortcuts import get_object_or_404
|
||||||
|
from django.utils.functional import SimpleLazyObject
|
||||||
from drf_spectacular.types import OpenApiTypes
|
from drf_spectacular.types import OpenApiTypes
|
||||||
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
|
||||||
from guardian.shortcuts import get_objects_for_user
|
from guardian.shortcuts import get_objects_for_user
|
||||||
from rest_framework.decorators import action
|
from rest_framework.decorators import action
|
||||||
from rest_framework.fields import ReadOnlyField
|
from rest_framework.fields import ReadOnlyField, SerializerMethodField
|
||||||
from rest_framework.parsers import MultiPartParser
|
from rest_framework.parsers import MultiPartParser
|
||||||
from rest_framework.request import Request
|
from rest_framework.request import Request
|
||||||
from rest_framework.response import Response
|
from rest_framework.response import Response
|
||||||
|
@ -39,11 +42,22 @@ def user_app_cache_key(user_pk: str) -> str:
|
||||||
class ApplicationSerializer(ModelSerializer):
|
class ApplicationSerializer(ModelSerializer):
|
||||||
"""Application Serializer"""
|
"""Application Serializer"""
|
||||||
|
|
||||||
launch_url = ReadOnlyField(source="get_launch_url")
|
launch_url = SerializerMethodField()
|
||||||
provider_obj = ProviderSerializer(source="get_provider", required=False)
|
provider_obj = ProviderSerializer(source="get_provider", required=False)
|
||||||
|
|
||||||
meta_icon = ReadOnlyField(source="get_meta_icon")
|
meta_icon = ReadOnlyField(source="get_meta_icon")
|
||||||
|
|
||||||
|
def get_launch_url(self, app: Application) -> Optional[str]:
|
||||||
|
"""Allow formatting of launch URL"""
|
||||||
|
url = app.get_launch_url()
|
||||||
|
if not url:
|
||||||
|
return url
|
||||||
|
user = self.context["request"].user
|
||||||
|
if isinstance(user, SimpleLazyObject):
|
||||||
|
user._setup()
|
||||||
|
user = user._wrapped
|
||||||
|
return url % user.__dict__
|
||||||
|
|
||||||
class Meta:
|
class Meta:
|
||||||
|
|
||||||
model = Application
|
model = Application
|
||||||
|
|
|
@ -13,7 +13,9 @@ class TestApplicationsAPI(APITestCase):
|
||||||
|
|
||||||
def setUp(self) -> None:
|
def setUp(self) -> None:
|
||||||
self.user = create_test_admin_user()
|
self.user = create_test_admin_user()
|
||||||
self.allowed = Application.objects.create(name="allowed", slug="allowed")
|
self.allowed = Application.objects.create(
|
||||||
|
name="allowed", slug="allowed", meta_launch_url="https://goauthentik.io/%(username)s"
|
||||||
|
)
|
||||||
self.denied = Application.objects.create(name="denied", slug="denied")
|
self.denied = Application.objects.create(name="denied", slug="denied")
|
||||||
PolicyBinding.objects.create(
|
PolicyBinding.objects.create(
|
||||||
target=self.denied,
|
target=self.denied,
|
||||||
|
@ -64,8 +66,8 @@ class TestApplicationsAPI(APITestCase):
|
||||||
"slug": "allowed",
|
"slug": "allowed",
|
||||||
"provider": None,
|
"provider": None,
|
||||||
"provider_obj": None,
|
"provider_obj": None,
|
||||||
"launch_url": None,
|
"launch_url": f"https://goauthentik.io/{self.user.username}",
|
||||||
"meta_launch_url": "",
|
"meta_launch_url": "https://goauthentik.io/%(username)s",
|
||||||
"meta_icon": None,
|
"meta_icon": None,
|
||||||
"meta_description": "",
|
"meta_description": "",
|
||||||
"meta_publisher": "",
|
"meta_publisher": "",
|
||||||
|
@ -100,8 +102,8 @@ class TestApplicationsAPI(APITestCase):
|
||||||
"slug": "allowed",
|
"slug": "allowed",
|
||||||
"provider": None,
|
"provider": None,
|
||||||
"provider_obj": None,
|
"provider_obj": None,
|
||||||
"launch_url": None,
|
"launch_url": f"https://goauthentik.io/{self.user.username}",
|
||||||
"meta_launch_url": "",
|
"meta_launch_url": "https://goauthentik.io/%(username)s",
|
||||||
"meta_icon": None,
|
"meta_icon": None,
|
||||||
"meta_description": "",
|
"meta_description": "",
|
||||||
"meta_publisher": "",
|
"meta_publisher": "",
|
||||||
|
|
|
@ -24,6 +24,9 @@ The following aspects can be configured:
|
||||||
|
|
||||||
- *Name*: This is the name shown for the application card
|
- *Name*: This is the name shown for the application card
|
||||||
- *Launch URL*: The URL that is opened when a user clicks on the application. When left empty, authentik tries to guess it based on the provider
|
- *Launch URL*: The URL that is opened when a user clicks on the application. When left empty, authentik tries to guess it based on the provider
|
||||||
|
|
||||||
|
Starting with authentik 2022.2, you can use placeholders in the launch url to build them dynamically based on logged in user. For example, you can set the Launch URL to `https://goauthentik.io/%(username)s`, which will be replaced with the currently logged in user's username.
|
||||||
|
|
||||||
- *Icon (URL)*: Optionally configure an Icon for the application
|
- *Icon (URL)*: Optionally configure an Icon for the application
|
||||||
- *Publisher*: Text shown below the application
|
- *Publisher*: Text shown below the application
|
||||||
- *Description*: Subtext shown on the application card below the publisher
|
- *Description*: Subtext shown on the application card below the publisher
|
||||||
|
|
Reference in New Issue