From b65547c3afcbefd0dc7fbe0687879027fec9e9a5 Mon Sep 17 00:00:00 2001 From: lian Date: Sat, 5 Jan 2019 11:59:36 +0800 Subject: [PATCH 1/5] remove unused filed (#2763) root, desc, magic, enc_version, repaired and random_key --- seahub/api2/views.py | 7 ------- seahub/utils/__init__.py | 2 -- 2 files changed, 9 deletions(-) diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 3cb7a7d8c7..36161e8506 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -988,7 +988,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), @@ -998,12 +997,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) @@ -4525,7 +4519,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, diff --git a/seahub/utils/__init__.py b/seahub/utils/__init__.py index f5546ebf79..ed7d024c2b 100644 --- a/seahub/utils/__init__.py +++ b/seahub/utils/__init__.py @@ -326,7 +326,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, @@ -342,7 +341,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) From 71228ae651bdbd3cc9ebf0510514d86174391458 Mon Sep 17 00:00:00 2001 From: lian Date: Mon, 7 Jan 2019 16:50:27 +0800 Subject: [PATCH 2/5] add update share link permission api (#2761) --- seahub/api2/endpoints/share_links.py | 107 +++++++++++------- tests/api/endpoints/test_share_links.py | 140 +++++++++++++++++++++++- 2 files changed, 205 insertions(+), 42 deletions(-) diff --git a/seahub/api2/endpoints/share_links.py b/seahub/api2/endpoints/share_links.py index 334df68465..412231f6da 100644 --- a/seahub/api2/endpoints/share_links.py +++ b/seahub/api2/endpoints/share_links.py @@ -78,6 +78,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) @@ -96,45 +135,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. @@ -244,7 +244,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) @@ -319,6 +319,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. diff --git a/tests/api/endpoints/test_share_links.py b/tests/api/endpoints/test_share_links.py index 16ac2cc5f2..2ce3259c11 100644 --- a/tests/api/endpoints/test_share_links.py +++ b/tests/api/endpoints/test_share_links.py @@ -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) From 7b70adaa6db11fa51283fadc1e774e6f91179e60 Mon Sep 17 00:00:00 2001 From: lian Date: Wed, 9 Jan 2019 15:11:17 +0800 Subject: [PATCH 3/5] update dir detail (#2796) remove file_count, dir_count and size field --- seahub/api2/endpoints/dir.py | 4 ---- seahub/templates/js/templates.html | 13 ------------- static/scripts/app/views/dirent-details.js | 3 --- tests/api/endpoints/test_dir_view.py | 2 -- 4 files changed, 22 deletions(-) diff --git a/seahub/api2/endpoints/dir.py b/seahub/api2/endpoints/dir.py index 6999614f6c..144ac6a61c 100644 --- a/seahub/api2/endpoints/dir.py +++ b/seahub/api2/endpoints/dir.py @@ -356,7 +356,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' @@ -366,9 +365,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), } diff --git a/seahub/templates/js/templates.html b/seahub/templates/js/templates.html index 781d4bd5b8..e975b8a9f6 100644 --- a/seahub/templates/js/templates.html +++ b/seahub/templates/js/templates.html @@ -1118,19 +1118,6 @@ - - {% trans "Folders" %} - - - - {% trans "Files" %} - - - - {% trans "Size" %} - - - {% trans "Location" %} <%- path %> diff --git a/static/scripts/app/views/dirent-details.js b/static/scripts/app/views/dirent-details.js index c751f799e6..72160a339e 100644 --- a/static/scripts/app/views/dirent-details.js +++ b/static/scripts/app/views/dirent-details.js @@ -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(); } }, diff --git a/tests/api/endpoints/test_dir_view.py b/tests/api/endpoints/test_dir_view.py index ee226829b7..d8564287ad 100644 --- a/tests/api/endpoints/test_dir_view.py +++ b/tests/api/endpoints/test_dir_view.py @@ -394,8 +394,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): From 485b9c8e6ff8936f51c2cd5c7f09518fcda2efe9 Mon Sep 17 00:00:00 2001 From: zhengxie Date: Fri, 11 Jan 2019 11:01:42 +0800 Subject: [PATCH 4/5] [api2] Fix search per_page argument --- seahub/api2/views.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/seahub/api2/views.py b/seahub/api2/views.py index 36161e8506..486b04fa2b 100644 --- a/seahub/api2/views.py +++ b/seahub/api2/views.py @@ -374,6 +374,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 From 0104f29ff1695e3d864db0def5bd427460a6ff9a Mon Sep 17 00:00:00 2001 From: lian Date: Sat, 19 Jan 2019 12:32:47 +0800 Subject: [PATCH 5/5] add RESUMABLE_UPLOAD_FILE_BLOCK_SIZE setting (#2744) --- seahub/settings.py | 1 + seahub/templates/libraries.html | 1 + seahub/views/__init__.py | 1 + static/scripts/app/views/fileupload.js | 2 +- 4 files changed, 4 insertions(+), 1 deletion(-) diff --git a/seahub/settings.py b/seahub/settings.py index b099df210d..1ecc4e78e0 100644 --- a/seahub/settings.py +++ b/seahub/settings.py @@ -297,6 +297,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 diff --git a/seahub/templates/libraries.html b/seahub/templates/libraries.html index 7e548db695..5b7c0756cc 100644 --- a/seahub/templates/libraries.html +++ b/seahub/templates/libraries.html @@ -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 }}, diff --git a/seahub/views/__init__.py b/seahub/views/__init__.py index 10bc391495..65b367fc15 100644 --- a/seahub/views/__init__.py +++ b/seahub/views/__init__.py @@ -713,6 +713,7 @@ def libraries(request): 'enable_wiki': settings.ENABLE_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, diff --git a/static/scripts/app/views/fileupload.js b/static/scripts/app/views/fileupload.js index 9d55429ee6..bd4622919f 100644 --- a/static/scripts/app/views/fileupload.js +++ b/static/scripts/app/views/fileupload.js @@ -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);