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:
Jens Langhammer 2022-02-08 23:46:23 +01:00
parent 1a072c6c39
commit 6314be14ad
3 changed files with 26 additions and 7 deletions

View File

@ -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

View File

@ -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": "",

View File

@ -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