1
0
mirror of https://github.com/haiwen/seahub.git synced 2025-09-19 18:29:23 +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.authentication import TokenAuthentication
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.utils import gen_shared_link, is_org_context
from seahub.share.models import FileShare
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.utils.timeutils import datetime_to_isoformat_timestr
from seahub.constants import PERMISSION_READ_WRITE
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__)
@@ -343,3 +345,64 @@ class ShareLink(APIView):
return api_error(status.HTTP_500_INTERNAL_SERVER_ERROR, error_msg)
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);
{% if can_edit %}
{% if not share_link_token %}
var interval;
var refreshLock = function() {
$.ajax({
@@ -76,6 +77,29 @@ var SEAFILE_GLOBAL = {
});
};
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 %}
</script>
{% if enable_watermark %}

View File

@@ -51,6 +51,7 @@ var SEAFILE_GLOBAL = {
document.getElementById('office_frame').className = '';
{% if can_edit %}
{% if not share_link_token %}
var interval;
var refreshLock = function() {
$.ajax({
@@ -75,6 +76,29 @@ var SEAFILE_GLOBAL = {
});
};
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 %}
</script>
{% 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.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_repos import SharedRepos, SharedRepo
from seahub.api2.endpoints.upload_links import UploadLinks, UploadLink, \
@@ -251,6 +252,8 @@ urlpatterns = [
## 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/(?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
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.translation import get_language, ugettext as _
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.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)
username = request.user.username
repo = get_repo(fileshare.repo_id)
if not repo:
raise Http404
@@ -952,6 +952,7 @@ def _download_file_from_share_link(request, fileshare):
return HttpResponseRedirect(gen_file_get_url(dl_token, filename))
@ensure_csrf_cookie
@share_link_audit
@share_link_login_required
def view_shared_file(request, fileshare):
@@ -1042,6 +1043,23 @@ def view_shared_file(request, fileshare):
else:
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:
action_name = 'edit' if can_edit else 'view'
@@ -1050,6 +1068,10 @@ def view_shared_file(request, fileshare):
language_code=request.LANGUAGE_CODE)
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)
else:
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)
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',
onlyoffice_dict)
else: