mirror of
https://github.com/zulip/zulip.git
synced 2025-11-03 05:23:35 +00:00
user-groups: Add update members API endpoint.
Significantly modified by tabbott to fix some bugs.
This commit is contained in:
@@ -69,7 +69,7 @@ from zerver.models import Realm, RealmEmoji, Stream, UserProfile, UserActivity,
|
||||
custom_profile_fields_for_realm, get_huddle_user_ids, \
|
||||
CustomProfileFieldValue, validate_attachment_request, get_system_bot, \
|
||||
get_display_recipient_by_id, query_for_ids, get_huddle_recipient, \
|
||||
UserGroup
|
||||
UserGroup, UserGroupMembership
|
||||
|
||||
from zerver.lib.alert_words import alert_words_in_realm
|
||||
from zerver.lib.avatar import avatar_url
|
||||
@@ -4203,3 +4203,16 @@ def do_update_user_group_description(user_group, description):
|
||||
# type: (UserGroup, Text) -> None
|
||||
user_group.description = description
|
||||
user_group.save(update_fields=['description'])
|
||||
|
||||
def bulk_add_members_to_user_group(user_group_id, user_profiles):
|
||||
# type: (int, List[UserProfile]) -> None
|
||||
memberships = [UserGroupMembership(user_group_id=user_group_id,
|
||||
user_profile=user_profile)
|
||||
for user_profile in user_profiles]
|
||||
UserGroupMembership.objects.bulk_create(memberships)
|
||||
|
||||
def remove_members_from_user_group(user_group_id, user_profiles):
|
||||
# type: (int, List[UserProfile]) -> None
|
||||
UserGroupMembership.objects.filter(
|
||||
user_group_id=user_group_id,
|
||||
user_profile__in=user_profiles).delete()
|
||||
|
||||
@@ -52,3 +52,9 @@ def create_user_group(name, members, realm, description=''):
|
||||
for member in members
|
||||
])
|
||||
return user_group
|
||||
|
||||
def get_memberships_of_users(user_group, members):
|
||||
# type: (UserGroup, List[UserProfile]) -> List[int]
|
||||
return list(UserGroupMembership.objects.filter(
|
||||
user_group=user_group,
|
||||
user_profile__in=members).values_list('user_profile_id', flat=True))
|
||||
|
||||
@@ -12,6 +12,7 @@ from zerver.lib.user_groups import (
|
||||
create_user_group,
|
||||
get_user_groups,
|
||||
user_groups_in_realm,
|
||||
get_memberships_of_users,
|
||||
)
|
||||
from zerver.models import UserProfile, UserGroup, get_realm, Realm, \
|
||||
UserGroupMembership
|
||||
@@ -148,3 +149,59 @@ class UserGroupAPITestCase(ZulipTestCase):
|
||||
# Test when invalid user group is supplied
|
||||
result = self.client_delete('/json/user_groups/1111')
|
||||
self.assert_json_error(result, "Invalid user group")
|
||||
|
||||
def test_update_members_of_user_group(self):
|
||||
# type: () -> None
|
||||
hamlet = self.example_user('hamlet')
|
||||
self.login(self.example_email("hamlet"))
|
||||
params = {
|
||||
'name': 'support',
|
||||
'members': ujson.dumps([hamlet.id]),
|
||||
'description': 'Support team',
|
||||
}
|
||||
self.client_post('/json/user_groups/create', info=params)
|
||||
user_group = UserGroup.objects.first()
|
||||
|
||||
# Test add members
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 1)
|
||||
othello = self.example_user('othello')
|
||||
add = [othello.id]
|
||||
params = {'add': ujson.dumps(add)}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 2)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello])
|
||||
self.assertEqual(len(members), 2)
|
||||
|
||||
# Test adding a member already there.
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
info=params)
|
||||
self.assert_json_error(result, "User 6 is already a member of this group")
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 2)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello])
|
||||
self.assertEqual(len(members), 2)
|
||||
|
||||
# Test remove members
|
||||
params = {'delete': ujson.dumps([hamlet.id, othello.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 0)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello])
|
||||
self.assertEqual(len(members), 0)
|
||||
|
||||
# Test remove a member that's already removed; arguably we should make this an error.
|
||||
params = {'delete': ujson.dumps([hamlet.id, othello.id])}
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assertEqual(UserGroupMembership.objects.count(), 0)
|
||||
members = get_memberships_of_users(user_group, [hamlet, othello])
|
||||
self.assertEqual(len(members), 0)
|
||||
|
||||
# Test when nothing is provided
|
||||
result = self.client_post('/json/user_groups/{}/members'.format(user_group.id),
|
||||
info={})
|
||||
msg = 'Nothing to do. Specify at least one of "add" or "delete".'
|
||||
self.assert_json_error(result, msg)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from typing import Any, Optional, Tuple, List, Set, Iterable, Mapping, Callable, Dict, Text
|
||||
from typing import Any, Optional, Tuple, List, Set, Iterable, Mapping, Callable, Dict, Text, \
|
||||
Union
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
from django.conf import settings
|
||||
@@ -107,7 +108,7 @@ def list_subscriptions_backend(request, user_profile):
|
||||
# type: (HttpRequest, UserProfile) -> HttpResponse
|
||||
return json_success({"subscriptions": gather_subscriptions(user_profile)[0]})
|
||||
|
||||
FuncKwargPair = Tuple[Callable[..., HttpResponse], Dict[str, Iterable[Any]]]
|
||||
FuncKwargPair = Tuple[Callable[..., HttpResponse], Dict[str, Union[int, Iterable[Any]]]]
|
||||
|
||||
@has_request_variables
|
||||
def update_subscriptions_backend(request, user_profile,
|
||||
|
||||
@@ -5,15 +5,17 @@ from typing import List, Text
|
||||
|
||||
from zerver.context_processors import get_realm_from_request
|
||||
from zerver.lib.actions import check_add_user_group, do_update_user_group_name, \
|
||||
do_update_user_group_description
|
||||
do_update_user_group_description, bulk_add_members_to_user_group, \
|
||||
remove_members_from_user_group
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.request import has_request_variables, REQ
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.lib.users import user_ids_to_users
|
||||
from zerver.lib.validator import check_list, check_string, check_int, \
|
||||
check_short_string
|
||||
from zerver.lib.user_groups import access_user_group_by_id
|
||||
from zerver.models import UserProfile, UserGroup
|
||||
from zerver.lib.user_groups import access_user_group_by_id, get_memberships_of_users
|
||||
from zerver.models import UserProfile, UserGroup, UserGroupMembership
|
||||
from zerver.views.streams import compose_views, FuncKwargPair
|
||||
|
||||
@has_request_variables
|
||||
def add_user_group(request, user_profile,
|
||||
@@ -52,3 +54,46 @@ def delete_user_group(request, user_profile, user_group_id=REQ(validator=check_i
|
||||
user_group = access_user_group_by_id(user_group_id, user_profile.realm)
|
||||
user_group.delete()
|
||||
return json_success()
|
||||
|
||||
@has_request_variables
|
||||
def update_user_group_backend(request, user_profile,
|
||||
user_group_id=REQ(validator=check_int),
|
||||
delete=REQ(validator=check_list(check_int), default=[]),
|
||||
add=REQ(validator=check_list(check_int), default=[])):
|
||||
# type: (HttpRequest, UserProfile, int, List[int], List[int]) -> HttpResponse
|
||||
if not add and not delete:
|
||||
return json_error(_('Nothing to do. Specify at least one of "add" or "delete".'))
|
||||
|
||||
method_kwarg_pairs = [
|
||||
(add_members_to_group_backend,
|
||||
dict(user_group_id=user_group_id, members=add)),
|
||||
(remove_members_from_group_backend,
|
||||
dict(user_group_id=user_group_id, members=delete))
|
||||
] # type: List[FuncKwargPair]
|
||||
return compose_views(request, user_profile, method_kwarg_pairs)
|
||||
|
||||
def add_members_to_group_backend(request, user_profile, user_group_id, members):
|
||||
# type: (HttpRequest, UserProfile, int, List[int]) -> HttpResponse
|
||||
if not members:
|
||||
return json_success()
|
||||
|
||||
user_group = access_user_group_by_id(user_group_id, user_profile.realm)
|
||||
user_profiles = user_ids_to_users(members, user_profile.realm)
|
||||
|
||||
existing_member_ids = set(get_memberships_of_users(user_group, user_profiles))
|
||||
for user_profile in user_profiles:
|
||||
if user_profile.id in existing_member_ids:
|
||||
raise JsonableError(_("User %s is already a member of this group" % (user_profile.id,)))
|
||||
|
||||
bulk_add_members_to_user_group(user_group_id, user_profiles)
|
||||
return json_success()
|
||||
|
||||
def remove_members_from_group_backend(request, user_profile, user_group_id, members):
|
||||
# type: (HttpRequest, UserProfile, int, List[int]) -> HttpResponse
|
||||
if not members:
|
||||
return json_success()
|
||||
|
||||
user_profiles = user_ids_to_users(members, user_profile.realm)
|
||||
user_group = access_user_group_by_id(user_group_id, user_profile.realm)
|
||||
remove_members_from_user_group(user_group, user_profiles)
|
||||
return json_success()
|
||||
|
||||
@@ -221,6 +221,8 @@ v1_api_and_json_patterns = [
|
||||
url(r'^user_groups/(?P<user_group_id>\d+)$', rest_dispatch,
|
||||
{'PATCH': 'zerver.views.user_groups.edit_user_group',
|
||||
'DELETE': 'zerver.views.user_groups.delete_user_group'}),
|
||||
url(r'^user_groups/(?P<user_group_id>\d+)/members$', rest_dispatch,
|
||||
{'POST': 'zerver.views.user_groups.update_user_group_backend'}),
|
||||
|
||||
# users/me -> zerver.views.user_settings
|
||||
url(r'^users/me/api_key/regenerate$', rest_dispatch,
|
||||
|
||||
Reference in New Issue
Block a user