1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-08-02 07:47:32 +00:00

Merge pull request #2003 from haiwen/share-link-upload

add api for upload file via upload link foken
This commit is contained in:
xiez 2018-02-08 14:37:51 +08:00 committed by GitHub
commit 35b7d76c82
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 146 additions and 41 deletions

View File

@ -94,7 +94,7 @@ class AdminUploadLinkUpload(APIView):
throttle_classes = (UserRateThrottle,)
def get(self, request, token):
""" Get FileServer url of the shared file.
""" Get FileServer url of the shared folder.
Permission checking:
1. only admin can perform this action.

View File

@ -16,56 +16,57 @@ from pysearpc import SearpcError
from seahub.api2.utils import api_error
from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle
from seahub.api2.throttling import AnonRateThrottle, UserRateThrottle
from seahub.api2.permissions import CanGenerateUploadLink
from seahub.share.models import UploadLinkShare
from seahub.utils import gen_shared_upload_link
from seahub.utils import gen_shared_upload_link, gen_file_upload_url
from seahub.views import check_folder_permission
from seahub.utils.timeutils import datetime_to_isoformat_timestr
logger = logging.getLogger(__name__)
def get_upload_link_info(uls):
data = {}
token = uls.token
repo_id = uls.repo_id
try:
repo = seafile_api.get_repo(repo_id)
except Exception as e:
logger.error(e)
repo = None
path = uls.path
if path:
obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/'))
else:
obj_name = ''
if uls.ctime:
ctime = datetime_to_isoformat_timestr(uls.ctime)
else:
ctime = ''
data['repo_id'] = repo_id
data['repo_name'] = repo.repo_name if repo else ''
data['path'] = path
data['obj_name'] = obj_name
data['view_cnt'] = uls.view_cnt
data['ctime'] = ctime
data['link'] = gen_shared_upload_link(token)
data['token'] = token
data['username'] = uls.username
return data
class UploadLinks(APIView):
authentication_classes = (TokenAuthentication, SessionAuthentication)
permission_classes = (IsAuthenticated, CanGenerateUploadLink)
throttle_classes = (UserRateThrottle, )
def _get_upload_link_info(self, uls):
data = {}
token = uls.token
repo_id = uls.repo_id
try:
repo = seafile_api.get_repo(repo_id)
except Exception as e:
logger.error(e)
repo = None
path = uls.path
if path:
obj_name = '/' if path == '/' else os.path.basename(path.rstrip('/'))
else:
obj_name = ''
if uls.ctime:
ctime = datetime_to_isoformat_timestr(uls.ctime)
else:
ctime = ''
data['repo_id'] = repo_id
data['repo_name'] = repo.repo_name if repo else ''
data['path'] = path
data['obj_name'] = obj_name
data['view_cnt'] = uls.view_cnt
data['ctime'] = ctime
data['link'] = gen_shared_upload_link(token)
data['token'] = token
data['username'] = uls.username
return data
def get(self, request):
""" Get all upload links of a user.
@ -108,7 +109,7 @@ class UploadLinks(APIView):
result = []
for uls in upload_link_shares:
link_info = self._get_upload_link_info(uls)
link_info = get_upload_link_info(uls)
result.append(link_info)
if len(result) == 1:
@ -169,7 +170,7 @@ class UploadLinks(APIView):
uls = UploadLinkShare.objects.create_upload_link_share(username,
repo_id, path, password)
link_info = self._get_upload_link_info(uls)
link_info = get_upload_link_info(uls)
return Response(link_info)
class UploadLink(APIView):
@ -191,7 +192,7 @@ class UploadLink(APIView):
error_msg = 'token %s not found.' % token
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
link_info = self._get_upload_link_info(uls)
link_info = get_upload_link_info(uls)
return Response(link_info)
def delete(self, request, token):
@ -220,3 +221,49 @@ class UploadLink(APIView):
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True})
class UploadLinkUpload(APIView):
throttle_classes = (AnonRateThrottle, )
def get(self, request, token):
""" Get file upload url according to upload link token.
Permission checking:
1. anyone has the upload link token can perform this action;
"""
try:
uls = UploadLinkShare.objects.get(token=token)
except UploadLinkShare.DoesNotExist:
error_msg = 'token %s not found.' % token
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
# currently not support encrypted upload link
if uls.is_encrypted():
error_msg = 'Upload link %s is encrypted.' % token
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
repo_id = uls.repo_id
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)
path = uls.path
dir_id = seafile_api.get_dir_id_by_path(repo_id, path)
if not dir_id:
error_msg = 'Folder %s not found.' % path
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
token = seafile_api.get_fileserver_access_token(repo_id,
dir_id, 'upload', uls.username, use_onetime=False)
if not token:
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
result = {}
result['upload_link'] = gen_file_upload_url(token, 'upload-api')
return Response(result)

View File

@ -27,7 +27,8 @@ from seahub.api2.endpoints.search_group import SearchGroup
from seahub.api2.endpoints.share_links import ShareLinks, ShareLink
from seahub.api2.endpoints.shared_folders import SharedFolders
from seahub.api2.endpoints.shared_repos import SharedRepos, SharedRepo
from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink
from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink, \
UploadLinkUpload
from seahub.api2.endpoints.repos_batch import ReposBatchView, \
ReposBatchCopyDirView, ReposBatchCreateDirView
from seahub.api2.endpoints.repos import RepoView
@ -237,6 +238,7 @@ urlpatterns = patterns(
## user::shared-upload-links
url(r'^api/v2.1/upload-links/$', UploadLinks.as_view(), name='api-v2.1-upload-links'),
url(r'^api/v2.1/upload-links/(?P<token>[a-f0-9]+)/$', UploadLink.as_view(), name='api-v2.1-upload-link'),
url(r'^api/v2.1/upload-links/(?P<token>[a-f0-9]+)/upload/$', UploadLinkUpload.as_view(), name='api-v2.1-upload-link-upload'),
## user::revision-tags
url(r'^api/v2.1/revision-tags/tagged-items/$', TaggedItemsView.as_view(), name='api-v2.1-revision-tags-tagged-items'),

View File

@ -3,6 +3,9 @@ import json
from mock import patch
from django.core.urlresolvers import reverse
from tests.common.utils import upload_file_test, randstring
from seahub.test_utils import BaseTestCase
from seahub.share.models import UploadLinkShare
from seahub.api2.permissions import CanGenerateUploadLink
@ -163,3 +166,56 @@ class UploadLinksTest(BaseTestCase):
url = reverse('api-v2.1-upload-link', args=[token])
resp = self.client.delete(url, {}, 'application/x-www-form-urlencoded')
self.assertEqual(403, resp.status_code)
class UploadLinkUploadTest(BaseTestCase):
def setUp(self):
self.repo_id = self.repo.id
self.folder_path= self.folder
self.invalid_token = '00000000000000000000'
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)
return fs.token
def _remove_upload_link(self, token):
link = UploadLinkShare.objects.get(token=token)
link.delete()
def test_get_upload_link(self):
token = self._add_upload_link()
url = reverse('api-v2.1-upload-link-upload', args=[token])
resp = self.client.get(url)
self.assertEqual(200, resp.status_code)
json_resp = json.loads(resp.content)
assert '8082' in json_resp['upload_link']
assert 'upload' in json_resp['upload_link']
# test upload file via `upload_link`
upload_file_test(json_resp['upload_link'])
self._remove_upload_link(token)
def test_can_not_get_upload_link_with_invalid_token(self):
url = reverse('api-v2.1-upload-link-upload',
args=[self.invalid_token])
resp = self.client.get(url)
self.assertEqual(404, resp.status_code)
def test_can_not_get_upload_link_for_encrypted_upload_link_share(self):
token = self._add_upload_link(password=randstring(10))
url = reverse('api-v2.1-upload-link-upload', args=[token])
resp = self.client.get(url)
self.assertEqual(403, resp.status_code)