1
0
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:
lian 2016-06-24 11:10:26 +08:00
parent 85bb2cd076
commit ed10512a53
4 changed files with 300 additions and 40 deletions

View File

@ -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({

View File

@ -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)

View File

@ -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)

View File

@ -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)