scim: Extract ROLE_TYPE_TO_NAME dict to UserProfile.

This allows these mappings to used in other APIs. Specifically, we want
to use this for syncing role during SAML auth.
This commit is contained in:
Mateusz Mandera 2024-08-16 00:29:51 +02:00 committed by Tim Abbott
parent 76b41e433a
commit 8c1a1ea8db
3 changed files with 15 additions and 14 deletions

View File

@ -32,15 +32,6 @@ class ZulipSCIMUser(SCIMUser):
id_field = "id"
ROLE_TYPE_TO_NAME = {
UserProfile.ROLE_REALM_OWNER: "owner",
UserProfile.ROLE_REALM_ADMINISTRATOR: "administrator",
UserProfile.ROLE_MODERATOR: "moderator",
UserProfile.ROLE_MEMBER: "member",
UserProfile.ROLE_GUEST: "guest",
}
ROLE_NAME_TO_TYPE = {v: k for k, v in ROLE_TYPE_TO_NAME.items()}
def __init__(self, obj: UserProfile, request: HttpRequest | None = None) -> None:
# We keep the function signature from the superclass, but this actually
# shouldn't be called with request being None.
@ -116,7 +107,7 @@ class ZulipSCIMUser(SCIMUser):
"name": name,
"displayName": self.display_name,
"active": self.obj.is_active,
"role": self.ROLE_TYPE_TO_NAME[self.obj.role],
"role": UserProfile.ROLE_ID_TO_API_NAME[self.obj.role],
# meta is a property implemented in the superclass
# TODO: The upstream implementation uses `user_profile.date_joined`
# as the value of the lastModified meta attribute, which is not
@ -200,10 +191,10 @@ class ZulipSCIMUser(SCIMUser):
def change_role(self, new_role_name: str) -> None:
try:
role = self.ROLE_NAME_TO_TYPE[new_role_name]
role = UserProfile.ROLE_API_NAME_TO_ID[new_role_name]
except KeyError:
raise scim_exceptions.BadRequestError(
f"Invalid role: {new_role_name}. Valid values are: {list(self.ROLE_NAME_TO_TYPE.keys())}"
f"Invalid role: {new_role_name}. Valid values are: {list(UserProfile.ROLE_API_NAME_TO_ID.keys())}"
)
if role != self.obj.role:
self._role_new_value = role

View File

@ -603,6 +603,17 @@ class UserProfile(AbstractBaseUser, PermissionsMixin, UserBaseSettings):
ROLE_GUEST: gettext_lazy("Guest"),
}
# Mapping of role ids to simple string identifiers for the roles,
# to be used in API contexts such as SCIM provisioning.
ROLE_ID_TO_API_NAME = {
ROLE_REALM_OWNER: "owner",
ROLE_REALM_ADMINISTRATOR: "administrator",
ROLE_MODERATOR: "moderator",
ROLE_MEMBER: "member",
ROLE_GUEST: "guest",
}
ROLE_API_NAME_TO_ID = {v: k for k, v in ROLE_ID_TO_API_NAME.items()}
class Meta:
indexes = [
models.Index(Upper("email"), name="upper_userprofile_email_idx"),

View File

@ -9,7 +9,6 @@ from django.conf import settings
from typing_extensions import override
from zerver.actions.user_settings import do_change_full_name
from zerver.lib.scim import ZulipSCIMUser
from zerver.lib.stream_subscription import get_subscribed_stream_ids_for_user
from zerver.lib.test_classes import ZulipTestCase
from zerver.models import UserProfile
@ -39,7 +38,7 @@ class SCIMTestCase(ZulipTestCase):
"userName": user_profile.delivery_email,
"name": {"formatted": user_profile.full_name},
"displayName": user_profile.full_name,
"role": ZulipSCIMUser.ROLE_TYPE_TO_NAME[user_profile.role],
"role": UserProfile.ROLE_ID_TO_API_NAME[user_profile.role],
"active": True,
"meta": {
"resourceType": "User",