mirror of
https://github.com/haiwen/seahub.git
synced 2025-05-12 18:05:05 +00:00
Merge branch '6.3'
This commit is contained in:
commit
d772dba34b
@ -502,7 +502,6 @@ class DirDetailView(APIView):
|
||||
|
||||
try:
|
||||
dir_obj = seafile_api.get_dirent_by_path(repo_id, path)
|
||||
count_info = seafile_api.get_file_count_info_by_path(repo_id, path)
|
||||
except SearpcError as e:
|
||||
logger.error(e)
|
||||
error_msg = 'Internal Server Error'
|
||||
@ -512,9 +511,6 @@ class DirDetailView(APIView):
|
||||
'repo_id': repo_id,
|
||||
'path': path,
|
||||
'name': dir_obj.obj_name,
|
||||
'file_count': count_info.file_count,
|
||||
'dir_count': count_info.dir_count,
|
||||
'size': count_info.size,
|
||||
'mtime': timestamp_to_isoformat_timestr(dir_obj.mtime),
|
||||
}
|
||||
|
||||
|
@ -77,6 +77,45 @@ def get_share_link_info(fileshare):
|
||||
data['permissions'] = fileshare.get_permissions()
|
||||
return data
|
||||
|
||||
def check_permissions_arg(request):
|
||||
permissions = request.data.get('permissions', None)
|
||||
if permissions is not None:
|
||||
if isinstance(permissions, dict):
|
||||
perm_dict = permissions
|
||||
elif isinstance(permissions, basestring):
|
||||
import json
|
||||
try:
|
||||
perm_dict = json.loads(permissions)
|
||||
except ValueError:
|
||||
error_msg = 'permissions invalid: %s' % permissions
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
else:
|
||||
error_msg = 'permissions invalid: %s' % permissions
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
else:
|
||||
perm_dict = None
|
||||
|
||||
can_download = True
|
||||
can_edit = False
|
||||
|
||||
if perm_dict is not None:
|
||||
can_download = perm_dict.get('can_download', True)
|
||||
can_edit = perm_dict.get('can_edit', False)
|
||||
|
||||
if not can_edit and can_download:
|
||||
perm = FileShare.PERM_VIEW_DL
|
||||
|
||||
if not can_edit and not can_download:
|
||||
perm = FileShare.PERM_VIEW_ONLY
|
||||
|
||||
if can_edit and can_download:
|
||||
perm = FileShare.PERM_EDIT_DL
|
||||
|
||||
if can_edit and not can_download:
|
||||
perm = FileShare.PERM_EDIT_ONLY
|
||||
|
||||
return perm
|
||||
|
||||
class ShareLinks(APIView):
|
||||
|
||||
authentication_classes = (TokenAuthentication, SessionAuthentication)
|
||||
@ -95,45 +134,6 @@ class ShareLinks(APIView):
|
||||
|
||||
return (None, None)
|
||||
|
||||
def _check_permissions_arg(self, request):
|
||||
permissions = request.data.get('permissions', None)
|
||||
if permissions is not None:
|
||||
if isinstance(permissions, dict):
|
||||
perm_dict = permissions
|
||||
elif isinstance(permissions, basestring):
|
||||
import json
|
||||
try:
|
||||
perm_dict = json.loads(permissions)
|
||||
except ValueError:
|
||||
error_msg = 'permissions invalid: %s' % permissions
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
else:
|
||||
error_msg = 'permissions invalid: %s' % permissions
|
||||
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
|
||||
else:
|
||||
perm_dict = None
|
||||
|
||||
can_download = True
|
||||
can_edit = False
|
||||
|
||||
if perm_dict is not None:
|
||||
can_download = perm_dict.get('can_download', True)
|
||||
can_edit = perm_dict.get('can_edit', False)
|
||||
|
||||
if not can_edit and can_download:
|
||||
perm = FileShare.PERM_VIEW_DL
|
||||
|
||||
if not can_edit and not can_download:
|
||||
perm = FileShare.PERM_VIEW_ONLY
|
||||
|
||||
if can_edit and can_download:
|
||||
perm = FileShare.PERM_EDIT_DL
|
||||
|
||||
if can_edit and not can_download:
|
||||
perm = FileShare.PERM_EDIT_ONLY
|
||||
|
||||
return perm
|
||||
|
||||
def get(self, request):
|
||||
""" Get all share links of a user.
|
||||
|
||||
@ -243,7 +243,7 @@ class ShareLinks(APIView):
|
||||
else:
|
||||
expire_date = timezone.now() + relativedelta(days=expire_days)
|
||||
|
||||
perm = self._check_permissions_arg(request)
|
||||
perm = check_permissions_arg(request)
|
||||
|
||||
# resource check
|
||||
repo = seafile_api.get_repo(repo_id)
|
||||
@ -317,6 +317,33 @@ class ShareLink(APIView):
|
||||
link_info = get_share_link_info(fs)
|
||||
return Response(link_info)
|
||||
|
||||
def put(self, request, token):
|
||||
""" Update share link, currently only available for permission.
|
||||
|
||||
Permission checking:
|
||||
share link creater
|
||||
"""
|
||||
|
||||
try:
|
||||
fs = FileShare.objects.get(token=token)
|
||||
except FileShare.DoesNotExist:
|
||||
error_msg = 'token %s not found.' % token
|
||||
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
|
||||
|
||||
username = request.user.username
|
||||
if not fs.is_owner(username):
|
||||
error_msg = 'Permission denied.'
|
||||
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
|
||||
|
||||
permissions = request.data.get('permissions', None)
|
||||
if permissions:
|
||||
perm = check_permissions_arg(request)
|
||||
fs.permission = perm
|
||||
fs.save()
|
||||
|
||||
link_info = get_share_link_info(fs)
|
||||
return Response(link_info)
|
||||
|
||||
def delete(self, request, token):
|
||||
""" Delete share link.
|
||||
|
||||
|
@ -427,6 +427,8 @@ class Search(APIView):
|
||||
try:
|
||||
current_page = int(request.GET.get('page', '1'))
|
||||
per_page = int(request.GET.get('per_page', '10'))
|
||||
if per_page > 100:
|
||||
per_page = 100
|
||||
except ValueError:
|
||||
current_page = 1
|
||||
per_page = 10
|
||||
@ -1050,7 +1052,6 @@ class PubRepos(APIView):
|
||||
repo = {
|
||||
"id": r.repo_id,
|
||||
"name": r.repo_name,
|
||||
"desc": r.repo_desc,
|
||||
"owner": r.user,
|
||||
"owner_nickname": email2nickname(r.user),
|
||||
"owner_name": email2nickname(r.user),
|
||||
@ -1060,12 +1061,7 @@ class PubRepos(APIView):
|
||||
"size_formatted": filesizeformat(r.size),
|
||||
"encrypted": r.encrypted,
|
||||
"permission": r.permission,
|
||||
"root": r.root,
|
||||
}
|
||||
if r.encrypted:
|
||||
repo["enc_version"] = r.enc_version
|
||||
repo["magic"] = r.magic
|
||||
repo["random_key"] = r.random_key
|
||||
repos_json.append(repo)
|
||||
|
||||
return Response(repos_json)
|
||||
@ -4714,7 +4710,6 @@ class GroupRepos(APIView):
|
||||
repo = {
|
||||
"id": r.id,
|
||||
"name": r.name,
|
||||
"desc": r.desc,
|
||||
"size": r.size,
|
||||
"size_formatted": filesizeformat(r.size),
|
||||
"mtime": r.last_modified,
|
||||
|
@ -301,6 +301,7 @@ ENABLE_UPLOAD_FOLDER = True
|
||||
|
||||
# enable resumable fileupload or not
|
||||
ENABLE_RESUMABLE_FILEUPLOAD = False
|
||||
RESUMABLE_UPLOAD_FILE_BLOCK_SIZE = 8
|
||||
|
||||
## maxNumberOfFiles for fileupload
|
||||
MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD = 1000
|
||||
|
@ -1148,19 +1148,6 @@
|
||||
<th width="35%"></th>
|
||||
<td width="65%"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Folders" %}</th>
|
||||
<td class="dir-folder-counts"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Files" %}</th>
|
||||
<td class="dir-file-counts"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th>{% trans "Size" %}</th>
|
||||
<td class="dir-size"></td>
|
||||
</tr>
|
||||
|
||||
<tr>
|
||||
<th>{% trans "Location" %}</th>
|
||||
<td><%- path %></td>
|
||||
|
@ -285,6 +285,7 @@ app["pageOptions"] = {
|
||||
enable_wiki: {% if enable_wiki %} true {% else %} false {% endif %},
|
||||
enable_upload_folder: {% if enable_upload_folder %} true {% else %} false {% endif %},
|
||||
enable_resumable_fileupload: {% if enable_resumable_fileupload %} true {% else %} false {% endif %},
|
||||
resumable_upload_file_block_size: {{ resumable_upload_file_block_size }},
|
||||
max_number_of_files_for_fileupload: {{ max_number_of_files_for_fileupload }},
|
||||
enable_thumbnail: {% if enable_thumbnail %} true {% else %} false {% endif %},
|
||||
thumbnail_default_size: {{ thumbnail_default_size }},
|
||||
|
@ -353,7 +353,6 @@ def get_user_repos(username, org_id=None):
|
||||
# repos.
|
||||
r.id = r.repo_id
|
||||
r.name = r.repo_name
|
||||
r.desc = r.repo_desc
|
||||
r.last_modify = r.last_modified
|
||||
else:
|
||||
owned_repos = seafile_api.get_org_owned_repo_list(org_id,
|
||||
@ -369,7 +368,6 @@ def get_user_repos(username, org_id=None):
|
||||
# repos.
|
||||
r.id = r.repo_id
|
||||
r.name = r.repo_name
|
||||
r.desc = r.repo_desc
|
||||
r.last_modify = r.last_modified
|
||||
|
||||
return (owned_repos, shared_repos, groups_repos, public_repos)
|
||||
|
@ -720,6 +720,7 @@ def libraries(request):
|
||||
'enable_wiki': request.user.permissions.can_use_wiki(),
|
||||
'enable_upload_folder': settings.ENABLE_UPLOAD_FOLDER,
|
||||
'enable_resumable_fileupload': settings.ENABLE_RESUMABLE_FILEUPLOAD,
|
||||
'resumable_upload_file_block_size': settings.RESUMABLE_UPLOAD_FILE_BLOCK_SIZE,
|
||||
'max_number_of_files_for_fileupload': settings.MAX_NUMBER_OF_FILES_FOR_FILEUPLOAD,
|
||||
'enable_thumbnail': settings.ENABLE_THUMBNAIL,
|
||||
'enable_repo_snapshot_label': settings.ENABLE_REPO_SNAPSHOT_LABEL,
|
||||
|
@ -49,9 +49,6 @@ define([
|
||||
if (part_data.error_msg) {
|
||||
$('.error', $container).html(part_data.error_msg).show();
|
||||
} else {
|
||||
this.$('.dir-folder-counts').html(part_data.dir_count);
|
||||
this.$('.dir-file-counts').html(part_data.file_count);
|
||||
this.$('.dir-size').html(part_data.size);
|
||||
$('table', $container).show();
|
||||
}
|
||||
},
|
||||
|
@ -192,7 +192,7 @@ define([
|
||||
data.jqXHR = popup.fileupload('send', data);
|
||||
|
||||
} else {
|
||||
var block_size = 1024 * 1024;
|
||||
var block_size = app.pageOptions.resumable_upload_file_block_size * 1024 * 1024;
|
||||
if (enable_resumable_fileupload &&
|
||||
file.size && file.size > block_size) {
|
||||
popup.fileupload('option', 'maxChunkSize', block_size);
|
||||
|
@ -616,8 +616,6 @@ class DirDetailViewTest(BaseTestCase):
|
||||
json_resp = json.loads(resp.content)
|
||||
|
||||
assert json_resp['name'] == self.folder_name
|
||||
assert json_resp['file_count'] == 1
|
||||
assert json_resp['dir_count'] == 1
|
||||
|
||||
def test_get_dir_detail_with_invalid_perm(self):
|
||||
|
||||
|
@ -2,12 +2,12 @@
|
||||
import json
|
||||
|
||||
from mock import patch
|
||||
from seaserv import seafile_api
|
||||
from django.core.urlresolvers import reverse
|
||||
|
||||
from seahub.test_utils import BaseTestCase
|
||||
from seahub.share.models import FileShare
|
||||
from seahub.api2.permissions import CanGenerateShareLink
|
||||
from seahub.utils import gen_token
|
||||
|
||||
try:
|
||||
from seahub.settings import LOCAL_PRO_DEV_ENV
|
||||
@ -41,7 +41,7 @@ class ShareLinksTest(BaseTestCase):
|
||||
link = FileShare.objects.get(token=token)
|
||||
link.delete()
|
||||
|
||||
def test_get_file_share_link(self):
|
||||
def test_get_file_share_links(self):
|
||||
self.login_as(self.user)
|
||||
token = self._add_file_share_link()
|
||||
|
||||
@ -309,3 +309,139 @@ class ShareLinksTest(BaseTestCase):
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.delete(url, {}, 'application/x-www-form-urlencoded')
|
||||
self.assertEqual(403, resp.status_code)
|
||||
|
||||
|
||||
class ShareLinkTest(BaseTestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.repo_id = self.repo.id
|
||||
self.file_path= self.file
|
||||
|
||||
def tearDown(self):
|
||||
self.remove_repo()
|
||||
|
||||
def _remove_share_link(self, token):
|
||||
link = FileShare.objects.get(token=token)
|
||||
link.delete()
|
||||
|
||||
def test_get_file_share_link(self):
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
# create a share link first
|
||||
json_str = json.dumps({'path': self.file_path, 'repo_id': self.repo_id})
|
||||
url = reverse('api-v2.1-share-links')
|
||||
resp = self.client.post(url, json_str,
|
||||
content_type="application/json")
|
||||
json_resp = json.loads(resp.content)
|
||||
token = json_resp['token']
|
||||
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['token'] == token
|
||||
|
||||
self._remove_share_link(token)
|
||||
|
||||
def test_get_file_share_link_with_invalid_token(self):
|
||||
|
||||
self.login_as(self.user)
|
||||
invalid_token = gen_token(max_length=20)
|
||||
url = reverse('api-v2.1-share-link', args=[invalid_token])
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(404, resp.status_code)
|
||||
|
||||
def test_update_file_share_link_permissions(self):
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
# create a share link first
|
||||
# all True
|
||||
json_str = json.dumps({'path': self.file_path, 'repo_id': self.repo_id,
|
||||
'permissions': {
|
||||
'can_edit': True,
|
||||
'can_download': True
|
||||
}})
|
||||
url = reverse('api-v2.1-share-links')
|
||||
resp = self.client.post(url, json_str,
|
||||
content_type="application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['permissions']['can_edit'] == True
|
||||
assert json_resp['permissions']['can_download'] == True
|
||||
|
||||
token = json_resp['token']
|
||||
|
||||
# update share link permission
|
||||
# all False
|
||||
json_str = json.dumps({'permissions': {'can_edit': False, 'can_download': False}})
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.put(url, json_str,
|
||||
content_type="application/json")
|
||||
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['token'] == token
|
||||
assert json_resp['permissions']['can_edit'] == False
|
||||
assert json_resp['permissions']['can_download'] == False
|
||||
|
||||
self._remove_share_link(token)
|
||||
|
||||
def test_update_file_share_link_permission_if_not_creator(self):
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
# create a share link first
|
||||
# all True
|
||||
json_str = json.dumps({'path': self.file_path, 'repo_id': self.repo_id,
|
||||
'permissions': {
|
||||
'can_edit': True,
|
||||
'can_download': True
|
||||
}})
|
||||
url = reverse('api-v2.1-share-links')
|
||||
resp = self.client.post(url, json_str,
|
||||
content_type="application/json")
|
||||
self.assertEqual(200, resp.status_code)
|
||||
json_resp = json.loads(resp.content)
|
||||
assert json_resp['permissions']['can_edit'] == True
|
||||
assert json_resp['permissions']['can_download'] == True
|
||||
|
||||
token = json_resp['token']
|
||||
|
||||
self.logout()
|
||||
self.login_as(self.admin)
|
||||
|
||||
# update share link permission
|
||||
# all False
|
||||
json_str = json.dumps({'permissions': {'can_edit': False, 'can_download': False}})
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.put(url, json_str,
|
||||
content_type="application/json")
|
||||
|
||||
self.assertEqual(403, resp.status_code)
|
||||
self._remove_share_link(token)
|
||||
|
||||
def test_delete_file_share_link(self):
|
||||
|
||||
self.login_as(self.user)
|
||||
|
||||
# create a share link first
|
||||
json_str = json.dumps({'path': self.file_path, 'repo_id': self.repo_id})
|
||||
url = reverse('api-v2.1-share-links')
|
||||
resp = self.client.post(url, json_str,
|
||||
content_type="application/json")
|
||||
json_resp = json.loads(resp.content)
|
||||
token = json_resp['token']
|
||||
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.get(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
# delete share link
|
||||
url = reverse('api-v2.1-share-link', args=[token])
|
||||
resp = self.client.delete(url)
|
||||
self.assertEqual(200, resp.status_code)
|
||||
|
||||
assert not FileShare.objects.filter(token=token)
|
||||
|
Loading…
Reference in New Issue
Block a user