def delete(self, request, repo_id, format=None): """ Delete repo group share permission. Permission checking: 1. is group admin """ # parameter check 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) # permission check username = request.user.username repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) path = request.data.get('path', '/') if path == '/': seafile_api.unset_group_repo(repo_id, to_group_id, username) else: seafile_api.unshare_subdir_for_group( repo_id, path, repo_owner, group_id) permission = check_group_share_out_permission(repo_id, path, group_id, False) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, path, permission) return Response({'success': True})
def delete(self, request, repo_id, org_id, format=None): """ Delete repo group share permission. Permission checking: 1. is group admin """ # parameter check 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) # permission check username = request.user.username repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) path = request.data.get('path', '/') SeafileAPI.delete_shared_group_by_repo_path( repo_id, repo_owner, to_group_id, path, org_id) permission = check_group_share_out_permission( repo_id, path, group_id, is_org_context(request)) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, path, permission) return Response({'success': True})
def delete(self, request, repo, path, share_type): """ Delete user/group share permission. Permission checking: 1. admin user. """ # current `request.user.username` is admin user, # so need to identify the repo owner specifically. repo_owner = seafile_api.get_repo_owner(repo.repo_id) username = request.user.username share_to = request.data.get('share_to', None) if share_type == 'user': email = share_to if not email or not is_valid_username(email): error_msg = 'email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not has_shared_to_user(repo.repo_id, path, email): error_msg = 'Shared items not found' return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: permission = check_user_share_out_permission( repo.repo_id, path, email) if path == '/': seafile_api.remove_share(repo.repo_id, repo_owner, email) else: seafile_api.unshare_subdir_for_user( repo.repo_id, path, repo_owner, email) if path == '/': ExtraSharePermission.objects.delete_share_permission( repo.repo_id, email) send_perm_audit_msg('delete-repo-perm', username, email, repo.repo_id, path, permission) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if share_type == 'group': group_id = share_to try: group_id = int(group_id) except ValueError: error_msg = 'group_id %s invalid' % group_id return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not has_shared_to_group(repo.repo_id, path, group_id): error_msg = 'Shared items not found' return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: permission = check_group_share_out_permission( repo.repo_id, path, group_id) if path == '/': seafile_api.unset_group_repo(repo.repo_id, group_id, repo_owner) else: seafile_api.unshare_subdir_for_group( repo.repo_id, path, repo_owner, group_id) if path == '/': ExtraGroupsSharePermission.objects.delete_share_permission( repo.repo_id, group_id) send_perm_audit_msg('delete-repo-perm', username, group_id, repo.repo_id, path, permission) 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 delete(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) 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.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) if shared_to_user: shared_to = request.GET.get('username') if shared_to is None or not is_valid_username(shared_to): return api_error(status.HTTP_400_BAD_REQUEST, 'Email %s invalid.' % shared_to) permission = check_user_share_out_permission( repo_id, path, shared_to, 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 if path == '/': seaserv.seafserv_threaded_rpc.org_remove_share( org_id, repo_id, repo_owner, shared_to) else: seafile_api.org_unshare_subdir_for_user( org_id, repo_id, path, repo_owner, shared_to) else: if path == '/': seaserv.remove_share(repo_id, repo_owner, shared_to) else: seafile_api.unshare_subdir_for_user( repo_id, path, repo_owner, shared_to) # Delete share permission at ExtraSharePermission table. if path == '/': ExtraSharePermission.objects.delete_share_permission( repo_id, shared_to) send_perm_audit_msg('delete-repo-perm', username, shared_to, repo_id, path, permission) if shared_to_group: group_id = request.GET.get('group_id') try: group_id = int(group_id) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid' % group_id) # hacky way to get group repo permission is_org = is_org_context(request) permission = check_group_share_out_permission( repo_id, path, group_id, is_org) if is_org: # when calling seafile API to share authority related functions, change the uesrname to repo owner. org_id = request.user.org.org_id if path == '/': seaserv.del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.org_unshare_subdir_for_group( org_id, repo_id, path, repo_owner, group_id) else: if path == '/': seafile_api.unset_group_repo(repo_id, group_id, username) else: seafile_api.unshare_subdir_for_group( repo_id, path, repo_owner, group_id) # delete share permission if repo is deleted if path == '/': ExtraGroupsSharePermission.objects.delete_share_permission( repo_id, group_id) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, path, permission) return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
def delete(self, request, repo_id, format=None): """ Unshare a repo. Permission checking: 1. Only repo owner can unshare a library. """ # argument check share_type = request.GET.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 ('personal', 'group', 'public'): error_msg = "share_type can only be 'personal' or 'group' or 'public'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) # permission check username = request.user.username if is_org_context(request): repo_owner = seafile_api.get_org_repo_owner(repo_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) if username != repo_owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # delete share org_id = None is_org = False if is_org_context(request): org_id = request.user.org.org_id is_org = True if share_type == 'personal': user = request.GET.get('user', None) if not user or not is_valid_username(user): error_msg = 'user invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = check_user_share_out_permission( repo_id, '/', user, is_org) try: if org_id: seafile_api.org_remove_share(org_id, repo_id, username, user) else: seafile_api.remove_share(repo_id, username, user) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) send_perm_audit_msg('delete-repo-perm', username, user, repo_id, '/', permission) if share_type == 'group': group_id = request.GET.get('group_id', None) if not group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: group_id = int(group_id) except ValueError: error_msg = 'group_id must be integer.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = check_group_share_out_permission( repo_id, '/', group_id, is_org) try: if is_org: seaserv.del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, '/', permission) if share_type == 'public': pub_repos = [] if org_id: pub_repos = seaserv.list_org_inner_pub_repos(org_id, username) if not request.cloud_mode: pub_repos = seaserv.list_inner_pub_repos(username) try: if org_id: seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo( org_id, repo_id) else: seafile_api.remove_inner_pub_repo(repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) permission = '' for repo in pub_repos: if repo.repo_id == repo_id: permission = repo.permission break if permission: send_perm_audit_msg('delete-repo-perm', username, 'all', repo_id, '/', permission) return Response({'success': True})
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 [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ]: 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)
def delete(self, request, repo, path, share_type): """ Delete user/group share permission. Permission checking: 1. admin user. """ # current `request.user.username` is admin user, # so need to identify the repo owner specifically. repo_owner = seafile_api.get_repo_owner(repo.repo_id) username = request.user.username share_to = request.data.get('share_to', None) if share_type == 'user': email = share_to if not email or not is_valid_username(email): error_msg = 'email %s invalid.' % email return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not has_shared_to_user(repo.repo_id, path, email): error_msg = 'Shared items not found' return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: permission = check_user_share_out_permission(repo.repo_id, path, email) if path == '/': seafile_api.remove_share(repo.repo_id, repo_owner, email) else: seafile_api.unshare_subdir_for_user( repo.repo_id, path, repo_owner, email) if path == '/': ExtraSharePermission.objects.delete_share_permission(repo.repo_id, email) send_perm_audit_msg('delete-repo-perm', username, email, repo.repo_id, path, permission) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) if share_type == 'group': group_id = share_to try: group_id = int(group_id) except ValueError: error_msg = 'group_id %s invalid' % group_id return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not has_shared_to_group(repo.repo_id, path, group_id): error_msg = 'Shared items not found' return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: permission = check_group_share_out_permission(repo.repo_id, path, group_id) if path == '/': seafile_api.unset_group_repo(repo.repo_id, group_id, repo_owner) else: seafile_api.unshare_subdir_for_group( repo.repo_id, path, repo_owner, group_id) if path == '/': ExtraGroupsSharePermission.objects.delete_share_permission(repo.repo_id, group_id) send_perm_audit_msg('delete-repo-perm', username, group_id, repo.repo_id, path, permission) 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 delete(self, request, repo_id, format=None): """ Unshare a repo. Permission checking: 1. Only repo owner and system admin can unshare a publib library. """ # argument check share_type = request.GET.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 ('personal', 'group', 'public'): error_msg = "share_type can only be 'personal' or 'group' or 'public'." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) # permission check username = request.user.username if is_org_context(request): repo_owner = seafile_api.get_org_repo_owner(repo_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) if not request.user.is_staff and not username == repo_owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # delete share org_id = None is_org = False if is_org_context(request): org_id = request.user.org.org_id is_org = True if share_type == 'personal': user = request.GET.get('user', None) if not user or not is_valid_username(user): error_msg = 'user invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = check_user_share_out_permission(repo_id, '/', user, is_org) try: if org_id: seafile_api.org_remove_share(org_id, repo_id, username, user) else: seafile_api.remove_share(repo_id, username, user) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) send_perm_audit_msg('delete-repo-perm', username, user, repo_id, '/', permission) if share_type == 'group': group_id = request.GET.get('group_id', None) if not group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: group_id = int(group_id) except ValueError: error_msg = 'group_id must be integer.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) permission = check_group_share_out_permission(repo_id, '/', group_id, is_org) try: if is_org: seaserv.del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, '/', permission) if share_type == 'public': pub_repos = [] if org_id: pub_repos = seaserv.list_org_inner_pub_repos(org_id, username) if not request.cloud_mode: pub_repos = seaserv.list_inner_pub_repos(username) try: if org_id: seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id, repo_id) else: seafile_api.remove_inner_pub_repo(repo_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) permission = '' for repo in pub_repos: if repo.repo_id == repo_id: permission = repo.permission break if permission: send_perm_audit_msg('delete-repo-perm', username, 'all', repo_id, '/', permission) return Response({'success': True})
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)