diff --git a/frontend/src/shared-dir-view.js b/frontend/src/shared-dir-view.js index 3086b53f7f..a93318c33d 100644 --- a/frontend/src/shared-dir-view.js +++ b/frontend/src/shared-dir-view.js @@ -527,7 +527,7 @@ class SharedDirView extends React.Component { 'parentDir': item.file_path.slice(0, item.file_path.indexOf(name)), 'thumbnail': `${siteRoot}thumbnail/${token}/${thumbnailSizeForOriginal}${Utils.encodePath(item.file_path)}`, 'src': src, - 'downloadURL': fileURL + '&dl=1', + 'downloadURL': fileURL + '&dl=1' }; }; diff --git a/seahub/api2/endpoints/internal_api.py b/seahub/api2/endpoints/internal_api.py index 7e87db0b13..64c08eb755 100644 --- a/seahub/api2/endpoints/internal_api.py +++ b/seahub/api2/endpoints/internal_api.py @@ -1,5 +1,6 @@ # Copyright (c) 2012-2016 Seafile Ltd. import logging +from django.contrib.sessions.backends.db import SessionStore from rest_framework import status from rest_framework.response import Response from rest_framework.views import APIView @@ -15,6 +16,7 @@ from seaserv import seafile_api from seahub.utils.repo import parse_repo_perm from seahub.views.file import send_file_access_msg from seahub.utils import normalize_file_path +from seahub.views import check_folder_permission logger = logging.getLogger(__name__) @@ -195,3 +197,60 @@ class InternalCheckFileOperationAccess(APIView): return api_error(status.HTTP_403_FORBIDDEN, error_msg) return Response({'user': rat.app_name}) + +class CheckThumbnailAccess(APIView): + authentication_classes = (SessionCRSFCheckFreeAuthentication, ) + + def post(self, request, repo_id): + auth = request.META.get('HTTP_AUTHORIZATION', '').split() + path = request.data.get('path') + is_valid = is_valid_internal_jwt(auth) + if not is_valid: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if not path: + error_msg = 'path invalid' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + if check_folder_permission(request, repo_id, path) is None: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + return Response({'success': True}) + +class CheckShareLinkThumbnailAccess(APIView): + authentication_classes = (SessionCRSFCheckFreeAuthentication,) + + def post(self, request): + auth = request.META.get('HTTP_AUTHORIZATION', '').split() + link_token = request.data.get('token') + is_valid = is_valid_internal_jwt(auth) + if not is_valid: + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + + share_obj = FileShare.objects.filter(token=link_token).first() + + if not share_obj: + error_msg = 'Link does not exist.' + return api_error(status.HTTP_404_NOT_FOUND, error_msg) + + if share_obj.is_expired(): + error_msg = 'Link is expired.' + return api_error(status.HTTP_400_BAD_REQUEST, error_msg) + + if share_obj.is_encrypted() and not check_share_link_access(request, + link_token): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + if not check_share_link_access_by_scope(request, share_obj): + error_msg = 'Permission denied.' + return api_error(status.HTTP_403_FORBIDDEN, error_msg) + + resp_json = { + 'success': True, + 'repo_id': share_obj.repo_id, + 'share_path': share_obj.path, + 'share_type': share_obj.s_type + } + return Response(resp_json) diff --git a/seahub/api2/endpoints/share_links.py b/seahub/api2/endpoints/share_links.py index 944a9ccd93..637515f6f7 100644 --- a/seahub/api2/endpoints/share_links.py +++ b/seahub/api2/endpoints/share_links.py @@ -40,7 +40,7 @@ from seahub.utils import gen_shared_link, is_org_context, normalize_file_path, \ check_filename_with_rename, gen_file_upload_url, \ get_password_strength_level, is_valid_password, is_valid_email, string2list, gen_file_get_url_by_sharelink from seahub.utils.file_op import if_locked_by_online_office -from seahub.utils.file_types import IMAGE, VIDEO, XMIND +from seahub.utils.file_types import IMAGE, VIDEO, XMIND, PDF from seahub.utils.file_tags import get_tagged_files, get_files_tags_in_dir from seahub.utils.timeutils import datetime_to_isoformat_timestr, \ timestamp_to_isoformat_timestr @@ -49,7 +49,7 @@ from seahub.thumbnail.utils import get_share_link_thumbnail_src from seahub.settings import SHARE_LINK_EXPIRE_DAYS_MAX, \ SHARE_LINK_EXPIRE_DAYS_MIN, SHARE_LINK_LOGIN_REQUIRED, \ SHARE_LINK_EXPIRE_DAYS_DEFAULT, THUMBNAIL_DEFAULT_SIZE, \ - ENABLE_VIDEO_THUMBNAIL, \ + ENABLE_VIDEO_THUMBNAIL, ENABLE_PDF_THUMBNAIL,\ THUMBNAIL_ROOT, ENABLE_UPLOAD_LINK_VIRUS_CHECK from seahub.wiki.models import Wiki from seahub.views.file import can_edit_file @@ -990,7 +990,8 @@ class ShareLinkDirents(APIView): file_type, file_ext = get_file_type_and_ext(dirent.obj_name) if file_type in (IMAGE, XMIND) or \ - (file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL): + (file_type == VIDEO and ENABLE_VIDEO_THUMBNAIL) or \ + (file_type == PDF and ENABLE_PDF_THUMBNAIL): if os.path.exists(os.path.join(THUMBNAIL_ROOT, str(thumbnail_size), dirent.obj_id)): req_image_path = posixpath.join(request_path, dirent.obj_name) diff --git a/seahub/urls.py b/seahub/urls.py index d72df7219e..9794cadcee 100644 --- a/seahub/urls.py +++ b/seahub/urls.py @@ -5,7 +5,7 @@ from django.views.generic import TemplateView from seahub.ai.apis import ImageCaption, GenerateSummary, GenerateFileTags, OCR, Translate, WritingAssistant from seahub.api2.endpoints.share_link_auth import ShareLinkUserAuthView, ShareLinkEmailAuthView from seahub.api2.endpoints.internal_api import InternalUserListView, InternalCheckShareLinkAccess, \ - InternalCheckFileOperationAccess + InternalCheckFileOperationAccess, CheckThumbnailAccess, CheckShareLinkThumbnailAccess from seahub.auth.views import multi_adfs_sso, login_simple_check from seahub.views import * from seahub.views.mobile import mobile_login @@ -814,7 +814,8 @@ urlpatterns = [ re_path(r'^api/v2.1/internal/user-list/$', InternalUserListView.as_view(), name="api-v2.1-internal-user-list"), re_path(r'^api/v2.1/internal/check-share-link-access/$', InternalCheckShareLinkAccess.as_view(), name="api-v2.1-internal-share-link-info"), re_path(r'^api/v2.1/internal/repos/(?P[-0-9a-f]{36})/check-access/$', InternalCheckFileOperationAccess.as_view(), name="api-v2.1-internal-check-file-op-access"), - + re_path(r'^api/v2.1/internal/repos/(?P[-0-9a-f]{36})/check-thumbnail/$', CheckThumbnailAccess.as_view(), name='api-v2.1-internal-check-thumbnail-access'), + re_path(r'^api/v2.1/internal/check-share-link-thumbnail/$', CheckShareLinkThumbnailAccess.as_view(), name='api-v2.1-internal-check-share-link-thumbnail-access'), ### system admin ### re_path(r'^sys/seafadmin/delete/(?P[-0-9a-f]{36})/$', sys_repo_delete, name='sys_repo_delete'), path('sys/useradmin/export-excel/', sys_useradmin_export_excel, name='sys_useradmin_export_excel'),