1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-20 19:08:21 +00:00

add new online office refresh lock api for share link (#2497)

This commit is contained in:
lian
2018-11-05 10:24:00 +08:00
committed by Daniel Pan
parent 4ad78173bd
commit 5f9d4e6298
5 changed files with 146 additions and 6 deletions

View File

@@ -19,15 +19,17 @@ from pysearpc import SearpcError
from seahub.api2.utils import api_error from seahub.api2.utils import api_error
from seahub.api2.authentication import TokenAuthentication from seahub.api2.authentication import TokenAuthentication
from seahub.api2.throttling import UserRateThrottle from seahub.api2.throttling import UserRateThrottle
from seahub.api2.permissions import CanGenerateShareLink from seahub.api2.permissions import CanGenerateShareLink, IsProVersion
from seahub.share.models import FileShare, OrgFileShare from seahub.share.models import FileShare
from seahub.utils import gen_shared_link, is_org_context from seahub.utils import gen_shared_link, is_org_context, normalize_file_path
from seahub.utils.file_op import if_locked_by_online_office
from seahub.views import check_folder_permission from seahub.views import check_folder_permission
from seahub.utils.timeutils import datetime_to_isoformat_timestr from seahub.utils.timeutils import datetime_to_isoformat_timestr
from seahub.constants import PERMISSION_READ_WRITE
from seahub.settings import SHARE_LINK_EXPIRE_DAYS_MAX, \ from seahub.settings import SHARE_LINK_EXPIRE_DAYS_MAX, \
SHARE_LINK_EXPIRE_DAYS_MIN SHARE_LINK_EXPIRE_DAYS_MIN, SHARE_LINK_LOGIN_REQUIRED
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -343,3 +345,64 @@ class ShareLink(APIView):
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg) return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
return Response({'success': True}) return Response({'success': True})
class ShareLinkOnlineOfficeLock(APIView):
permission_classes = (IsProVersion,)
throttle_classes = (UserRateThrottle,)
def put(self, request, token):
""" This api only used for refresh OnlineOffice lock
when user edit office file via share link.
Permission checking:
1, If enable SHARE_LINK_LOGIN_REQUIRED, user must have been authenticated.
2, Share link should have can_edit permission.
3, File must have been locked by OnlineOffice.
"""
if SHARE_LINK_LOGIN_REQUIRED and \
not request.user.is_authenticated():
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
try:
share_link = FileShare.objects.get(token=token)
except FileShare.DoesNotExist:
error_msg = 'Share link %s not found.' % token
return api_error(status.HTTP_404_NOT_FOUND, error_msg)
if share_link.is_expired():
error_msg = 'Share link %s is expired.' % token
return api_error(status.HTTP_400_BAD_REQUEST, error_msg)
shared_by = share_link.username
repo_id = share_link.repo_id
path = normalize_file_path(share_link.path)
parent_dir = os.path.dirname(path)
if seafile_api.check_permission_by_path(repo_id,
parent_dir, shared_by) != PERMISSION_READ_WRITE:
error_msg = 'Permission denied.'
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
permissions = share_link.get_permissions()
can_edit = permissions['can_edit']
if not can_edit:
error_msg = 'Share link %s has no edit permission.' % token
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
locked_by_online_office = if_locked_by_online_office(repo_id, path)
if locked_by_online_office:
# refresh lock file
try:
seafile_api.refresh_file_lock(repo_id, path)
except SearpcError, e:
logger.error(e)
error_msg = 'Internal Server Error'
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
else:
error_msg = _("You can not refresh this file's lock.")
return api_error(status.HTTP_403_FORBIDDEN, error_msg)
return Response({'success': True})

View File

