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 delete(self, request, repo_id, org_id, format=None): """ User delete a repo shared to him/her. """ repo = seafile_api.get_repo(repo_id) if not repo: error_msg = 'Library %s not found.' % repo_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) if not check_folder_permission(request, repo_id, '/'): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) username = request.user.username repo_owner = get_repo_owner(request, repo_id) try: if org_id: is_org = True seafile_api.org_remove_share(org_id, repo_id, repo_owner, username) else: is_org = False seafile_api.remove_share(repo_id, repo_owner, username) except Exception as e: logger.error(e) error_msg = 'Internal Server Error' return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) permission = check_user_share_in_permission(repo_id, username, is_org) send_perm_audit_msg('delete-repo-perm', repo_owner, username, repo_id, '/', permission) return Response({'success': True})
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 unsetinnerpub(request, repo_id): """Unshare repos in organization or in share admin page. Only system admin, organization admin or repo owner can perform this op. """ repo = get_repo(repo_id) perm = request.GET.get('permission', None) if perm is None: return render_error(request, _(u'Argument is not valid')) if not repo: messages.error( request, _('Failed to unshare the library, as it does not exist.')) return HttpResponseRedirect(reverse('share_admin')) # permission check username = request.user.username if is_org_context(request): org_id = request.user.org.org_id repo_owner = seafile_api.get_org_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.org.is_staff or is_repo_owner): raise Http404 else: repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.is_staff or is_repo_owner): raise Http404 try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo( org_id, repo.id) else: seaserv.unset_inner_pub_repo(repo.id) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' send_perm_audit_msg('delete-repo-perm', username, 'all', perm_repo_id, perm_path, perm) messages.success(request, _('Unshare "%s" successfully.') % repo.name) except SearpcError: messages.error(request, _('Failed to unshare "%s".') % repo.name) referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer return HttpResponseRedirect(next)
def unsetinnerpub(request, repo_id): """Unshare repos in organization or in share admin page. Only system admin, organization admin or repo owner can perform this op. """ repo = get_repo(repo_id) perm = request.GET.get('permission', None) if perm is None: return render_error(request, _(u'Argument is not valid')) if not repo: messages.error(request, _('Failed to unshare the library, as it does not exist.')) return HttpResponseRedirect(reverse('share_admin')) # permission check username = request.user.username if is_org_context(request): org_id = request.user.org.org_id repo_owner = seafile_api.get_org_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.org.is_staff or is_repo_owner): raise Http404 else: repo_owner = seafile_api.get_repo_owner(repo.id) is_repo_owner = True if repo_owner == username else False if not (request.user.is_staff or is_repo_owner): raise Http404 try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.unset_org_inner_pub_repo(org_id, repo.id) else: seaserv.unset_inner_pub_repo(repo.id) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' send_perm_audit_msg('delete-repo-perm', username, 'all', perm_repo_id, perm_path, perm) messages.success(request, _('Unshare "%s" successfully.') % repo.name) except SearpcError: messages.error(request, _('Failed to unshare "%s".') % repo.name) referer = request.META.get('HTTP_REFERER', None) next = settings.SITE_ROOT if referer is None else referer return HttpResponseRedirect(next)
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, 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 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): # 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 post(self, request, group_id): """ Add a group library. Permission checking: 1. role permission, can_add_repo; 1. is group member; """ # argument check repo_name = request.data.get("repo_name", None) if not repo_name or \ not is_valid_dirent_name(repo_name): error_msg = "repo_name invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("password", None) if password and not config.ENABLE_ENCRYPTED_LIBRARY: error_msg = 'NOT allow to create encrypted library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if not request.user.permissions.can_add_repo(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create group repo org_id = -1 group_id = int(group_id) username = request.user.username is_org = False if is_org_context(request): is_org = True org_id = request.user.org.org_id repo_id = seafile_api.create_org_repo(repo_name, '', username, password, org_id) else: repo_id = seafile_api.create_repo(repo_name, '', username, password) repo = seafile_api.get_repo(repo_id) share_dir_to_group(repo, '/', username, username, group_id, permission, org_id if is_org else None) # for activities library_template = request.data.get("library_template", '') repo_created.send(sender=None, org_id=org_id, creator=username, repo_id=repo_id, repo_name=repo_name, library_template=library_template) # for notification share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path='/', org_id=org_id) # for perm audit send_perm_audit_msg('add-repo-perm', username, group_id, repo_id, '/', permission) group_repo = seafile_api.get_group_shared_repo_by_path( repo_id, None, group_id, is_org) group_repo_info = get_group_repo_info(request, group_repo) group_repo_info['owner_email'] = username group_repo_info['owner_name'] = email2nickname(username) group_repo_info['owner_contact_email'] = email2contact_email(username) modifier = group_repo.last_modifier group_repo_info['modifier_email'] = modifier group_repo_info['modifier_name'] = email2nickname(modifier) group_repo_info['modifier_contact_email'] = email2contact_email( modifier) return Response(group_repo_info)
def put(self, request, repo_id, format=None): """ Update permission of a shared repo. Permission checking: 1. Only repo owner can update. """ # argument check permission = request.data.get('permission', None) if permission not in ['r', 'rw']: error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 ('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) # recourse 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 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) # update share permission if share_type == 'personal': shared_to = request.data.get('user', None) if not shared_to or not is_valid_username(shared_to): error_msg = 'user invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_set_share_permission( org_id, repo_id, username, shared_to, permission) else: seafile_api.set_share_permission(repo_id, username, shared_to, permission) 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('modify-repo-perm', username, shared_to, repo_id, '/', permission) if share_type == 'group': group_id = request.data.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) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, group_id, repo_id, permission) else: seafile_api.set_group_repo_permission( group_id, repo_id, permission) 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('modify-repo-perm', username, group_id, repo_id, '/', permission) if share_type == 'public': try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( org_id, repo_id, permission) else: seafile_api.add_inner_pub_repo(repo_id, permission) 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('modify-repo-perm', username, 'all', repo_id, '/', 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 post(self, request, repo, path, share_type): """ Admin share a library to user/group. Permission checking: 1. admin user. """ # argument check permission = request.data.get('permission', None) if not permission or permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] share_to = request.data.getlist('share_to') # 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 if share_type == 'user': for email in share_to: if repo_owner == email: result['failed'].append({ 'user_email': email, 'error_msg': _(u'User %s is already library owner.') % email }) continue if not is_valid_username(email): result['failed'].append({ 'user_email': email, 'error_msg': _('Email %s invalid.') % email }) continue try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'user_email': email, 'error_msg': 'User %s not found.' % email }) continue if has_shared_to_user(repo.repo_id, path, email): result['failed'].append({ 'email': email, 'error_msg': _(u'This item has been shared to %s.') % email }) continue try: share_dir_to_user(repo, path, repo_owner, username, email, permission) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=email, repo=repo, path=path, org_id=None) send_perm_audit_msg('add-repo-perm', username, email, repo.repo_id, path, permission) except Exception as e: logger.error(e) result['failed'].append({ 'user_email': email, 'error_msg': 'Internal Server Error' }) continue result['success'].append({ "repo_id": repo.repo_id, "path": path, "share_type": share_type, "user_email": email, "user_name": email2nickname(email), "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) if share_type == 'group': for group_id in share_to: try: group_id = int(group_id) except ValueError as e: logger.error(e) result['failed'].append({ 'group_id': group_id, 'error_msg': 'group_id %s invalid.' % group_id }) continue group = ccnet_api.get_group(group_id) if not group: result['failed'].append({ 'group_id': group_id, 'error_msg': 'Group %s not found' % group_id }) continue if has_shared_to_group(repo.repo_id, path, group_id): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'This item has been shared to %s.') % group.group_name }) continue try: share_dir_to_group(repo, path, repo_owner, username, group_id, permission) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path=path, org_id=None) send_perm_audit_msg('add-repo-perm', username, group_id, repo.repo_id, path, permission) except Exception as e: logger.error(e) result['failed'].append({ "group_id": group_id, 'error_msg': 'Internal Server Error' }) continue result['success'].append({ "repo_id": repo.repo_id, "path": path, "share_type": share_type, "group_id": group_id, "group_name": group.group_name, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) return Response(result)
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) # check permission 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) if username != self.get_repo_owner(request, repo_id) and \ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') else: if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if shared_to_user: # if user not found, permission will be None permission = seafile_api.check_permission_by_path( repo_id, '/', shared_to) if is_org_context(request): username = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id if path == '/': seaserv.seafserv_threaded_rpc.org_remove_share( org_id, repo_id, username, shared_to) else: seafile_api.org_unshare_subdir_for_user( org_id, repo_id, path, username, shared_to) else: username = seafile_api.get_repo_owner(repo_id) if path == '/': seaserv.remove_share(repo_id, username, shared_to) else: seafile_api.unshare_subdir_for_user( repo_id, path, username, 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 permission = '' if is_org_context(request): org_id = request.user.org.org_id shared_groups = seafile_api.list_org_repo_shared_group( org_id, username, repo_id) else: shared_groups = seafile_api.list_repo_shared_group( username, repo_id) for e in shared_groups: if e.group_id == group_id: permission = e.perm break if is_org_context(request): 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, username, 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, username, 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 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 username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, "Permission denied.") 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.") permission = request.data.get("permission", "r") if permission not in ["r", "rw"]: 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 try: if is_org_context(request): org_id = request.user.org.org_id if path == "/": seaserv.seafserv_threaded_rpc.org_add_share(org_id, repo_id, username, to_user, permission) else: seafile_api.org_share_subdir_to_user(org_id, repo_id, path, username, to_user, permission) else: if path == "/": seafile_api.share_repo(repo_id, username, to_user, permission) else: seafile_api.share_subdir_to_user(repo_id, path, username, to_user, 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) result["success"].append( { "share_type": "user", "user_info": {"name": to_user, "nickname": email2nickname(to_user)}, "permission": permission, } ) 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: return api_error(status.HTTP_400_BAD_REQUEST, "group_id %s invalid." % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, "Group %s not found" % gid) try: if is_org_context(request): org_id = request.user.org.org_id if path == "/": seafile_api.add_org_group_repo(repo_id, org_id, gid, username, permission) else: seafile_api.org_share_subdir_to_group(org_id, repo_id, path, username, gid, permission) else: if path == "/": seafile_api.set_group_repo(repo_id, gid, username, permission) else: seafile_api.share_subdir_to_group(repo_id, path, username, gid, permission) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo) result["success"].append( { "share_type": "group", "group_info": {"id": gid, "name": group.group_name}, "permission": permission, } ) 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 repo_remove_share(request): """ If repo is shared from one person to another person, only these two person can remove share. If repo is shared from one person to a group, then only the one share the repo and group staff can remove share. """ repo_id = request.GET.get('repo_id', '') group_id = request.GET.get('gid', '') from_email = request.GET.get('from', '') perm = request.GET.get('permission', None) if not is_valid_username(from_email) or perm is None: return render_error(request, _(u'Argument is not valid')) username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' # if request params don't have 'gid', then remove repos that share to # to other person; else, remove repos that share to groups if not group_id: to_email = request.GET.get('to', '') if not is_valid_username(to_email): return render_error(request, _(u'Argument is not valid')) if username != from_email and username != to_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_context(request): org_id = request.user.org.org_id org_remove_share(org_id, repo_id, from_email, to_email) else: seaserv.remove_share(repo_id, from_email, to_email) send_perm_audit_msg('delete-repo-perm', from_email, to_email, \ perm_repo_id, perm_path, perm) else: try: group_id = int(group_id) except: return render_error(request, _(u'group id is not valid')) group = seaserv.get_group(group_id) if not group: return render_error(request, _(u"Failed to unshare: the group doesn't exist.")) if not seaserv.check_group_staff(group_id, username) \ and username != from_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_group(group_id): org_id = get_org_id_by_group(group_id) del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, from_email) send_perm_audit_msg('delete-repo-perm', from_email, group_id, \ perm_repo_id, perm_path, perm) messages.success(request, _('Successfully removed share')) next = request.META.get('HTTP_REFERER', SITE_ROOT) return HttpResponseRedirect(next)
def share_permission_admin(request): """Change repo share permission in ShareAdmin. """ share_type = request.GET.get('share_type', '') content_type = 'application/json; charset=utf-8' form = RepoShareForm(request.POST) form.is_valid() email_or_group = form.cleaned_data['email_or_group'] repo_id = form.cleaned_data['repo_id'] permission = form.cleaned_data['permission'] from_email = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' if share_type == 'personal': if not is_valid_username(email_or_group): return HttpResponse(json.dumps({'success': False}), status=400, content_type=content_type) try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_set_share_permission( org_id, repo_id, from_email, email_or_group, permission) else: seafile_api.set_share_permission(repo_id, from_email, email_or_group, permission) send_perm_audit_msg('modify-repo-perm', from_email, \ email_or_group, perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) elif share_type == 'group': try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, int(email_or_group), repo_id, permission) else: group_id = int(email_or_group) seafile_api.set_group_repo_permission(group_id, repo_id, permission) send_perm_audit_msg('modify-repo-perm', from_email, \ group_id, perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) elif share_type == 'public': try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo( org_id, repo_id, permission) else: seafile_api.add_inner_pub_repo(repo_id, permission) send_perm_audit_msg('modify-repo-perm', from_email, 'all', \ perm_repo_id, perm_path, permission) except SearpcError: return HttpResponse(json.dumps({'success': False}), status=500, content_type=content_type) return HttpResponse(json.dumps({'success': True}), content_type=content_type) else: return HttpResponse(json.dumps({'success': False}), status=400, content_type=content_type)
def share_repo(request): """ Handle POST method to share a repo to public/groups/users based on form data. Return to ``myhome`` page and notify user whether success or failure. """ next = request.META.get('HTTP_REFERER', None) if not next: next = SITE_ROOT form = RepoShareForm(request.POST) if not form.is_valid(): # TODO: may display error msg on form raise Http404 email_or_group = form.cleaned_data['email_or_group'] repo_id = form.cleaned_data['repo_id'] permission = form.cleaned_data['permission'] repo = seafile_api.get_repo(repo_id) if not repo: raise Http404 # Test whether user is the repo owner. username = request.user.username if not seafile_api.is_repo_owner(username, repo_id) and \ not is_org_repo_owner(username, repo_id): msg = _(u'Only the owner of the library has permission to share it.') messages.error(request, msg) return HttpResponseRedirect(next) # Parsing input values. share_to_all, share_to_groups, share_to_users = False, [], [] user_groups = request.user.joined_groups share_to_list = string2list(email_or_group) for share_to in share_to_list: if share_to == 'all': share_to_all = True elif share_to.find('@') == -1: for user_group in user_groups: if user_group.group_name == share_to: share_to_groups.append(user_group) else: share_to = share_to.lower() if is_valid_username(share_to): share_to_users.append(share_to) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' if share_to_all: share_to_public(request, repo, permission) send_perm_audit_msg('add-repo-perm', username, 'all', \ perm_repo_id, perm_path, permission) for group in share_to_groups: if share_to_group(request, repo, group, permission): send_perm_audit_msg('add-repo-perm', username, group.id, \ perm_repo_id, perm_path, permission) for email in share_to_users: # Add email to contacts. mail_sended.send(sender=None, user=request.user.username, email=email) if share_to_user(request, repo, email, permission): send_perm_audit_msg('add-repo-perm', username, email, \ perm_repo_id, perm_path, permission) return HttpResponseRedirect(next)
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_400_BAD_REQUEST, 'Repo not found.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_400_BAD_REQUEST, 'Directory not found.') if path == '/': shared_repo = repo else: try: sub_repo = self.get_sub_repo_by_path(request, repo, path) if sub_repo: shared_repo = sub_repo else: return api_error(status.HTTP_400_BAD_REQUEST, 'No sub repo found') except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo') 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, 'Bad argument.') if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_remove_share( org_id, shared_repo.id, username, shared_to) else: seaserv.remove_share(shared_repo.id, username, shared_to) permission = seafile_api.check_permission_by_path(repo.id, path, 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, 'Bad group id') # hacky way to get group repo permission permission = '' for e in seafile_api.list_repo_shared_group(username, shared_repo.id): if e.group_id == group_id: permission = e.perm break if is_org_context(request): org_id = request.user.org.org_id seaserv.del_org_group_repo(shared_repo.id, org_id, group_id) else: seafile_api.unset_group_repo(shared_repo.id, group_id, username) 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 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_400_BAD_REQUEST, 'Repo not found.') path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_400_BAD_REQUEST, 'Directory not found.') if path != '/': try: sub_repo = self.get_or_create_sub_repo_by_path(request, repo, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo') else: sub_repo = None share_type = request.DATA.get('share_type') if share_type != 'user' and share_type != 'group': return api_error(status.HTTP_400_BAD_REQUEST, 'Bad share type') permission = request.DATA.get('permission', 'r') if permission not in ['r', 'rw']: return api_error(status.HTTP_400_BAD_REQUEST, 'Bad permission') shared_repo = repo if path == '/' else sub_repo success, failed = [], [] 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): return api_error(status.HTTP_400_BAD_REQUEST, 'Username must be a valid email address.') if not check_user_share_quota(username, shared_repo, users=[to_user]): return api_error(status.HTTP_403_FORBIDDEN, 'Failed to share: No enough quota.') try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share( org_id, shared_repo.id, username, to_user, permission) else: seafile_api.share_repo(shared_repo.id, username, to_user, permission) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=shared_repo) success.append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(to_user) continue if share_type == 'group': group_ids = request.DATA.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'Bad group id: %s' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_400_BAD_REQUEST, 'Group not found: %s' % gid) if not check_user_share_quota(username, shared_repo, groups=[group]): return api_error(status.HTTP_403_FORBIDDEN, 'Failed to share: No enough quota.') try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo(shared_repo.repo_id, org_id, gid, username, permission) else: seafile_api.set_group_repo(shared_repo.repo_id, gid, username, permission) success.append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(group.group_name) continue return HttpResponse(json.dumps({ "success": success, "failed": failed }), status=200, content_type=json_content_type)
def repo_remove_share(request): """ If repo is shared from one person to another person, only these two person can remove share. If repo is shared from one person to a group, then only the one share the repo and group staff can remove share. """ repo_id = request.GET.get('repo_id', '') group_id = request.GET.get('gid', '') from_email = request.GET.get('from', '') perm = request.GET.get('permission', None) if not is_valid_username(from_email) or perm is None: return render_error(request, _(u'Argument is not valid')) username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return render_error(request, _(u'Library does not exist')) origin_repo_id, origin_path = get_origin_repo_info(repo.id) if origin_repo_id is not None: perm_repo_id = origin_repo_id perm_path = origin_path else: perm_repo_id = repo.id perm_path = '/' # if request params don't have 'gid', then remove repos that share to # to other person; else, remove repos that share to groups if not group_id: to_email = request.GET.get('to', '') if not is_valid_username(to_email): return render_error(request, _(u'Argument is not valid')) if username != from_email and username != to_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_context(request): org_id = request.user.org.org_id org_remove_share(org_id, repo_id, from_email, to_email) else: seaserv.remove_share(repo_id, from_email, to_email) send_perm_audit_msg('delete-repo-perm', from_email, to_email, \ perm_repo_id, perm_path, perm) else: try: group_id = int(group_id) except: return render_error(request, _(u'group id is not valid')) group = seaserv.get_group(group_id) if not group: return render_error( request, _(u"Failed to unshare: the group doesn't exist.")) if not seaserv.check_group_staff(group_id, username) \ and username != from_email: return render_permission_error(request, _(u'Failed to remove share')) if is_org_group(group_id): org_id = get_org_id_by_group(group_id) del_org_group_repo(repo_id, org_id, group_id) else: seafile_api.unset_group_repo(repo_id, group_id, from_email) send_perm_audit_msg('delete-repo-perm', from_email, group_id, \ perm_repo_id, perm_path, perm) messages.success(request, _('Successfully removed share')) next = request.META.get('HTTP_REFERER', SITE_ROOT) return HttpResponseRedirect(next)
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 post(self, request, repo_id, format=None): """Update shared item permission. """ username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_400_BAD_REQUEST, 'Repo not found.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) permission = request.DATA.get('permission', 'r') if permission not in ['r', 'rw']: return api_error(status.HTTP_400_BAD_REQUEST, 'Bad permission') path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_400_BAD_REQUEST, 'Directory not found.') if path == '/': shared_repo = repo else: try: sub_repo = self.get_sub_repo_by_path(request, repo, path) if sub_repo: shared_repo = sub_repo else: return api_error(status.HTTP_400_BAD_REQUEST, 'No sub repo found') except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo') 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, 'Bad username.') if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_set_share_permission( org_id, shared_repo.id, username, shared_to, permission) else: seafile_api.set_share_permission(shared_repo.id, username, shared_to, permission) send_perm_audit_msg('modify-repo-perm', username, shared_to, repo_id, path, permission) if shared_to_group: gid = request.GET.get('group_id') try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'Bad group id: %s' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_400_BAD_REQUEST, 'Group not found: %s' % gid) if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, gid, shared_repo.id, permission) else: seafile_api.set_group_repo_permission(gid, shared_repo.id, permission) send_perm_audit_msg('modify-repo-perm', username, gid, repo_id, path, permission) return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
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, 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) 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.') if share_type == 'user': if username != self.get_repo_owner(request, repo_id) and \ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') else: if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') permission = request.data.get('permission', PERMISSION_READ) if permission not in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ]: 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': _(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 try: extra_share_permission = '' if permission == PERMISSION_ADMIN: extra_share_permission = permission permission = PERMISSION_READ_WRITE if is_org_context(request): username = seafile_api.get_org_repo_owner(repo_id) 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 if path == '/': seaserv.seafserv_threaded_rpc.org_add_share( org_id, repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_user( org_id, repo_id, path, username, to_user, permission) 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 username = seafile_api.get_repo_owner(repo_id) if path == '/': seafile_api.share_repo(repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.share_subdir_to_user( repo_id, path, username, to_user, permission) if path == '/' and extra_share_permission == PERMISSION_ADMIN: ExtraSharePermission.objects.create_share_permission( repo_id, to_user, extra_share_permission) # send a signal when sharing repo successful if path == '/': share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=sub_repo) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission, "is_admin": extra_share_permission == PERMISSION_ADMIN }) 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': _(u'group_id %s invalid.') % gid}) continue group = ccnet_api.get_group(gid) if not group: result['failed'].append( {'error_msg': _(u'Group %s not found') % gid}) continue if not config.ENABLE_SHARE_TO_ALL_GROUPS and \ not ccnet_api.is_group_user(gid, username): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _(u'Permission denied.') }) 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 try: if is_org_context(request): org_id = request.user.org.org_id if path == '/': seafile_api.add_org_group_repo( repo_id, org_id, gid, username, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_group( org_id, repo_id, path, username, gid, permission) else: if path == '/': seafile_api.set_group_repo(repo_id, gid, username, permission) else: sub_repo_id = seafile_api.share_subdir_to_group( repo_id, path, username, gid, permission) if path == '/': share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=sub_repo) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) 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 put(self, request, repo_id, format=None): """ Update permission of a shared repo. Permission checking: 1. Only repo owner can update. """ # argument check permission = request.data.get('permission', None) if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) 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 ('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) # recourse 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 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) # update share permission if share_type == 'personal': shared_to = request.data.get('user', None) if not shared_to or not is_valid_username(shared_to): error_msg = 'user invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) try: if is_org_context(request): org_id = request.user.org.org_id update_user_dir_permission(repo_id, '/', repo_owner, shared_to, permission, org_id) else: update_user_dir_permission(repo_id, '/', repo_owner, shared_to, permission) 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('modify-repo-perm', username, shared_to, repo_id, '/', permission) if share_type == 'group': group_id = request.data.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) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %s not found.' % group_id return api_error(status.HTTP_404_NOT_FOUND, error_msg) try: if is_org_context(request): org_id = request.user.org.org_id update_group_dir_permission(repo_id, '/', repo_owner, group_id, permission, org_id) else: update_group_dir_permission(repo_id, '/', repo_owner, group_id, permission) 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('modify-repo-perm', username, group_id, repo_id, '/', permission) if share_type == 'public': try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.set_org_inner_pub_repo(org_id, repo_id, permission) else: if not request.user.permissions.can_add_public_repo(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) seafile_api.add_inner_pub_repo(repo_id, permission) 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('modify-repo-perm', username, 'all', repo_id, '/', permission) return Response({'success': True})
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 post(self, request, repo_id, format=None): """Update shared item permission. """ 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) permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') 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) try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered') 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 update_user_dir_permission(repo_id, path, repo_owner, shared_to, permission, org_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) update_user_dir_permission(repo_id, path, repo_owner, shared_to, permission) send_perm_audit_msg('modify-repo-perm', username, shared_to, repo_id, path, permission) if shared_to_group: gid = request.GET.get('group_id') try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found.' % gid) 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 update_group_dir_permission(repo_id, path, repo_owner, gid, permission, org_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) update_group_dir_permission(repo_id, path, repo_owner, gid, permission, None) send_perm_audit_msg('modify-repo-perm', username, gid, repo_id, path, permission) return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
def put(self, request, repo, path, share_type): """ Update user/group share permission. Permission checking: 1. admin user. """ # argument check permission = request.data.get('permission', None) if not permission or permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_info = {} share_info['repo_id'] = repo.repo_id share_info['path'] = path share_info['share_type'] = share_type # 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) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) 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: update_user_dir_permission(repo.repo_id, path, repo_owner, email, permission) send_perm_audit_msg('modify-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) share_info['user_email'] = email share_info['user_name'] = email2nickname(email) share_info['permission'] = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission share_info['is_admin'] = permission == PERMISSION_ADMIN 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) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %s not found' % group_id return api_error(status.HTTP_404_NOT_FOUND, 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: update_group_dir_permission(repo.repo_id, path, repo_owner, group_id, permission) send_perm_audit_msg('modify-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) share_info['group_id'] = group_id share_info['group_name'] = group.group_name share_info['permission'] = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission share_info['is_admin'] = permission == PERMISSION_ADMIN return Response(share_info)
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 if is_org_context(request): org_id = request.user.org.org_id 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) # if user not found, permission will be None permission = seafile_api.check_permission_by_path( repo_id, '/', user) 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) # hacky way to get group repo permission permission = '' if org_id: for e in seafile_api.list_org_repo_shared_group( org_id, username, repo_id): if e.group_id == group_id: permission = e.perm break else: for e in seafile_api.list_repo_shared_group_by_user(username, repo_id): if e.group_id == group_id: permission = e.perm break try: if org_id: 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 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 username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if path != '/': try: sub_repo = self.get_or_create_sub_repo_by_path(request, repo, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo.') else: sub_repo = None 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.') permission = request.data.get('permission', 'r') if permission not in ['r', 'rw']: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') shared_repo = repo if path == '/' else sub_repo 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 try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share( org_id, shared_repo.id, username, to_user, permission) else: seafile_api.share_repo(shared_repo.id, username, to_user, permission) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=shared_repo) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission }) 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: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found' % gid) try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo(shared_repo.repo_id, org_id, gid, username, permission) else: seafile_api.set_group_repo(shared_repo.repo_id, gid, username, permission) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=shared_repo) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) 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 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 username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, "Permission denied.") if path != "/": try: sub_repo = self.get_or_create_sub_repo_by_path(request, repo, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, "Failed to get sub repo.") else: sub_repo = None 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.") permission = request.data.get("permission", "r") if permission not in ["r", "rw"]: return api_error(status.HTTP_400_BAD_REQUEST, "permission invalid.") shared_repo = repo if path == "/" else sub_repo success, failed = [], [] 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): failed.append(to_user) continue try: User.objects.get(email=to_user) except User.DoesNotExist: failed.append(to_user) continue if not check_user_share_quota(username, shared_repo, users=[to_user]): return api_error(status.HTTP_403_FORBIDDEN, "Not enough quota.") try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share( org_id, shared_repo.id, username, to_user, permission ) else: seafile_api.share_repo(shared_repo.id, username, to_user, permission) # send a signal when sharing repo successful share_repo_to_user_successful.send( sender=None, from_user=username, to_user=to_user, repo=shared_repo ) success.append( { "share_type": "user", "user_info": {"name": to_user, "nickname": email2nickname(to_user)}, "permission": permission, } ) send_perm_audit_msg("add-repo-perm", username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(to_user) continue if share_type == "group": group_ids = request.data.getlist("group_id") for gid in group_ids: try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, "group_id %s invalid." % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, "Group %s not found" % gid) if not check_user_share_quota(username, shared_repo, groups=[group]): return api_error(status.HTTP_403_FORBIDDEN, "Not enough quota.") try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo(shared_repo.repo_id, org_id, gid, username, permission) else: seafile_api.set_group_repo(shared_repo.repo_id, gid, username, permission) success.append( { "share_type": "group", "group_info": {"id": gid, "name": group.group_name}, "permission": permission, } ) send_perm_audit_msg("add-repo-perm", username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(group.group_name) continue return HttpResponse( json.dumps({"success": success, "failed": failed}), status=200, content_type=json_content_type )
def post(self, request, repo_id, format=None): """Update shared item permission. """ 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_400_BAD_REQUEST, 'Directory not found.') if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) permission = request.data.get('permission', 'r') if permission not in ['r', 'rw']: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') 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 path == '/': shared_repo = repo else: try: sub_repo = self.get_sub_repo_by_path(request, repo, path) if sub_repo: shared_repo = sub_repo else: # unlikely to happen return api_error(status.HTTP_404_NOT_FOUND, 'Failed to get sub repo') except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Internal Server Error') 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) try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered') if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_set_share_permission( org_id, shared_repo.id, username, shared_to, permission) else: seafile_api.set_share_permission(shared_repo.id, username, shared_to, permission) send_perm_audit_msg('modify-repo-perm', username, shared_to, repo_id, path, permission) if shared_to_group: gid = request.GET.get('group_id') try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found.' % gid) if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, gid, shared_repo.id, permission) else: seafile_api.set_group_repo_permission(gid, shared_repo.id, permission) send_perm_audit_msg('modify-repo-perm', username, gid, repo_id, path, permission) return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
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 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) if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) if path == '/': shared_repo = repo else: try: sub_repo = self.get_sub_repo_by_path(request, repo, path) if sub_repo: shared_repo = sub_repo else: return api_error(status.HTTP_404_NOT_FOUND, 'Sub-library not found.') except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub-library.') 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.' % share_to) try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered') if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_remove_share( org_id, shared_repo.id, username, shared_to) else: seaserv.remove_share(shared_repo.id, username, shared_to) permission = seafile_api.check_permission_by_path( repo.id, path, 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 permission = '' for e in seafile_api.list_repo_shared_group( username, shared_repo.id): if e.group_id == group_id: permission = e.perm break if is_org_context(request): org_id = request.user.org.org_id seaserv.del_org_group_repo(shared_repo.id, org_id, group_id) else: seafile_api.unset_group_repo(shared_repo.id, group_id, username) 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 put(self, request, repo, path, share_type): """ Update user/group share permission. Permission checking: 1. admin user. """ # argument check permission = request.data.get('permission', None) if not permission or permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_info = {} share_info['repo_id'] = repo.repo_id share_info['path'] = path share_info['share_type'] = share_type # 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) try: User.objects.get(email=email) except User.DoesNotExist: error_msg = 'User %s not found.' % email return api_error(status.HTTP_404_NOT_FOUND, error_msg) 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: update_user_dir_permission(repo.repo_id, path, repo_owner, email, permission) send_perm_audit_msg('modify-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) share_info['user_email'] = email share_info['user_name'] = email2nickname(email) share_info[ 'permission'] = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission share_info['is_admin'] = permission == PERMISSION_ADMIN 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) group = ccnet_api.get_group(group_id) if not group: error_msg = 'Group %s not found' % group_id return api_error(status.HTTP_404_NOT_FOUND, 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: update_group_dir_permission(repo.repo_id, path, repo_owner, group_id, permission) send_perm_audit_msg('modify-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) share_info['group_id'] = group_id share_info['group_name'] = group.group_name share_info[ 'permission'] = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission share_info['is_admin'] = permission == PERMISSION_ADMIN return Response(share_info)
def post(self, request, group_id): """ Add a group library. Permission checking: 1. role permission, can_add_repo; 1. is group member; """ # argument check repo_name = request.data.get("repo_name", None) if not repo_name or \ not is_valid_dirent_name(repo_name): error_msg = "repo_name invalid." return api_error(status.HTTP_400_BAD_REQUEST, error_msg) password = request.data.get("password", None) if password and not config.ENABLE_ENCRYPTED_LIBRARY: error_msg = 'NOT allow to create encrypted library.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) # permission check if not request.user.permissions.can_add_repo(): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) if not is_group_member(group_id, request.user.username): error_msg = 'Permission denied.' return api_error(status.HTTP_403_FORBIDDEN, error_msg) # create group repo org_id = -1 group_id = int(group_id) username = request.user.username is_org = False if is_org_context(request): is_org = True org_id = request.user.org.org_id repo_id = seafile_api.create_org_repo(repo_name, '', username, password, org_id) else: repo_id = seafile_api.create_repo(repo_name, '', username, password) repo = seafile_api.get_repo(repo_id) share_dir_to_group(repo, '/', username, username, group_id, permission, org_id if is_org else None) # for activities library_template = request.data.get("library_template", '') repo_created.send(sender=None, org_id=org_id, creator=username, repo_id=repo_id, repo_name=repo_name, library_template=library_template) # for notification share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path='/', org_id=org_id) # for perm audit send_perm_audit_msg('add-repo-perm', username, group_id, repo_id, '/', permission) group_repo = seafile_api.get_group_shared_repo_by_path(repo_id, None, group_id, is_org) group_repo_info = get_group_repo_info(request, group_repo) group_repo_info['owner_email'] = username group_repo_info['owner_name'] = email2nickname(username) group_repo_info['owner_contact_email'] = email2contact_email(username) modifier = group_repo.last_modifier group_repo_info['modifier_email'] = modifier group_repo_info['modifier_name'] = email2nickname(modifier) group_repo_info['modifier_contact_email'] = email2contact_email(modifier) return Response(group_repo_info)
def 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 put(self, request, repo_id, format=None): username = request.user.username repo = seafile_api.get_repo(repo_id) if not repo: return api_error(status.HTTP_404_NOT_FOUND, 'Library %s not found.' % repo_id) path = request.GET.get('p', '/') if seafile_api.get_dir_id_by_path(repo.id, path) is None: return api_error(status.HTTP_404_NOT_FOUND, 'Folder %s not found.' % path) if repo.encrypted and path != '/': return api_error(status.HTTP_400_BAD_REQUEST, 'Folder invalid.') share_type = request.data.get('share_type') if share_type != 'user' and share_type != 'group': return api_error(status.HTTP_400_BAD_REQUEST, 'share_type invalid.') repo_owner = self.get_repo_owner(request, repo_id) if repo_owner != username and not is_repo_admin(username, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') permission = request.data.get('permission', PERMISSION_READ) if permission not in get_available_repo_perms(): return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') result = {} result['failed'] = [] result['success'] = [] if share_type == 'user': share_to_users = request.data.getlist('username') for to_user in share_to_users: if not is_valid_username(to_user): result['failed'].append({ 'email': to_user, 'error_msg': _('username invalid.') }) continue try: User.objects.get(email=to_user) except User.DoesNotExist: result['failed'].append({ 'email': to_user, 'error_msg': _('User %s not found.') % to_user }) continue if self.has_shared_to_user(request, repo_id, path, to_user): result['failed'].append({ 'email': to_user, 'error_msg': _('This item has been shared to %s.') % email2nickname(to_user) }) continue try: org_id = None if is_org_context(request): org_id = request.user.org.org_id if not is_org_user(to_user, int(org_id)): org_name = request.user.org.org_name error_msg = 'User %s is not member of organization %s.' \ % (to_user, org_name) result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, org_id) else: if is_org_user(to_user): error_msg = 'User %s is a member of organization.' % to_user result['failed'].append({ 'email': to_user, 'error_msg': error_msg }) continue repo_owner = seafile_api.get_repo_owner(repo_id) # can't share to owner if to_user == repo_owner: error_msg = "Library can not be shared to owner" return api_error(status.HTTP_400_BAD_REQUEST, error_msg) share_dir_to_user(repo, path, repo_owner, username, to_user, permission, None) avatar_url, is_default, date_uploaded = api_avatar_url( to_user, 72) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), "contact_email": email2contact_email(to_user), "avatar_url": avatar_url, }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'email': to_user, 'error_msg': 'Internal Server Error' }) continue if share_type == 'group': group_ids = request.data.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: result['failed'].append( {'error_msg': 'group_id %s invalid.' % gid}) continue group = ccnet_api.get_group(gid) if not group: result['failed'].append( {'error_msg': 'Group %s not found' % gid}) continue if not config.ENABLE_SHARE_TO_ALL_GROUPS and \ not is_group_member(gid, username): result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Permission denied.' }) continue if self.has_shared_to_group(request, repo_id, path, gid): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _('This item has been shared to %s.') % group.group_name }) continue try: org_id = None if is_org_context(request): # when calling seafile API to share authority related functions, change the uesrname to repo owner. repo_owner = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id share_dir_to_group(repo, path, repo_owner, username, gid, permission, org_id) else: repo_owner = seafile_api.get_repo_owner(repo_id) share_dir_to_group(repo, path, repo_owner, username, gid, permission, None) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo, path=path, org_id=org_id) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) result['failed'].append({ 'group_name': group.group_name, 'error_msg': 'Internal Server Error' }) continue return HttpResponse(json.dumps(result), status=200, content_type=json_content_type)
def 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) if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') shared_to_user, shared_to_group = self.handle_shared_to_args(request) if path == '/': shared_repo = repo else: try: sub_repo = self.get_sub_repo_by_path(request, repo, path) if sub_repo: shared_repo = sub_repo else: return api_error(status.HTTP_404_NOT_FOUND, 'Sub-library not found.') except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub-library.') 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) try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered') if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_remove_share( org_id, shared_repo.id, username, shared_to) else: seaserv.remove_share(shared_repo.id, username, shared_to) permission = seafile_api.check_permission_by_path(repo.id, path, 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 permission = '' for e in seafile_api.list_repo_shared_group_by_user(username, shared_repo.id): if e.group_id == group_id: permission = e.perm break if is_org_context(request): org_id = request.user.org.org_id seaserv.del_org_group_repo(shared_repo.id, org_id, group_id) else: seafile_api.unset_group_repo(shared_repo.id, group_id, username) 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 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 username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') 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.') permission = request.data.get('permission', 'r') if permission not in ['r', 'rw']: 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 try: if is_org_context(request): org_id = request.user.org.org_id if path == '/': seaserv.seafserv_threaded_rpc.org_add_share( org_id, repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_user(org_id, repo_id, path, username, to_user, permission) else: if path == '/': seafile_api.share_repo( repo_id, username, to_user, permission) else: sub_repo_id = seafile_api.share_subdir_to_user( repo_id, path, username, to_user, permission) # send a signal when sharing repo successful if path == '/': share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=sub_repo) result['success'].append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission }) 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: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found' % gid) try: if is_org_context(request): org_id = request.user.org.org_id if path == '/': seafile_api.add_org_group_repo( repo_id, org_id, gid, username, permission) else: sub_repo_id = seafile_api.org_share_subdir_to_group(org_id, repo_id, path, username, gid, permission) else: if path == '/': seafile_api.set_group_repo( repo_id, gid, username, permission) else: sub_repo_id = seafile_api.share_subdir_to_group( repo_id, path, username, gid, permission) if path == '/': share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=repo) else: sub_repo = seafile_api.get_repo(sub_repo_id) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=gid, repo=sub_repo) result['success'].append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) 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 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 username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if path != '/': try: sub_repo = self.get_or_create_sub_repo_by_path( request, repo, path) except SearpcError as e: logger.error(e) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, 'Failed to get sub repo.') else: sub_repo = None 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.') permission = request.data.get('permission', 'r') if permission not in ['r', 'rw']: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') shared_repo = repo if path == '/' else sub_repo success, failed = [], [] 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): failed.append(to_user) continue try: User.objects.get(email=to_user) except User.DoesNotExist: failed.append(to_user) continue if not check_user_share_quota( username, shared_repo, users=[to_user]): return api_error(status.HTTP_403_FORBIDDEN, 'Not enough quota.') try: if is_org_context(request): org_id = request.user.org.org_id seaserv.seafserv_threaded_rpc.org_add_share( org_id, shared_repo.id, username, to_user, permission) else: seafile_api.share_repo(shared_repo.id, username, to_user, permission) # send a signal when sharing repo successful share_repo_to_user_successful.send(sender=None, from_user=username, to_user=to_user, repo=shared_repo) success.append({ "share_type": "user", "user_info": { "name": to_user, "nickname": email2nickname(to_user), }, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, to_user, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(to_user) continue if share_type == 'group': group_ids = request.data.getlist('group_id') for gid in group_ids: try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found' % gid) if not check_user_share_quota( username, shared_repo, groups=[group]): return api_error(status.HTTP_403_FORBIDDEN, 'Not enough quota.') try: if is_org_context(request): org_id = request.user.org.org_id seafile_api.add_org_group_repo(shared_repo.repo_id, org_id, gid, username, permission) else: seafile_api.set_group_repo(shared_repo.repo_id, gid, username, permission) success.append({ "share_type": "group", "group_info": { "id": gid, "name": group.group_name, }, "permission": permission }) send_perm_audit_msg('add-repo-perm', username, gid, repo_id, path, permission) except SearpcError as e: logger.error(e) failed.append(group.group_name) continue return HttpResponse(json.dumps({ "success": success, "failed": failed }), status=200, content_type=json_content_type)
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) if username != self.get_repo_owner(request, 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) # if user not found, permission will be None permission = seafile_api.check_permission_by_path( repo_id, '/', shared_to) if is_org_context(request): org_id = request.user.org.org_id if path == '/': seaserv.seafserv_threaded_rpc.org_remove_share( org_id, repo_id, username, shared_to) else: seafile_api.org_unshare_subdir_for_user( org_id, repo_id, path, username, shared_to) else: if path == '/': seaserv.remove_share(repo_id, username, shared_to) else: seafile_api.unshare_subdir_for_user( repo_id, path, username, 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 permission = '' if is_org_context(request): org_id = request.user.org.org_id shared_groups = seafile_api.list_org_repo_shared_group( org_id, username, repo_id) else: shared_groups = seafile_api.list_repo_shared_group( username, repo_id) for e in shared_groups: if e.group_id == group_id: permission = e.perm break if is_org_context(request): 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, username, 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, username, 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 post(self, request, repo, path, share_type): """ Admin share a library to user/group. Permission checking: 1. admin user. """ # argument check permission = request.data.get('permission', None) if not permission or permission not in get_available_repo_perms(): error_msg = 'permission invalid.' return api_error(status.HTTP_400_BAD_REQUEST, error_msg) result = {} result['failed'] = [] result['success'] = [] share_to = request.data.getlist('share_to') # 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 if share_type == 'user': for email in share_to: if repo_owner == email: result['failed'].append({ 'user_email': email, 'error_msg': _('User %s is already library owner.') % email }) continue if not is_valid_username(email): result['failed'].append({ 'user_email': email, 'error_msg': _('Email %s invalid.') % email }) continue try: User.objects.get(email=email) except User.DoesNotExist: result['failed'].append({ 'user_email': email, 'error_msg': 'User %s not found.' % email }) continue if has_shared_to_user(repo.repo_id, path, email): result['failed'].append({ 'email': email, 'error_msg': _('This item has been shared to %s.') % email }) continue try: share_dir_to_user(repo, path, repo_owner, username, email, permission) share_repo_to_user_successful.send(sender=None, from_user=username, to_user=email, repo=repo, path=path, org_id=None) send_perm_audit_msg('add-repo-perm', username, email, repo.repo_id, path, permission) except Exception as e: logger.error(e) result['failed'].append({ 'user_email': email, 'error_msg': 'Internal Server Error' }) continue result['success'].append({ "repo_id": repo.repo_id, "path": path, "share_type": share_type, "user_email": email, "user_name": email2nickname(email), "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) if share_type == 'group': for group_id in share_to: try: group_id = int(group_id) except ValueError as e: logger.error(e) result['failed'].append({ 'group_id': group_id, 'error_msg': 'group_id %s invalid.' % group_id }) continue group = ccnet_api.get_group(group_id) if not group: result['failed'].append({ 'group_id': group_id, 'error_msg': 'Group %s not found' % group_id }) continue if has_shared_to_group(repo.repo_id, path, group_id): result['failed'].append({ 'group_name': group.group_name, 'error_msg': _('This item has been shared to %s.') % group.group_name }) continue try: share_dir_to_group(repo, path, repo_owner, username, group_id, permission) share_repo_to_group_successful.send(sender=None, from_user=username, group_id=group_id, repo=repo, path=path, org_id=None) send_perm_audit_msg('add-repo-perm', username, group_id, repo.repo_id, path, permission) except Exception as e: logger.error(e) result['failed'].append({ "group_id": group_id, 'error_msg': 'Internal Server Error' }) continue result['success'].append({ "repo_id": repo.repo_id, "path": path, "share_type": share_type, "group_id": group_id, "group_name": group.group_name, "permission": PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else permission, "is_admin": permission == PERMISSION_ADMIN }) return Response(result)
def post(self, request, repo_id, format=None): """Update shared item permission. """ 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) permission = request.data.get('permission', PERMISSION_READ) if permission not in [ PERMISSION_READ, PERMISSION_READ_WRITE, PERMISSION_ADMIN ]: return api_error(status.HTTP_400_BAD_REQUEST, 'permission invalid.') 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) if username != self.get_repo_owner(request, repo_id) and \ ExtraSharePermission.objects.get_user_permission(repo_id, username) != PERMISSION_ADMIN: return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') else: if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, 'Permission denied.') if shared_to_user: try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, 'Invalid user, should be registered') extra_share_permission = "" if permission not in [PERMISSION_READ, PERMISSION_READ_WRITE]: extra_share_permission = permission permission = PERMISSION_READ_WRITE if permission == PERMISSION_ADMIN else PERMISSION_READ if is_org_context(request): username = seafile_api.get_org_repo_owner(repo_id) org_id = request.user.org.org_id if path == '/': seafile_api.org_set_share_permission( org_id, repo_id, username, shared_to, permission) else: seafile_api.org_update_share_subdir_perm_for_user( org_id, repo_id, path, username, shared_to, permission) else: username = seafile_api.get_repo_owner(repo_id) if path == '/': seafile_api.set_share_permission(repo_id, username, shared_to, permission) else: seafile_api.update_share_subdir_perm_for_user( repo_id, path, username, shared_to, permission) if path == '/': ExtraSharePermission.objects.update_share_permission( repo_id, shared_to, extra_share_permission) send_perm_audit_msg('modify-repo-perm', username, shared_to, repo_id, path, permission) if shared_to_group: gid = request.GET.get('group_id') try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, 'group_id %s invalid.' % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, 'Group %s not found.' % gid) if is_org_context(request): org_id = request.user.org.org_id if path == '/': seaserv.seafserv_threaded_rpc.set_org_group_repo_permission( org_id, gid, repo.id, permission) else: seafile_api.org_update_share_subdir_perm_for_group( org_id, repo_id, path, username, gid, permission) else: if path == '/': seafile_api.set_group_repo_permission( gid, repo.id, permission) else: seafile_api.update_share_subdir_perm_for_group( repo_id, path, username, gid, permission) send_perm_audit_msg('modify-repo-perm', username, gid, repo_id, path, permission) return HttpResponse(json.dumps({'success': True}), status=200, content_type=json_content_type)
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 post(self, request, repo_id, format=None): """Update shared item permission. """ 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_400_BAD_REQUEST, "Directory not found.") if username != self.get_repo_owner(request, repo_id): return api_error(status.HTTP_403_FORBIDDEN, "Permission denied.") shared_to_user, shared_to_group = self.handle_shared_to_args(request) permission = request.data.get("permission", "r") if permission not in ["r", "rw"]: return api_error(status.HTTP_400_BAD_REQUEST, "permission invalid.") 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 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) try: User.objects.get(email=shared_to) except User.DoesNotExist: return api_error(status.HTTP_400_BAD_REQUEST, "Invalid user, should be registered") if is_org_context(request): org_id = request.user.org.org_id if path == "/": seafile_api.org_set_share_permission(org_id, repo_id, username, shared_to, permission) else: seafile_api.org_update_share_subdir_perm_for_user( org_id, repo_id, path, username, shared_to, permission ) else: if path == "/": seafile_api.set_share_permission(repo_id, username, shared_to, permission) else: seafile_api.update_share_subdir_perm_for_user(repo_id, path, username, shared_to, permission) send_perm_audit_msg("modify-repo-perm", username, shared_to, repo_id, path, permission) if shared_to_group: gid = request.GET.get("group_id") try: gid = int(gid) except ValueError: return api_error(status.HTTP_400_BAD_REQUEST, "group_id %s invalid." % gid) group = seaserv.get_group(gid) if not group: return api_error(status.HTTP_404_NOT_FOUND, "Group %s not found." % gid) if is_org_context(request): org_id = request.user.org.org_id if path == "/": seaserv.seafserv_threaded_rpc.set_org_group_repo_permission(org_id, gid, repo.id, permission) else: seafile_api.org_update_share_subdir_perm_for_group(org_id, repo_id, path, username, gid, permission) else: if path == "/": seafile_api.set_group_repo_permission(gid, repo.id, permission) else: seafile_api.update_share_subdir_perm_for_group(repo_id, path, username, gid, permission) send_perm_audit_msg("modify-repo-perm", username, gid, repo_id, path, permission) return HttpResponse(json.dumps({"success": True}), status=200, content_type=json_content_type)