diff --git a/seahub/api2/endpoints/share_link_zip_task.py b/seahub/api2/endpoints/share_link_zip_task.py index b663cb75b4..769e1158cf 100644 --- a/seahub/api2/endpoints/share_link_zip_task.py +++ b/seahub/api2/endpoints/share_link_zip_task.py @@ -85,6 +85,11 @@ class ShareLinkZipTaskView(APIView): error_msg = 'Folder %s not found.' % real_path return api_error(status.HTTP_404_NOT_FOUND, error_msg) + if not seafile_api.check_permission_by_path(repo_id, '/', + fileshare.username): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + # get file server access token dir_name = repo.name if real_path == '/' else \ os.path.basename(real_path.rstrip('/')) diff --git a/seahub/api2/endpoints/upload_links.py b/seahub/api2/endpoints/upload_links.py index e5dc2116e2..53c8ddead9 100644 --- a/seahub/api2/endpoints/upload_links.py +++ b/seahub/api2/endpoints/upload_links.py @@ -257,6 +257,11 @@ class UploadLinkUpload(APIView): error_msg = 'Folder %s not found.' % path return api_error(status.HTTP_404_NOT_FOUND, error_msg) + if repo.encrypted or \ + seafile_api.check_permission_by_path(repo_id, '/', uls.username) != 'rw': + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + token = seafile_api.get_fileserver_access_token(repo_id, dir_id, 'upload', uls.username, use_onetime=False) diff --git a/seahub/views/ajax.py b/seahub/views/ajax.py index 5de0c0588b..c41704689a 100644 --- a/seahub/views/ajax.py +++ b/seahub/views/ajax.py @@ -1061,12 +1061,23 @@ def get_file_upload_url_ul(request, token): return HttpResponse(json.dumps({"error": _("Bad upload link token.")}), status=400, content_type=content_type) + shared_by = uls.username repo_id = uls.repo_id r = request.GET.get('r', '') if repo_id != r: # perm check return HttpResponse(json.dumps({"error": _("Bad repo id in upload link.")}), status=403, content_type=content_type) + repo = get_repo(repo_id) + if not repo: + return HttpResponse(json.dumps({"error": _("Library does not exist")}), + status=404, content_type=content_type) + + if repo.encrypted or \ + seafile_api.check_permission_by_path(repo_id, '/', shared_by) != 'rw': + return HttpResponse(json.dumps({"error": _("Permission denied")}), + status=403, content_type=content_type) + username = request.user.username or request.session.get('anonymous_email') or '' args = [repo_id, json.dumps({'anonymous_user': username}), 'upload', ''] diff --git a/seahub/views/file.py b/seahub/views/file.py index ea908c57e0..dae8de6ca9 100644 --- a/seahub/views/file.py +++ b/seahub/views/file.py @@ -852,6 +852,9 @@ def view_shared_file(request, fileshare): if not obj_id: return render_error(request, _(u'File does not exist')) + if not seafile_api.check_permission_by_path(repo_id, '/', shared_by): + return render_error(request, _(u'Permission denied')) + filename = os.path.basename(path) filetype, fileext = get_file_type_and_ext(filename) @@ -990,6 +993,10 @@ def view_raw_shared_file(request, token, obj_id, file_name): if real_obj_id != obj_id: # perm check raise Http404 + if not seafile_api.check_permission_by_path(repo_id, '/', + fileshare.username): + return render_error(request, _(u'Permission denied')) + filename = os.path.basename(file_path) username = request.user.username token = seafile_api.get_fileserver_access_token(repo_id, @@ -1018,13 +1025,6 @@ def view_file_via_shared_dir(request, fileshare): return render_to_response('share_access_validation.html', d, context_instance=RequestContext(request)) - if request.GET.get('dl', '') == '1': - if fileshare.get_permissions()['can_download'] is False: - raise Http404 - - # download shared file - return _download_file_from_share_link(request, fileshare) - shared_by = fileshare.username repo_id = fileshare.repo_id repo = get_repo(repo_id) @@ -1045,6 +1045,16 @@ def view_file_via_shared_dir(request, fileshare): if not obj_id: return render_error(request, _(u'File does not exist')) + if not seafile_api.check_permission_by_path(repo_id, '/', shared_by): + return render_error(request, _(u'Permission denied')) + + if request.GET.get('dl', '') == '1': + if fileshare.get_permissions()['can_download'] is False: + raise Http404 + + # download shared file + return _download_file_from_share_link(request, fileshare) + filename = os.path.basename(req_path) if request.GET.get('raw', '0') == '1': if fileshare.get_permissions()['can_download'] is False: diff --git a/seahub/views/repo.py b/seahub/views/repo.py index ae07745866..e2742af9cd 100644 --- a/seahub/views/repo.py +++ b/seahub/views/repo.py @@ -195,7 +195,8 @@ def view_shared_dir(request, fileshare): if not repo: raise Http404 - if repo.encrypted: + if repo.encrypted or not \ + seafile_api.check_permission_by_path(repo_id, '/', username): return render_error(request, _(u'Permission denied')) # Check path still exist, otherwise show error @@ -292,6 +293,10 @@ def view_shared_upload_link(request, uploadlink): if not repo: raise Http404 + if repo.encrypted or \ + seafile_api.check_permission_by_path(repo_id, '/', username) != 'rw': + return render_error(request, _(u'Permission denied')) + uploadlink.view_cnt = F('view_cnt') + 1 uploadlink.save() diff --git a/tests/api/endpoints/test_upload_links.py b/tests/api/endpoints/test_upload_links.py index 322ed9bc7a..98534e9c59 100644 --- a/tests/api/endpoints/test_upload_links.py +++ b/tests/api/endpoints/test_upload_links.py @@ -6,6 +6,8 @@ from django.core.urlresolvers import reverse from tests.common.utils import upload_file_test, randstring +from seaserv import seafile_api + from seahub.test_utils import BaseTestCase from seahub.share.models import UploadLinkShare from seahub.api2.permissions import CanGenerateUploadLink @@ -18,6 +20,8 @@ except ImportError: class UploadLinksTest(BaseTestCase): def setUp(self): + self.user_name = self.user.username + self.admin_name = self.admin.username self.repo_id = self.repo.id self.folder_path= self.folder self.url = reverse('api-v2.1-upload-links') @@ -26,8 +30,8 @@ class UploadLinksTest(BaseTestCase): self.remove_repo() def _add_upload_link(self): - upload_link = UploadLinkShare.objects.create_upload_link_share(self.user.username, - self.repo.id, self.folder, None, None) + upload_link = UploadLinkShare.objects.create_upload_link_share(self.user_name, + self.repo_id, self.folder_path, None, None) return upload_link.token @@ -172,6 +176,8 @@ class UploadLinkUploadTest(BaseTestCase): def setUp(self): + self.user_name = self.user.username + self.admin_name = self.admin.username self.repo_id = self.repo.id self.folder_path= self.folder self.invalid_token = '00000000000000000000' @@ -179,7 +185,7 @@ class UploadLinkUploadTest(BaseTestCase): def _add_upload_link(self, password=None): fs = UploadLinkShare.objects.create_upload_link_share( - self.user.username, self.repo.id, self.folder_path, password, None) + self.user_name, self.repo_id, self.folder_path, password, None) return fs.token @@ -219,3 +225,26 @@ class UploadLinkUploadTest(BaseTestCase): url = reverse('api-v2.1-upload-link-upload', args=[token]) resp = self.client.get(url) self.assertEqual(403, resp.status_code) + + def test_can_not_get_upload_link_with_invalid_creator_repo_permission(self): + + # user share repo to admin + seafile_api.share_repo(self.repo_id, self.user_name, self.admin_name, 'rw') + + # admin create upload link + upload_link = UploadLinkShare.objects.create_upload_link_share( + self.admin_name, self.repo_id, '/', None, None) + token = upload_link.token + + # can get url for upload file + url = reverse('api-v2.1-upload-link-upload', args=[token]) + resp = self.client.get(url) + self.assertEqual(200, resp.status_code) + + # user unshare repo + seafile_api.remove_share(self.repo_id, self.user_name, self.admin_name) + + # can not get url for upload file + url = reverse('api-v2.1-upload-link-upload', args=[token]) + resp = self.client.get(url) + self.assertEqual(403, resp.status_code)