mirror of
https://github.com/haiwen/seahub.git
synced 2025-09-13 05:39:59 +00:00
update create dir sub repo api
This commit is contained in:
@@ -55,7 +55,7 @@ urlpatterns = patterns('',
|
|||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revert/$', FileRevert.as_view(), name='api2-file-revert'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/revert/$', FileRevert.as_view(), name='api2-file-revert'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/shared-link/$', FileSharedLinkView.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/file/shared-link/$', FileSharedLinkView.as_view()),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='DirView'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/$', DirView.as_view(), name='DirView'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/sub_repo/$', DirSubRepoView.as_view()),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/sub_repo/$', DirSubRepoView.as_view(), name="api2-dir-sub-repo"),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/shared_items/$', DirSharedItemsEndpoint.as_view(), name="api2-dir-shared-items"),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/shared_items/$', DirSharedItemsEndpoint.as_view(), name="api2-dir-shared-items"),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/download/$', DirDownloadView.as_view(), name='api2-dir-download'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/download/$', DirDownloadView.as_view(), name='api2-dir-download'),
|
||||||
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/revert/$', DirRevert.as_view(), name='api2-dir-revert'),
|
url(r'^repos/(?P<repo_id>[-0-9-a-f]{36})/dir/revert/$', DirRevert.as_view(), name='api2-dir-revert'),
|
||||||
|
@@ -2660,67 +2660,94 @@ class DirRevert(APIView):
|
|||||||
|
|
||||||
|
|
||||||
class DirSubRepoView(APIView):
|
class DirSubRepoView(APIView):
|
||||||
authentication_classes = (TokenAuthentication, )
|
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||||
permission_classes = (IsAuthenticated,)
|
permission_classes = (IsAuthenticated,)
|
||||||
throttle_classes = (UserRateThrottle, )
|
throttle_classes = (UserRateThrottle,)
|
||||||
|
|
||||||
# from seahub.views.ajax.py::sub_repo
|
|
||||||
def get(self, request, repo_id, format=None):
|
def get(self, request, repo_id, format=None):
|
||||||
'''
|
""" Create sub-repo for folder
|
||||||
check if a dir has a corresponding sub_repo
|
|
||||||
if it does not have, create one
|
|
||||||
'''
|
|
||||||
|
|
||||||
result = {}
|
Permission checking:
|
||||||
|
1. user with `r` or `rw` permission.
|
||||||
|
2. password correct for encrypted repo.
|
||||||
|
"""
|
||||||
|
|
||||||
path = request.GET.get('p')
|
# argument check
|
||||||
name = request.GET.get('name')
|
path = request.GET.get('p', None)
|
||||||
password = request.GET.get('password', None)
|
if not path:
|
||||||
|
error_msg = 'p invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
name = request.GET.get('name', None)
|
||||||
|
if not name:
|
||||||
|
error_msg = 'name invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
|
||||||
|
# recourse check
|
||||||
repo = get_repo(repo_id)
|
repo = get_repo(repo_id)
|
||||||
if not repo:
|
if not repo:
|
||||||
result['error'] = 'Library not found.'
|
error_msg = 'Library %s not found.' % repo_id
|
||||||
return HttpResponse(json.dumps(result), status=404, content_type=json_content_type)
|
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||||
|
|
||||||
if not (path and name):
|
# permission check
|
||||||
result['error'] = 'Argument missing'
|
if not check_folder_permission(request, repo_id, path) or \
|
||||||
return HttpResponse(json.dumps(result), status=400, content_type=json_content_type)
|
not request.user.permissions.can_add_repo():
|
||||||
|
error_msg = 'Permission denied.'
|
||||||
|
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||||
|
|
||||||
username = request.user.username
|
username = request.user.username
|
||||||
|
password = request.GET.get('password', '')
|
||||||
# check if the sub-lib exist
|
|
||||||
try:
|
|
||||||
sub_repo = seafile_api.get_virtual_repo(repo_id, path, username)
|
|
||||||
except SearpcError, e:
|
|
||||||
result['error'] = e.msg
|
|
||||||
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
|
|
||||||
|
|
||||||
if sub_repo:
|
|
||||||
result['sub_repo_id'] = sub_repo.id
|
|
||||||
else:
|
|
||||||
if not request.user.permissions.can_add_repo():
|
|
||||||
return api_error(status.HTTP_403_FORBIDDEN,
|
|
||||||
'You do not have permission to create library.')
|
|
||||||
|
|
||||||
# create a sub-lib
|
|
||||||
try:
|
|
||||||
# use name as 'repo_name' & 'repo_desc' for sub_repo
|
|
||||||
if repo.encrypted:
|
if repo.encrypted:
|
||||||
if password:
|
# check password for encrypted repo
|
||||||
sub_repo_id = seafile_api.create_virtual_repo(repo_id,
|
if not password:
|
||||||
path, name, name, username, password)
|
error_msg = 'password invalid.'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
else:
|
else:
|
||||||
result['error'] = 'Password Required.'
|
try:
|
||||||
return HttpResponse(json.dumps(result), status=403, content_type=json_content_type)
|
seafile_api.set_passwd(repo_id, username, password)
|
||||||
|
except SearpcError as e:
|
||||||
|
if e.msg == 'Bad arguments':
|
||||||
|
error_msg = 'Bad arguments'
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
elif e.msg == 'Incorrect password':
|
||||||
|
error_msg = _(u'Wrong password')
|
||||||
|
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||||
|
elif e.msg == 'Internal server error':
|
||||||
|
error_msg = _(u'Internal server error')
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
else:
|
else:
|
||||||
sub_repo_id = seafile_api.create_virtual_repo(repo_id, path, name, name, username)
|
error_msg = _(u'Decrypt library error')
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
result['sub_repo_id'] = sub_repo_id
|
# create sub-lib for encrypted repo
|
||||||
except SearpcError, e:
|
try:
|
||||||
result['error'] = e.msg
|
if is_org_context(request):
|
||||||
return HttpResponse(json.dumps(result), status=500, content_type=json_content_type)
|
org_id = request.user.org.org_id
|
||||||
|
sub_repo_id = seafile_api.create_org_virtual_repo(
|
||||||
|
org_id, repo_id, path, name, name, username, password)
|
||||||
|
else:
|
||||||
|
sub_repo_id = seafile_api.create_virtual_repo(
|
||||||
|
repo_id, path, name, name, username, password)
|
||||||
|
except SearpcError as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
else:
|
||||||
|
# create sub-lib for common repo
|
||||||
|
try:
|
||||||
|
if is_org_context(request):
|
||||||
|
org_id = request.user.org.org_id
|
||||||
|
sub_repo_id = seafile_api.create_org_virtual_repo(
|
||||||
|
org_id, repo_id, path, name, name, username)
|
||||||
|
else:
|
||||||
|
sub_repo_id = seafile_api.create_virtual_repo(
|
||||||
|
repo_id, path, name, name, username)
|
||||||
|
except SearpcError as e:
|
||||||
|
logger.error(e)
|
||||||
|
error_msg = 'Internal Server Error'
|
||||||
|
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
|
||||||
|
|
||||||
return HttpResponse(json.dumps(result), content_type=json_content_type)
|
return Response({'sub_repo_id': sub_repo_id})
|
||||||
|
|
||||||
########## Sharing
|
########## Sharing
|
||||||
class SharedRepos(APIView):
|
class SharedRepos(APIView):
|
||||||
|
118
tests/api/test_dir_sub_repo.py
Normal file
118
tests/api/test_dir_sub_repo.py
Normal file
@@ -0,0 +1,118 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
from django.core.urlresolvers import reverse
|
||||||
|
|
||||||
|
from seaserv import seafile_api
|
||||||
|
from seahub.test_utils import BaseTestCase
|
||||||
|
from tests.common.utils import randstring
|
||||||
|
|
||||||
|
try:
|
||||||
|
from seahub.settings import LOCAL_PRO_DEV_ENV
|
||||||
|
except ImportError:
|
||||||
|
LOCAL_PRO_DEV_ENV = False
|
||||||
|
|
||||||
|
class DirSubRepoViewTest(BaseTestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.user_name = self.user.username
|
||||||
|
self.user_repo_id = self.repo.id
|
||||||
|
self.user_folder_path = self.folder
|
||||||
|
self.user_folder_name = os.path.basename(self.folder.rstrip('/'))
|
||||||
|
|
||||||
|
self.admin_name = self.admin.username
|
||||||
|
|
||||||
|
self.url = reverse("api2-dir-sub-repo", args=[self.user_repo_id])
|
||||||
|
|
||||||
|
def tearDown(self):
|
||||||
|
self.remove_repo()
|
||||||
|
|
||||||
|
def test_can_create_dir_sub_repo(self):
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
|
||||||
|
resp = self.client.get(self.url + args)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['sub_repo_id']) == 36
|
||||||
|
|
||||||
|
def test_can_create_in_encrypted_lib(self):
|
||||||
|
|
||||||
|
password = randstring(8)
|
||||||
|
encrypted_repo_id = seafile_api.create_repo(
|
||||||
|
'encrypted_repo_name', '', self.user_name, password)
|
||||||
|
|
||||||
|
dirname = randstring(8)
|
||||||
|
seafile_api.post_dir(repo_id=encrypted_repo_id,
|
||||||
|
parent_dir='/', dirname=dirname, username=self.user_name)
|
||||||
|
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
url = reverse("api2-dir-sub-repo", args=[encrypted_repo_id])
|
||||||
|
args = "?p=/%s&name=%s&password=%s" % (dirname, dirname, password)
|
||||||
|
resp = self.client.get(url + args)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['sub_repo_id']) == 36
|
||||||
|
|
||||||
|
self.remove_repo(encrypted_repo_id)
|
||||||
|
|
||||||
|
def test_create_in_encrypted_lib_with_invalid_password(self):
|
||||||
|
|
||||||
|
password = randstring(8)
|
||||||
|
encrypted_repo_id = seafile_api.create_repo(
|
||||||
|
'encrypted_repo_name', '', self.user_name, password)
|
||||||
|
|
||||||
|
dirname = randstring(8)
|
||||||
|
seafile_api.post_dir(repo_id=encrypted_repo_id,
|
||||||
|
parent_dir='/', dirname=dirname, username=self.user_name)
|
||||||
|
|
||||||
|
self.login_as(self.user)
|
||||||
|
|
||||||
|
url = reverse("api2-dir-sub-repo", args=[encrypted_repo_id])
|
||||||
|
|
||||||
|
# test invalid password argument
|
||||||
|
args = "?p=/%s&name=%s&invalid_password=%s" % (dirname, dirname, password)
|
||||||
|
resp = self.client.get(url + args)
|
||||||
|
self.assertEqual(400, resp.status_code)
|
||||||
|
|
||||||
|
# test wrong password
|
||||||
|
args = "?p=/%s&name=%s&password=%s" % (dirname, dirname, 'invalid_password')
|
||||||
|
resp = self.client.get(url + args)
|
||||||
|
self.assertEqual(400, resp.status_code)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert json_resp['error_msg'] == 'Wrong password'
|
||||||
|
|
||||||
|
self.remove_repo(encrypted_repo_id)
|
||||||
|
|
||||||
|
def test_create_with_invalid_repo_permission(self):
|
||||||
|
self.login_as(self.admin)
|
||||||
|
|
||||||
|
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
|
||||||
|
resp = self.client.get(self.url + args)
|
||||||
|
self.assertEqual(403, resp.status_code)
|
||||||
|
|
||||||
|
def test_create_with_r_permission_folder(self):
|
||||||
|
|
||||||
|
if not LOCAL_PRO_DEV_ENV:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set_user_folder_r_permission_to_admin()
|
||||||
|
|
||||||
|
self.login_as(self.admin)
|
||||||
|
|
||||||
|
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
|
||||||
|
resp = self.client.get(self.url + args)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['sub_repo_id']) == 36
|
||||||
|
|
||||||
|
def test_create_with_rw_permission_folder(self):
|
||||||
|
|
||||||
|
if not LOCAL_PRO_DEV_ENV:
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set_user_folder_r_permission_to_admin()
|
||||||
|
|
||||||
|
self.login_as(self.admin)
|
||||||
|
|
||||||
|
args = "?p=%s&name=%s" % (self.user_folder_path, self.user_folder_name)
|
||||||
|
resp = self.client.get(self.url + args)
|
||||||
|
json_resp = json.loads(resp.content)
|
||||||
|
assert len(json_resp['sub_repo_id']) == 36
|
Reference in New Issue
Block a user