Repository: goauthentik/authentik

Issue:
User cannot create app password
**Describe the bug**

User cannot create app password, return 405 error


**To Reproduce**

user login

https://<host>/if/user/#/settings;%7B%22page%22%3A%22page-tokens%22%7D



1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

**Expected behavior**

the user app passord is created

**Screenshots**

![image](https://github.com/goauthentik/authentik/assets/60494468/c10d3676-4e79-429f-ad0a-5b1091d2c9c1)


**Logs**

**Version and Deployment (please complete the following information):**

-   authentik version: 2024.4.0
-   Deployment: docker-compose

**Additional context**

locale setting also not working.




Discussion:

Resolving patch:
diff --git a/authentik/core/api/tokens.py b/authentik/core/api/tokens.py
--- a/authentik/core/api/tokens.py
+++ b/authentik/core/api/tokens.py
@@ -2,6 +2,7 @@
 
 from typing import Any
 
+from django.utils.timezone import now
 from django_filters.rest_framework import DjangoFilterBackend
 from drf_spectacular.utils import OpenApiResponse, extend_schema, inline_serializer
 from guardian.shortcuts import assign_perm, get_anonymous_user
@@ -27,7 +28,6 @@
     TokenIntents,
     User,
     default_token_duration,
-    token_expires_from_timedelta,
 )
 from authentik.events.models import Event, EventAction
 from authentik.events.utils import model_to_dict
@@ -68,15 +68,17 @@ def validate(self, attrs: dict[Any, str]) -> dict[Any, str]:
             max_token_lifetime_dt = default_token_duration()
             if max_token_lifetime is not None:
                 try:
-                    max_token_lifetime_dt = timedelta_from_string(max_token_lifetime)
+                    max_token_lifetime_dt = now() + timedelta_from_string(max_token_lifetime)
                 except ValueError:
-                    max_token_lifetime_dt = default_token_duration()
+                    pass
 
-            if "expires" in attrs and attrs.get("expires") > token_expires_from_timedelta(
-                max_token_lifetime_dt
-            ):
+            if "expires" in attrs and attrs.get("expires") > max_token_lifetime_dt:
                 raise ValidationError(
-                    {"expires": f"Token expires exceeds maximum lifetime ({max_token_lifetime})."}
+                    {
+                        "expires": (
+                            f"Token expires exceeds maximum lifetime ({max_token_lifetime_dt} UTC)."
+                        )
+                    }
                 )
         elif attrs.get("intent") == TokenIntents.INTENT_API:
             # For API tokens, expires cannot be overridden
diff --git a/authentik/core/models.py b/authentik/core/models.py
--- a/authentik/core/models.py
+++ b/authentik/core/models.py
@@ -1,6 +1,6 @@
 """authentik core models"""
 
-from datetime import datetime, timedelta
+from datetime import datetime
 from hashlib import sha256
 from typing import Any, Optional, Self
 from uuid import uuid4
@@ -68,11 +68,6 @@ def default_token_duration() -> datetime:
     return now() + timedelta_from_string(token_duration)
 
 
-def token_expires_from_timedelta(dt: timedelta) -> datetime:
-    """Return a `datetime.datetime` object with the duration of the Token"""
-    return now() + dt
-
-
 def default_token_key() -> str:
     """Default token key"""
     current_tenant = get_current_tenant()
diff --git a/authentik/tenants/models.py b/authentik/tenants/models.py
--- a/authentik/tenants/models.py
+++ b/authentik/tenants/models.py
@@ -23,7 +23,7 @@
 
 VALID_SCHEMA_NAME = re.compile(r"^t_[a-z0-9]{1,61}$")
 
-DEFAULT_TOKEN_DURATION = "minutes=30"  # nosec
+DEFAULT_TOKEN_DURATION = "days=1"  # nosec
 DEFAULT_TOKEN_LENGTH = 60
 
 


Test patch: