models: Add realm owner role and is_realm_owner property for user.

The new realm_owner role is added as option for role field in
UserProfile model and is_realm_owner is added as property for the user
profile.

Aside from some basic tests validating the logic, this has no effect
as users cannot end up with set as realm owners.
This commit is contained in:
sahil839 2020-05-16 23:40:42 +05:30 committed by Tim Abbott
parent 1db0775e6e
commit 8bbc07474f
3 changed files with 23 additions and 7 deletions

View File

@ -249,6 +249,7 @@ def realm_user_count(realm: Realm) -> int:
def realm_user_count_by_role(realm: Realm) -> Dict[str, Any]: def realm_user_count_by_role(realm: Realm) -> Dict[str, Any]:
human_counts = {UserProfile.ROLE_REALM_ADMINISTRATOR: 0, human_counts = {UserProfile.ROLE_REALM_ADMINISTRATOR: 0,
UserProfile.ROLE_REALM_OWNER: 0,
UserProfile.ROLE_MEMBER: 0, UserProfile.ROLE_MEMBER: 0,
UserProfile.ROLE_GUEST: 0} UserProfile.ROLE_GUEST: 0}
for value_dict in list(UserProfile.objects.filter( for value_dict in list(UserProfile.objects.filter(

View File

@ -438,8 +438,9 @@ class Realm(models.Model):
notifications to all administrator users. notifications to all administrator users.
""" """
# TODO: Change return type to QuerySet[UserProfile] # TODO: Change return type to QuerySet[UserProfile]
return UserProfile.objects.filter(realm=self, role=UserProfile.ROLE_REALM_ADMINISTRATOR, return UserProfile.objects.filter(realm=self, is_active=True,
is_active=True) role__in=[UserProfile.ROLE_REALM_ADMINISTRATOR,
UserProfile.ROLE_REALM_OWNER])
def get_human_admin_users(self) -> QuerySet: def get_human_admin_users(self) -> QuerySet:
"""Use this in contexts where we want only human users with """Use this in contexts where we want only human users with
@ -447,9 +448,9 @@ class Realm(models.Model):
realm's administrators (bots don't have real email addresses). realm's administrators (bots don't have real email addresses).
""" """
# TODO: Change return type to QuerySet[UserProfile] # TODO: Change return type to QuerySet[UserProfile]
return UserProfile.objects.filter(realm=self, is_bot=False, return UserProfile.objects.filter(realm=self, is_bot=False, is_active=True,
role=UserProfile.ROLE_REALM_ADMINISTRATOR, role__in=[UserProfile.ROLE_REALM_ADMINISTRATOR,
is_active=True) UserProfile.ROLE_REALM_OWNER])
def get_active_users(self) -> Sequence['UserProfile']: def get_active_users(self) -> Sequence['UserProfile']:
# TODO: Change return type to QuerySet[UserProfile] # TODO: Change return type to QuerySet[UserProfile]
@ -869,7 +870,7 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
# future roles to be inserted between currently adjacent # future roles to be inserted between currently adjacent
# roles. These constants appear in RealmAuditLog.extra_data, so # roles. These constants appear in RealmAuditLog.extra_data, so
# changes to them will require a migration of RealmAuditLog. # changes to them will require a migration of RealmAuditLog.
# ROLE_REALM_OWNER = 100 ROLE_REALM_OWNER = 100
ROLE_REALM_ADMINISTRATOR = 200 ROLE_REALM_ADMINISTRATOR = 200
# ROLE_MODERATOR = 300 # ROLE_MODERATOR = 300
ROLE_MEMBER = 400 ROLE_MEMBER = 400
@ -1105,7 +1106,8 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
@property @property
def is_realm_admin(self) -> bool: def is_realm_admin(self) -> bool:
return self.role == UserProfile.ROLE_REALM_ADMINISTRATOR return self.role == UserProfile.ROLE_REALM_ADMINISTRATOR or \
self.role == UserProfile.ROLE_REALM_OWNER
@is_realm_admin.setter @is_realm_admin.setter
def is_realm_admin(self, value: bool) -> None: def is_realm_admin(self, value: bool) -> None:
@ -1116,6 +1118,10 @@ class UserProfile(AbstractBaseUser, PermissionsMixin):
# ROLE_GUEST to ROLE_MEMBER here. # ROLE_GUEST to ROLE_MEMBER here.
self.role = UserProfile.ROLE_MEMBER self.role = UserProfile.ROLE_MEMBER
@property
def is_realm_owner(self) -> bool:
return self.role == UserProfile.ROLE_REALM_OWNER
@property @property
def is_guest(self) -> bool: def is_guest(self) -> bool:
return self.role == UserProfile.ROLE_GUEST return self.role == UserProfile.ROLE_GUEST

View File

@ -90,12 +90,21 @@ class PermissionTest(ZulipTestCase):
def test_get_admin_users(self) -> None: def test_get_admin_users(self) -> None:
user_profile = self.example_user('hamlet') user_profile = self.example_user('hamlet')
do_change_user_role(user_profile, UserProfile.ROLE_MEMBER) do_change_user_role(user_profile, UserProfile.ROLE_MEMBER)
self.assertFalse(user_profile.is_realm_owner)
admin_users = user_profile.realm.get_human_admin_users() admin_users = user_profile.realm.get_human_admin_users()
self.assertFalse(user_profile in admin_users) self.assertFalse(user_profile in admin_users)
admin_users = user_profile.realm.get_admin_users_and_bots() admin_users = user_profile.realm.get_admin_users_and_bots()
self.assertFalse(user_profile in admin_users) self.assertFalse(user_profile in admin_users)
do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR) do_change_user_role(user_profile, UserProfile.ROLE_REALM_ADMINISTRATOR)
self.assertFalse(user_profile.is_realm_owner)
admin_users = user_profile.realm.get_human_admin_users()
self.assertTrue(user_profile in admin_users)
admin_users = user_profile.realm.get_admin_users_and_bots()
self.assertTrue(user_profile in admin_users)
do_change_user_role(user_profile, UserProfile.ROLE_REALM_OWNER)
self.assertTrue(user_profile.is_realm_owner)
admin_users = user_profile.realm.get_human_admin_users() admin_users = user_profile.realm.get_human_admin_users()
self.assertTrue(user_profile in admin_users) self.assertTrue(user_profile in admin_users)
admin_users = user_profile.realm.get_admin_users_and_bots() admin_users = user_profile.realm.get_admin_users_and_bots()