def can_access_by_user_through_group(self, username): """ user can access this dataset when 1. user can access dataset's original dtable's owner group, or 2. user can access dataset's related groups user can access a group, means user is member of that group """ # 1. check user can access dataset's original dtable's owner group # -> 1. get original dtable which generate current dataset # -> 2. get group id which is owner of 1's dtable # -> 3. check wether user is member of 2's group dtable = DTables.objects.filter(uuid=self.dtable_uuid).first() group_id = dtable.get_owner_group_id() if group_id != -1 and is_group_member(group_id, username): return True # 2. check user can access dataset's related groups # -> 1. get groups id related to current dataset # -> 2. for each group id in 1's list, check wether user is member related_groups_id = DTableCommonDatasetGroupAccess.objects.get_related_groups_id( dataset=self) for group_id in related_groups_id: if is_group_member(group_id, username): return True return False
def get(self, request, group_id, email): """ Get info of a specific group member. """ try: # only group member can get info of a specific group member if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) 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)
def get(self, request, group_id, email): """ Get info of a specific group member. """ try: # only group member can get info of a specific group member if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) 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)
def put(self, request, group_id, email): """ Set/unset a specific group member as admin. """ username = request.user.username is_admin = request.data.get('is_admin', '') try: # only group owner can set/unset a specific group member as admin if not is_group_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # set/unset a specific group member as admin if is_admin.lower() == 'true': seaserv.ccnet_threaded_rpc.group_set_admin(group_id, email) elif is_admin.lower() == 'false': seaserv.ccnet_threaded_rpc.group_unset_admin(group_id, email) else: error_msg = 'is_admin invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except SearpcError as e: logger.error(e) 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) return Response(member_info)
def _decorated(request, group_id, *args, **kwargs): group_id_int = int(group_id) # Checked by URL Conf group = get_group(group_id_int) if not group: group_list_url = reverse('groups') return HttpResponseRedirect(group_list_url) group.is_staff = False if PublicGroup.objects.filter(group_id=group.id): group.is_pub = True else: group.is_pub = False if not request.user.is_authenticated(): if not group.is_pub: login_url = settings.LOGIN_URL path = urlquote(request.get_full_path()) tup = login_url, REDIRECT_FIELD_NAME, path return HttpResponseRedirect('%s?%s=%s' % tup) else: group.view_perm = "pub" return func(request, group, *args, **kwargs) joined = is_group_member(group_id_int, request.user.username) if joined: group.view_perm = "joined" group.is_staff = is_group_staff(group, request.user) return func(request, group, *args, **kwargs) if group.is_pub: group.view_perm = "pub" return func(request, group, *args, **kwargs) return render(request, 'error.html', { 'error_msg': _('Permission denied'), })
def post(self, request, group_id): """ Add a group member. """ email = request.data.get('email', None) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) username = request.user.username try: # only group owner/admin can add a group member if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_group_member(group_id, email): error_msg = _(u'User %s is already group member.') % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) seaserv.ccnet_threaded_rpc.group_add_member( group_id, username, email) except SearpcError as e: logger.error(e) 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) return Response(member_info, status=status.HTTP_201_CREATED)
def post(self, request, email, format=None): # migrate an account's repos and groups to an exist account if not is_valid_username(email): return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % email) op = request.data.get('op', '').lower() if op == 'migrate': from_user = email to_user = request.data.get('to_user', '') if not is_valid_username(to_user): return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % to_user) try: user2 = User.objects.get(email=to_user) except User.DoesNotExist: return api_error(status.HTTP_404_NOT_FOUND, 'User %s not found.' % to_user) # transfer owned repos to new user for r in seafile_api.get_owned_repo_list(from_user): seafile_api.set_repo_owner(r.id, user2.username) # transfer joined groups to new user for g in seaserv.get_personal_groups_by_user(from_user): if not is_group_member(g.id, user2.username): # add new user to the group on behalf of the group creator ccnet_threaded_rpc.group_add_member(g.id, g.creator_name, to_user) if from_user == g.creator_name: ccnet_threaded_rpc.set_group_creator(g.id, to_user) return Response({'success': True}) else: return api_error(status.HTTP_400_BAD_REQUEST, 'op can only be migrate.')
def _decorated(request, group_id, *args, **kwargs): group_id_int = int(group_id) # Checked by URL Conf group = get_group(group_id_int) if not group: return HttpResponseRedirect(HASH_URLS['GROUP_LIST']) group.is_staff = False if PublicGroup.objects.filter(group_id=group.id): group.is_pub = True else: group.is_pub = False if not request.user.is_authenticated(): if not group.is_pub: login_url = settings.LOGIN_URL path = urlquote(request.get_full_path()) tup = login_url, REDIRECT_FIELD_NAME, path return HttpResponseRedirect('%s?%s=%s' % tup) else: group.view_perm = "pub" return func(request, group, *args, **kwargs) joined = is_group_member(group_id_int, request.user.username) if joined: group.view_perm = "joined" group.is_staff = is_group_staff(group, request.user) return func(request, group, *args, **kwargs) if group.is_pub: group.view_perm = "pub" return func(request, group, *args, **kwargs) return render(request, 'error.html', { 'error_msg': _('Permission denied'), })
def _decorated(view, request, group_id, *args, **kwargs): group_id_int = int(group_id) # Checked by URL Conf group = get_group(group_id_int) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group not found.') group.is_staff = False group.is_pub = False joined = is_group_member(group_id_int, request.user.username) if joined: group.view_perm = "joined" group.is_staff = is_group_staff(group, request.user) return func(view, request, group, *args, **kwargs) if request.user.is_staff: # viewed by system admin group.view_perm = "sys_admin" return func(view, request, group, *args, **kwargs) if group.is_pub: group.view_perm = "pub" return func(view, request, group, *args, **kwargs) # Return group public info page. return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this group.')
def put(self, request, group_id): """ Admin transfer a group Permission checking: 1. Admin user; """ # argument check new_owner = request.data.get('new_owner', None) if not new_owner or not is_valid_username(new_owner): error_msg = 'new_owner %s invalid.' % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # recourse check group_id = int(group_id) # Checked by URL Conf group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if new_owner exists, # NOT need to check old_owner for old_owner may has been deleted. try: User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) old_owner = group.creator_name if new_owner == old_owner: error_msg = _(u'User %s is already group owner.') % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # transfer a group try: if not is_group_member(group_id, new_owner): ccnet_api.group_add_member(group_id, old_owner, new_owner) if not is_group_admin(group_id, new_owner): ccnet_api.group_set_admin(group_id, new_owner) ccnet_api.set_group_creator(group_id, new_owner) ccnet_api.group_unset_admin(group_id, old_owner) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # send admin operation log signal admin_op_detail = { "id": group_id, "name": group.group_name, "from": old_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=GROUP_TRANSFER, detail=admin_op_detail) group_info = get_group_info(group_id) return Response(group_info)
def check_dtable_permission(username, workspace, dtable=None, org_id=None): """Check workspace/dtable access permission of a user. """ owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if is_group_member(group_id, username): return PERMISSION_READ_WRITE else: if username == owner: return PERMISSION_READ_WRITE if dtable: # check user's all permissions from `share`, `group-share` and checkout higher one dtable_share = DTableShare.objects.get_by_dtable_and_to_user( dtable, username) if dtable_share and dtable_share.permission == PERMISSION_READ_WRITE: return dtable_share.permission permission = dtable_share.permission if dtable_share else None if org_id and org_id > 0: groups = ccnet_api.get_org_groups_by_user(org_id, username) else: groups = ccnet_api.get_groups(username, return_ancestors=True) group_ids = [group.id for group in groups] group_permissions = DTableGroupShare.objects.filter( dtable=dtable, group_id__in=group_ids).values_list('permission', flat=True) for group_permission in group_permissions: permission = permission if permission else group_permission if group_permission == PERMISSION_READ_WRITE: return group_permission return permission return None
def post(self, request, group_id): """ Add a group member. """ email = request.data.get('email', None) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) username = request.user.username try: # only group owner/admin can add a group member if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_group_member(group_id, email): error_msg = _(u'User %s is already a group member.') % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) seaserv.ccnet_threaded_rpc.group_add_member(group_id, username, email) except SearpcError as e: logger.error(e) 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) return Response(member_info, status=status.HTTP_201_CREATED)
def get(self, request, group_id): """ Get all group libraries. Permission checking: 1. is group member; """ # only group member can get group libraries if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_org_context(request): org_id = request.user.org.org_id group_repos = seafile_api.get_org_group_repos(org_id, group_id) else: group_repos = seafile_api.get_repos_by_group(group_id) group_repos.sort(lambda x, y: cmp(y.last_modified, x.last_modified)) result = [] for repo in group_repos: group_repo_info = get_group_repo_info(request, repo) result.append(group_repo_info) return Response(result)
def get(self, request, group_id, format=None): """ Get all group members. """ try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE try: # only group member can get info of all group members if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) members = seaserv.get_group_members(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) group_members = [] is_admin = request.GET.get('is_admin', 'false') for m in members: # only return group admins if is_admin == 'true' and not m.is_staff: continue member_info = get_group_member_info(request, group_id, m.user_name, avatar_size) group_members.append(member_info) return Response(group_members)
def _decorated(view, request, group_id, *args, **kwargs): group_id_int = int(group_id) # Checked by URL Conf group = get_group(group_id_int) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group not found.') group.is_staff = False if PublicGroup.objects.filter(group_id=group.id): group.is_pub = True else: group.is_pub = False joined = is_group_member(group_id_int, request.user.username) if joined: group.view_perm = "joined" group.is_staff = is_group_staff(group, request.user) return func(view, request, group, *args, **kwargs) if request.user.is_staff: # viewed by system admin group.view_perm = "sys_admin" return func(view, request, group, *args, **kwargs) if group.is_pub: group.view_perm = "pub" return func(view, request, group, *args, **kwargs) # Return group public info page. return api_error(status.HTTP_403_FORBIDDEN, 'Forbid to access this group.')
def create_group_repo(request, group_id): """Create a repo and share it to current group""" content_type = 'application/json; charset=utf-8' def json_error(err_msg): result = {'error': err_msg} return HttpResponseBadRequest(json.dumps(result), content_type=content_type) group_id = int(group_id) group = get_group(group_id) if not group: return json_error(_(u'Failed to create: the group does not exist.')) # Check whether user belongs to the group. username = request.user.username if not is_group_member(group_id, username): return json_error(_(u'Failed to create: you are not in the group.')) form = SharedRepoCreateForm(request.POST) if not form.is_valid(): return json_error(str(form.errors.values()[0])) # Form is valid, create group repo repo_name = form.cleaned_data['repo_name'] repo_desc = form.cleaned_data['repo_desc'] permission = form.cleaned_data['permission'] encryption = int(form.cleaned_data['encryption']) uuid = form.cleaned_data['uuid'] magic_str = form.cleaned_data['magic_str'] encrypted_file_key = form.cleaned_data['encrypted_file_key'] if is_org_context(request): org_id = request.user.org.org_id try: if encryption: repo_id = seafile_api.create_org_enc_repo(uuid, repo_name, repo_desc, username, magic_str, encrypted_file_key, enc_version=2, org_id=org_id) else: repo_id = seafile_api.create_org_repo(repo_name, repo_desc, username, None, org_id) except SearpcError, e: logger.error(e) return json_error(_(u'Failed to create')) try: seafile_api.add_org_group_repo(repo_id, org_id, group.id, username, permission) except SearpcError, e: logger.error(e) return json_error(_(u'Failed to create: internal error.'))
def post(self, request, group_id): """ Bulk add group members. Permission checking: 1. only admin can perform this action. """ # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) emails = request.POST.getlist('email', '') if not emails: error_msg = 'Email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] emails_need_add = [] for email in emails: try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'email': email, 'error_msg': 'User %s not found.' % email }) continue if is_group_member(group_id, email, in_structure=False): result['failed'].append({ 'email': email, 'error_msg': 'User %s is already a group member.' % email2nickname(email) }) continue emails_need_add.append(email) # Add user to group. for email in emails_need_add: try: ccnet_api.group_add_member(group_id, group.creator_name, email) member_info = get_group_member_info(request, group_id, email) result['success'].append(member_info) except Exception as e: logger.error(e) result['failed'].append({ 'email': email, 'error_msg': 'Internal Server Error' }) return Response(result)
def get(self, request, workspace_id): """view table file, get table download link """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) reuse = request.GET.get('reuse', '0') if reuse not in ('1', '0'): error_msg = 'reuse invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) table_file_name = table_name + FILE_TYPE table_path = normalize_file_path(table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path) if not table_file_id: error_msg = 'file %s not found.' % table_file_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # send stats message send_file_access_msg(request, repo, table_path, 'api') op = request.GET.get('op', 'download') use_onetime = False if reuse == '1' else True return get_repo_file(request, repo_id, table_file_id, table_file_name, op, use_onetime)
def delete(self, request, group_id, email): """ User leave group or group owner/admin delete a group member. """ try: if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) username = request.user.username # user leave group if username == email: try: seaserv.ccnet_threaded_rpc.quit_group(group_id, username) # remove repo-group share info of all 'email' owned repos seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # group owner/admin delete a group member try: if is_group_owner(group_id, username): # group owner can delete all group member seaserv.ccnet_threaded_rpc.group_remove_member( group_id, username, email) seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) elif is_group_admin(group_id, username): # group admin can NOT delete group owner/admin if not is_group_admin_or_owner(group_id, email): seaserv.ccnet_threaded_rpc.group_remove_member( group_id, username, email) seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) else: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def get(self, request, workspace_id): """get table file update link """ # argument check table_name = request.GET.get('name', None) if not table_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: error_msg = 'Workspace %s not found.' % workspace_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) dtable = DTables.objects.get_dtable(workspace, table_name) if not dtable: error_msg = 'dtable %s not found.' % table_name return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: token = seafile_api.get_fileserver_access_token(repo_id, 'dummy', 'update', username, use_onetime=False) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) dtable.modifier = username dtable.save() url = gen_file_upload_url(token, 'update-api') return Response(url)
def is_repo_admin(username, repo_id): is_administrator = ExtraSharePermission.objects.\ get_user_permission(repo_id, username) == PERMISSION_ADMIN belong_to_admin_group = False group_ids = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo_id) for group_id in group_ids: if is_group_member(group_id, username): belong_to_admin_group = True break return is_administrator or belong_to_admin_group
def create_group_repo(request, group_id): """Create a repo and share it to current group""" content_type = 'application/json; charset=utf-8' def json_error(err_msg): result = {'error': err_msg} return HttpResponseBadRequest(json.dumps(result), content_type=content_type) group_id = int(group_id) group = get_group(group_id) if not group: return json_error(_(u'Failed to create: the group does not exist.')) # Check whether user belongs to the group. username = request.user.username if not is_group_member(group_id, username): return json_error(_(u'Failed to create: you are not in the group.')) form = SharedRepoCreateForm(request.POST) if not form.is_valid(): return json_error(str(form.errors.values()[0])) # Form is valid, create group repo repo_name = form.cleaned_data['repo_name'] repo_desc = form.cleaned_data['repo_desc'] permission = form.cleaned_data['permission'] encryption = int(form.cleaned_data['encryption']) uuid = form.cleaned_data['uuid'] magic_str = form.cleaned_data['magic_str'] encrypted_file_key = form.cleaned_data['encrypted_file_key'] if is_org_context(request): org_id = request.user.org.org_id try: if encryption: repo_id = seafile_api.create_org_enc_repo( uuid, repo_name, repo_desc, username, magic_str, encrypted_file_key, enc_version=2, org_id=org_id) else: repo_id = seafile_api.create_org_repo(repo_name, repo_desc, username, None, org_id) except SearpcError, e: logger.error(e) return json_error(_(u'Failed to create')) try: seafile_api.add_org_group_repo(repo_id, org_id, group.id, username, permission) except SearpcError, e: logger.error(e) return json_error(_(u'Failed to create: internal error.'))
def delete(self, request, group_id, email): """ User leave group or group owner/admin delete a group member. """ try: if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) username = request.user.username # user leave group if username == email: try: seaserv.ccnet_threaded_rpc.quit_group(group_id, username) # remove repo-group share info of all 'email' owned repos seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # group owner/admin delete a group member try: if is_group_owner(group_id, username): # group owner can delete all group member seaserv.ccnet_threaded_rpc.group_remove_member(group_id, username, email) seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) elif is_group_admin(group_id, username): # group admin can NOT delete group owner/admin if not is_group_admin_or_owner(group_id, email): seaserv.ccnet_threaded_rpc.group_remove_member(group_id, username, email) seafile_api.remove_group_repos_by_owner(group_id, email) return Response({'success': True}) else: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def put(self, request, group_id): """ Admin transfer a group Permission checking: 1. Admin user; """ # argument check new_owner = request.data.get('new_owner', None) if not new_owner or not is_valid_username(new_owner): error_msg = 'new_owner %s invalid.' % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # recourse check group_id = int(group_id) # Checked by URL Conf group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if new_owner exists, # NOT need to check old_owner for old_owner may has been deleted. try: User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) old_owner = group.creator_name if new_owner == old_owner: error_msg = _(u'User %s is already group owner.') % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # transfer a group try: if not is_group_member(group_id, new_owner): ccnet_api.group_add_member(group_id, old_owner, new_owner) if not is_group_admin(group_id, new_owner): ccnet_api.group_set_admin(group_id, new_owner) ccnet_api.set_group_creator(group_id, new_owner) ccnet_api.group_unset_admin(group_id, old_owner) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_info = get_group_info(group_id) return Response(group_info)
def get(self, request): """list all departments """ if not is_pro_version(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') try: departments = ccnet_api.list_all_departments() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: avatar_size = int( request.GET.get('avatar_size', GROUP_AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = GROUP_AVATAR_DEFAULT_SIZE result = [] for department in departments: department = seaserv.get_group(department.id) username = request.user.username if not is_group_member(department.id, username): continue try: avatar_url, is_default, date_uploaded = api_grp_avatar_url( department.id, avatar_size) except Exception as e: logger.error(e) avatar_url = get_default_group_avatar_url() created_at = timestamp_to_isoformat_timestr(department.timestamp) department_info = { "id": department.id, "email": '%s@seafile_group' % str(department.id), "parent_group_id": department.parent_group_id, "name": department.group_name, "owner": department.creator_name, "created_at": created_at, "avatar_url": request.build_absolute_uri(avatar_url), } result.append(department_info) return Response(result)
def put(self, request, group_id, email, format=None): """ update role of a group member Permission checking: 1. only admin can perform this action. """ if not request.user.admin_permissions.can_manage_group(): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) is_admin = request.data.get('is_admin', '') try: # set/unset a specific group member as admin if is_admin.lower() == 'true': ccnet_api.group_set_admin(group_id, email) elif is_admin.lower() == 'false': ccnet_api.group_unset_admin(group_id, email) else: error_msg = 'is_admin invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except Exception as e: logger.error(e) 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) return Response(member_info)
def check_dtable_permission(username, owner): """Check workspace/dtable access permission of a user. """ if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): return None else: return PERMISSION_READ_WRITE else: if username != owner: return None else: return PERMISSION_READ_WRITE
def dtable_file_view(request, workspace_id, name): # resource check workspace = Workspaces.objects.get_workspace_by_id(workspace_id) if not workspace: raise Http404 repo_id = workspace.repo_id repo = seafile_api.get_repo(repo_id) if not repo: raise Http404 dtable = DTables.objects.get_dtable(workspace, name) if not dtable: return render_error(request, _(u'Table does not exist')) table_file_name = name + FILE_TYPE table_path = normalize_file_path(table_file_name) table_file_id = seafile_api.get_file_id_by_path(repo_id, table_path) if not table_file_id: return render_error(request, _(u'Table does not exist')) # permission check username = request.user.username owner = workspace.owner if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if not is_group_member(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if username != owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) return_dict = { 'share_link_expire_days_default': SHARE_LINK_EXPIRE_DAYS_DEFAULT, 'share_link_expire_days_min': SHARE_LINK_EXPIRE_DAYS_MIN, 'share_link_expire_days_max': SHARE_LINK_EXPIRE_DAYS_MAX, 'repo': repo, 'filename': name, 'path': table_path, 'filetype': 'dtable', 'workspace_id': workspace_id, } return render(request, 'dtable_file_view_react.html', return_dict)
def post(self, request, group_id): """ Add a group member. """ username = request.user.username # only group owner/admin can add a group member if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) email = request.data.get('email', None) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if is_group_member(group_id, email): error_msg = _('User %s is already a group member.' ) % email2nickname(email) return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if is_org_context(request): org_id = request.user.org.org_id if not ccnet_api.org_user_exists(org_id, email): error_msg = _('User %s not found in organization.' ) % email2nickname(email) return api_error(status.HTTP_404_NOT_FOUND, error_msg) elif is_org_user(email): error_msg = _('User %s is an organization user.') % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) ccnet_api.group_add_member(group_id, username, email) add_user_to_group.send(sender=None, group_staff=username, group_id=group_id, added_user=email) except SearpcError as e: logger.error(e) 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) return Response(member_info, status=status.HTTP_201_CREATED)
def get(self, request, group_id, format=None): """ Get all group members. """ try: avatar_size = int( request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE try: page = int(request.GET.get('page', '1')) per_page = int(request.GET.get('per_page', '100')) except ValueError: page = 1 per_page = 100 start = (page - 1) * per_page limit = per_page try: # only group member can get info of all group members if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) members = ccnet_api.get_group_members(group_id, start, limit) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_members = [] is_admin = request.GET.get('is_admin', 'false') for m in members: # only return group admins if is_admin == 'true' and not m.is_staff: continue member_info = get_group_member_info(request, group_id, m.user_name, avatar_size) group_members.append(member_info) return Response(group_members)
def put(self, request, group_id, email, format=None): """ update role of a group member Permission checking: 1. only admin can perform this action. """ # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if not is_group_member(group_id, email): error_msg = 'Email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) is_admin = request.data.get('is_admin', '') try: # set/unset a specific group member as admin if is_admin.lower() == 'true': ccnet_api.group_set_admin(group_id, email) elif is_admin.lower() == 'false': ccnet_api.group_unset_admin(group_id, email) else: error_msg = 'is_admin invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) except Exception as e: logger.error(e) 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) return Response(member_info)
def get(self, request): """list all departments """ try: departments = ccnet_api.list_all_departments() except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) try: avatar_size = int(request.GET.get('avatar_size', GROUP_AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = GROUP_AVATAR_DEFAULT_SIZE result = [] for department in departments: department = seaserv.get_group(department.id) username = request.user.username if not is_group_member(department.id, username): continue try: avatar_url, is_default, date_uploaded = api_grp_avatar_url(department.id, avatar_size) except Exception as e: logger.error(e) avatar_url = get_default_group_avatar_url() created_at = timestamp_to_isoformat_timestr(department.timestamp) department_info = { "id": department.id, "email": '%s@seafile_group' % str(department.id), "parent_group_id": department.parent_group_id, "name": department.group_name, "owner": department.creator_name, "created_at": created_at, "avatar_url": request.build_absolute_uri(avatar_url), } result.append(department_info) return Response(result)
def delete(self, request, group_id, email, format=None): """ Delete an user from group Permission checking: 1. only admin can perform this action. """ # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) # delete member from group try: if not is_group_member(group_id, email): return Response({'success': True}) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if group.creator_name == email: error_msg = '%s is group owner, can not be removed.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: ccnet_api.group_remove_member(group_id, group.creator_name, email) # remove repo-group share info of all 'email' owned repos seafile_api.remove_group_repos_by_owner(group_id, email) except Exception 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})
def post(self, request, group_id): """ Add a group member. """ username = request.user.username # only group owner/admin can add a group member if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) email = request.data.get('email', None) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if is_group_member(group_id, email): error_msg = _(u'User %s is already a group member.') % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if is_org_context(request): org_id = request.user.org.org_id if not ccnet_api.org_user_exists(org_id, email): error_msg = _(u'User %s not found in organization.') % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) ccnet_api.group_add_member(group_id, username, email) add_user_to_group.send(sender=None, group_staff=username, group_id=group_id, added_user=email) except SearpcError as e: logger.error(e) 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) return Response(member_info, status=status.HTTP_201_CREATED)
def get(self, request, group_id): """ Get info of a group. """ try: # only group member can get info of a group if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) 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)
def check_dtable_permission(username, workspace, dtable=None): """Check workspace/dtable access permission of a user. """ owner = workspace.owner if dtable: dtable_share = DTableShare.objects.get_by_dtable_and_to_user( dtable, username) if dtable_share: return dtable_share.permission if '@seafile_group' in owner: group_id = int(owner.split('@')[0]) if is_group_member(group_id, username): return PERMISSION_READ_WRITE else: return None else: if username == owner: return PERMISSION_READ_WRITE else: return None
def delete(self, request, group_id, email, format=None): """ Delete an user from group Permission checking: 1. only admin can perform this action. """ # argument check group_id = int(group_id) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # delete member from group try: if not is_group_member(group_id, email): return Response({'success': True}) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if group.creator_name == email: error_msg = '%s is group owner, can not be removed.' % email return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: ccnet_api.group_remove_member(group_id, group.creator_name, email) # remove repo-group share info of all 'email' owned repos seafile_api.remove_group_repos_by_owner(group_id, email) except Exception 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})
def get(self, request, group_id, format=None): """ Search group member by email. """ q = request.GET.get('q', '') if not q: error_msg = 'q invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) group_members = [] members = ccnet_api.search_group_members(group_id, q) for member in members: member_info = get_group_member_info(request, group_id, member.user_name) group_members.append(member_info) return Response(group_members)
def group_wiki(request, group, page_name="home"): username = request.user.username # get available modules(wiki, etc) mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) wiki_exists = True try: content, repo, dirent = get_group_wiki_page(username, group, page_name) except WikiDoesNotExist: wiki_exists = False group_repos = get_group_repos(group.id, username) group_repos = [r for r in group_repos if not r.encrypted] return render( request, "group/group_wiki.html", { "group": group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "mods_enabled": mods_enabled, "mods_available": mods_available, "group_repos": group_repos, }) except WikiPageMissing: '''create that page for user if he/she is a group member''' if not is_group_member(group.id, username): raise Http404 repo = get_group_wiki_repo(group, username) # No need to check whether repo is none, since repo is already created filename = page_name_to_file_name(clean_page_name(page_name)) if not post_empty_file(repo.id, "/", filename, username): return render_error( request, _("Failed to create wiki page. Please retry later.")) return HttpResponseRedirect( reverse('group_wiki', args=[group.id, page_name])) else: # fetch file modified time and modifier path = '/' + dirent.obj_name try: dirent = seafile_api.get_dirent_by_path(repo.id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 if is_registered_user(username): repo_perm = seafile_api.check_permission_by_path( repo.id, '/', username) else: # when anonymous user visit public group wiki, set permission as 'r' repo_perm = 'r' wiki_index_exists = True index_pagename = 'index' index_content = None try: index_content, index_repo, index_dirent = get_group_wiki_page( username, group, index_pagename) except (WikiDoesNotExist, WikiPageMissing) as e: wiki_index_exists = False return render( request, "group/group_wiki.html", { "group": group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "content": content, "page": os.path.splitext(dirent.obj_name)[0], "last_modified": last_modified, "latest_contributor": latest_contributor or _("Unknown"), "path": path, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "mods_enabled": mods_enabled, "mods_available": mods_available, "repo_perm": repo_perm, "wiki_index_exists": wiki_index_exists, "index_content": index_content, })
def get(self, request, group_id): """ Get all group libraries. Permission checking: 1. is group member; """ # only group member can get group libraries username = request.user.username if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if is_org_context(request): org_id = request.user.org.org_id group_repos = seafile_api.get_org_group_repos(org_id, group_id) else: group_repos = seafile_api.get_repos_by_group(group_id) group_repos.sort(lambda x, y: cmp(y.last_modified, x.last_modified)) # get repo id owner dict all_repo_owner = [] repo_id_owner_dict = {} for repo in group_repos: repo_id = repo.id if repo_id not in repo_id_owner_dict: repo_owner = get_repo_owner(request, repo_id) all_repo_owner.append(repo_owner) repo_id_owner_dict[repo_id] = repo_owner all_modifier = [r.last_modifier for r in group_repos] # Use dict to reduce memcache fetch cost in large for-loop. name_dict = {} contact_email_dict = {} for email in set(all_repo_owner + all_modifier): if email not in name_dict: if '@seafile_group' in email: group_id = get_group_id_by_repo_owner(email) group_name= group_id_to_name(group_id) name_dict[email] = group_name else: name_dict[email] = email2nickname(email) if email not in contact_email_dict: if '@seafile_group' in email: contact_email_dict[email] = '' else: contact_email_dict[email] = email2contact_email(email) try: starred_repos = UserStarredFiles.objects.get_starred_repos_by_user(username) starred_repo_id_list = [item.repo_id for item in starred_repos] except Exception as e: logger.error(e) starred_repo_id_list = [] result = [] for group_repo in group_repos: group_repo_info = get_group_repo_info(request, group_repo) repo_owner = repo_id_owner_dict[group_repo.id] group_repo_info['owner_email'] = repo_owner group_repo_info['owner_name'] = name_dict.get(repo_owner, '') group_repo_info['owner_contact_email'] = contact_email_dict.get(repo_owner, '') modifier = group_repo.last_modifier group_repo_info['modifier_email'] = modifier group_repo_info['modifier_name'] = name_dict.get(modifier, '') group_repo_info['modifier_contact_email'] = contact_email_dict.get(modifier, '') group_repo_info['starred'] = group_repo.id in starred_repo_id_list result.append(group_repo_info) return Response(result)
def put(self, request, repo_id, format=None): username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path) if repo.encrypted and path != '/': return api_error(status.HTTP_400_BAD_REQUEST, 'Folder invalid.') share_type = request.data.get('share_type') if share_type != 'user' and share_type != 'group': return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.') repo_owner = self.get_repo_owner(request, repo_id) if repo_owner != username and not is_repo_admin(username, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') result = {} result['failed'] = [] result['success'] = [] if share_type == 'user': share_to_users = request.data.getlist('username') for to_user in share_to_users: if not is_valid_username(to_user): result['failed'].append({ 'email': to_user, 'error_msg': _('username invalid.') }) continue try: User.objects.get(email=to_user) except User.DoesNotExist: result['failed'].append({ 'email': to_user, 'error_msg': _('User %s not found.') % to_user }) continue if self.has_shared_to_user(request, repo_id, path, to_user): result['failed'].append({ 'email': to_user, 'error_msg': _('This item has been shared to %s.') % email2nickname(to_user) }) continue try: org_id = None if is_org_context(request): org_id = request.user.org.org_id if not is_org_user(to_user, int(org_id)): org_name = request.user.org.org_name error_msg = 'User %s is not member of organization %s.' \ % (to_user, org_name) result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, org_id) else: if is_org_user(to_user): error_msg = 'User %s is a member of organization.' % to_user result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue repo_owner = seafile_api.get_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, None) avatar_url, is_default, date_uploaded = api_avatar_url( to_user, 72) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), "contact_email": email2contact_email(to_user), "avatar_url": avatar_url, }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'email': to_user, 'error_msg': 'Internal Server Error' }) continue if share_type == 'group': group_ids = request.data.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: result['failed'].append( {'error_msg': 'group_id %s invalid.' % gid}) continue group = ccnet_api.get_group(gid) if not group: result['failed'].append( {'error_msg': 'Group %s not found' % gid}) continue if not config.ENABLE_SHARE_TO_ALL_GROUPS and \ not is_group_member(gid, username): result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Permission denied.' }) continue if self.has_shared_to_group(request, repo_id, path, gid): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _('This item has been shared to %s.') % group.group_name }) continue try: org_id = None if is_org_context(request): # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id share_dir_to_group(repo, path, repo_owner, username, gid, permission, org_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) share_dir_to_group(repo, path, repo_owner, username, gid, permission, None) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Internal Server Error' }) continue return HttpResponse(json.dumps(result), status=200, content_type=json_content_type)
def add_admin_to_group(self): ccnet_api.group_add_member( self.group.id, self.user.username, self.admin.username) assert is_group_member(self.group.id, self.admin.username)
def post(self, request, group_id): """ Add a group library. Permission checking: 1. role permission, can_add_repo; 1. is group member; """ # argument check repo_name = request.data.get("repo_name", None) if not repo_name or \ not is_valid_dirent_name(repo_name): error_msg = "repo_name invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("password", None) if password and not config.ENABLE_ENCRYPTED_LIBRARY: error_msg = 'NOT allow to create encrypted library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if not request.user.permissions.can_add_repo(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create group repo org_id = -1 group_id = int(group_id) username = request.user.username is_org = False if is_org_context(request): is_org = True org_id = request.user.org.org_id repo_id = seafile_api.create_org_repo(repo_name, '', username, password, org_id) else: repo_id = seafile_api.create_repo(repo_name, '', username, password) repo = seafile_api.get_repo(repo_id) share_dir_to_group(repo, '/', username, username, group_id, permission, org_id if is_org else None) # for activities library_template = request.data.get("library_template", '') repo_created.send(sender=None, org_id=org_id, creator=username, repo_id=repo_id, repo_name=repo_name, library_template=library_template) # for notification share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path='/', org_id=org_id) # for perm audit send_perm_audit_msg('add-repo-perm', username, group_id, repo_id, '/', permission) group_repo = seafile_api.get_group_shared_repo_by_path(repo_id, None, group_id, is_org) group_repo_info = get_group_repo_info(request, group_repo) group_repo_info['owner_email'] = username group_repo_info['owner_name'] = email2nickname(username) group_repo_info['owner_contact_email'] = email2contact_email(username) modifier = group_repo.last_modifier group_repo_info['modifier_email'] = modifier group_repo_info['modifier_name'] = email2nickname(modifier) group_repo_info['modifier_contact_email'] = email2contact_email(modifier) return Response(group_repo_info)
def put(self, request, group_id): """ Admin update a group 1. transfer a group. 2. set group quota Permission checking: 1. Admin user; """ # recourse check group_id = int(group_id) # Checked by URL Conf group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %d not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) new_owner = request.data.get('new_owner', '') if new_owner: if not is_valid_username(new_owner): error_msg = 'new_owner %s invalid.' % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # check if new_owner exists, # NOT need to check old_owner for old_owner may has been deleted. try: User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) old_owner = group.creator_name if new_owner == old_owner: error_msg = _(u'User %s is already group owner.') % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # transfer a group try: if not is_group_member(group_id, new_owner): ccnet_api.group_add_member(group_id, old_owner, new_owner) if not is_group_admin(group_id, new_owner): ccnet_api.group_set_admin(group_id, new_owner) ccnet_api.set_group_creator(group_id, new_owner) ccnet_api.group_unset_admin(group_id, old_owner) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # send admin operation log signal admin_op_detail = { "id": group_id, "name": group.group_name, "from": old_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=GROUP_TRANSFER, detail=admin_op_detail) # set group quota group_quota = request.data.get('quota', '') if group_quota: try: group_quota = int(group_quota) except ValueError: error_msg = 'quota invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not (group_quota > 0 or group_quota == -2): error_msg = 'quota invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: seafile_api.set_group_quota(group_id, group_quota) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_info = get_group_info(group_id) return Response(group_info)
def has_permission(self, request, view, obj=None): group_id = int(view.kwargs.get('group_id', '')) username = request.user.username if request.user else '' return True if is_group_member(group_id, username) else False
def group_wiki(request, group, page_name="home"): username = request.user.username # get available modules(wiki, etc) mods_available = get_available_mods_by_group(group.id) mods_enabled = get_enabled_mods_by_group(group.id) wiki_exists = True try: content, repo, dirent = get_group_wiki_page(username, group, page_name) except WikiDoesNotExist: wiki_exists = False group_repos = get_group_repos(group.id, username) group_repos = [r for r in group_repos if not r.encrypted] return render(request, "group/group_wiki.html", { "group" : group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "mods_enabled": mods_enabled, "mods_available": mods_available, "group_repos": group_repos, }) except WikiPageMissing: '''create that page for user if he/she is a group member''' if not is_group_member(group.id, username): raise Http404 repo = get_group_wiki_repo(group, username) # No need to check whether repo is none, since repo is already created filename = page_name_to_file_name(clean_page_name(page_name)) if not post_empty_file(repo.id, "/", filename, username): return render_error(request, _("Failed to create wiki page. Please retry later.")) return HttpResponseRedirect(reverse('group_wiki', args=[group.id, page_name])) else: # fetch file modified time and modifier path = '/' + dirent.obj_name try: dirent = seafile_api.get_dirent_by_path(repo.id, path) if dirent: latest_contributor, last_modified = dirent.modifier, dirent.mtime else: latest_contributor, last_modified = None, 0 except SearpcError as e: logger.error(e) latest_contributor, last_modified = None, 0 if is_registered_user(username): repo_perm = seafile_api.check_permission_by_path(repo.id, '/', username) else: # when anonymous user visit public group wiki, set permission as preview only repo_perm = PERMISSION_PREVIEW wiki_index_exists = True index_pagename = 'index' index_content = None try: index_content, index_repo, index_dirent = get_group_wiki_page(username, group, index_pagename) except (WikiDoesNotExist, WikiPageMissing) as e: wiki_index_exists = False return render(request, "group/group_wiki.html", { "group" : group, "is_staff": group.is_staff, "wiki_exists": wiki_exists, "content": content, "page": os.path.splitext(dirent.obj_name)[0], "last_modified": last_modified, "latest_contributor": latest_contributor or _("Unknown"), "path": path, "repo_id": repo.id, "search_repo_id": repo.id, "search_wiki": True, "mods_enabled": mods_enabled, "mods_available": mods_available, "repo_perm": repo_perm, "wiki_index_exists": wiki_index_exists, "index_content": index_content, })
def post(self, request, group_id): """ Bulk add group members. """ username = request.user.username try: if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) 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: email_name = email2nickname(email) try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': 'User %s not found.' % email_name }) continue if is_group_member(group_id, email, in_structure=False): result['failed'].append({ 'email': email, 'email_name': email_name, 'error_msg': _(u'User %s is already a group member.') % email_name }) 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, 'email_name': email_name, 'error_msg': _(u'User %s not found in organization.') % email_name }) 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' }) add_user_to_group.send(sender=None, group_staff=username, group_id=group_id, added_user=email) return Response(result)
def put(self, request, group_id): """ Rename, transfer a specific group """ username = request.user.username new_group_name = request.data.get('name', None) # rename a group if new_group_name: try: # only group owner/admin can rename a group if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # Check whether group name is validate. if not validate_group_name(new_group_name): error_msg = _(u'Group name can only contain letters, numbers, blank, hyphen or underscore') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # Check whether group name is duplicated. if check_group_name_conflict(request, new_group_name): error_msg = _(u'There is already a group with that name.') return api_error(status.HTTP_400_BAD_REQUEST, error_msg) seaserv.ccnet_threaded_rpc.set_group_name(group_id, new_group_name) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) new_owner = request.data.get('owner', None) # transfer a group if new_owner: try: # only group owner can transfer a group if not is_group_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # augument check 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 is_group_owner(group_id, new_owner): error_msg = _(u'User %s is already group owner.') % new_owner return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # transfer a group if not is_group_member(group_id, new_owner): ccnet_api.group_add_member(group_id, username, new_owner) if not is_group_admin(group_id, new_owner): ccnet_api.group_set_admin(group_id, new_owner) ccnet_api.set_group_creator(group_id, new_owner) ccnet_api.group_unset_admin(group_id, username) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) wiki_enabled = request.data.get('wiki_enabled', None) # turn on/off group wiki if wiki_enabled: try: # only group owner/admin can turn on a group wiki if not is_group_admin_or_owner(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # augument check if wiki_enabled != 'true' and wiki_enabled != 'false': error_msg = 'wiki_enabled invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # turn on/off group wiki if wiki_enabled == 'true': enable_mod_for_group(group_id, MOD_GROUP_WIKI) else: disable_mod_for_group(group_id, MOD_GROUP_WIKI) except SearpcError as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_info = get_group_info(request, group_id) return Response(group_info)
def put(self, request, repo_id, format=None): """ transfer a library, rename a library Permission checking: 1. only admin can perform this action. """ repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) new_repo_name = request.data.get('name', None) if new_repo_name: try: res = seafile_api.edit_repo(repo_id, new_repo_name, '', None) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if res == -1: e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \ repo_id logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) new_owner = request.data.get('owner', None) if new_owner: try: new_owner_obj = User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not new_owner_obj.permissions.can_add_repo(): error_msg = _(u'Transfer failed: role of %s is %s, can not add library.') % \ (new_owner, new_owner_obj.role) return api_error(status.HTTP_403_FORBIDDEN, error_msg) if MULTI_TENANCY: try: if seafile_api.get_org_id_by_repo_id(repo_id) > 0: error_msg = 'Can not transfer organization library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if ccnet_api.get_orgs_by_user(new_owner): error_msg = 'Can not transfer library to organization user %s' % new_owner return api_error(status.HTTP_403_FORBIDDEN, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_owner = seafile_api.get_repo_owner(repo_id) if new_owner == repo_owner: error_msg = _(u"Library can not be transferred to owner.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # get repo shared to user/group list shared_users = seafile_api.list_repo_shared_to( repo_owner, repo_id) shared_groups = seafile_api.list_repo_shared_group_by_user( repo_owner, repo_id) # get all pub repos pub_repos = [] if not request.cloud_mode: pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner) # transfer repo seafile_api.set_repo_owner(repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.share_repo(repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not is_group_member(shared_group_id, new_owner): continue seafile_api.set_group_repo(repo_id, shared_group_id, new_owner, shared_group.perm) # reshare repo to links try: UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission) break # send admin operation log signal admin_op_detail = { "id": repo_id, "name": repo.name, "from": repo_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=REPO_TRANSFER, detail=admin_op_detail) repo = seafile_api.get_repo(repo_id) repo_info = get_repo_info(repo) return Response(repo_info)
def put(self, request, repo_id, format=None): """ update a library status, transfer a library, rename a library Permission checking: 1. only admin can perform this action. """ # argument check new_status = request.data.get('status', None) if new_status: if new_status not in ('normal', 'read-only'): error_msg = 'status invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_repo_name = request.data.get('name', None) if new_repo_name: if not is_valid_dirent_name(new_repo_name): error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) new_owner = request.data.get('owner', None) if new_owner: if not is_valid_email(new_owner): error_msg = 'owner invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if new_status: try: seafile_api.set_repo_status(repo_id, normalize_repo_status_str(new_status)) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if new_repo_name: try: res = seafile_api.edit_repo(repo_id, new_repo_name, '', None) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if res == -1: e = 'Admin rename failed: ID of library is %s, edit_repo api called failed.' % \ repo_id logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if new_owner: try: new_owner_obj = User.objects.get(email=new_owner) except User.DoesNotExist: error_msg = 'User %s not found.' % new_owner return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not new_owner_obj.permissions.can_add_repo(): error_msg = _('Transfer failed: role of %s is %s, can not add library.') % \ (new_owner, new_owner_obj.role) return api_error(status.HTTP_403_FORBIDDEN, error_msg) if MULTI_TENANCY: try: if seafile_api.get_org_id_by_repo_id(repo_id) > 0: error_msg = 'Can not transfer organization library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if ccnet_api.get_orgs_by_user(new_owner): error_msg = 'Can not transfer library to organization user %s' % new_owner return api_error(status.HTTP_403_FORBIDDEN, error_msg) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_owner = seafile_api.get_repo_owner(repo_id) if new_owner == repo_owner: error_msg = _("Library can not be transferred to owner.") return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # get repo shared to user/group list shared_users = seafile_api.list_repo_shared_to( repo_owner, repo_id) shared_groups = seafile_api.list_repo_shared_group_by_user( repo_owner, repo_id) # get all pub repos pub_repos = [] if not request.cloud_mode: pub_repos = seafile_api.list_inner_pub_repos_by_owner(repo_owner) # transfer repo seafile_api.set_repo_owner(repo_id, new_owner) # reshare repo to user for shared_user in shared_users: shared_username = shared_user.user if new_owner == shared_username: continue seafile_api.share_repo(repo_id, new_owner, shared_username, shared_user.perm) # reshare repo to group for shared_group in shared_groups: shared_group_id = shared_group.group_id if not is_group_member(shared_group_id, new_owner): continue seafile_api.set_group_repo(repo_id, shared_group_id, new_owner, shared_group.perm) # reshare repo to links try: UploadLinkShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) FileShare.objects.filter(username=repo_owner, repo_id=repo_id).update(username=new_owner) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) # check if current repo is pub-repo # if YES, reshare current repo to public for pub_repo in pub_repos: if repo_id != pub_repo.id: continue seafile_api.add_inner_pub_repo(repo_id, pub_repo.permission) break # send admin operation log signal admin_op_detail = { "id": repo_id, "name": repo.name, "from": repo_owner, "to": new_owner, } admin_operation.send(sender=None, admin_name=request.user.username, operation=REPO_TRANSFER, detail=admin_op_detail) repo = seafile_api.get_repo(repo_id) repo_info = get_repo_info(repo) return Response(repo_info)
def post(self, request): # argument check operation = request.data.get('operation', None) if not operation: error_msg = 'operation invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # operation could be `share`, `unshare`, `delete`, `transfer` # we now only use `share`, `unshare` if operation not in ('share', 'unshare'): error_msg = 'operation can only be "share", "unshare".' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] username = request.user.username repo_id_list = request.data.getlist('repo_id') valid_repo_id_list = [] # filter out invalid repo id for repo_id in repo_id_list: if not seafile_api.get_repo(repo_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Library %s not found.' % repo_id }) continue repo_owner = get_repo_owner(request, repo_id) if repo_owner != username and not is_repo_admin(username, repo_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Permission denied.' }) continue valid_repo_id_list.append(repo_id) # share repo if operation == 'share': share_type = request.data.get('share_type', None) if not share_type: error_msg = 'share_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if share_type not in ('user', 'group'): error_msg = 'share_type can only be "user", "group".' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = request.data.get('permission', 'rw') if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # share repo to user if share_type == 'user': to_username = request.data.get('username', None) if not to_username: error_msg = 'username invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: User.objects.get(email=to_username) except User.DoesNotExist: error_msg = 'User %s not found.' % to_username return api_error(status.HTTP_404_NOT_FOUND, error_msg) # check if to_user is an org user try: org_of_to_user = ccnet_api.get_orgs_by_user(to_username) except Exception as e: logger.error(e) org_of_to_user = [] if is_org_context(request): org_id = request.user.org.org_id org_name = request.user.org.org_name if len(org_of_to_user) == 0 or org_id != org_of_to_user[0].org_id: error_msg = 'User %s is not member of organization %s.' \ % (to_username, org_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) else: if len(org_of_to_user) >= 1: error_msg = 'User %s is member of organization %s.' \ % (to_username, org_of_to_user[0].org_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) for repo_id in valid_repo_id_list: if self.has_shared_to_user(request, repo_id, to_username): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has been shared to %s.' % to_username }) continue try: org_id = None if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share(org_id, repo_id, username, to_username, permission) else: seafile_api.share_repo( repo_id, username, to_username, permission) # send a signal when sharing repo successful repo = seafile_api.get_repo(repo_id) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_username, repo=repo, path='/', org_id=org_id) result['success'].append({ "repo_id": repo_id, "username": to_username, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_username, repo_id, '/', permission) except Exception as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) # share repo to group if share_type == 'group': to_group_id = request.data.get('group_id', None) if not to_group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: to_group_id = int(to_group_id) except ValueError: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) group = ccnet_api.get_group(to_group_id) if not group: error_msg = 'Group %s not found.' % to_group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) group_name = group.group_name if not is_group_member(to_group_id, username): error_msg = 'User %s is not member of group %s.' % (username, group_name) return api_error(status.HTTP_403_FORBIDDEN, error_msg) for repo_id in valid_repo_id_list: if self.has_shared_to_group(request, repo_id, to_group_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has been shared to %s.' % group_name }) continue try: org_id = None if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo( repo_id, org_id, to_group_id, username, permission) else: seafile_api.set_group_repo( repo_id, to_group_id, username, permission) # send a signal when sharing repo successful repo = seafile_api.get_repo(repo_id) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=to_group_id, repo=repo, path='/', org_id=org_id) result['success'].append({ "repo_id": repo_id, "group_id": to_group_id, "group_name": group_name, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_group_id, repo_id, '/', permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) # unshare repo if operation == 'unshare': share_type = request.data.get('share_type', None) if not share_type: error_msg = 'share_type invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if share_type not in ('user', 'group'): error_msg = 'share_type can only be "user", "group".' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # unshare repo from user if share_type == 'user': to_username = request.data.get('username', None) if not to_username: error_msg = 'username invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) for repo_id in valid_repo_id_list: if not self.has_shared_to_user(request, repo_id, to_username): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has not been shared to %s.' % to_username }) continue repo_owner = get_repo_owner(request, repo_id) try: # get share permission before unshare operation permission = check_user_share_out_permission(repo_id, '/', to_username, is_org_context(request)) if is_org_context(request): # when calling seafile API to share authority related functions, change the uesrname to repo owner. org_id = request.user.org.org_id seafile_api.org_remove_share(org_id, repo_id, repo_owner, to_username) else: seafile_api.remove_share(repo_id, repo_owner, to_username) # Delete share permission at ExtraSharePermission table. ExtraSharePermission.objects.delete_share_permission(repo_id, to_username) # send message send_perm_audit_msg('delete-repo-perm', username, to_username, repo_id, '/', permission) result['success'].append({ "repo_id": repo_id, "username": to_username, }) except Exception as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) # unshare repo from group if share_type == 'group': to_group_id = request.data.get('group_id', None) if not to_group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: to_group_id = int(to_group_id) except ValueError: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) group = ccnet_api.get_group(to_group_id) group_name = group.group_name if group else '' for repo_id in valid_repo_id_list: if not self.has_shared_to_group(request, repo_id, to_group_id): result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'This item has not been shared to %s.' % group_name }) continue try: # get share permission before unshare operation permission = check_group_share_out_permission(repo_id, '/', to_group_id, is_org_context(request)) org_id = None if is_org_context(request): org_id = request.user.org.org_id seafile_api.del_org_group_repo(repo_id, org_id, to_group_id) else: seafile_api.unset_group_repo( repo_id, to_group_id, username) # Delete share permission at ExtraSharePermission table. ExtraGroupsSharePermission.objects.delete_share_permission(repo_id, to_group_id) # send message send_perm_audit_msg('delete-repo-perm', username, to_group_id, repo_id, '/', permission) result['success'].append({ "repo_id": repo_id, "group_id": to_group_id, "group_name": group_name, }) except SearpcError as e: logger.error(e) result['failed'].append({ 'repo_id': repo_id, 'error_msg': 'Internal Server Error' }) return Response(result)