1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-01 07:10:55 +00:00

Merge pull request #977 from haiwen/update-grp-api

update grp api & add group members api
This commit is contained in:
Daniel Pan 2015-12-31 15:26:24 +08:00
commit f348dfb717
4 changed files with 253 additions and 68 deletions

View File

@ -9,6 +9,7 @@ from rest_framework.views import APIView
from rest_framework import status
import seaserv
from seaserv import seafile_api
from pysearpc import SearpcError
from seahub.profile.models import Profile
@ -18,7 +19,7 @@ from seahub.api2.authentication import TokenAuthentication
from seahub.avatar.settings import AVATAR_DEFAULT_SIZE
from seahub.avatar.templatetags.avatar_tags import api_avatar_url, \
get_default_avatar_url
from seahub.utils import is_valid_username
from seahub.utils import is_valid_username, string2list, is_org_context
from seahub.base.templatetags.seahub_tags import email2nickname
from seahub.base.accounts import User
@ -29,7 +30,7 @@ logger = logging.getLogger(__name__)
def get_group_member_info(request, group_id, email, avatar_size=AVATAR_DEFAULT_SIZE):
p = Profile.objects.get_profile_by_user(email)
if p:
login_id = p.login_id if p.login_id != '' else ''
login_id = p.login_id if p.login_id else ''
else:
login_id = ''
@ -73,22 +74,18 @@ class GroupMembers(APIView):
members = seaserv.get_group_members(group_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
try:
only_admin = int(request.GET.get('only_admin', 0))
except ValueError:
only_admin = 0
if only_admin not in (0, 1):
error_msg = _(u'Argument is not valid')
is_admin = request.GET.get('is_admin', 'false')
if is_admin.lower() not in ('true', 'false'):
error_msg = 'is_admin invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
group_members = []
for m in members:
# only return group admins
if only_admin and not m.is_staff:
if is_admin == 'true' and not m.is_staff:
continue
member_info = get_group_member_info(request, group_id, m.user_name, avatar_size)
@ -102,22 +99,179 @@ class GroupMembers(APIView):
Add a group member.
"""
username = request.user.username
email = request.data.get('email', None)
try:
User.objects.get(email=email)
except User.DoesNotExist:
error_msg = _(u'Invalid username')
error_msg = 'Email %s invalid.' % email
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
seaserv.group_add_member(group_id, username, email)
seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, email)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
member_info = get_group_member_info(request, group_id, email, AVATAR_DEFAULT_SIZE)
member_info = get_group_member_info(request, group_id, email)
return Response(member_info, status=status.HTTP_201_CREATED)
class GroupMember(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
@api_check_group_member
def get(self, request, group_id, email):
"""
Get info of a specific group member.
"""
try:
avatar_size = int(request.GET.get('avatar_size',
AVATAR_DEFAULT_SIZE))
except ValueError:
avatar_size = AVATAR_DEFAULT_SIZE
member_info = get_group_member_info(request, group_id, email, avatar_size)
return Response(member_info)
@api_check_group_staff
def put(self, request, group_id, email):
"""
Set/unset a specific group member as admin.
"""
is_admin = request.data.get('is_admin', '')
if is_admin.lower() == 'true':
try:
seaserv.ccnet_threaded_rpc.group_set_admin(group_id, email)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
elif is_admin.lower() == 'false':
try:
seaserv.ccnet_threaded_rpc.group_unset_admin(group_id, email)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
error_msg = 'is_admin invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
member_info = get_group_member_info(request, group_id, email)
return Response(member_info)
@api_check_group_member
def delete(self, request, group_id, email):
"""
Delete a group member.
"""
username = request.user.username
if not is_valid_username(email):
error_msg = 'Email %s invalid.' % email
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if username == email:
# user leave group
try:
seaserv.ccnet_threaded_rpc.quit_group(group_id, username)
seafile_api.remove_group_repos_by_owner(group_id, email)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
# admin delete group memeber
try:
if not seaserv.check_group_staff(group_id, username):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
seaserv.ccnet_threaded_rpc.group_remove_member(group_id, username, email)
seafile_api.remove_group_repos_by_owner(group_id, email)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True})
class GroupMembersBulk(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
@api_check_group_staff
def post(self, request, group_id):
"""
Bulk add group members.
"""
username = request.user.username
emails_str = request.data.get('emails', '')
emails_list = string2list(emails_str)
emails_list = [x.lower() for x in emails_list]
result = {}
result['failed'] = []
result['success'] = []
emails_need_add = []
org_id = None
if is_org_context(request):
org_id = request.user.org.org_id
for email in emails_list:
try:
User.objects.get(email=email)
except User.DoesNotExist:
result['failed'].append({
'email': email,
'error_msg': 'Email %s invalid.' % email
})
continue
if seaserv.is_group_user(group_id, email):
result['failed'].append({
'email': email,
'error_msg': _(u'User %s is already a group member.') % email
})
continue
# Can only invite organization users to group
if org_id and not \
seaserv.ccnet_threaded_rpc.org_user_exists(org_id, email):
result['failed'].append({
'email': email,
'error_msg': _(u'User %s not found in organizaiont.') % email
})
continue
emails_need_add.append(email)
# Add user to group.
for email in emails_need_add:
try:
seaserv.ccnet_threaded_rpc.group_add_member(group_id,
username, email)
member_info = get_group_member_info(request, group_id, email)
result['success'].append(member_info)
except SearpcError as e:
logger.error(e)
result['failed'].append({
'email': email,
'error_msg': 'Internal Server Error'
})
return Response(result)

View File

@ -27,7 +27,8 @@ from seahub.group.views import remove_group_common
from seahub.base.templatetags.seahub_tags import email2nickname, \
translate_seahub_time
from .utils import api_check_group_staff
from .utils import api_check_group_staff, api_check_group_member, \
api_check_group_owner
logger = logging.getLogger(__name__)
@ -53,7 +54,7 @@ def get_group_info(request, group_id, avatar_size=GROUP_AVATAR_DEFAULT_SIZE):
group_info = {
"id": group.id,
"name": group.group_name,
"creator": group.creator_name,
"owner": group.creator_name,
"created_at": val.strftime("%Y-%m-%dT%H:%M:%S") + DateFormat(val).format('O'),
"avatar_url": request.build_absolute_uri(avatar_url),
"admins": get_group_admins(group.id),
@ -84,9 +85,9 @@ class Groups(APIView):
user_groups = seaserv.get_personal_groups_by_user(username)
try:
size = int(request.GET.get('avatar_size', GROUP_AVATAR_DEFAULT_SIZE))
avatar_size = int(request.GET.get('avatar_size', GROUP_AVATAR_DEFAULT_SIZE))
except ValueError:
size = GROUP_AVATAR_DEFAULT_SIZE
avatar_size = GROUP_AVATAR_DEFAULT_SIZE
try:
with_repos = int(request.GET.get('with_repos', 0))
@ -94,12 +95,12 @@ class Groups(APIView):
with_repos = 0
if with_repos not in (0, 1):
error_msg = _(u'Argument can only be 0 or 1')
error_msg = 'with_repos invalid.'
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
groups = []
for g in user_groups:
group_info = get_group_info(request, g.id , size)
group_info = get_group_info(request, g.id , avatar_size)
if with_repos:
if org_id:
@ -112,7 +113,6 @@ class Groups(APIView):
repo = {
"id": r.id,
"name": r.name,
"desc": r.desc,
"size": r.size,
"size_formatted": filesizeformat(r.size),
"mtime": r.last_modified,
@ -120,8 +120,7 @@ class Groups(APIView):
"encrypted": r.encrypted,
"permission": r.permission,
"owner": r.user,
"owner_nickname": email2nickname(r.user),
"share_from_me": True if username == r.user else False,
"owner_name": email2nickname(r.user),
}
repos.append(repo)
@ -135,7 +134,7 @@ class Groups(APIView):
""" Create a group
"""
if not self._can_add_group(request):
error_msg = _(u'You do not have permission to create group.')
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
username = request.user.username
@ -157,11 +156,11 @@ class Groups(APIView):
group_id = seaserv.ccnet_threaded_rpc.create_group(group_name, username)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Failed')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
# get info of new group
group_info = get_group_info(request, group_id, GROUP_AVATAR_DEFAULT_SIZE)
group_info = get_group_info(request, group_id)
return Response(group_info, status=status.HTTP_201_CREATED)
@ -172,6 +171,19 @@ class Group(APIView):
permission_classes = (IsAuthenticated,)
throttle_classes = (UserRateThrottle, )
@api_check_group_member
def get(self, request, group_id):
""" Get info of a group.
"""
try:
avatar_size = int(request.GET.get('avatar_size', GROUP_AVATAR_DEFAULT_SIZE))
except ValueError:
avatar_size = GROUP_AVATAR_DEFAULT_SIZE
group_info = get_group_info(request, group_id, avatar_size)
return Response(group_info)
@api_check_group_staff
def put(self, request, group_id):
""" Rename, transfer a specific group
@ -197,39 +209,45 @@ class Group(APIView):
seaserv.ccnet_threaded_rpc.set_group_name(group_id, new_group_name)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
new_creator= request.data.get('creator', None)
if new_creator:
new_owner = request.data.get('owner', None)
if new_owner:
# transfer a group
if not is_valid_username(new_creator):
error_msg = _('Creator %s is not valid.') % new_creator
# only group owner can transfer a group
if not (username == group.creator_name):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
if not is_valid_username(new_owner):
error_msg = 'Email %s invalid.' % new_owner
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
if new_creator == group.creator_name:
error_msg = _('%s is already group owner') % new_creator
if new_owner == group.creator_name:
error_msg = _(u'User %s is already group owner.') % new_owner
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
try:
if not seaserv.is_group_user(group_id, new_creator):
seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, new_creator)
if not seaserv.is_group_user(group_id, new_owner):
seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, new_owner)
if not seaserv.check_group_staff(group_id, new_creator):
seaserv.ccnet_threaded_rpc.group_set_admin(group_id, new_creator)
if not seaserv.check_group_staff(group_id, new_owner):
seaserv.ccnet_threaded_rpc.group_set_admin(group_id, new_owner)
seaserv.ccnet_threaded_rpc.set_group_creator(group_id, new_creator)
seaserv.ccnet_threaded_rpc.set_group_creator(group_id, new_owner)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
# get new info of this group
group_info = get_group_info(request, group_id, GROUP_AVATAR_DEFAULT_SIZE)
group_info = get_group_info(request, group_id)
return Response(group_info)
@api_check_group_staff
@api_check_group_owner
def delete(self, request, group_id):
""" Delete a specific group
"""
@ -244,7 +262,7 @@ class Group(APIView):
remove_group_common(group_id, username, org_id=org_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True})

