mirror of
https://github.com/zulip/zulip.git
synced 2025-11-17 12:21:58 +00:00
user-groups: Add create API endpoint.
Significantly modified by tabbott for better security structure.
This commit is contained in:
@@ -4,6 +4,7 @@ from typing import (
|
||||
)
|
||||
from mypy_extensions import TypedDict
|
||||
|
||||
import django.db.utils
|
||||
from django.contrib.contenttypes.models import ContentType
|
||||
from django.utils.html import escape
|
||||
from django.utils.translation import ugettext as _
|
||||
@@ -48,6 +49,7 @@ from zerver.lib.topic_mutes import (
|
||||
add_topic_mute,
|
||||
remove_topic_mute,
|
||||
)
|
||||
from zerver.lib.user_groups import create_user_group
|
||||
from zerver.models import Realm, RealmEmoji, Stream, UserProfile, UserActivity, \
|
||||
RealmDomain, \
|
||||
Subscription, Recipient, Message, Attachment, UserMessage, RealmAuditLog, \
|
||||
@@ -4183,3 +4185,10 @@ def do_update_user_custom_profile_data(user_profile, data):
|
||||
update_or_create(user_profile=user_profile,
|
||||
field_id=field['id'],
|
||||
defaults={'value': field['value']})
|
||||
|
||||
def check_add_user_group(realm, name, initial_members, description):
|
||||
# type: (Realm, Text, List[UserProfile], Text) -> None
|
||||
try:
|
||||
create_user_group(name, initial_members, realm, description=description)
|
||||
except django.db.utils.IntegrityError:
|
||||
raise JsonableError(_("User group '%s' already exists." % (name,)))
|
||||
|
||||
@@ -1,9 +1,18 @@
|
||||
from __future__ import absolute_import
|
||||
|
||||
from django.db import transaction
|
||||
from django.utils.translation import ugettext as _
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.models import UserProfile, Realm, UserGroupMembership, UserGroup
|
||||
from typing import Dict, Iterable, List, Text
|
||||
|
||||
def access_user_group_by_id(user_group_id: int, realm: Realm) -> UserGroup:
|
||||
try:
|
||||
user_group = UserGroup.objects.get(id=user_group_id, realm=realm)
|
||||
except UserGroup.DoesNotExist:
|
||||
raise JsonableError(_("Invalid user group"))
|
||||
return user_group
|
||||
|
||||
def user_groups_in_realm(realm):
|
||||
# type: (Realm) -> List[UserGroup]
|
||||
user_groups = UserGroup.objects.filter(realm=realm)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
from typing import Text
|
||||
from typing import List, Text
|
||||
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
from zerver.lib.actions import do_change_full_name
|
||||
from zerver.lib.request import JsonableError
|
||||
from zerver.models import UserProfile, Service
|
||||
from zerver.models import UserProfile, Service, Realm, \
|
||||
get_user_profile_by_id
|
||||
|
||||
def check_full_name(full_name_raw):
|
||||
# type: (Text) -> Text
|
||||
@@ -43,3 +44,20 @@ def check_valid_interface_type(interface_type):
|
||||
# type: (int) -> None
|
||||
if interface_type not in Service.ALLOWED_INTERFACE_TYPES:
|
||||
raise JsonableError(_('Invalid interface type'))
|
||||
|
||||
def user_ids_to_users(user_ids: List[int], realm: Realm) -> List[UserProfile]:
|
||||
# TODO: Change this to do a single bulk query with
|
||||
# generic_bulk_cached_fetch; it'll be faster.
|
||||
#
|
||||
# TODO: Consider adding a flag to control whether deactivated
|
||||
# users should be included.
|
||||
user_profiles = []
|
||||
for user_id in user_ids:
|
||||
try:
|
||||
user_profile = get_user_profile_by_id(user_id)
|
||||
except UserProfile.DoesNotExist:
|
||||
raise JsonableError(_("Invalid user ID: %s" % (user_id,)))
|
||||
if user_profile.realm != realm:
|
||||
raise JsonableError(_("Invalid user ID: %s" % (user_id,)))
|
||||
user_profiles.append(user_profile)
|
||||
return user_profiles
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
from typing import Any, List, Optional, Text
|
||||
|
||||
import ujson
|
||||
import django
|
||||
import mock
|
||||
|
||||
@@ -55,3 +56,39 @@ class UserGroupTestCase(ZulipTestCase):
|
||||
with mock.patch('zerver.lib.user_groups.remove_user_from_user_group',
|
||||
side_effect=Exception):
|
||||
self.assertFalse(check_remove_user_from_user_group(othello, user_group))
|
||||
|
||||
class UserGroupAPITestCase(ZulipTestCase):
|
||||
def test_user_group_create(self):
|
||||
# type: () -> None
|
||||
hamlet = self.example_user('hamlet')
|
||||
|
||||
# Test success
|
||||
self.login(self.example_email("hamlet"))
|
||||
params = {
|
||||
'name': 'support',
|
||||
'members': ujson.dumps([hamlet.id]),
|
||||
'description': 'Support team',
|
||||
}
|
||||
result = self.client_post('/json/user_groups/create', info=params)
|
||||
self.assert_json_success(result)
|
||||
self.assert_length(UserGroup.objects.all(), 1)
|
||||
|
||||
# Test invalid member error
|
||||
params = {
|
||||
'name': 'backend',
|
||||
'members': ujson.dumps([1111]),
|
||||
'description': 'Backend team',
|
||||
}
|
||||
result = self.client_post('/json/user_groups/create', info=params)
|
||||
self.assert_json_error(result, "Invalid user ID: 1111")
|
||||
self.assert_length(UserGroup.objects.all(), 1)
|
||||
|
||||
# Test we cannot add hamlet again
|
||||
params = {
|
||||
'name': 'support',
|
||||
'members': ujson.dumps([hamlet.id]),
|
||||
'description': 'Support team',
|
||||
}
|
||||
result = self.client_post('/json/user_groups/create', info=params)
|
||||
self.assert_json_error(result, "User group 'support' already exists.")
|
||||
self.assert_length(UserGroup.objects.all(), 1)
|
||||
|
||||
@@ -24,6 +24,7 @@ from zerver.models import UserProfile, Recipient, \
|
||||
|
||||
from zerver.lib.avatar import avatar_url
|
||||
from zerver.lib.email_mirror import create_missed_message_address
|
||||
from zerver.lib.exceptions import JsonableError
|
||||
from zerver.lib.send_email import send_future_email
|
||||
from zerver.lib.actions import (
|
||||
get_emails_from_user_ids,
|
||||
@@ -35,6 +36,7 @@ from zerver.lib.actions import (
|
||||
)
|
||||
from zerver.lib.topic_mutes import add_topic_mute
|
||||
from zerver.lib.stream_topic import StreamTopicTarget
|
||||
from zerver.lib.users import user_ids_to_users
|
||||
|
||||
from django.conf import settings
|
||||
|
||||
@@ -265,6 +267,18 @@ class UserProfileTest(ZulipTestCase):
|
||||
|
||||
self.assertFalse(m.called)
|
||||
|
||||
def test_user_ids_to_users(self) -> None:
|
||||
real_user_ids = [
|
||||
self.example_user('hamlet').id,
|
||||
self.example_user('cordelia').id,
|
||||
]
|
||||
|
||||
user_ids_to_users(real_user_ids, get_realm("zulip"))
|
||||
with self.assertRaises(JsonableError):
|
||||
user_ids_to_users([1234], get_realm("zephyr"))
|
||||
with self.assertRaises(JsonableError):
|
||||
user_ids_to_users(real_user_ids, get_realm("zephyr"))
|
||||
|
||||
class ActivateTest(ZulipTestCase):
|
||||
def test_basics(self) -> None:
|
||||
user = self.example_user('hamlet')
|
||||
|
||||
22
zerver/views/user_groups.py
Normal file
22
zerver/views/user_groups.py
Normal file
@@ -0,0 +1,22 @@
|
||||
from django.http import HttpResponse, HttpRequest
|
||||
|
||||
from typing import List, Text
|
||||
|
||||
from zerver.context_processors import get_realm_from_request
|
||||
from zerver.lib.actions import check_add_user_group
|
||||
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.models import UserProfile
|
||||
|
||||
@has_request_variables
|
||||
def add_user_group(request, user_profile,
|
||||
name=REQ(),
|
||||
members=REQ(validator=check_list(check_int), default=[]),
|
||||
description=REQ()):
|
||||
# type: (HttpRequest, UserProfile, Text, List[int], Text) -> HttpResponse
|
||||
user_profiles = user_ids_to_users(members, user_profile.realm)
|
||||
check_add_user_group(user_profile.realm, name, user_profiles, description)
|
||||
return json_success()
|
||||
@@ -27,6 +27,7 @@ import zerver.views.zephyr
|
||||
import zerver.views.users
|
||||
import zerver.views.unsubscribe
|
||||
import zerver.views.integrations
|
||||
import zerver.views.user_groups
|
||||
import zerver.views.user_settings
|
||||
import zerver.views.muting
|
||||
import zerver.views.streams
|
||||
@@ -214,6 +215,10 @@ v1_api_and_json_patterns = [
|
||||
{'POST': 'zerver.views.push_notifications.add_android_reg_id',
|
||||
'DELETE': 'zerver.views.push_notifications.remove_android_reg_id'}),
|
||||
|
||||
# user_groups -> zerver.views.user_groups
|
||||
url(r'^user_groups/create$', rest_dispatch,
|
||||
{'POST': 'zerver.views.user_groups.add_user_group'}),
|
||||
|
||||
# users/me -> zerver.views.user_settings
|
||||
url(r'^users/me/api_key/regenerate$', rest_dispatch,
|
||||
{'POST': 'zerver.views.user_settings.regenerate_api_key'}),
|
||||
|
||||
Reference in New Issue
Block a user