core: allow users to create non-expiring tokens when flag is set
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
30aa24ce6e
commit
6f98833150
|
@ -12,7 +12,7 @@ from authentik.api.decorators import permission_required
|
||||||
from authentik.core.api.used_by import UsedByMixin
|
from authentik.core.api.used_by import UsedByMixin
|
||||||
from authentik.core.api.users import UserSerializer
|
from authentik.core.api.users import UserSerializer
|
||||||
from authentik.core.api.utils import PassiveSerializer
|
from authentik.core.api.utils import PassiveSerializer
|
||||||
from authentik.core.models import Token, TokenIntents
|
from authentik.core.models import USER_ATTRIBUTE_TOKEN_EXPIRING, Token, TokenIntents
|
||||||
from authentik.events.models import Event, EventAction
|
from authentik.events.models import Event, EventAction
|
||||||
from authentik.managed.api import ManagedSerializer
|
from authentik.managed.api import ManagedSerializer
|
||||||
|
|
||||||
|
@ -61,11 +61,19 @@ class TokenViewSet(UsedByMixin, ModelViewSet):
|
||||||
"intent",
|
"intent",
|
||||||
"user__username",
|
"user__username",
|
||||||
"description",
|
"description",
|
||||||
|
"expires",
|
||||||
|
"expiring",
|
||||||
]
|
]
|
||||||
ordering = ["expires"]
|
ordering = ["expires"]
|
||||||
|
|
||||||
def perform_create(self, serializer: TokenSerializer):
|
def perform_create(self, serializer: TokenSerializer):
|
||||||
serializer.save(user=self.request.user, intent=TokenIntents.INTENT_API)
|
serializer.save(
|
||||||
|
user=self.request.user,
|
||||||
|
intent=TokenIntents.INTENT_API,
|
||||||
|
expiring=self.request.user.attributes.get(
|
||||||
|
USER_ATTRIBUTE_TOKEN_EXPIRING, True
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
@permission_required("authentik_core.view_token_key")
|
@permission_required("authentik_core.view_token_key")
|
||||||
@extend_schema(
|
@extend_schema(
|
||||||
|
|
|
@ -37,6 +37,7 @@ LOGGER = get_logger()
|
||||||
USER_ATTRIBUTE_DEBUG = "goauthentik.io/user/debug"
|
USER_ATTRIBUTE_DEBUG = "goauthentik.io/user/debug"
|
||||||
USER_ATTRIBUTE_SA = "goauthentik.io/user/service-account"
|
USER_ATTRIBUTE_SA = "goauthentik.io/user/service-account"
|
||||||
USER_ATTRIBUTE_SOURCES = "goauthentik.io/user/sources"
|
USER_ATTRIBUTE_SOURCES = "goauthentik.io/user/sources"
|
||||||
|
USER_ATTRIBUTE_TOKEN_EXPIRING = "goauthentik.io/user/token-expires" # nosec
|
||||||
|
|
||||||
GRAVATAR_URL = "https://secure.gravatar.com"
|
GRAVATAR_URL = "https://secure.gravatar.com"
|
||||||
DEFAULT_AVATAR = static("dist/assets/images/user_default.png")
|
DEFAULT_AVATAR = static("dist/assets/images/user_default.png")
|
||||||
|
|
|
@ -2,7 +2,12 @@
|
||||||
from django.urls.base import reverse
|
from django.urls.base import reverse
|
||||||
from rest_framework.test import APITestCase
|
from rest_framework.test import APITestCase
|
||||||
|
|
||||||
from authentik.core.models import Token, TokenIntents, User
|
from authentik.core.models import (
|
||||||
|
USER_ATTRIBUTE_TOKEN_EXPIRING,
|
||||||
|
Token,
|
||||||
|
TokenIntents,
|
||||||
|
User,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestTokenAPI(APITestCase):
|
class TestTokenAPI(APITestCase):
|
||||||
|
@ -22,3 +27,17 @@ class TestTokenAPI(APITestCase):
|
||||||
token = Token.objects.get(identifier="test-token")
|
token = Token.objects.get(identifier="test-token")
|
||||||
self.assertEqual(token.user, self.user)
|
self.assertEqual(token.user, self.user)
|
||||||
self.assertEqual(token.intent, TokenIntents.INTENT_API)
|
self.assertEqual(token.intent, TokenIntents.INTENT_API)
|
||||||
|
self.assertEqual(token.expiring, True)
|
||||||
|
|
||||||
|
def test_token_create_non_expiring(self):
|
||||||
|
"""Test token creation endpoint"""
|
||||||
|
self.user.attributes[USER_ATTRIBUTE_TOKEN_EXPIRING] = False
|
||||||
|
self.user.save()
|
||||||
|
response = self.client.post(
|
||||||
|
reverse("authentik_api:token-list"), {"identifier": "test-token"}
|
||||||
|
)
|
||||||
|
self.assertEqual(response.status_code, 201)
|
||||||
|
token = Token.objects.get(identifier="test-token")
|
||||||
|
self.assertEqual(token.user, self.user)
|
||||||
|
self.assertEqual(token.intent, TokenIntents.INTENT_API)
|
||||||
|
self.assertEqual(token.expiring, False)
|
||||||
|
|
|
@ -2429,6 +2429,15 @@ paths:
|
||||||
name: description
|
name: description
|
||||||
schema:
|
schema:
|
||||||
type: string
|
type: string
|
||||||
|
- in: query
|
||||||
|
name: expires
|
||||||
|
schema:
|
||||||
|
type: string
|
||||||
|
format: date-time
|
||||||
|
- in: query
|
||||||
|
name: expiring
|
||||||
|
schema:
|
||||||
|
type: boolean
|
||||||
- in: query
|
- in: query
|
||||||
name: identifier
|
name: identifier
|
||||||
schema:
|
schema:
|
||||||
|
|
|
@ -47,9 +47,8 @@ export class UserTokenForm extends ModelForm<Token, string> {
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
<ak-form-element-horizontal
|
<ak-form-element-horizontal
|
||||||
label=${t`Description`}
|
label=${t`Description`}
|
||||||
?required=${true}
|
|
||||||
name="description">
|
name="description">
|
||||||
<input type="text" value="${ifDefined(this.instance?.description)}" class="pf-c-form-control" required>
|
<input type="text" value="${ifDefined(this.instance?.description)}" class="pf-c-form-control">
|
||||||
</ak-form-element-horizontal>
|
</ak-form-element-horizontal>
|
||||||
</form>`;
|
</form>`;
|
||||||
}
|
}
|
||||||
|
|
Reference in New Issue