View File

@ -1,7 +1,5 @@
import logging
from django.utils.translation import ugettext as _
from rest_framework import status
import seaserv
@ -21,11 +19,11 @@ def api_check_group_member(func):
group = seaserv.get_group(group_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not group:
error_msg = _(u'Group does not exist.')
error_msg = 'Group %d not found.' % group_id
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
username = request.user.username
@ -34,18 +32,17 @@ def api_check_group_member(func):
username)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not is_group_member:
error_msg = _(u'Permission denied')
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
return func(view, request, group_id, *args, **kwargs)
return _decorated
def api_check_group_staff(func):
"""
Decorator for check if group valid and if is group staff
@ -56,35 +53,49 @@ def api_check_group_staff(func):
group = seaserv.get_group(group_id)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not group:
error_msg = _(u'Group does not exist.')
error_msg = 'Group %d not found.' % group_id
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
username = request.user.username
try:
is_group_member = seaserv.is_group_user(group_id,
username)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not is_group_member:
error_msg = _(u'Permission denied')
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
try:
is_group_staff = seaserv.check_group_staff(group_id, username)
except SearpcError as e:
logger.error(e)
error_msg = _(u'Internal Server Error')
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not is_group_staff:
error_msg = _(u'Permission denied')
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
return func(view, request, group_id, *args, **kwargs)
return _decorated
def api_check_group_owner(func):
"""
Decorator for check if group valid and if is group owner
"""
def _decorated(view, request, group_id, *args, **kwargs):
group_id = int(group_id) # Checked by URL Conf
try:
group = seaserv.get_group(group_id)
except SearpcError as e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
if not group:
error_msg = 'Group %d not found.' % group_id
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
username = request.user.username
if not (username == group.creator_name):
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
return func(view, request, group_id, *args, **kwargs)

View File

@ -20,7 +20,7 @@ from seahub.views.wiki import personal_wiki, personal_wiki_pages, \
from seahub.views.sysadmin import *
from seahub.views.ajax import *
from seahub.api2.endpoints.groups import Groups, Group
from seahub.api2.endpoints.group_members import GroupMembers
from seahub.api2.endpoints.group_members import GroupMembers, GroupMembersBulk, GroupMember
# Uncomment the next two lines to enable the admin:
#from django.contrib import admin
@ -196,6 +196,8 @@ urlpatterns = patterns(
url(r'^api/v2.1/groups/$', Groups.as_view(), name='api-v2.1-groups'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/$', Group.as_view(), name='api-v2.1-group'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/$', GroupMembers.as_view(), name='api-v2.1-group-members'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/bulk/$', GroupMembersBulk.as_view(), name='api-v2.1-group-members-bulk'),
url(r'^api/v2.1/groups/(?P<group_id>\d+)/members/(?P<email>[^/]+)/$', GroupMember.as_view(), name='api-v2.1-group-member'),
(r'^avatar/', include('seahub.avatar.urls')),
(r'^notification/', include('seahub.notifications.urls')),
(r'^contacts/', include('seahub.contacts.urls')),