core: add USER_ATTRIBUTE_CHANGE_EMAIL

Signed-off-by: Jens Langhammer <jens.langhammer@beryju.org>

#1590 and #1677
This commit is contained in:
Jens Langhammer 2021-10-27 11:54:19 +02:00
parent 9c0bc78ca0
commit 971de4fcb9
4 changed files with 32 additions and 9 deletions

View File

@ -45,6 +45,7 @@ from authentik.core.api.used_by import UsedByMixin
from authentik.core.api.utils import LinkSerializer, PassiveSerializer, is_dict
from authentik.core.middleware import SESSION_IMPERSONATE_ORIGINAL_USER, SESSION_IMPERSONATE_USER
from authentik.core.models import (
USER_ATTRIBUTE_CHANGE_EMAIL,
USER_ATTRIBUTE_CHANGE_USERNAME,
USER_ATTRIBUTE_SA,
USER_ATTRIBUTE_TOKEN_EXPIRING,
@ -122,6 +123,14 @@ class UserSelfSerializer(ModelSerializer):
"pk": group.pk,
}
def validate_email(self, email: str):
"""Check if the user is allowed to change their email"""
if self.instance.group_attributes().get(USER_ATTRIBUTE_CHANGE_EMAIL, True):
return email
if email != self.instance.email:
raise ValidationError("Not allowed to change email.")
return email
def validate_username(self, username: str):
"""Check if the user is allowed to change their username"""
if self.instance.group_attributes().get(USER_ATTRIBUTE_CHANGE_USERNAME, True):
@ -320,13 +329,14 @@ class UserViewSet(UsedByMixin, ModelViewSet):
# pylint: disable=invalid-name
def me(self, request: Request) -> Response:
"""Get information about current user"""
serializer = SessionUserSerializer(data={"user": UserSelfSerializer(request.user).data})
serializer = SessionUserSerializer(
data={"user": UserSelfSerializer(instance=request.user).data}
)
if SESSION_IMPERSONATE_USER in request._request.session:
serializer.initial_data["original"] = UserSelfSerializer(
request._request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
instance=request._request.session[SESSION_IMPERSONATE_ORIGINAL_USER]
).data
serializer.is_valid()
return Response(serializer.data)
return Response(serializer.initial_data)
@extend_schema(request=UserSelfSerializer, responses={200: SessionUserSerializer(many=False)})
@action(
@ -346,9 +356,7 @@ class UserViewSet(UsedByMixin, ModelViewSet):
# since it caches the full object
if SESSION_IMPERSONATE_USER in request.session:
request.session[SESSION_IMPERSONATE_USER] = new_user
serializer = SessionUserSerializer(data={"user": data.data})
serializer.is_valid()
return Response(serializer.data)
return Response({"user": data.data})
@permission_required("authentik_core.view_user", ["authentik_events.view_event"])
@extend_schema(responses={200: UserMetricsSerializer(many=False)})

View File

@ -39,7 +39,8 @@ USER_ATTRIBUTE_DEBUG = "goauthentik.io/user/debug"
USER_ATTRIBUTE_SA = "goauthentik.io/user/service-account"
USER_ATTRIBUTE_SOURCES = "goauthentik.io/user/sources"
USER_ATTRIBUTE_TOKEN_EXPIRING = "goauthentik.io/user/token-expires" # nosec
USER_ATTRIBUTE_CHANGE_USERNAME = "goauthentik.io/user/can-change-username" # nosec
USER_ATTRIBUTE_CHANGE_USERNAME = "goauthentik.io/user/can-change-username"
USER_ATTRIBUTE_CHANGE_EMAIL = "goauthentik.io/user/can-change-email"
USER_ATTRIBUTE_CAN_OVERRIDE_IP = "goauthentik.io/user/override-ips"
GRAVATAR_URL = "https://secure.gravatar.com"

View File

@ -2,7 +2,7 @@
from django.urls.base import reverse
from rest_framework.test import APITestCase
from authentik.core.models import USER_ATTRIBUTE_CHANGE_USERNAME, User
from authentik.core.models import USER_ATTRIBUTE_CHANGE_EMAIL, USER_ATTRIBUTE_CHANGE_USERNAME, User
from authentik.flows.models import Flow, FlowDesignation
from authentik.stages.email.models import EmailStage
from authentik.tenants.models import Tenant
@ -33,6 +33,16 @@ class TestUsersAPI(APITestCase):
)
self.assertEqual(response.status_code, 400)
def test_update_self_email_denied(self):
"""Test update_self"""
self.admin.attributes[USER_ATTRIBUTE_CHANGE_EMAIL] = False
self.admin.save()
self.client.force_login(self.admin)
response = self.client.put(
reverse("authentik_api:user-update-self"), data={"email": "foo", "name": "foo"}
)
self.assertEqual(response.status_code, 400)
def test_metrics(self):
"""Test user's metrics"""
self.client.force_login(self.admin)

View File

@ -8,6 +8,10 @@ title: User
Optional flag, when set to false prevents the user from changing their own username.
### `goauthentik.io/user/can-change-email`
Optional flag, when set to false prevents the user from changing their own email.
### `goauthentik.io/user/token-expires`:
Optional flag, when set to false, Tokens created by the user will not expire.