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:
		@ -1,13 +1,16 @@
 | 
			
		||||
"""Application API Views"""
 | 
			
		||||
from typing import Optional
 | 
			
		||||
 | 
			
		||||
from django.core.cache import cache
 | 
			
		||||
from django.db.models import QuerySet
 | 
			
		||||
from django.http.response import HttpResponseBadRequest
 | 
			
		||||
from django.shortcuts import get_object_or_404
 | 
			
		||||
from django.utils.functional import SimpleLazyObject
 | 
			
		||||
from drf_spectacular.types import OpenApiTypes
 | 
			
		||||
from drf_spectacular.utils import OpenApiParameter, OpenApiResponse, extend_schema
 | 
			
		||||
from guardian.shortcuts import get_objects_for_user
 | 
			
		||||
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.request import Request
 | 
			
		||||
from rest_framework.response import Response
 | 
			
		||||
@ -39,11 +42,22 @@ def user_app_cache_key(user_pk: str) -> str:
 | 
			
		||||
class ApplicationSerializer(ModelSerializer):
 | 
			
		||||
    """Application Serializer"""
 | 
			
		||||
 | 
			
		||||
    launch_url = ReadOnlyField(source="get_launch_url")
 | 
			
		||||
    launch_url = SerializerMethodField()
 | 
			
		||||
    provider_obj = ProviderSerializer(source="get_provider", required=False)
 | 
			
		||||
 | 
			
		||||
    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:
 | 
			
		||||
 | 
			
		||||
        model = Application
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,9 @@ class TestApplicationsAPI(APITestCase):
 | 
			
		||||
 | 
			
		||||
    def setUp(self) -> None:
 | 
			
		||||
        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")
 | 
			
		||||
        PolicyBinding.objects.create(
 | 
			
		||||
            target=self.denied,
 | 
			
		||||
@ -64,8 +66,8 @@ class TestApplicationsAPI(APITestCase):
 | 
			
		||||
                        "slug": "allowed",
 | 
			
		||||
                        "provider": None,
 | 
			
		||||
                        "provider_obj": None,
 | 
			
		||||
                        "launch_url": None,
 | 
			
		||||
                        "meta_launch_url": "",
 | 
			
		||||
                        "launch_url": f"https://goauthentik.io/{self.user.username}",
 | 
			
		||||
                        "meta_launch_url": "https://goauthentik.io/%(username)s",
 | 
			
		||||
                        "meta_icon": None,
 | 
			
		||||
                        "meta_description": "",
 | 
			
		||||
                        "meta_publisher": "",
 | 
			
		||||
@ -100,8 +102,8 @@ class TestApplicationsAPI(APITestCase):
 | 
			
		||||
                        "slug": "allowed",
 | 
			
		||||
                        "provider": None,
 | 
			
		||||
                        "provider_obj": None,
 | 
			
		||||
                        "launch_url": None,
 | 
			
		||||
                        "meta_launch_url": "",
 | 
			
		||||
                        "launch_url": f"https://goauthentik.io/{self.user.username}",
 | 
			
		||||
                        "meta_launch_url": "https://goauthentik.io/%(username)s",
 | 
			
		||||
                        "meta_icon": None,
 | 
			
		||||
                        "meta_description": "",
 | 
			
		||||
                        "meta_publisher": "",
 | 
			
		||||
 | 
			
		||||
@ -24,6 +24,9 @@ The following aspects can be configured:
 | 
			
		||||
 | 
			
		||||
- *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
 | 
			
		||||
 | 
			
		||||
    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
 | 
			
		||||
- *Publisher*: Text shown below the application
 | 
			
		||||
- *Description*: Subtext shown on the application card below the publisher
 | 
			
		||||
 | 
			
		||||
		Reference in New Issue
	
	Block a user