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:
@@ -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})
|
||||
|
@@ -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 %}
|
||||
|
@@ -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 %}
|
||||
|
@@ -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'),
|
||||
|
@@ -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:
|
||||
|
Reference in New Issue
Block a user