mirror of
https://github.com/haiwen/seahub.git
synced 2025-08-19 15:38:38 +00:00
update repo share
1. reshare repo after user/admin transfer repo 2. show org repo share out list at share popup in org mode
This commit is contained in:
parent
85bb2cd076
commit
ed10512a53
@ -32,15 +32,25 @@ class DirSharedItemsEndpoint(APIView):
|
||||
"""
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
permission_classes = (IsAuthenticated, IsRepoAccessible)
|
||||
throttle_classes = (UserRateThrottle, )
|
||||
throttle_classes = (UserRateThrottle,)
|
||||
|
||||
def list_user_shared_items(self, request, repo_id, path):
|
||||
username = request.user.username
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_repo_shared_to(username, repo_id)
|
||||
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_org_repo_shared_to(org_id,
|
||||
username, repo_id)
|
||||
else:
|
||||
share_items = seafile_api.get_org_shared_users_for_subdir(org_id,
|
||||
repo_id, path, username)
|
||||
else:
|
||||
share_items = seafile_api.get_shared_users_for_subdir(repo_id,
|
||||
path, username)
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_repo_shared_to(username, repo_id)
|
||||
else:
|
||||
share_items = seafile_api.get_shared_users_for_subdir(repo_id,
|
||||
path, username)
|
||||
ret = []
|
||||
for item in share_items:
|
||||
ret.append({
|
||||
@ -55,11 +65,20 @@ class DirSharedItemsEndpoint(APIView):
|
||||
|
||||
def list_group_shared_items(self, request, repo_id, path):
|
||||
username = request.user.username
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_repo_shared_group_by_user(username, repo_id)
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_org_repo_shared_group(org_id,
|
||||
username, repo_id)
|
||||
else:
|
||||
share_items = seafile_api.get_org_shared_groups_for_subdir(org_id,
|
||||
repo_id, path, username)
|
||||
else:
|
||||
share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
|
||||
path, username)
|
||||
if path == '/':
|
||||
share_items = seafile_api.list_repo_shared_group_by_user(username, repo_id)
|
||||
else:
|
||||
share_items = seafile_api.get_shared_groups_for_subdir(repo_id,
|
||||
path, username)
|
||||
ret = []
|
||||
for item in share_items:
|
||||
ret.append({
|
||||
|
@ -20,7 +20,7 @@ from rest_framework.response import Response
|
||||
from django.contrib.auth.hashers import check_password
|
||||
from django.contrib.sites.models import RequestSite
|
||||
from django.db import IntegrityError
|
||||
from django.db.models import F, Q
|
||||
from django.db.models import F
|
||||
from django.http import HttpResponse
|
||||
from django.template import RequestContext
|
||||
from django.template.loader import render_to_string
|
||||
@ -55,7 +55,6 @@ from seahub.group.utils import BadGroupNameError, ConflictGroupNameError, \
|
||||
from seahub.thumbnail.utils import generate_thumbnail
|
||||
from seahub.notifications.models import UserNotification
|
||||
from seahub.options.models import UserOptions
|
||||
from seahub.contacts.models import Contact
|
||||
from seahub.profile.models import Profile, DetailedProfile
|
||||
from seahub.signals import (repo_created, repo_deleted)
|
||||
from seahub.share.models import FileShare, OrgFileShare, UploadLinkShare
|
||||
@ -86,7 +85,7 @@ if HAS_OFFICE_CONVERTER:
|
||||
from seahub.utils import query_office_convert_status, prepare_converted_html
|
||||
import seahub.settings as settings
|
||||
from seahub.settings import THUMBNAIL_EXTENSION, THUMBNAIL_ROOT, \
|
||||
ENABLE_GLOBAL_ADDRESSBOOK, FILE_LOCK_EXPIRATION_DAYS, \
|
||||
FILE_LOCK_EXPIRATION_DAYS, \
|
||||
ENABLE_THUMBNAIL, ENABLE_FOLDER_PERM
|
||||
try:
|
||||
from seahub.settings import CLOUD_MODE
|
||||
@ -1072,48 +1071,120 @@ class RepoOwner(APIView):
|
||||
content_type=json_content_type)
|
||||
|
||||
def put(self, request, repo_id, format=None):
|
||||
repo = 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)
|
||||
""" Currently only for transfer repo.
|
||||
|
||||
Permission checking:
|
||||
1. only repo owner can transfer repo.
|
||||
"""
|
||||
|
||||
org_id = None
|
||||
if is_org_context(request):
|
||||
org_id = request.user.org.org_id
|
||||
|
||||
# check permission
|
||||
if org_id:
|
||||
repo_owner = seafile_api.get_org_repo_owner(repo.id)
|
||||
else:
|
||||
repo_owner = seafile_api.get_repo_owner(repo.id)
|
||||
|
||||
if request.user.username != repo_owner:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# check new owner validation
|
||||
# argument check
|
||||
new_owner = request.data.get('owner', '').lower()
|
||||
if not new_owner:
|
||||
error_msg = 'owner invalid.'
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
|
||||
# resource check
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
if not repo:
|
||||
error_msg = 'Library %s not found.' % repo_id
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
try:
|
||||
User.objects.get(email=new_owner)
|
||||
except User.DoesNotExist:
|
||||
error_msg = 'User %s not found.' % new_owner
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
if org_id and not ccnet_api.org_user_exists(org_id, new_owner):
|
||||
error_msg = _(u'User %s not found in organization.') % new_owner
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
# permission check
|
||||
if org_id:
|
||||
if not ccnet_api.org_user_exists(org_id, new_owner):
|
||||
error_msg = _(u'User %s not found in organization.') % new_owner
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
repo_owner = seafile_api.get_org_repo_owner(repo_id)
|
||||
else:
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
|
||||
username = request.user.username
|
||||
if username != repo_owner:
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
# get users/groups repo already shared to
|
||||
if org_id:
|
||||
shared_users = seafile_api.list_org_repo_shared_to(org_id,
|
||||
repo_owner, repo_id)
|
||||
shared_groups = seafile_api.list_org_repo_shared_group(org_id,
|
||||
repo_owner, repo_id)
|
||||
pub_repos = seaserv.seafserv_threaded_rpc.list_org_inner_pub_repos_by_owner(
|
||||
org_id, repo_owner)
|
||||
else:
|
||||
shared_users = seafile_api.list_repo_shared_to(
|
||||
repo_owner, repo_id)
|
||||
shared_groups = seafile_api.list_repo_shared_group_by_user(
|
||||
repo_owner, repo_id)
|
||||
pub_repos = seaserv.seafserv_threaded_rpc.list_inner_pub_repos_by_owner(
|
||||
repo_owner)
|
||||
|
||||
# transfer repo
|
||||
if org_id:
|
||||
seafile_api.set_org_repo_owner(org_id, repo_id, new_owner)
|
||||
else:
|
||||
if ccnet_api.get_orgs_by_user(new_owner):
|
||||
# can not transfer library to organization user %s.
|
||||
error_msg = 'Email %s invalid.' % new_owner
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
try:
|
||||
if org_id:
|
||||
seafile_api.set_org_repo_owner(org_id, repo_id, new_owner)
|
||||
else:
|
||||
seafile_api.set_repo_owner(repo_id, new_owner)
|
||||
if ccnet_api.get_orgs_by_user(new_owner):
|
||||
# can not transfer library to organization user %s.
|
||||
error_msg = 'Email %s invalid.' % new_owner
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
else:
|
||||
seafile_api.set_repo_owner(repo_id, new_owner)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||
|
||||
# reshare repo
|
||||
for shared_user in shared_users:
|
||||
shared_username = shared_user.user
|
||||
|
||||
if new_owner == shared_username:
|
||||
continue
|
||||
|
||||
if org_id:
|
||||
seaserv.seafserv_threaded_rpc.org_add_share(org_id, repo_id,
|
||||
new_owner, shared_username, shared_user.perm)
|
||||
else:
|
||||
seafile_api.share_repo(repo_id, new_owner,
|
||||
shared_username, shared_user.perm)
|
||||
|
||||
for shared_group in shared_groups:
|
||||
shared_group_id = shared_group.group_id
|
||||
|
||||
if not ccnet_api.is_group_user(shared_group_id, new_owner):
|
||||
continue
|
||||
|
||||
if org_id:
|
||||
seafile_api.add_org_group_repo(repo_id, org_id,
|
||||
shared_group_id, new_owner, shared_group.perm)
|
||||
else:
|
||||
seafile_api.set_group_repo(repo_id, shared_group_id,
|
||||
new_owner, shared_group.perm)
|
||||
|
||||
for pub_repo in pub_repos:
|
||||
if repo_id != pub_repo.id:
|
||||
continue
|
||||
|
||||
if org_id:
|
||||
seaserv.seafserv_threaded_rpc.set_org_inner_pub_repo(
|
||||
org_id, repo_id, pub_repo.permission)
|
||||
else:
|
||||
seaserv.seafserv_threaded_rpc.set_inner_pub_repo(
|
||||
repo_id, pub_repo.permission)
|
||||
|
||||
break
|
||||
|
||||
return HttpResponse(json.dumps({'success': True}),
|
||||
content_type=json_content_type)
|
||||
|
@ -22,7 +22,7 @@ from django.utils.translation import ugettext as _
|
||||
|
||||
import seaserv
|
||||
from seaserv import ccnet_threaded_rpc, seafserv_threaded_rpc, \
|
||||
seafile_api, get_group, get_group_members
|
||||
seafile_api, get_group, get_group_members, ccnet_api
|
||||
from pysearpc import SearpcError
|
||||
|
||||
from seahub.base.accounts import User
|
||||
@ -1611,8 +1611,45 @@ def sys_repo_transfer(request):
|
||||
except SearpcError: # XXX: ignore rpc not found error
|
||||
pass
|
||||
|
||||
repo_owner = seafile_api.get_repo_owner(repo_id)
|
||||
shared_users = seafile_api.list_repo_shared_to(
|
||||
repo_owner, repo_id)
|
||||
shared_groups = seafile_api.list_repo_shared_group_by_user(
|
||||
repo_owner, repo_id)
|
||||
pub_repos = seaserv.seafserv_threaded_rpc.list_inner_pub_repos_by_owner(
|
||||
repo_owner)
|
||||
|
||||
# transfer repo
|
||||
seafile_api.set_repo_owner(repo_id, new_owner)
|
||||
|
||||
# reshare repo
|
||||
for shared_user in shared_users:
|
||||
shared_username = shared_user.user
|
||||
|
||||
if new_owner == shared_username:
|
||||
continue
|
||||
|
||||
seafile_api.share_repo(repo_id, new_owner,
|
||||
shared_username, shared_user.perm)
|
||||
|
||||
for shared_group in shared_groups:
|
||||
shared_group_id = shared_group.group_id
|
||||
|
||||
if not ccnet_api.is_group_user(shared_group_id, new_owner):
|
||||
continue
|
||||
|
||||
seafile_api.set_group_repo(repo_id, shared_group_id,
|
||||
new_owner, shared_group.perm)
|
||||
|
||||
for pub_repo in pub_repos:
|
||||
if repo_id != pub_repo.id:
|
||||
continue
|
||||
|
||||
seaserv.seafserv_threaded_rpc.set_inner_pub_repo(
|
||||
repo_id, pub_repo.permission)
|
||||
|
||||
break
|
||||
|
||||
messages.success(request, _(u'Successfully transfered.'))
|
||||
return HttpResponseRedirect(next)
|
||||
|
||||
|
@ -4,12 +4,17 @@ import json
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from seahub.base.accounts import User
|
||||
from tests.common.utils import randstring
|
||||
|
||||
class RepoTest(BaseTestCase):
|
||||
from seaserv import seafile_api, ccnet_api
|
||||
|
||||
class RepoOwnerTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.user_name = self.user.username
|
||||
self.user_repo_id = self.repo.id
|
||||
self.group_id = self.group.id
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
@ -36,6 +41,134 @@ class RepoTest(BaseTestCase):
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
def test_reshare_to_user_after_transfer_repo(self):
|
||||
|
||||
tmp_user = 'tmp_user@email.com'
|
||||
User.objects.create_user(tmp_user)
|
||||
|
||||
# share user's repo to tmp_user with 'rw' permission
|
||||
seafile_api.share_repo(self.user_repo_id, self.user.username,
|
||||
tmp_user, 'rw')
|
||||
|
||||
assert seafile_api.check_permission_by_path(self.user_repo_id,
|
||||
'/', tmp_user) == 'rw'
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = reverse("api2-repo-owner", args=[self.user_repo_id])
|
||||
data = 'owner=%s' % self.admin.email
|
||||
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
assert seafile_api.check_permission_by_path(self.user_repo_id,
|
||||
'/', tmp_user) == 'rw'
|
||||
|
||||
def test_not_reshare_to_user_after_transfer_repo(self):
|
||||
# Remove share if repo already shared to new owner
|
||||
|
||||
# share user's repo to admin with 'rw' permission
|
||||
seafile_api.share_repo(self.user_repo_id, self.user.username,
|
||||
self.admin.username, 'rw')
|
||||
|
||||
# repo in admin's be shared repo list
|
||||
shared_repos = seafile_api.get_share_in_repo_list(self.admin.username, -1, -1)
|
||||
assert shared_repos[0].repo_name == self.repo.repo_name
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = reverse("api2-repo-owner", args=[self.user_repo_id])
|
||||
data = 'owner=%s' % self.admin.email
|
||||
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# repo NOT in admin's be shared repo list
|
||||
shared_repos = seafile_api.get_share_in_repo_list(self.admin.username, -1, -1)
|
||||
assert len(shared_repos) == 0
|
||||
|
||||
def test_reshare_to_group_after_transfer_repo(self):
|
||||
# If new owner in group repo shared to, reshare to group
|
||||
|
||||
# share user's repo to group with 'r' permission
|
||||
seafile_api.set_group_repo(self.user_repo_id, self.group_id,
|
||||
self.user_name, 'r')
|
||||
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
assert group_repos[0].permission == 'r'
|
||||
|
||||
# add admin user to group
|
||||
ccnet_api.group_add_member(self.group_id, self.user_name, self.admin.username)
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = reverse("api2-repo-owner", args=[self.user_repo_id])
|
||||
data = 'owner=%s' % self.admin.email
|
||||
|
||||
# transfer repo to admin
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
assert group_repos[0].permission == 'r'
|
||||
|
||||
def test_not_reshare_to_group_after_transfer_repo(self):
|
||||
# If new owner NOT in group repo shared to, NOT reshare to group
|
||||
|
||||
# share user's repo to group with 'r' permission
|
||||
seafile_api.set_group_repo(self.user_repo_id, self.group_id,
|
||||
self.user_name, 'r')
|
||||
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
assert group_repos[0].permission == 'r'
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = reverse("api2-repo-owner", args=[self.user_repo_id])
|
||||
data = 'owner=%s' % self.admin.email
|
||||
|
||||
# transfer repo to admin
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
assert len(group_repos) == 0
|
||||
|
||||
def test_reshare_to_user_group_after_transfer_repo(self):
|
||||
|
||||
tmp_user = 'tmp_user@email.com'
|
||||
User.objects.create_user(tmp_user)
|
||||
|
||||
# add admin user to group
|
||||
ccnet_api.group_add_member(self.group_id, self.user_name, self.admin.username)
|
||||
|
||||
# share user's repo to tmp_user with 'rw' permission
|
||||
seafile_api.share_repo(self.user_repo_id, self.user.username,
|
||||
tmp_user, 'rw')
|
||||
|
||||
# share user's repo to group with 'r' permission
|
||||
seafile_api.set_group_repo(self.user_repo_id, self.group_id,
|
||||
self.user_name, 'r')
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
|
||||
assert group_repos[0].permission == 'r'
|
||||
assert seafile_api.check_permission_by_path(self.user_repo_id,
|
||||
'/', tmp_user) == 'rw'
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
url = reverse("api2-repo-owner", args=[self.user_repo_id])
|
||||
data = 'owner=%s' % self.admin.email
|
||||
|
||||
# transfer repo to admin
|
||||
resp = self.client.put(url, data, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
group_repos = seafile_api.get_repos_by_group(self.group_id)
|
||||
assert group_repos[0].permission == 'r'
|
||||
assert seafile_api.check_permission_by_path(self.user_repo_id,
|
||||
'/', tmp_user) == 'rw'
|
||||
|
||||
def test_can_not_transfer_if_not_repo_owner(self):
|
||||
self.login_as(self.admin)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user