@@ -52,6 +52,7 @@ var SEAFILE_GLOBAL = {
var docEditor = new DocsAPI.DocEditor("placeholder", config); var docEditor = new DocsAPI.DocEditor("placeholder", config);
{% if can_edit %} {% if can_edit %}
{% if not share_link_token %}
var interval; var interval;
var refreshLock = function() { var refreshLock = function() {
$.ajax({ $.ajax({
@@ -76,6 +77,29 @@ var SEAFILE_GLOBAL = {
}); });
}; };
interval = setInterval(refreshLock, 60 * 1000); interval = setInterval(refreshLock, 60 * 1000);
{% else %}
var interval;
var refreshLock = function() {
$.ajax({
url: '{% url "api-v2.1-share-link-online-office-lock" share_link_token %}',
type: 'PUT',
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
success: function(data) {
},
error: function(xhr) {
if (xhr.responseText) {
feedback(JSON.parse(xhr.responseText).error_msg, 'error');
} else {
feedback("{% trans "Failed. Please check the network." %}", 'error');
}
clearInterval(interval);
}
});
};
interval = setInterval(refreshLock, 60 * 1000);
{% endif %}
{% endif %} {% endif %}
</script> </script>
{% if enable_watermark %} {% if enable_watermark %}

View File

@@ -51,6 +51,7 @@ var SEAFILE_GLOBAL = {
document.getElementById('office_frame').className = ''; document.getElementById('office_frame').className = '';
{% if can_edit %} {% if can_edit %}
{% if not share_link_token %}
var interval; var interval;
var refreshLock = function() { var refreshLock = function() {
$.ajax({ $.ajax({
@@ -75,6 +76,29 @@ var SEAFILE_GLOBAL = {
}); });
}; };
interval = setInterval(refreshLock, 60 * 1000); interval = setInterval(refreshLock, 60 * 1000);
{% else %}
var interval;
var refreshLock = function() {
$.ajax({
url: '{% url "api-v2.1-share-link-online-office-lock" share_link_token %}',
type: 'PUT',
dataType: 'json',
cache: false,
beforeSend: prepareCSRFToken,
success: function(data) {
},
error: function(xhr) {
if (xhr.responseText) {
feedback(JSON.parse(xhr.responseText).error_msg, 'error');
} else {
feedback("{% trans "Failed. Please check the network." %}", 'error');
}
clearInterval(interval);
}
});
};
interval = setInterval(refreshLock, 60 * 1000);
{% endif %}
{% endif %} {% endif %}
</script> </script>
{% if enable_watermark %} {% if enable_watermark %}

View File

@@ -34,7 +34,8 @@ from seahub.api2.endpoints.address_book.members import AddressBookGroupsSearchMe
from seahub.api2.endpoints.group_members import GroupMembers, GroupMembersBulk, GroupMember from seahub.api2.endpoints.group_members import GroupMembers, GroupMembersBulk, GroupMember
from seahub.api2.endpoints.search_group import SearchGroup from seahub.api2.endpoints.search_group import SearchGroup
from seahub.api2.endpoints.share_links import ShareLinks, ShareLink from seahub.api2.endpoints.share_links import ShareLinks, ShareLink, \
ShareLinkOnlineOfficeLock
from seahub.api2.endpoints.shared_folders import SharedFolders from seahub.api2.endpoints.shared_folders import SharedFolders
from seahub.api2.endpoints.shared_repos import SharedRepos, SharedRepo 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, \
@@ -251,6 +252,8 @@ urlpatterns = [
## user::shared-download-links ## user::shared-download-links
url(r'^api/v2.1/share-links/$', ShareLinks.as_view(), name='api-v2.1-share-links'), url(r'^api/v2.1/share-links/$', ShareLinks.as_view(), name='api-v2.1-share-links'),
url(r'^api/v2.1/share-links/(?P<token>[a-f0-9]+)/$', ShareLink.as_view(), name='api-v2.1-share-link'), url(r'^api/v2.1/share-links/(?P<token>[a-f0-9]+)/$', ShareLink.as_view(), name='api-v2.1-share-link'),
url(r'^api/v2.1/share-links/(?P<token>[a-f0-9]+)/online-office-lock/$',
ShareLinkOnlineOfficeLock.as_view(), name='api-v2.1-share-link-online-office-lock'),
## user::shared-upload-links ## 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/$', UploadLinks.as_view(), name='api-v2.1-upload-links'),

View File

@@ -28,6 +28,7 @@ from django.shortcuts import render
from django.utils.http import urlquote from django.utils.http import urlquote
from django.utils.translation import get_language, ugettext as _ from django.utils.translation import get_language, ugettext as _
from django.views.decorators.http import require_POST from django.views.decorators.http import require_POST
from django.views.decorators.csrf import ensure_csrf_cookie
from django.template.defaultfilters import filesizeformat from django.template.defaultfilters import filesizeformat
from django.views.decorators.csrf import csrf_exempt from django.views.decorators.csrf import csrf_exempt
@@ -915,7 +916,6 @@ def _download_file_from_share_link(request, fileshare):
""" """
next = request.META.get('HTTP_REFERER', settings.SITE_ROOT) next = request.META.get('HTTP_REFERER', settings.SITE_ROOT)
username = request.user.username
repo = get_repo(fileshare.repo_id) repo = get_repo(fileshare.repo_id)
if not repo: if not repo:
raise Http404 raise Http404
@@ -952,6 +952,7 @@ def _download_file_from_share_link(request, fileshare):
return HttpResponseRedirect(gen_file_get_url(dl_token, filename)) return HttpResponseRedirect(gen_file_get_url(dl_token, filename))
@ensure_csrf_cookie
@share_link_audit @share_link_audit
@share_link_login_required @share_link_login_required
def view_shared_file(request, fileshare): def view_shared_file(request, fileshare):
@@ -1042,6 +1043,23 @@ def view_shared_file(request, fileshare):
else: else:
username = request.user.username username = request.user.username
def online_office_lock_or_refresh_lock(repo_id, path, username):
# check file lock info
try:
is_locked, locked_by_me = check_file_lock(repo_id, path, username)
except Exception as e:
logger.error(e)
is_locked = False
locked_by_online_office = if_locked_by_online_office(repo_id, path)
try:
if not is_locked:
seafile_api.lock_file(repo_id, path, ONLINE_OFFICE_LOCK_OWNER, 0)
elif locked_by_online_office:
seafile_api.refresh_file_lock(repo_id, path)
except Exception as e:
logger.error(e)
if ENABLE_OFFICE_WEB_APP and fileext in OFFICE_WEB_APP_FILE_EXTENSION: if ENABLE_OFFICE_WEB_APP and fileext in OFFICE_WEB_APP_FILE_EXTENSION:
action_name = 'edit' if can_edit else 'view' action_name = 'edit' if can_edit else 'view'
@@ -1050,6 +1068,10 @@ def view_shared_file(request, fileshare):
language_code=request.LANGUAGE_CODE) language_code=request.LANGUAGE_CODE)
if wopi_dict: if wopi_dict:
if is_pro_version() and can_edit:
online_office_lock_or_refresh_lock(repo_id, path, username)
wopi_dict['share_link_token'] = token
return render(request, 'view_file_wopi.html', wopi_dict) return render(request, 'view_file_wopi.html', wopi_dict)
else: else:
ret_dict['err'] = _(u'Error when prepare Office Online file preview page.') ret_dict['err'] = _(u'Error when prepare Office Online file preview page.')
@@ -1060,6 +1082,10 @@ def view_shared_file(request, fileshare):
can_edit=can_edit, can_download=can_download) can_edit=can_edit, can_download=can_download)
if onlyoffice_dict: if onlyoffice_dict:
if is_pro_version() and can_edit:
online_office_lock_or_refresh_lock(repo_id, path, username)
onlyoffice_dict['share_link_token'] = token
return render(request, 'view_file_onlyoffice.html', return render(request, 'view_file_onlyoffice.html',
onlyoffice_dict) onlyoffice_dict)
else: else: