From f7f0a072397a2c5969c396d86404f3ed2a9c4a4b Mon Sep 17 00:00:00 2001 From: Alexandr Fedorov Date: Mon, 15 Feb 2021 17:24:56 +0300 Subject: [PATCH] ruby: added forcesave --- .../ruby/app/controllers/home_controller.rb | 110 ++------- .../ruby/app/models/document_helper.rb | 26 ++ .../ruby/app/models/file_model.rb | 19 +- .../ruby/app/models/track_helper.rb | 223 ++++++++++++++++++ .../ruby/config/application.rb | 2 + 5 files changed, 283 insertions(+), 97 deletions(-) create mode 100644 web/documentserver-example/ruby/app/models/track_helper.rb diff --git a/web/documentserver-example/ruby/app/controllers/home_controller.rb b/web/documentserver-example/ruby/app/controllers/home_controller.rb index a6721d47..00ba2251 100644 --- a/web/documentserver-example/ruby/app/controllers/home_controller.rb +++ b/web/documentserver-example/ruby/app/controllers/home_controller.rb @@ -124,110 +124,40 @@ class HomeController < ApplicationController end def track - - user_address = params[:userAddress] - file_name = File.basename(params[:fileName]) - - storage_path = DocumentHelper.storage_path(file_name, user_address) - body = request.body.read - - if body == nil || body.empty? + file_data = TrackHelper.read_body(request) + if file_data == nil || file_data.empty? + render plain: '{"error":1}' return end - file_data = JSON.parse(body) - - if JwtHelper.is_enabled - inHeader = false - token = nil - jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header; - if file_data["token"] - token = JwtHelper.decode(file_data["token"]) - elsif request.headers[jwtHeader] - hdr = request.headers[jwtHeader] - hdr.slice!(0, "Bearer ".length) - token = JwtHelper.decode(hdr) - inHeader = true - else - raise "Expected JWT" - end - if !token - raise "Invalid JWT signature" - end - - file_data = JSON.parse(token) - if inHeader - file_data = file_data["payload"] - end - end - status = file_data['status'].to_i - if status == 2 || status == 3 #MustSave, Corrupted + user_address = params[:userAddress] + file_name = File.basename(params[:fileName]) - saved = 0 - - begin - - def save_from_uri(path, uristr) - uri = URI.parse(uristr) - http = Net::HTTP.new(uri.host, uri.port) - - if uristr.start_with?('https') - http.use_ssl = true - http.verify_mode = OpenSSL::SSL::VERIFY_NONE - end - - req = Net::HTTP::Get.new(uri) - res = http.request(req) - data = res.body - - if data == nil - raise 'stream is null' - end - - File.open(path, 'wb') do |file| - file.write(data) - end - end - - hist_dir = DocumentHelper.history_dir(storage_path) - ver_dir = DocumentHelper.version_dir(hist_dir, DocumentHelper.get_file_version(hist_dir)) - - FileUtils.mkdir_p(ver_dir) - - FileUtils.move(storage_path, File.join(ver_dir, "prev#{File.extname(file_name)}")) - save_from_uri(storage_path, file_data['url']) - - if (file_data["changesurl"]) - save_from_uri(File.join(ver_dir, "diff.zip"), file_data["changesurl"]) - end - - hist_data = file_data["changeshistory"] - if (!hist_data) - hist_data = file_data["history"].to_json - end - if (hist_data) - File.open(File.join(ver_dir, "changes.json"), 'wb') do |file| - file.write(hist_data) - end - end - - File.open(File.join(ver_dir, "key.txt"), 'wb') do |file| - file.write(file_data["key"]) - end - - rescue StandardError => msg - saved = 1 + if status == 1 #Editing + if file_data['actions'][0]['type'] == 0 #Finished edit + user = file_data['actions'][0]['userid'] + if !file_data['users'].index(user) + json_data = TrackHelper.command_request("forcesave", file_data['key']) + end end + end + if status == 2 || status == 3 #MustSave, Corrupted + saved = TrackHelper.process_save(file_data, file_name, user_address) + render plain: '{"error":' + saved.to_s + '}' + return + end + + if status == 6 || status == 7 # MustForceave, CorruptedForcesave + saved = TrackHelper.process_force_save(file_data, file_name, user_address) render plain: '{"error":' + saved.to_s + '}' return end render plain: '{"error":0}' return - end def remove diff --git a/web/documentserver-example/ruby/app/models/document_helper.rb b/web/documentserver-example/ruby/app/models/document_helper.rb index 5a561cae..3e6c31a5 100644 --- a/web/documentserver-example/ruby/app/models/document_helper.rb +++ b/web/documentserver-example/ruby/app/models/document_helper.rb @@ -77,6 +77,32 @@ class DocumentHelper directory.join(File.basename(file_name)).to_s end + def forcesave_path(file_name, user_address, create) + directory = Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address)) + + unless File.directory?(directory) + return "" + end + + directory = directory.join("#{File.basename(file_name)}-hist") + unless File.directory?(directory) + if create + FileUtils.mkdir_p(directory) + else + return "" + end + end + + directory = directory.join(File.basename(file_name)) + unless File.file?(directory) + if !create + return "" + end + end + + return directory.to_s + end + def history_dir(storage_path) directory = "#{storage_path}-hist" diff --git a/web/documentserver-example/ruby/app/models/file_model.rb b/web/documentserver-example/ruby/app/models/file_model.rb index 93042146..5d4f6341 100644 --- a/web/documentserver-example/ruby/app/models/file_model.rb +++ b/web/documentserver-example/ruby/app/models/file_model.rb @@ -106,6 +106,9 @@ class FileModel :shareUrl => file_uri_user, :toolbarDocked => "top" }, + :customization => { + :forcesave => false + } } } @@ -144,14 +147,16 @@ class FileModel obj["version"] = i if (i == 1) - File.open(File.join(hist_dir, "createdInfo.json"), 'r') do |file| - cr_info = JSON.parse(file.read()) + if File.file?(File.join(hist_dir, "createdInfo.json")) + File.open(File.join(hist_dir, "createdInfo.json"), 'r') do |file| + cr_info = JSON.parse(file.read()) - obj["created"] = cr_info["created"] - obj["user"] = { - :id => cr_info["created"], - :name => cr_info["name"] - } + obj["created"] = cr_info["created"] + obj["user"] = { + :id => cr_info["created"], + :name => cr_info["name"] + } + end end end diff --git a/web/documentserver-example/ruby/app/models/track_helper.rb b/web/documentserver-example/ruby/app/models/track_helper.rb new file mode 100644 index 00000000..9608773f --- /dev/null +++ b/web/documentserver-example/ruby/app/models/track_helper.rb @@ -0,0 +1,223 @@ +# +# (c) Copyright Ascensio System SIA 2020 +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# + +require 'net/http' + +class TrackHelper + + class << self + + def read_body(request) + body = request.body.read + + if body == nil || body.empty? + return "" + end + + file_data = JSON.parse(body) + + if JwtHelper.is_enabled + inHeader = false + token = nil + jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header; + if file_data["token"] + token = JwtHelper.decode(file_data["token"]) + elsif request.headers[jwtHeader] + hdr = request.headers[jwtHeader] + hdr.slice!(0, "Bearer ".length) + token = JwtHelper.decode(hdr) + inHeader = true + else + raise "Expected JWT" + end + + if !token + raise "Invalid JWT signature" + end + + file_data = JSON.parse(token) + + if inHeader + file_data = file_data["payload"] + end + end + + return file_data + end + + def process_save(file_data, file_name, user_address) + download_uri = file_data['url'] + new_file_name = file_name + + cur_ext = File.extname(file_name) + download_ext = File.extname(download_uri) + + if (!cur_ext.eql?(download_ext)) + key = ServiceConverter.generate_revision_id(download_uri) + begin + percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false) + if (new_file_uri == nil || new_file_uri.empty?) + new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext) + else + download_uri = new_file_uri + end + rescue StandardError => msg + new_file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext) + end + end + + saved = 1 + begin + storage_path = DocumentHelper.storage_path(new_file_name, user_address) + + hist_dir = DocumentHelper.history_dir(storage_path) + ver_dir = DocumentHelper.version_dir(hist_dir, DocumentHelper.get_file_version(hist_dir)) + + FileUtils.mkdir_p(ver_dir) + + FileUtils.move(DocumentHelper.storage_path(file_name, user_address), File.join(ver_dir, "prev#{cur_ext}")) + save_from_uri(storage_path, download_uri) + + if (file_data["changesurl"]) + save_from_uri(File.join(ver_dir, "diff.zip"), file_data["changesurl"]) + end + + hist_data = file_data["changeshistory"] + if (!hist_data) + hist_data = file_data["history"].to_json + end + if (hist_data) + File.open(File.join(ver_dir, "changes.json"), 'wb') do |file| + file.write(hist_data) + end + end + + File.open(File.join(ver_dir, "key.txt"), 'wb') do |file| + file.write(file_data["key"]) + end + + forcesave_path = DocumentHelper.forcesave_path(new_file_name, user_address, false) + if (!forcesave_path.eql?("")) + File.delete(forcesave_path) + end + + saved = 0 + rescue StandardError => msg + saved = 1 + end + + return saved + end + + def process_force_save(file_data, file_name, user_address) + download_uri = file_data['url'] + + cur_ext = File.extname(file_name) + download_ext = File.extname(download_uri) + + if (!cur_ext.eql?(download_ext)) + key = ServiceConverter.generate_revision_id(download_uri) + begin + percent, new_file_uri = ServiceConverter.get_converted_uri(download_uri, download_ext.delete('.'), cur_ext.delete('.'), key, false) + if (new_file_uri == nil || new_file_uri.empty?) + file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext) + else + download_uri = new_file_uri + end + rescue StandardError => msg + file_name = DocumentHelper.get_correct_name(File.basename(file_name, cur_ext) + download_ext) + end + end + + saved = 1 + begin + forcesave_path = DocumentHelper.forcesave_path(file_name, user_address, false) + if (forcesave_path.eql?("")) + forcesave_path = DocumentHelper.forcesave_path(file_name, user_address, true) + end + + save_from_uri(forcesave_path, download_uri) + + saved = 0 + rescue StandardError => msg + saved = 1 + end + + return saved + end + + def command_request(method, key) + document_command_url = Rails.configuration.urlSite + Rails.configuration.commandUrl + + payload = { + :c => method, + :key => key + } + + data = nil + begin + + uri = URI.parse(document_command_url) + http = Net::HTTP.new(uri.host, uri.port) + + if document_command_url.start_with?('https') + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + + req = Net::HTTP::Post.new(uri.request_uri) + req.add_field("Content-Type", "application/json") + + if JwtHelper.is_enabled + payload["token"] = JwtHelper.encode(payload) + jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header; + req.add_field(jwtHeader, "Bearer #{JwtHelper.encode({ :payload => payload })}") + end + + req.body = payload.to_json + res = http.request(req) + data = res.body + rescue => ex + raise ex.message + end + + json_data = JSON.parse(data) + return json_data + end + + def save_from_uri(path, uristr) + uri = URI.parse(uristr) + http = Net::HTTP.new(uri.host, uri.port) + + if uristr.start_with?('https') + http.use_ssl = true + http.verify_mode = OpenSSL::SSL::VERIFY_NONE + end + + req = Net::HTTP::Get.new(uri) + res = http.request(req) + data = res.body + + if data == nil + raise 'stream is null' + end + + File.open(path, 'wb') do |file| + file.write(data) + end + end + end +end \ No newline at end of file diff --git a/web/documentserver-example/ruby/config/application.rb b/web/documentserver-example/ruby/config/application.rb index 2e020e29..48763839 100644 --- a/web/documentserver-example/ruby/config/application.rb +++ b/web/documentserver-example/ruby/config/application.rb @@ -40,6 +40,8 @@ module OnlineEditorsExampleRuby Rails.configuration.urlConverter="ConvertService.ashx" Rails.configuration.urlApi="web-apps/apps/api/documents/api.js" Rails.configuration.urlPreloader="web-apps/apps/api/documents/cache-scripts.html" + Rails.configuration.commandUrl="coauthoring/CommandService.ashx" + Rails.configuration.urlExample="" Rails.configuration.jwtSecret = ""