def is_repo_admin(username, repo_id): repo_owner = seafile_api.get_repo_owner(repo_id) try: if '@seafile_group' in repo_owner: # is group owned repo group_id = int(repo_owner.split('@')[0]) if is_group_admin(group_id, username): return True else: user_share_permission = ExtraSharePermission.objects.\ get_user_permission(repo_id, username) if user_share_permission == PERMISSION_ADMIN: return True # get all groups that repo is shared to with admin permission group_ids = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo(repo_id) for group_id in group_ids: if is_group_admin(group_id, username): return True return False except Exception as e: logger.error(e) return False
def test_can_clean_department_repo_trash(self): if not LOCAL_PRO_DEV_ENV: return # create a department group_id = ccnet_api.create_group('department_test', 'system admin', parent_group_id=-1) seafile_api.set_group_quota(group_id, -2) repo_id = seafile_api.add_group_owned_repo(group_id, 'dep_test', 'rw') repo_owner = seafile_api.get_repo_owner(repo_id) assert '@seafile_group' in repo_owner group_repos = seafile_api.get_repos_by_group(group_id) assert len(group_repos) == 1 group = ccnet_api.get_group(group_id) # department add user ccnet_api.group_add_member(group_id, group.creator_name, self.user_name) ccnet_api.group_add_member(group_id, group.creator_name, self.tmp_user.username) ccnet_api.group_set_admin(group_id, self.user_name) ccnet_api.group_unset_admin(group_id, self.tmp_user.username) assert is_group_admin(group_id, self.user_name) assert not is_group_admin(group_id, self.tmp_user.username) file_name = 'dep_test.txt' self.create_file(repo_id=repo_id, parent_dir='/', filename=file_name, username=self.user_name) # delete a file first seafile_api.del_file(repo_id, '/', file_name, self.user_name) # get trash item count self.login_as(self.user) resp = self.client.get(reverse('api-v2.1-repo-trash', args=[repo_id])) json_resp = json.loads(resp.content) assert len(json_resp['data']) > 0 # department member can not clean trash self.logout() self.login_as(self.tmp_user) resp = self.client.delete(self.url) self.assertEqual(403, resp.status_code) # department admin can clean library trash self.logout() self.login_as(self.user) ccnet_api.group_set_admin(group_id, self.user_name) resp = self.client.delete(self.url) self.assertEqual(200, resp.status_code) # get trash item count again resp = self.client.get(self.url) json_resp = json.loads(resp.content) assert len(json_resp['data']) == 0
def delete(self, request, repo_id, org_id, format=None): """ Delete repo user share permission. Permission checking: 1. is group admin """ # parameter check to_user = request.data.get('username', None) if not to_user: error_msg = 'username invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) username = request.user.username 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_user_by_repo_path( repo_id, repo_owner, to_user, path, org_id=org_id) permission = check_user_share_out_permission(repo_id, path, to_user, is_org_context(request)) send_perm_audit_msg('delete-repo-perm', username, to_user, repo_id, path, permission) return Response({'success': True})
def get(self, request, repo_id): """ List repo user share info. Permission checking: 1. is group admin """ # 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = request.GET.get('path', '/') if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = self.list_user_shared_items(request, repo_id, path) return Response(result)
def delete(self, request, group_id, repo_id, org_id): """ Delete a group owned library. Permission checking: 1. is group admin; """ 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) group_id = int(group_id) username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: SeafileAPI.delete_group_owned_repo(group_id, repo_id, org_id) 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 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 put(self, request, repo_id, org_id, format=None): """ Update 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 = request.data.get('permission', PERMISSION_READ) if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not ccnet_api.get_group(to_group_id): error_msg = 'Group %s not found.' % to_group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = request.data.get('path', '/') if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) update_group_dir_permission( repo_id, path, repo_owner, to_group_id, permission, org_id) send_perm_audit_msg('modify-repo-perm', username, to_group_id, repo_id, path, permission) return Response({'success': True})
def test_can_set_department_repo(self): if not LOCAL_PRO_DEV_ENV: return # create a department group_id = ccnet_api.create_group('department_test', 'system admin', parent_group_id=-1) seafile_api.set_group_quota(group_id, -2) repo_id = seafile_api.add_group_owned_repo(group_id, 'dep_test', 'rw') repo_owner = seafile_api.get_repo_owner(repo_id) assert '@seafile_group' in repo_owner group_repos = seafile_api.get_repos_by_group(group_id) assert len(group_repos) == 1 group = ccnet_api.get_group(group_id) # department add user ccnet_api.group_add_member(group_id, group.creator_name, self.user.username) ccnet_api.group_add_member(group_id, group.creator_name, self.tmp_user.username) ccnet_api.group_set_admin(group_id, self.user.username) ccnet_api.group_unset_admin(group_id, self.tmp_user.username) assert is_group_admin(group_id, self.user.username) assert not is_group_admin(group_id, self.tmp_user.username) url = reverse("api2-repo-history-limit", args=[repo_id]) self.config.ENABLE_REPO_HISTORY_SETTING = True # department member can not set self.logout() self.login_as(self.tmp_user) data = 'keep_days=%s' % 6 resp = self.client.put(url, data, 'application/x-www-form-urlencoded') self.assertEqual(403, resp.status_code) # department admin can set self.logout() self.login_as(self.user) data = 'keep_days=%s' % 6 resp = self.client.put(url, data, 'application/x-www-form-urlencoded') self.assertEqual(200, resp.status_code) self.remove_group(group_id) self.remove_repo(repo_id)
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 delete(self, request, repo_id, format=None): """ Clean library's trash. Permission checking: 1. repo owner can perform this action. 2. is group admin. """ # argument check try: keep_days = int(request.data.get('keep_days', 0)) except ValueError: error_msg = 'keep_days 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) # permission check username = request.user.username repo_owner = get_repo_owner(request, repo_id) if not config.ENABLE_USER_CLEAN_TRASH: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if '@seafile_group' in repo_owner: 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) else: if username != repo_owner: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.clean_up_repo_history(repo_id, keep_days) org_id = None if not request.user.org else request.user.org.org_id clean_up_repo_trash.send(sender=None, org_id=org_id, operator=username, repo_id=repo_id, repo_name=repo.name, repo_owner=repo_owner, days=keep_days) 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, group_id, repo_id): """ Delete a group library. Permission checking: 1. is group admin; 1. is repo owner; 1. repo is shared to group with `admin` permission; """ group_id = int(group_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) is_org = False if is_org_context(request): is_org = True group_repo = seafile_api.get_group_shared_repo_by_path( repo_id, None, group_id, is_org) if not group_repo: error_msg = 'Group library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # only group admin or repo owner can delete group repo. username = request.user.username repo_owner = get_repo_owner(request, repo_id) if not is_group_admin(group_id, username) and \ repo_owner != username and \ not is_repo_admin(username, repo_id): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permission = check_group_share_in_permission(repo_id, group_id, is_org) if is_org: org_id = ccnet_api.get_org_id_by_group(group_id) seafile_api.del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, username) origin_repo_id = group_repo.origin_repo_id or repo_id origin_path = group_repo.origin_path or '/' send_perm_audit_msg('delete-repo-perm', username, group_id, origin_repo_id, origin_path, permission) # delete extra share permission ExtraGroupsSharePermission.objects.delete_share_permission( repo_id, group_id) return Response({'success': True})
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 delete(self, request, group_id, repo_id): """ Delete a group library. Permission checking: 1. is repo owner; 2. is repo admin; 3. is group admin; """ group_id = int(group_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) is_org = False if is_org_context(request): is_org = True group_repo = seafile_api.get_group_shared_repo_by_path(repo_id, None, group_id, is_org) if not group_repo: error_msg = 'Group library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # only group admin or repo owner can delete group repo. username = request.user.username repo_owner = get_repo_owner(request, repo_id) if not is_group_admin(group_id, username) and \ repo_owner != username and \ not is_repo_admin(username, repo_id): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permission = check_group_share_in_permission(repo_id, group_id, is_org) if is_org: org_id = ccnet_api.get_org_id_by_group(group_id) seafile_api.del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, username) origin_repo_id = group_repo.origin_repo_id or repo_id origin_path = group_repo.origin_path or '/' send_perm_audit_msg('delete-repo-perm', username, group_id, origin_repo_id, origin_path, permission) # delete extra share permission ExtraGroupsSharePermission.objects.delete_share_permission(repo_id, group_id) return Response({'success': True})
def delete(self, request, repo_id): """ Delete repo user folder perm. Permission checking: 1. is group admin """ # argument check user = request.data.get('user_email', None) if not user: error_msg = 'user_email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = request.data.get('folder_path', None) if not path: error_msg = 'folder_path 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # delete permission path = normalize_dir_path(path) permission = seafile_api.get_folder_user_perm(repo_id, path, user) if not permission: return Response({'success': True}) try: seafile_api.rm_folder_user_perm(repo_id, path, user) send_perm_audit_msg('delete-repo-perm', username, user, repo_id, path, permission) 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)
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 is_repo_admin(username, repo_id): # repo is shared to user with admin permission try: user_share_permission = ExtraSharePermission.objects. \ get_user_permission(repo_id, username) if user_share_permission == PERMISSION_ADMIN: return True # get all groups that repo is shared to with admin permission group_ids = ExtraGroupsSharePermission.objects.get_admin_groups_by_repo( repo_id) for group_id in group_ids: if is_group_admin(group_id, username): return True except Exception as e: logger.error(e) return False repo_owner = seafile_api.get_repo_owner( repo_id) or seafile_api.get_org_repo_owner(repo_id) if not repo_owner: logger.error('repo %s owner is None' % repo_id) return False # repo owner if username == repo_owner: return True # user is department admin if '@seafile_group' in repo_owner: # is group owned repo group_id = int(repo_owner.split('@')[0]) if is_group_admin(group_id, username): return True return False
def repo_snapshot(request, repo_id): """View repo in history. """ repo = get_repo(repo_id) if not repo: raise Http404 username = request.user.username user_perm = check_folder_permission(request, repo.id, '/') if user_perm is None: return render_error(request, _('Permission denied')) try: server_crypto = UserOptions.objects.is_server_crypto(username) except CryptoOptionNotSetError: # Assume server_crypto is ``False`` if this option is not set. server_crypto = False reverse_url = reverse('lib_view', args=[repo_id, repo.name, '']) if repo.encrypted and \ (repo.enc_version == 1 or (repo.enc_version == 2 and server_crypto)) \ and not is_password_set(repo.id, username): return render( request, 'decrypt_repo_form.html', { 'repo': repo, 'next': get_next_url_from_request(request) or reverse_url, }) commit_id = request.GET.get('commit_id', None) if commit_id is None: return HttpResponseRedirect(reverse_url) current_commit = get_commit(repo.id, repo.version, commit_id) if not current_commit: current_commit = get_commit(repo.id, repo.version, repo.head_cmmt_id) has_perm = is_repo_owner(request, repo.id, username) # department admin if not has_perm: repo_owner = seafile_api.get_repo_owner(repo_id) if '@seafile_group' in repo_owner: group_id = get_group_id_by_repo_owner(repo_owner) has_perm = is_group_admin(group_id, username) return render( request, 'repo_snapshot_react.html', { 'repo': repo, "can_restore_repo": has_perm, 'current_commit': current_commit, })
def post(self, request, repo_id, commit_id, format=None): """ revert commit in repo history Permission checking: 1. only repo owner can perform this action. """ username = request.user.username # 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) commit = seafile_api.get_commit(repo.id, repo.version, commit_id) if not commit: error_msg = 'Commit %s not found.' % commit_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check has_perm = is_repo_owner(request, repo.id, username) if not has_perm: repo_owner = get_repo_owner(request, repo_id) # department admin if '@seafile_group' in repo_owner: group_id = get_group_id_by_repo_owner(repo_owner) has_perm = is_group_admin(group_id, username) if not has_perm: error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # main if repo.encrypted: ret = seafile_api.is_password_set(repo_id, username) is_decrypted = False if ret == 0 else True if not is_decrypted: error_msg = _('This library has not been decrypted.') return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.revert_repo(repo_id, commit_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) return Response({'success': True})
def get(self, request, repo_id, format=None): """ List repo group folder perms (by folder_path). Permission checking: 1. is group admin """ # 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) results = [] path = request.GET.get('folder_path', None) group_folder_perms = seafile_api.list_folder_group_perm_by_repo(repo_id) for perm in group_folder_perms: result = {} if path: if path == perm.path: result = self._get_group_folder_perm_info( perm.group_id, perm.repo_id, perm.path, perm.permission) else: result = self._get_group_folder_perm_info( perm.group_id, perm.repo_id, perm.path, perm.permission) if result: results.append(result) return Response(results)
def put(self, request, group_id, repo_id): """ Set sub repo folder permission. Permission checking: 1. is group admin; """ path = request.data.get('path', None) if not path: error_msg = 'path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) perm = request.data.get('permission', None) if not perm or perm not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) path = normalize_dir_path(path) if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check group_id = int(group_id) username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: seafile_api.add_folder_group_perm(repo_id, path, perm, group_id) 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 put(self, request, group_id, repo_id): """ Rename a library. Permission checking: 1. is group admin; """ # argument check new_repo_name = request.data.get('name', '') if not new_repo_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_repo_name): error_msg = 'name 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) # permission check group_id = int(group_id) username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # rename repo try: repo_owner = get_repo_owner(request, repo_id) # desc is '' seafile_api.edit_repo(repo_id, new_repo_name, '', repo_owner) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_info = get_group_owned_repo_info(request, repo_id) return Response(repo_info)
def get(self, request, group_id): """ List sub groups of a group in address book. """ if not is_group_admin(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) try: groups = ccnet_api.get_descendants_groups(group_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return_results = [] for group in groups: return_results.append(address_book_group_to_dict(group)) return Response(return_results)
def put(self, request, group_id, repo_id): """ Rename a library. Permission checking: 1. is group admin; """ # argument check new_repo_name = request.data.get('name', '') if not new_repo_name: error_msg = 'name invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not is_valid_dirent_name(new_repo_name): error_msg = 'name 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) # permission check group_id = int(group_id) username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # rename repo try: # desc is '' seafile_api.edit_repo(repo_id, new_repo_name, '', username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) repo_info = get_group_owned_repo_info(request, repo_id) return Response(repo_info)
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 post(self, request, repo_id, org_id, format=None): """ Share repo to group. Permission checking: 1. is group admin """ # parameter check permission = request.data.get('permission', PERMISSION_READ) if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = request.data.get('path', '/') if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] 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 self.has_shared_to_group(request, repo_id, path, gid): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'This item has been shared to %s.') % group.group_name }) continue share_dir_to_group(repo, path, repo_owner, username, gid, permission, org_id) result['success'].append({ "group_id": gid, "group_name": group.group_name, "permission": permission, }) 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) return Response(result)
def get(self, request, group_id): """ List members of a group (and in its sub groups) in address book. """ try: avatar_size = int(request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE # argument check q = request.GET.get('q', None) if not q: return api_error(status.HTTP_400_BAD_REQUEST, 'q invalid.') # permission check if not is_group_admin(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # search user from the whole Seafile system email_list = [] email_list += search_user_from_ccnet(q) email_list += search_user_from_profile(q) # remove duplicate emails email_list = {}.fromkeys(email_list).keys() try: # get all members in current group and its sub groups all_members = ccnet_api.get_members_with_prefix(group_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_email_list = [m.user_name for m in all_members] # remove duplicate emails group_email_list = {}.fromkeys(group_email_list).keys() email_result = [] for email in group_email_list: # if email searched from the whole Seafile system # is NOT group member, filter it out. if email not in email_list: continue try: # remove nonexistent or inactive user user = User.objects.get(email=email) if not user.is_active: continue except User.DoesNotExist: continue email_result.append(email) # format the email results result = format_searched_user_result(request, email_result, avatar_size) return Response(result)
def put(self, request, repo_id, format=None): """ Modify repo user folder perm. Permission checking: 1. is group admin """ # argument check user = request.data.get('user_email', None) if not user: error_msg = 'user_email invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) path = request.data.get('folder_path', None) if not path: error_msg = 'folder_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) perm = request.data.get('permission', None) if not perm or perm not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) path = normalize_dir_path(path) if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: User.objects.get(email=user) except User.DoesNotExist: error_msg = 'User %s not found.' % user return api_error(status.HTTP_404_NOT_FOUND, error_msg) permission = seafile_api.get_folder_user_perm(repo_id, path, user) if not permission: error_msg = 'Folder permission not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # modify permission try: seafile_api.set_folder_user_perm(repo_id, path, perm, user) send_perm_audit_msg('modify-repo-perm', username, user, repo_id, path, perm) new_perm = seafile_api.get_folder_user_perm(repo_id, path, user) result = self._get_user_folder_perm_info(user, repo_id, path, new_perm) return Response(result) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
def post(self, request, repo_id, format=None): """ Add repo group folder perm. Permission checking: 1. is group admin """ # argument check path = request.data.get('folder_path', None) if not path: error_msg = 'folder_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) perm = request.data.get('permission', None) if not perm or perm not in get_available_repo_perms(): error_msg = 'permission 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) path = normalize_dir_path(path) if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) result = {} result['failed'] = [] result['success'] = [] group_ids = request.data.getlist('group_id') for group_id in group_ids: try: group_id = int(group_id) except ValueError: result['failed'].append({ 'group_id': group_id, 'error_msg': 'group_id invalid.' }) continue if not ccnet_api.get_group(group_id): result['failed'].append({ 'group_id': group_id, 'error_msg': 'Group %s not found.' % group_id }) continue permission = seafile_api.get_folder_group_perm(repo_id, path, group_id) if permission: result['failed'].append({ 'group_id': group_id, 'error_msg': _(u'Permission already exists.') }) continue try: seafile_api.add_folder_group_perm(repo_id, path, perm, group_id) send_perm_audit_msg('add-repo-perm', username, group_id, repo_id, path, perm) except Exception as e: logger.error(e) result['failed'].append({ 'group_id': group_id, 'error_msg': 'Internal Server Error' }) new_perm = seafile_api.get_folder_group_perm(repo_id, path, group_id) new_perm_info = self._get_group_folder_perm_info( group_id, repo_id, path, new_perm) result['success'].append(new_perm_info) return Response(result)
def get(self, request, group_id): """ List members of a group (and in its sub groups) in address book. """ try: avatar_size = int( request.GET.get('avatar_size', AVATAR_DEFAULT_SIZE)) except ValueError: avatar_size = AVATAR_DEFAULT_SIZE # argument check q = request.GET.get('q', None) if not q: return api_error(status.HTTP_400_BAD_REQUEST, 'q invalid.') # permission check if not is_group_admin(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # search user from the whole Seafile system email_list = [] email_list += search_user_from_ccnet(q) email_list += search_user_from_profile(q) # remove duplicate emails email_list = list({}.fromkeys(email_list).keys()) try: # get all members in current group and its sub groups all_members = ccnet_api.get_members_with_prefix(group_id) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) group_email_list = [m.user_name for m in all_members] # remove duplicate emails group_email_list = list({}.fromkeys(group_email_list).keys()) email_result = [] for email in group_email_list: # if email searched from the whole Seafile system # is NOT group member, filter it out. if email not in email_list: continue try: # remove nonexistent or inactive user user = User.objects.get(email=email) if not user.is_active: continue except User.DoesNotExist: continue email_result.append(email) # format the email results result = format_searched_user_result(request, email_result, avatar_size) 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(): permission = normalize_custom_permission_name(permission) if not permission: 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 # is sharing repo to department if group.parent_group_id != 0: if not ENABLE_SHARE_TO_DEPARTMENT or \ ENABLE_SHARE_TO_DEPARTMENT and not is_group_admin(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 post(self, request, repo_id, org_id): """ Share repo to users. Permission checking: 1. is group admin """ # parameter check permission = request.data.get('permission', PERMISSION_READ) if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) path = request.data.get('path', '/') if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # share repo to user result = {} result['failed'] = [] result['success'] = [] share_to_users = request.data.getlist('username') for to_user in share_to_users: to_user = to_user.strip() if not is_valid_username(to_user): result['failed'].append({ 'email': to_user, 'error_msg': _(u'username invalid.') }) continue try: User.objects.get(email=to_user) except User.DoesNotExist: result['failed'].append({ 'email': to_user, 'error_msg': _(u'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': _(u'This item has been shared to %s.') % to_user }) continue if is_valid_org_id(org_id): if not is_org_user(to_user, 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 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 share_dir_to_user(repo, path, repo_owner, username, to_user, permission, org_id) result['success'].append({ "user_email": to_user, "user_name": email2nickname(to_user), "user_contact_email": email2contact_email(to_user), "permission": permission, }) # 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) return Response(result)
def delete(self, request, repo_id, format=None): """ Delete repo group folder perm. Permission checking: 1. is group admin """ # arguments check group_id = request.data.get('group_id', None) path = request.data.get('folder_path', None) if not group_id: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) if not path: error_msg = 'folder_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: group_id = int(group_id) except ValueError: error_msg = 'group_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # resource check if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) 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) repo_owner = get_repo_owner(request, repo_id) library_group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(library_group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(library_group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # delete permission path = path.rstrip('/') if path != '/' else path permission = seafile_api.get_folder_group_perm(repo_id, path, group_id) if not permission: return Response({'success': True}) try: seafile_api.rm_folder_group_perm(repo_id, path, group_id) send_perm_audit_msg('delete-repo-perm', username, group_id, repo_id, path, permission) 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)
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 post(self, request, group_id, org_id): """ Add a group owned library. Permission checking: 1. role permission, can_add_repo; 1. is group admin; """ # argument check repo_name = request.data.get("name", None) if not repo_name or \ not is_valid_dirent_name(repo_name): error_msg = "name invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("passwd", 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_WRITE) if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: 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_admin(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) group_quota = seafile_api.get_group_quota(group_id) group_quota = int(group_quota) if group_quota <= 0 and group_quota != -2: error_msg = 'No group quota.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create group owned repo group_id = int(group_id) if is_pro_version() and ENABLE_STORAGE_CLASSES: if STORAGE_CLASS_MAPPING_POLICY in ('USER_SELECT', 'ROLE_BASED'): storages = get_library_storages(request) storage_id = request.data.get("storage_id", None) if storage_id and storage_id not in [s['storage_id'] for s in storages]: error_msg = 'storage_id invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) repo_id = seafile_api.add_group_owned_repo(group_id, repo_name, password, permission, storage_id) else: # STORAGE_CLASS_MAPPING_POLICY == 'REPO_ID_MAPPING' repo_id = SeafileAPI.add_group_owned_repo( group_id, repo_name, password, permission, org_id=org_id) else: repo_id = SeafileAPI.add_group_owned_repo( group_id, repo_name, password, permission, org_id=org_id) # for activities username = request.user.username 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 repo = seafile_api.get_repo(repo_id) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path='/', org_id=org_id) info = get_group_owned_repo_info(request, repo_id) # TODO info['permission'] = permission return Response(info)
def put(self, request, repo_id, format=None): """ Modify repo group folder perm. Permission checking: 1. is group admin """ # argument check path = request.data.get('folder_path', None) if not path: error_msg = 'folder_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) perm = request.data.get('permission', None) if not perm or perm not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) group_id = request.data.get('group_id') 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 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) path = normalize_dir_path(path) if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = get_repo_owner(request, repo_id) library_group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(library_group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) permission = seafile_api.get_folder_group_perm(repo_id, path, group_id) if not permission: error_msg = 'Folder permission not found.' return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(library_group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # modify permission try: seafile_api.set_folder_group_perm(repo_id, path, perm, group_id) send_perm_audit_msg('modify-repo-perm', username, group_id, repo_id, path, perm) new_perm = seafile_api.get_folder_group_perm(repo_id, path, group_id) result = self._get_group_folder_perm_info(group_id, repo_id, path, new_perm) return Response(result) except Exception 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 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 post(self, request, repo_id, format=None): """ Add repo user folder perm. Permission checking: 1. is group admin """ # argument check path = request.data.get('folder_path', None) if not path: error_msg = 'folder_path invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) perm = request.data.get('permission', None) if not perm or perm not in [PERMISSION_READ, PERMISSION_READ_WRITE]: error_msg = 'permission 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) path = normalize_dir_path(path) if not seafile_api.get_dir_id_by_path(repo_id, path): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) repo_owner = get_repo_owner(request, repo_id) group_id = get_group_id_by_repo_owner(repo_owner) if not ccnet_api.get_group(group_id): error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) # permission check username = request.user.username if not is_group_admin(group_id, username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # add repo user folder perm result = {} result['failed'] = [] result['success'] = [] users = request.data.getlist('user_email') for user in users: if not is_valid_username(user): result['failed'].append({ 'user_email': user, 'error_msg': 'user_email invalid.' }) continue try: User.objects.get(email=user) except User.DoesNotExist: result['failed'].append({ 'user_email': user, 'error_msg': 'User %s not found.' % user }) continue permission = seafile_api.get_folder_user_perm(repo_id, path, user) if permission: result['failed'].append({ 'user_email': user, 'error_msg': _(u'Permission already exists.') }) continue try: seafile_api.add_folder_user_perm(repo_id, path, perm, user) send_perm_audit_msg('add-repo-perm', username, user, repo_id, path, perm) except Exception as e: logger.error(e) result['failed'].append({ 'user_email': user, 'error_msg': 'Internal Server Error' }) new_perm = seafile_api.get_folder_user_perm(repo_id, path, user) new_perm_info = self._get_user_folder_perm_info( user, repo_id, path, new_perm) result['success'].append(new_perm_info) return Response(result)