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:
Jens Langhammer 2021-04-16 10:09:46 +02:00
parent 1992b89154
commit 5e67f68f2b
6 changed files with 59 additions and 30 deletions

View File

@ -1,4 +1,5 @@
"""User API Views""" """User API Views"""
from django.http.response import Http404
from django.urls import reverse_lazy from django.urls import reverse_lazy
from django.utils.http import urlencode from django.utils.http import urlencode
from drf_yasg.utils import swagger_auto_schema, swagger_serializer_method 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.core.models import Token, TokenIntents, User
from authentik.events.models import EventAction from authentik.events.models import EventAction
from authentik.flows.models import Flow, FlowDesignation
class UserSerializer(ModelSerializer): class UserSerializer(ModelSerializer):
@ -121,12 +123,16 @@ class UserViewSet(ModelViewSet):
@permission_required("authentik_core.reset_user_password") @permission_required("authentik_core.reset_user_password")
@swagger_auto_schema( @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=[]) @action(detail=True, pagination_class=None, filter_backends=[])
# pylint: disable=invalid-name, unused-argument # pylint: disable=invalid-name, unused-argument
def recovery(self, request: Request, pk: int) -> Response: def recovery(self, request: Request, pk: int) -> Response:
"""Create a temporary link that a user can use to recover their accounts""" """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() user: User = self.get_object()
token, __ = Token.objects.get_or_create( token, __ = Token.objects.get_or_create(
identifier=f"{user.uid}-password-reset", identifier=f"{user.uid}-password-reset",

View File

@ -1,8 +1,8 @@
"""OAuth Source tests""" """OAuth Source tests"""
from authentik.sources.oauth.api.source import OAuthSourceSerializer
from django.test import TestCase from django.test import TestCase
from django.urls import reverse from django.urls import reverse
from authentik.sources.oauth.api.source import OAuthSourceSerializer
from authentik.sources.oauth.models import OAuthSource from authentik.sources.oauth.models import OAuthSource
@ -21,20 +21,28 @@ class TestOAuthSource(TestCase):
def test_api_validate(self): def test_api_validate(self):
"""Test API validation""" """Test API validation"""
self.assertTrue(OAuthSourceSerializer(data={ self.assertTrue(
OAuthSourceSerializer(
data={
"name": "foo", "name": "foo",
"slug": "bar", "slug": "bar",
"provider_type": "google", "provider_type": "google",
"consumer_key": "foo", "consumer_key": "foo",
"consumer_secret": "foo", "consumer_secret": "foo",
}).is_valid()) }
self.assertFalse(OAuthSourceSerializer(data={ ).is_valid()
)
self.assertFalse(
OAuthSourceSerializer(
data={
"name": "foo", "name": "foo",
"slug": "bar", "slug": "bar",
"provider_type": "openid-connect", "provider_type": "openid-connect",
"consumer_key": "foo", "consumer_key": "foo",
"consumer_secret": "foo", "consumer_secret": "foo",
}).is_valid()) }
).is_valid()
)
def test_source_redirect(self): def test_source_redirect(self):
"""test redirect view""" """test redirect view"""

View File

@ -2237,15 +2237,15 @@ paths:
description: '' description: ''
schema: schema:
$ref: '#/definitions/Link' $ref: '#/definitions/Link'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
'404': '404':
description: Object does not exist or caller has insufficient permissions description: Object does not exist or caller has insufficient permissions
to access it. to access it.
schema: schema:
$ref: '#/definitions/APIException' $ref: '#/definitions/APIException'
'403':
description: Authentication credentials were invalid, absent or insufficient.
schema:
$ref: '#/definitions/GenericError'
tags: tags:
- core - core
parameters: parameters:

View File

@ -737,8 +737,8 @@ msgstr "Copy Key"
#: src/pages/stages/prompt/PromptStageForm.ts:98 #: src/pages/stages/prompt/PromptStageForm.ts:98
#: src/pages/user-settings/tokens/UserTokenList.ts:50 #: src/pages/user-settings/tokens/UserTokenList.ts:50
#: src/pages/user-settings/tokens/UserTokenList.ts:58 #: src/pages/user-settings/tokens/UserTokenList.ts:58
#: src/pages/users/UserListPage.ts:144 #: src/pages/users/UserListPage.ts:151
#: src/pages/users/UserListPage.ts:152 #: src/pages/users/UserListPage.ts:159
msgid "Create" msgid "Create"
msgstr "Create" msgstr "Create"
@ -808,7 +808,7 @@ msgstr "Create Stage binding"
msgid "Create Token" msgid "Create Token"
msgstr "Create Token" msgstr "Create Token"
#: src/pages/users/UserListPage.ts:147 #: src/pages/users/UserListPage.ts:154
msgid "Create User" msgid "Create User"
msgstr "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." 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." 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" msgid "Impersonate"
msgstr "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." msgid "No policies cached. Users may experience slow response times."
msgstr "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 #: src/pages/flows/BoundStagesList.ts:114
msgid "No stages are currently bound to this flow." msgid "No stages are currently bound to this flow."
msgstr "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." msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr "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 #: src/pages/users/UserViewPage.ts:165
msgid "Reset Password" msgid "Reset Password"
msgstr "Reset Password" msgstr "Reset Password"

View File

@ -731,8 +731,8 @@ msgstr ""
#: src/pages/stages/prompt/PromptStageForm.ts:98 #: src/pages/stages/prompt/PromptStageForm.ts:98
#: src/pages/user-settings/tokens/UserTokenList.ts:50 #: src/pages/user-settings/tokens/UserTokenList.ts:50
#: src/pages/user-settings/tokens/UserTokenList.ts:58 #: src/pages/user-settings/tokens/UserTokenList.ts:58
#: src/pages/users/UserListPage.ts:144 #: src/pages/users/UserListPage.ts:151
#: src/pages/users/UserListPage.ts:152 #: src/pages/users/UserListPage.ts:159
msgid "Create" msgid "Create"
msgstr "" msgstr ""
@ -802,7 +802,7 @@ msgstr ""
msgid "Create Token" msgid "Create Token"
msgstr "" msgstr ""
#: src/pages/users/UserListPage.ts:147 #: src/pages/users/UserListPage.ts:154
msgid "Create User" msgid "Create User"
msgstr "" msgstr ""
@ -1523,7 +1523,7 @@ msgstr ""
msgid "If your authentik Instance is using a self-signed certificate, set this value." msgid "If your authentik Instance is using a self-signed certificate, set this value."
msgstr "" msgstr ""
#: src/pages/users/UserListPage.ts:136 #: src/pages/users/UserListPage.ts:143
msgid "Impersonate" msgid "Impersonate"
msgstr "" msgstr ""
@ -1988,6 +1988,10 @@ msgstr ""
msgid "No policies cached. Users may experience slow response times." msgid "No policies cached. Users may experience slow response times."
msgstr "" msgstr ""
#: src/pages/users/UserListPage.ts:135
msgid "No recovery flow is configured."
msgstr ""
#: src/pages/flows/BoundStagesList.ts:114 #: src/pages/flows/BoundStagesList.ts:114
msgid "No stages are currently bound to this flow." msgid "No stages are currently bound to this flow."
msgstr "" msgstr ""
@ -2530,7 +2534,7 @@ msgstr ""
msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only." msgid "Required. 150 characters or fewer. Letters, digits and @/./+/-/_ only."
msgstr "" msgstr ""
#: src/pages/users/UserListPage.ts:133 #: src/pages/users/UserListPage.ts:140
#: src/pages/users/UserViewPage.ts:165 #: src/pages/users/UserViewPage.ts:165
msgid "Reset Password" msgid "Reset Password"
msgstr "" msgstr ""

View File

@ -127,6 +127,13 @@ export class UserListPage extends TablePage<User> {
message: t`Successfully generated recovery link`, message: t`Successfully generated recovery link`,
description: rec.link description: rec.link
}); });
}).catch((ex: Response) => {
ex.json().then(() => {
showMessage({
level: MessageLevel.error,
message: t`No recovery flow is configured.`,
});
});
}); });
}}> }}>
${t`Reset Password`} ${t`Reset Password`}