core: improve messaging when creating a recovery link for a user when no recovery flow exists
Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>
This commit is contained in:
parent
cfe0a7a694
commit
c5e2635903
|
@ -1,4 +1,5 @@
|
|||
"""User API Views"""
|
||||
from django.http.response import Http404
|
||||
from django.urls import reverse_lazy
|
||||
from django.utils.http import urlencode
|
||||
from drf_yasg.utils import swagger_auto_schema, swagger_serializer_method
|
||||
|
@ -19,6 +20,7 @@ from authentik.core.middleware import (
|
|||
)
|
||||
from authentik.core.models import Token, TokenIntents, User
|
||||
from authentik.events.models import EventAction
|
||||
from authentik.flows.models import Flow, FlowDesignation
|
||||
|
||||
|
||||
class UserSerializer(ModelSerializer):
|
||||
|
@ -121,12 +123,16 @@ class UserViewSet(ModelViewSet):
|
|||
|
||||
@permission_required("authentik_core.reset_user_password")
|
||||
@swagger_auto_schema(
|
||||
responses={"200": LinkSerializer(many=False)},
|
||||
responses={"200": LinkSerializer(many=False), "404": "No recovery flow found."},
|
||||
)
|
||||
@action(detail=True, pagination_class=None, filter_backends=[])
|
||||
# pylint: disable=invalid-name, unused-argument
|
||||
def recovery(self, request: Request, pk: int) -> Response:
|
||||
"""Create a temporary link that a user can use to recover their accounts"""
|
||||
# Check that there is a recovery flow, if not return an error
|
||||
flow = Flow.with_policy(request, designation=FlowDesignation.RECOVERY)
|
||||
if not flow:
|
||||
raise Http404
|
||||
user: User = self.get_object()
|
||||
token, __ = Token.objects.get_or_create(
|
||||
identifier=f"{user.uid}-password-reset",
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
"""OAuth Source tests"""
|
||||
from authentik.sources.oauth.api.source import OAuthSourceSerializer
|
||||
from django.test import TestCase
|
||||
from django.urls import reverse
|
||||
|
||||
from authentik.sources.oauth.api.source import OAuthSourceSerializer
|
||||
from authentik.sources.oauth.models import OAuthSource
|
||||
|
||||
|
||||
|
@ -21,20 +21,28 @@ class TestOAuthSource(TestCase):
|
|||
|
||||
def test_api_validate(self):
|
||||
"""Test API validation"""
|
||||
self.assertTrue(OAuthSourceSerializer(data={
|
||||
"name": "foo",
|
||||
"slug": "bar",
|
||||
"provider_type": "google",
|
||||
"consumer_key": "foo",
|
||||
"consumer_secret": "foo",
|
||||
}).is_valid())
|
||||
self.assertFalse(OAuthSourceSerializer(data={
|
||||
"name": "foo",
|
||||
"slug": "bar",
|
||||
"provider_type": "openid-connect",
|
||||
"consumer_key": "foo",
|
||||
"consumer_secret": "foo",
|
||||
}).is_valid())
|
||||
self.assertTrue(
|
||||
OAuthSourceSerializer(
|
||||
data={
|
||||
"name": "foo",
|
||||
"slug": "bar",
|
||||
"provider_type": "google",
|
||||
"consumer_key": "foo",
|
||||
"consumer_secret": "foo",
|
||||
}
|
||||
).is_valid()
|
||||
)
|
||||
self.assertFalse(
|
||||
OAuthSourceSerializer(
|
||||
data={
|
||||
"name": "foo",
|
||||
"slug": "bar",
|
||||
"provider_type": "openid-connect",
|
||||
"consumer_key": "foo",
|
||||
"consumer_secret": "foo",
|
||||
}
|
||||
).is_valid()
|
||||
)
|
||||
|
||||
def test_source_redirect(self):
|
||||
"""test redirect view"""
|
||||
|
|
|
@ -2237,15 +2237,15 @@ paths:
|
|||
description: ''
|
||||
schema:
|
||||
$ref: '#/definitions/Link'
|
||||
'403':
|
||||
description: Authentication credentials were invalid, absent or insufficient.
|
||||
schema:
|
||||
$ref: '#/definitions/GenericError'
|
||||
'404':
|
||||
description: Object does not exist or caller has insufficient permissions
|
||||
to access it.
|
||||
schema:
|
||||
$ref: '#/definitions/APIException'
|
||||
'403':
|
||||
description: Authentication credentials were invalid, absent or insufficient.
|
||||
schema:
|
||||
$ref: '#/definitions/GenericError'
|
||||
tags:
|
||||
- core
|
||||
parameters:
|
||||
|
|
|
@ -737,8 +737,8 @@ msgstr "Copy Key"
|
|||
#: src/pages/stages/prompt/PromptStageForm.ts:98
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts:50
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts:58
|
||||
#: src/pages/users/UserListPage.ts:144
|
||||
#: src/pages/users/UserListPage.ts:152
|
||||
#: src/pages/users/UserListPage.ts:151
|
||||
#: src/pages/users/UserListPage.ts:159
|
||||
msgid "Create"
|
||||
msgstr "Create"
|
||||
|
||||
|
@ -808,7 +808,7 @@ msgstr "Create Stage binding"
|
|||
msgid "Create Token"
|
||||
msgstr "Create Token"
|
||||
|
||||
#: src/pages/users/UserListPage.ts:147
|
||||
#: src/pages/users/UserListPage.ts:154
|
||||
msgid "Create User"
|
||||
msgstr "Create User"
|
||||
|
||||
|
@ -1531,7 +1531,7 @@ msgstr "If this flag is set, this Stage will jump to the next Stage when no Invi
|
|||
msgid "If your authentik Instance is using a self-signed certificate, set this value."
|
||||
msgstr "If your authentik Instance is using a self-signed certificate, set this value."
|
||||
|
||||
#: src/pages/users/UserListPage.ts:136
|
||||
#: src/pages/users/UserListPage.ts:143
|
||||
msgid "Impersonate"
|
||||
msgstr "Impersonate"
|
||||
|
||||
|
@ -1996,6 +1996,10 @@ msgstr "No policies are currently bound to this object."
|
|||
msgid "No policies cached. Users may experience slow response times."
|
||||
msgstr "No policies cached. Users may experience slow response times."
|
||||
|
||||
#: src/pages/users/UserListPage.ts:135
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr "No recovery flow is configured."
|
||||
|
||||
#: src/pages/flows/BoundStagesList.ts:114
|
||||
msgid "No stages are currently bound to this flow."
|
||||
msgstr "No stages are currently bound to this flow."
|
||||
|
@ -2538,7 +2542,7 @@ msgstr "Required"
|
|||
msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
|
||||
msgstr "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
|
||||
|
||||
#: src/pages/users/UserListPage.ts:133
|
||||
#: src/pages/users/UserListPage.ts:140
|
||||
#: src/pages/users/UserViewPage.ts:165
|
||||
msgid "Reset Password"
|
||||
msgstr "Reset Password"
|
||||
|
|
|
@ -731,8 +731,8 @@ msgstr ""
|
|||
#: src/pages/stages/prompt/PromptStageForm.ts:98
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts:50
|
||||
#: src/pages/user-settings/tokens/UserTokenList.ts:58
|
||||
#: src/pages/users/UserListPage.ts:144
|
||||
#: src/pages/users/UserListPage.ts:152
|
||||
#: src/pages/users/UserListPage.ts:151
|
||||
#: src/pages/users/UserListPage.ts:159
|
||||
msgid "Create"
|
||||
msgstr ""
|
||||
|
||||
|
@ -802,7 +802,7 @@ msgstr ""
|
|||
msgid "Create Token"
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts:147
|
||||
#: src/pages/users/UserListPage.ts:154
|
||||
msgid "Create User"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1523,7 +1523,7 @@ msgstr ""
|
|||
msgid "If your authentik Instance is using a self-signed certificate, set this value."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts:136
|
||||
#: src/pages/users/UserListPage.ts:143
|
||||
msgid "Impersonate"
|
||||
msgstr ""
|
||||
|
||||
|
@ -1988,6 +1988,10 @@ msgstr ""
|
|||
msgid "No policies cached. Users may experience slow response times."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts:135
|
||||
msgid "No recovery flow is configured."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/flows/BoundStagesList.ts:114
|
||||
msgid "No stages are currently bound to this flow."
|
||||
msgstr ""
|
||||
|
@ -2530,7 +2534,7 @@ msgstr ""
|
|||
msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
|
||||
msgstr ""
|
||||
|
||||
#: src/pages/users/UserListPage.ts:133
|
||||
#: src/pages/users/UserListPage.ts:140
|
||||
#: src/pages/users/UserViewPage.ts:165
|
||||
msgid "Reset Password"
|
||||
msgstr ""
|
||||
|
|
|
@ -127,6 +127,13 @@ export class UserListPage extends TablePage<User> {
|
|||
message: t`Successfully generated recovery link`,
|
||||
description: rec.link
|
||||
});
|
||||
}).catch((ex: Response) => {
|
||||
ex.json().then(() => {
|
||||
showMessage({
|
||||
level: MessageLevel.error,
|
||||
message: t`No recovery flow is configured.`,
|
||||
});
|
||||
});
|
||||
});
|
||||
}}>
|
||||
${t`Reset Password`}
|
||||
|
|
Reference in New Issue