mirror of
https://github.com/ONLYOFFICE/document-server-integration.git
synced 2026-04-07 14:06:11 +08:00
Compare commits
26 Commits
v99.99.99.
...
feature/ru
| Author | SHA1 | Date | |
|---|---|---|---|
| 8ae1fd1c55 | |||
| b472709542 | |||
| 38c439c817 | |||
| a172afc904 | |||
| 0b5692f085 | |||
| 87cdf95c17 | |||
| 060cc1f0cc | |||
| 321e48bad2 | |||
| 30aaaa2b67 | |||
| 43368fd9fa | |||
| 1c5b64bba7 | |||
| df93bbda77 | |||
| 3754bb6b03 | |||
| a51fad84e9 | |||
| 1469ce6c0f | |||
| c534989cb3 | |||
| f57292a3ae | |||
| 4961da4c11 | |||
| c21f87bdb0 | |||
| bd98cd4e54 | |||
| 9429e080b2 | |||
| 26a9de9250 | |||
| 874f551318 | |||
| 5e50db62f2 | |||
| 64fdfe62d9 | |||
| 036b1e50d4 |
5
.gitignore
vendored
5
.gitignore
vendored
@ -22,8 +22,3 @@
|
||||
/web/documentserver-example/csharp/packages
|
||||
/web/documentserver-example/csharp-mvc/packages
|
||||
/web/documentserver-example/java-spring/documents/
|
||||
/web/documentserver-example/ruby/.bundle
|
||||
/web/documentserver-example/ruby/db/*.sqlite3
|
||||
/web/documentserver-example/ruby/db/*.sqlite3-journal
|
||||
/web/documentserver-example/ruby/log/*
|
||||
/web/documentserver-example/ruby/tmp
|
||||
|
||||
16
web/documentserver-example/ruby/.gitignore
vendored
Normal file
16
web/documentserver-example/ruby/.gitignore
vendored
Normal file
@ -0,0 +1,16 @@
|
||||
# User-specific files: editor, system, etc.
|
||||
.DS_Store
|
||||
.idea
|
||||
.project
|
||||
.settings
|
||||
.vs
|
||||
.vscode
|
||||
*.suo
|
||||
*.user
|
||||
|
||||
# Project files.
|
||||
bin
|
||||
db
|
||||
log
|
||||
sorbet
|
||||
tmp
|
||||
17
web/documentserver-example/ruby/Dockerfile
Normal file
17
web/documentserver-example/ruby/Dockerfile
Normal file
@ -0,0 +1,17 @@
|
||||
FROM ruby:3.2.2-alpine3.18 AS example
|
||||
WORKDIR /srv
|
||||
COPY . .
|
||||
RUN \
|
||||
apk update && \
|
||||
apk add --no-cache \
|
||||
build-base \
|
||||
gcompat \
|
||||
git \
|
||||
make \
|
||||
nodejs && \
|
||||
gem install bundler -v 2.3.7 && \
|
||||
make prod
|
||||
CMD ["make", "prod-server"]
|
||||
|
||||
FROM nginx:1.23.4-alpine3.17 AS proxy
|
||||
COPY proxy/nginx.conf /etc/nginx/nginx.conf
|
||||
@ -2,15 +2,19 @@ source "https://rubygems.org"
|
||||
|
||||
gem "byebug", "~> 11.1", :groups => [:development, :test]
|
||||
gem "coffee-rails", "~> 5.0"
|
||||
gem "dalli", "~> 3.2", :group => :development
|
||||
gem "jbuilder", "~> 2.11"
|
||||
gem "jquery-rails", "~> 4.5"
|
||||
gem "jwt", "~> 2.7"
|
||||
gem "mimemagic", github: "mimemagicrb/mimemagic", ref: "01f92d86d15d85cfd0f20dabd025dcbd36a8a60f"
|
||||
gem "rack-cors", "~> 2.0"
|
||||
gem "rails", "~> 7.0"
|
||||
gem "rubocop", "~> 1.52", :group => :development
|
||||
gem "sass-rails", "~> 6.0"
|
||||
gem "sdoc", "~> 2.6", :group => :doc
|
||||
gem "sqlite3", "1.4.2"
|
||||
gem "sorbet", "~> 0.5.10871", :group => :development
|
||||
gem "sorbet-runtime", "~> 0.5.10871"
|
||||
gem "tapioca", "~> 0.11.6", :group => :development
|
||||
gem "turbolinks", "~> 5.2"
|
||||
gem "tzinfo-data", "~> 1.2023"
|
||||
gem "uglifier", "~> 4.2"
|
||||
|
||||
@ -73,6 +73,7 @@ GEM
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
ast (2.4.2)
|
||||
bindex (0.8.1)
|
||||
builder (3.2.4)
|
||||
byebug (11.1.3)
|
||||
@ -85,7 +86,9 @@ GEM
|
||||
coffee-script-source (1.12.2)
|
||||
concurrent-ruby (1.2.2)
|
||||
crass (1.0.6)
|
||||
dalli (3.2.4)
|
||||
date (3.3.3)
|
||||
diff-lcs (1.5.0)
|
||||
erubi (1.12.0)
|
||||
execjs (2.8.1)
|
||||
ffi (1.15.5)
|
||||
@ -100,6 +103,7 @@ GEM
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
json (2.6.3)
|
||||
jwt (2.7.0)
|
||||
loofah (2.21.3)
|
||||
crass (~> 1.0.2)
|
||||
@ -124,6 +128,7 @@ GEM
|
||||
timeout
|
||||
net-smtp (0.3.3)
|
||||
net-protocol
|
||||
netrc (0.11.0)
|
||||
nio4r (2.5.9)
|
||||
nokogiri (1.15.2-arm64-darwin)
|
||||
racc (~> 1.4)
|
||||
@ -131,6 +136,10 @@ GEM
|
||||
racc (~> 1.4)
|
||||
nokogiri (1.15.2-x86_64-linux)
|
||||
racc (~> 1.4)
|
||||
parallel (1.23.0)
|
||||
parser (3.2.2.3)
|
||||
ast (~> 2.4.1)
|
||||
racc
|
||||
psych (5.1.0)
|
||||
stringio
|
||||
racc (1.7.0)
|
||||
@ -166,9 +175,30 @@ GEM
|
||||
rake (>= 12.2)
|
||||
thor (~> 1.0)
|
||||
zeitwerk (~> 2.5)
|
||||
rainbow (3.1.1)
|
||||
rake (13.0.6)
|
||||
rbi (0.0.16)
|
||||
ast
|
||||
parser (>= 2.6.4.0)
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
unparser
|
||||
rdoc (6.5.0)
|
||||
psych (>= 4.0.0)
|
||||
regexp_parser (2.8.0)
|
||||
rexml (3.2.5)
|
||||
rubocop (1.52.0)
|
||||
json (~> 2.3)
|
||||
parallel (~> 1.10)
|
||||
parser (>= 3.2.0.0)
|
||||
rainbow (>= 2.2.2, < 4.0)
|
||||
regexp_parser (>= 1.8, < 3.0)
|
||||
rexml (>= 3.2.5, < 4.0)
|
||||
rubocop-ast (>= 1.28.0, < 2.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (>= 2.4.0, < 3.0)
|
||||
rubocop-ast (1.29.0)
|
||||
parser (>= 3.2.1.0)
|
||||
ruby-progressbar (1.13.0)
|
||||
sass-rails (6.0.0)
|
||||
sassc-rails (~> 2.1, >= 2.1.1)
|
||||
sassc (2.4.0)
|
||||
@ -181,6 +211,18 @@ GEM
|
||||
tilt
|
||||
sdoc (2.6.1)
|
||||
rdoc (>= 5.0)
|
||||
sorbet (0.5.10871)
|
||||
sorbet-static (= 0.5.10871)
|
||||
sorbet-runtime (0.5.10871)
|
||||
sorbet-static (0.5.10871-universal-darwin-22)
|
||||
sorbet-static (0.5.10871-x86_64-linux)
|
||||
sorbet-static-and-runtime (0.5.10871)
|
||||
sorbet (= 0.5.10871)
|
||||
sorbet-runtime (= 0.5.10871)
|
||||
spoom (1.2.1)
|
||||
sorbet (>= 0.5.10187)
|
||||
sorbet-runtime (>= 0.5.9204)
|
||||
thor (>= 0.19.2)
|
||||
sprockets (4.2.0)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (>= 2.2.4, < 4)
|
||||
@ -188,9 +230,17 @@ GEM
|
||||
actionpack (>= 5.2)
|
||||
activesupport (>= 5.2)
|
||||
sprockets (>= 3.0.0)
|
||||
sqlite3 (1.4.2)
|
||||
stringio (3.0.7)
|
||||
systemu (2.6.5)
|
||||
tapioca (0.11.6)
|
||||
bundler (>= 2.2.25)
|
||||
netrc (>= 0.11.0)
|
||||
parallel (>= 1.21.0)
|
||||
rbi (~> 0.0.0, >= 0.0.16)
|
||||
sorbet-static-and-runtime (>= 0.5.10187)
|
||||
spoom (~> 1.2.0, >= 1.2.0)
|
||||
thor (>= 1.2.0)
|
||||
yard-sorbet
|
||||
thor (1.2.2)
|
||||
tilt (2.2.0)
|
||||
timeout (0.3.2)
|
||||
@ -203,6 +253,10 @@ GEM
|
||||
tzinfo (>= 1.0.0)
|
||||
uglifier (4.2.0)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (2.4.2)
|
||||
unparser (0.6.7)
|
||||
diff-lcs (~> 1.3)
|
||||
parser (>= 3.2.0)
|
||||
uuid (2.3.9)
|
||||
macaddr (~> 1.0)
|
||||
web-console (4.2.0)
|
||||
@ -214,6 +268,10 @@ GEM
|
||||
websocket-driver (0.7.5)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.5)
|
||||
yard (0.9.34)
|
||||
yard-sorbet (0.8.1)
|
||||
sorbet-runtime (>= 0.5)
|
||||
yard (>= 0.9)
|
||||
zeitwerk (2.6.8)
|
||||
|
||||
PLATFORMS
|
||||
@ -224,15 +282,19 @@ PLATFORMS
|
||||
DEPENDENCIES
|
||||
byebug (~> 11.1)
|
||||
coffee-rails (~> 5.0)
|
||||
dalli (~> 3.2)
|
||||
jbuilder (~> 2.11)
|
||||
jquery-rails (~> 4.5)
|
||||
jwt (~> 2.7)
|
||||
mimemagic!
|
||||
rack-cors (~> 2.0)
|
||||
rails (~> 7.0)
|
||||
rubocop (~> 1.52)
|
||||
sass-rails (~> 6.0)
|
||||
sdoc (~> 2.6)
|
||||
sqlite3 (= 1.4.2)
|
||||
sorbet (~> 0.5.10871)
|
||||
sorbet-runtime (~> 0.5.10871)
|
||||
tapioca (~> 0.11.6)
|
||||
turbolinks (~> 5.2)
|
||||
tzinfo-data (~> 1.2023)
|
||||
uglifier (~> 4.2)
|
||||
|
||||
36
web/documentserver-example/ruby/Makefile
Normal file
36
web/documentserver-example/ruby/Makefile
Normal file
@ -0,0 +1,36 @@
|
||||
.DEFAULT_GOAL := help
|
||||
|
||||
.PHONY: help
|
||||
help: # Show help message for each of the Makefile recipes.
|
||||
@grep -E "^[a-z-]+: #" $(MAKEFILE_LIST) | \
|
||||
sort --dictionary-order | \
|
||||
awk 'BEGIN {FS = ": # "}; {printf "%s: %s\n", $$1, $$2}'
|
||||
|
||||
.PHONY: dev
|
||||
dev: # Install development dependencies and initialize the project.
|
||||
@bundle install
|
||||
@rake app:update:bin
|
||||
@bundle exec tapioca init
|
||||
|
||||
.PHONY: dev-server
|
||||
dev-server: # Start the development server on localhost at $PORT (default: 3000).
|
||||
@rails server --using webrick
|
||||
|
||||
.PHONY: lint
|
||||
lint: # Lint the source code for style and check for types.
|
||||
@bundle exec rubocop
|
||||
@bundle exec srb tc
|
||||
|
||||
.PHONY: prod
|
||||
prod: # Install production dependencies.
|
||||
@bundle install --without development doc test
|
||||
@rake app:update:bin
|
||||
|
||||
.PHONY: prod-server
|
||||
prod-server: # Start the poruction server on 0.0.0.0 at $PORT (default: 3000).
|
||||
@rails server --environment production --using webrick
|
||||
|
||||
.PHONY: up
|
||||
up: # Build and up docker containers.
|
||||
@docker-compose build
|
||||
@docker-compose up -d
|
||||
@ -1,6 +1,3 @@
|
||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||
|
||||
require File.expand_path('../config/application', __FILE__)
|
||||
require_relative 'config/application'
|
||||
|
||||
Rails.application.load_tasks
|
||||
|
||||
102
web/documentserver-example/ruby/app/authorization.rb
Normal file
102
web/documentserver-example/ruby/app/authorization.rb
Normal file
@ -0,0 +1,102 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
|
||||
require 'jwt'
|
||||
require_relative 'models/configuration_manager'
|
||||
require_relative 'response'
|
||||
|
||||
class AuthorizationManager
|
||||
extend T::Sig
|
||||
|
||||
sig { params(config: ConfigurationManager).void }
|
||||
def initialize(config:)
|
||||
@config = config
|
||||
end
|
||||
|
||||
sig { params(headers: ActionDispatch::Http::Headers).returns(T::Boolean) }
|
||||
def authorize(headers:)
|
||||
enabled ? verify(headers:) : true
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def enabled
|
||||
!@config.jwt_secret.empty?
|
||||
end
|
||||
|
||||
sig { params(headers: ActionDispatch::Http::Headers).returns(T::Boolean) }
|
||||
def document_server_authorize(headers:)
|
||||
document_server_enabled ? verify(headers:) : true
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def document_server_enabled
|
||||
enabled && @config.jwt_use_for_request
|
||||
end
|
||||
|
||||
sig { params(headers: ActionDispatch::Http::Headers).returns(T::Boolean) }
|
||||
def verify(headers:)
|
||||
header = headers[@config.jwt_header]
|
||||
return false unless header
|
||||
token = header.sub('Bearer ', '')
|
||||
decoded = decode(token)
|
||||
!decoded.nil?
|
||||
end
|
||||
|
||||
sig { params(payload: T.untyped).returns(String) }
|
||||
def encode(payload:)
|
||||
JWT.encode(
|
||||
payload,
|
||||
@config.jwt_secret,
|
||||
AuthorizationManager.algorithm
|
||||
)
|
||||
end
|
||||
|
||||
sig { params(payload: String).returns(T.untyped) }
|
||||
def decode(payload:)
|
||||
decoded = JWT.decode(
|
||||
payload,
|
||||
@config.jwt_secret,
|
||||
true,
|
||||
{
|
||||
algorithm: AuthorizationManager.algorithm
|
||||
}
|
||||
)
|
||||
decoded[0]
|
||||
rescue StandardError
|
||||
nil
|
||||
end
|
||||
|
||||
def self.algorithm
|
||||
'HS256'
|
||||
end
|
||||
end
|
||||
|
||||
class AuthorizationResponseError
|
||||
include ResponseError
|
||||
extend T::Sig
|
||||
|
||||
sig { returns(AuthorizationResponseError) }
|
||||
def self.forbidden
|
||||
AuthorizationResponseError.new(
|
||||
'forbidden'
|
||||
)
|
||||
end
|
||||
end
|
||||
@ -14,6 +14,13 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# typed: true
|
||||
# rubocop:disable Metrics/ClassLength
|
||||
# rubocop:disable Metrics/MethodLength
|
||||
# rubocop:disable Metrics/AbcSize
|
||||
# rubocop:disable Metrics/CyclomaticComplexity
|
||||
# rubocop:disable Metrics/PerceivedComplexity
|
||||
|
||||
require 'net/http'
|
||||
require 'mimemagic'
|
||||
|
||||
@ -92,7 +99,7 @@ class HomeController < ApplicationController
|
||||
end
|
||||
|
||||
body = JSON.parse(file_data)
|
||||
|
||||
|
||||
file_name = File.basename(body["filename"])
|
||||
lang = cookies[:ulang] ? cookies[:ulang] : "en"
|
||||
file_pass = body["filePass"] ? body["filePass"] : nil
|
||||
@ -144,45 +151,6 @@ class HomeController < ApplicationController
|
||||
|
||||
end
|
||||
|
||||
# downloading a history file from public
|
||||
def downloadhistory
|
||||
begin
|
||||
file_name = File.basename(params[:fileName])
|
||||
user_address = params[:userAddress]
|
||||
version = params[:ver]
|
||||
file = params[:file]
|
||||
isEmbedded = params[:dmode]
|
||||
|
||||
if JwtHelper.is_enabled && JwtHelper.use_for_request
|
||||
jwtHeader = Rails.configuration.header.empty? ? "Authorization" : Rails.configuration.header;
|
||||
if request.headers[jwtHeader]
|
||||
hdr = request.headers[jwtHeader]
|
||||
hdr.slice!(0, "Bearer ".length)
|
||||
token = JwtHelper.decode(hdr)
|
||||
if !token || token.eql?("")
|
||||
render plain: "JWT validation failed", :status => 403
|
||||
return
|
||||
end
|
||||
else
|
||||
render plain: "JWT validation failed", :status => 403
|
||||
return
|
||||
end
|
||||
end
|
||||
hist_path = DocumentHelper.storage_path(file_name, user_address) + "-hist" # or to the original document
|
||||
|
||||
file_path = File.join(hist_path, version, file)
|
||||
|
||||
# add headers to the response to specify the page parameters
|
||||
response.headers['Content-Length'] = File.size(file_path).to_s
|
||||
response.headers['Content-Type'] = MimeMagic.by_path(file_path).eql?(nil) ? nil : MimeMagic.by_path(file_path).type
|
||||
response.headers['Content-Disposition'] = "attachment;filename*=UTF-8\'\'" + ERB::Util.url_encode(file)
|
||||
|
||||
send_file file_path, :x_sendfile => true
|
||||
rescue => ex
|
||||
render plain: '{ "error": "File not found"}'
|
||||
end
|
||||
end
|
||||
|
||||
# tracking file changes
|
||||
def track
|
||||
file_data = TrackHelper.read_body(request) # read the request body
|
||||
@ -325,7 +293,7 @@ class HomeController < ApplicationController
|
||||
res = http.request(req)
|
||||
data = res.body
|
||||
|
||||
if data.size <= 0 || data.size > Rails.configuration.fileSizeMax
|
||||
if data.size <= 0 || data.size > ConfigurationManager.new.maximum_file_size
|
||||
render plain: '{"error": "File size is incorrect"}'
|
||||
return
|
||||
end
|
||||
@ -368,7 +336,7 @@ class HomeController < ApplicationController
|
||||
def reference
|
||||
body = JSON.parse(request.body.read)
|
||||
fileName = ""
|
||||
|
||||
|
||||
|
||||
if body.key?("referenceData")
|
||||
referenceData = body["referenceData"]
|
||||
@ -411,4 +379,4 @@ class HomeController < ApplicationController
|
||||
|
||||
render plain: data.to_json
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
1009
web/documentserver-example/ruby/app/history.rb
Normal file
1009
web/documentserver-example/ruby/app/history.rb
Normal file
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,203 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
require 'uri'
|
||||
|
||||
# The Configuration class provides the environment based configuration for the
|
||||
# example instance.
|
||||
# rubocop:disable Metrics/ClassLength
|
||||
class ConfigurationManager
|
||||
extend T::Sig
|
||||
|
||||
def initialize
|
||||
@version = T.let('1.5.1', String)
|
||||
end
|
||||
|
||||
# The URI through which an example instance can be accessed.
|
||||
sig { returns(T.nilable(URI::Generic)) }
|
||||
def example_uri
|
||||
url = ENV['EXAMPLE_URL']
|
||||
return nil if url.nil?
|
||||
URI.parse(url)
|
||||
end
|
||||
|
||||
# The public URI through which a document-server instance can be accessed.
|
||||
# For example, it can be used to grant the user's browser access to a
|
||||
# document-server.
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_public_uri
|
||||
url = ENV['DOCUMENT_SERVER_PUBLIC_URL'] || 'http://document-server'
|
||||
URI.parse(url)
|
||||
end
|
||||
|
||||
# The private URI through which a document-server instance can be accessed.
|
||||
# If no private URI is specified, it will be redirected to the public URI.
|
||||
# For example, it can be used when both an example instance and a
|
||||
# document-server instance are on the same closed network.
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_private_uri
|
||||
url = ENV['DOCUMENT_SERVER_PRIVATE_URL']
|
||||
return document_server_public_uri if url.nil?
|
||||
URI.parse(url)
|
||||
end
|
||||
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_api_uri
|
||||
path =
|
||||
ENV['DOCUMENT_SERVER_API_PATH'] ||
|
||||
'/web-apps/apps/api/documents/api.js'
|
||||
URI.join(document_server_public_uri.to_s, path)
|
||||
end
|
||||
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_preloader_uri
|
||||
path =
|
||||
ENV['DOCUMENT_SERVER_PRELOADER_PATH'] ||
|
||||
'/web-apps/apps/api/documents/cache-scripts.html'
|
||||
URI.join(document_server_public_uri.to_s, path)
|
||||
end
|
||||
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_command_uri
|
||||
path =
|
||||
ENV['DOCUMENT_SERVER_COMMAND_PATH'] ||
|
||||
'/coauthoring/CommandService.ashx'
|
||||
URI.join(document_server_private_uri.to_s, path)
|
||||
end
|
||||
|
||||
sig { returns(URI::Generic) }
|
||||
def document_server_converter_uri
|
||||
path =
|
||||
ENV['DOCUMENT_SERVER_CONVERTER_PATH'] ||
|
||||
'/ConvertService.ashx'
|
||||
URI.join(document_server_private_uri.to_s, path)
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def jwt_secret
|
||||
ENV['JWT_SECRET'] || ''
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def jwt_header
|
||||
ENV['JWT_HEADER'] || 'Authorization'
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def jwt_use_for_request
|
||||
env = ENV['JWT_USE_FOR_REQUEST']
|
||||
return ActiveModel::Type::Boolean.new.cast(env) if env
|
||||
true
|
||||
end
|
||||
|
||||
sig { returns(T::Boolean) }
|
||||
def ssl_verify_peer_mode_enabled
|
||||
env = ENV['SSL_VERIFY_PEER_MODE_ENABLED']
|
||||
return ActiveModel::Type::Boolean.new.cast(env) if env
|
||||
false
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def storage_path
|
||||
ENV['STORAGE_PATH'] || 'app_data'
|
||||
end
|
||||
|
||||
sig { returns(Numeric) }
|
||||
def maximum_file_size
|
||||
env = ENV['MAXIMUM_FILE_SIZE']
|
||||
return env.to_i if env
|
||||
5 * 1024 * 1024
|
||||
end
|
||||
|
||||
sig { returns(Numeric) }
|
||||
def convertation_timeout
|
||||
120
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def fillable_file_extensions
|
||||
'.docx|.oform'
|
||||
.split('|')
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def viewable_file_extensions
|
||||
'.djvu|.oxps|.pdf|.xps'
|
||||
.split('|')
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def editable_file_extensions
|
||||
'.csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx'
|
||||
.split('|')
|
||||
end
|
||||
|
||||
sig { returns(T::Array[String]) }
|
||||
def convertable_file_extensions
|
||||
'.doc|.dot|.dps|.dpt|.epub|.et|.ett|.fb2|.fodp|.fods|.fodt|.htm|.html|.mht|.mhtml|.odp|.ods|.odt|.otp|.ots|.ott|.pot|.pps|.ppt|.rtf|.stw|.sxc|.sxi|.sxw|.wps|.wpt|.xls|.xlsb|.xlt|.xml'
|
||||
.split('|')
|
||||
end
|
||||
|
||||
sig { returns(T::Hash[String, String]) }
|
||||
def languages
|
||||
{
|
||||
'en' => 'English',
|
||||
'hy' => 'Armenian',
|
||||
'az' => 'Azerbaijani',
|
||||
'eu' => 'Basque',
|
||||
'be' => 'Belarusian',
|
||||
'bg' => 'Bulgarian',
|
||||
'ca' => 'Catalan',
|
||||
'zh' => 'Chinese (Simplified)',
|
||||
'zh-TW' => 'Chinese (Traditional)',
|
||||
'cs' => 'Czech',
|
||||
'da' => 'Danish',
|
||||
'nl' => 'Dutch',
|
||||
'fi' => 'Finnish',
|
||||
'fr' => 'French',
|
||||
'gl' => 'Galego',
|
||||
'de' => 'German',
|
||||
'el' => 'Greek',
|
||||
'hu' => 'Hungarian',
|
||||
'id' => 'Indonesian',
|
||||
'it' => 'Italian',
|
||||
'ja' => 'Japanese',
|
||||
'ko' => 'Korean',
|
||||
'lo' => 'Lao',
|
||||
'lv' => 'Latvian',
|
||||
'ms' => 'Malay (Malaysia)',
|
||||
'no' => 'Norwegian',
|
||||
'pl' => 'Polish',
|
||||
'pt' => 'Portuguese (Brazil)',
|
||||
'pt-PT' => 'Portuguese (Portugal)',
|
||||
'ro' => 'Romanian',
|
||||
'ru' => 'Russian',
|
||||
'si' => 'Sinhala (Sri Lanka)',
|
||||
'sk' => 'Slovak',
|
||||
'sl' => 'Slovenian',
|
||||
'es' => 'Spanish',
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese',
|
||||
'aa-AA' => 'Test Language'
|
||||
}
|
||||
end
|
||||
end
|
||||
# rubocop:enable Metrics/ClassLength
|
||||
@ -14,6 +14,8 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# rubocop:disable all
|
||||
|
||||
class DocumentHelper
|
||||
|
||||
@@runtime_cache = {}
|
||||
@ -29,11 +31,8 @@ class DocumentHelper
|
||||
|
||||
# define max file size
|
||||
def file_size_max
|
||||
if Rails.configuration.fileSizeMax == nil
|
||||
5 * 1024 * 1024
|
||||
else
|
||||
Rails.configuration.fileSizeMax # or get it from the config
|
||||
end
|
||||
config = ConfigurationManager.new
|
||||
config.maximum_file_size
|
||||
end
|
||||
|
||||
# all the supported file extensions
|
||||
@ -42,38 +41,26 @@ class DocumentHelper
|
||||
end
|
||||
|
||||
def fill_forms_exts
|
||||
if Rails.configuration.fillDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.fillDocs.split("|")
|
||||
end
|
||||
config = ConfigurationManager.new
|
||||
config.fillable_file_extensions
|
||||
end
|
||||
|
||||
# file extensions that can be viewed
|
||||
def viewed_exts
|
||||
if Rails.configuration.viewedDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.viewedDocs.split("|")
|
||||
end
|
||||
config = ConfigurationManager.new
|
||||
config.viewable_file_extensions
|
||||
end
|
||||
|
||||
# file extensions that can be edited
|
||||
def edited_exts
|
||||
if Rails.configuration.editedDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.editedDocs.split("|")
|
||||
end
|
||||
config = ConfigurationManager.new
|
||||
config.editable_file_extensions
|
||||
end
|
||||
|
||||
# file extensions that can be converted
|
||||
def convert_exts
|
||||
if Rails.configuration.convertDocs.empty?
|
||||
[]
|
||||
else
|
||||
Rails.configuration.convertDocs.split("|")
|
||||
end
|
||||
config = ConfigurationManager.new
|
||||
config.convertable_file_extensions
|
||||
end
|
||||
|
||||
# get current user host address
|
||||
@ -83,8 +70,9 @@ class DocumentHelper
|
||||
|
||||
# get the storage path of the given file
|
||||
def storage_path(file_name, user_address)
|
||||
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
|
||||
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address)) # get the path to the directory for the host address
|
||||
config = ConfigurationManager.new
|
||||
directory = File.absolute_path?(config.storage_path) ? config.storage_path
|
||||
: Rails.root.join('public', config.storage_path, cur_user_host_address(user_address)) # get the path to the directory for the host address
|
||||
|
||||
# create a new directory if it doesn't exist
|
||||
unless File.directory?(directory)
|
||||
@ -97,8 +85,9 @@ class DocumentHelper
|
||||
|
||||
# get the path to the forcesaved file version
|
||||
def forcesave_path(file_name, user_address, create)
|
||||
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
|
||||
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
|
||||
config = ConfigurationManager.new
|
||||
directory = File.absolute_path?(config.storage_path) ? config.storage_path
|
||||
: Rails.root.join('public', config.storage_path, cur_user_host_address(user_address))
|
||||
|
||||
# the directory with host address doesn't exist
|
||||
unless File.directory?(directory)
|
||||
@ -151,7 +140,8 @@ class DocumentHelper
|
||||
Dir.foreach(hist_dir) {|e| # run through all the file versions
|
||||
next if e.eql?(".")
|
||||
next if e.eql?("..")
|
||||
if File.directory?(File.join(hist_dir, e))
|
||||
path = File.join(hist_dir, e)
|
||||
if File.directory?(path) && !Dir.empty?(path)
|
||||
ver += 1 # and count them
|
||||
end
|
||||
}
|
||||
@ -176,8 +166,9 @@ class DocumentHelper
|
||||
|
||||
# get all the stored files from the folder
|
||||
def get_stored_files(user_address)
|
||||
directory = File.absolute_path?(Rails.configuration.storagePath) ? Rails.configuration.storagePath
|
||||
: Rails.root.join('public', Rails.configuration.storagePath, cur_user_host_address(user_address))
|
||||
config = ConfigurationManager.new
|
||||
directory = File.absolute_path?(config.storage_path) ? config.storage_path
|
||||
: Rails.root.join('public', config.storage_path, cur_user_host_address(user_address))
|
||||
|
||||
arr = [];
|
||||
|
||||
@ -230,26 +221,20 @@ class DocumentHelper
|
||||
|
||||
# get file url
|
||||
def get_file_uri(file_name, for_document_server)
|
||||
uri = get_server_url(for_document_server) + '/' + Rails.configuration.storagePath + '/' + cur_user_host_address(nil) + '/' + ERB::Util.url_encode(file_name)
|
||||
config = ConfigurationManager.new
|
||||
uri = get_server_url(for_document_server) + '/' + config.storage_path + '/' + cur_user_host_address(nil) + '/' + ERB::Util.url_encode(file_name)
|
||||
|
||||
return uri
|
||||
end
|
||||
|
||||
# get history path url
|
||||
def get_historypath_uri(file_name,version,file,is_serverUrl=true)
|
||||
# for redirection to my link
|
||||
user_host = is_serverUrl ? '&userAddress=' + cur_user_host_address(nil) : ""
|
||||
uri = get_server_url(is_serverUrl) + '/downloadhistory/?fileName=' + ERB::Util.url_encode(file_name) + '&ver='+ version.to_s + '&file='+ ERB::Util.url_encode(file) + user_host
|
||||
return uri
|
||||
end
|
||||
|
||||
# get server url
|
||||
def get_server_url(for_document_server)
|
||||
if for_document_server && !Rails.configuration.urlExample.empty?
|
||||
return Rails.configuration.urlExample
|
||||
config = ConfigurationManager.new
|
||||
if for_document_server && config.example_uri
|
||||
return config.example_uri.to_s
|
||||
else
|
||||
return @@base_url
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# get callback url
|
||||
@ -323,7 +308,7 @@ class DocumentHelper
|
||||
"contentLength" => "#{(File.size(directory)/ 1024.0).round(2)} KB",
|
||||
"pureContentLength" => File.size(directory),
|
||||
"title" => fileName,
|
||||
"updated" => File.mtime(directory)
|
||||
"updated" => File.mtime(directory)
|
||||
}
|
||||
|
||||
if file_id == nil # if file id is undefined
|
||||
@ -344,11 +329,11 @@ class DocumentHelper
|
||||
end
|
||||
# enable ignore certificate
|
||||
def verify_ssl(file_uri, http)
|
||||
if file_uri.start_with?('https') && Rails.configuration.verify_peer_off.eql?('true')
|
||||
if file_uri.start_with?('https') && ConfigurationManager.new.ssl_verify_peer_mode_enabled
|
||||
http.use_ssl = true
|
||||
http.verify_mode = OpenSSL::SSL::VERIFY_NONE # set the flags for the server certificate verification at the beginning of SSL session
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -14,6 +14,8 @@
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
# rubocop:disable all
|
||||
|
||||
class FileModel
|
||||
|
||||
attr_accessor :file_name, :mode, :type, :user_ip, :lang, :user, :action_data, :direct_url
|
||||
@ -39,14 +41,10 @@ class FileModel
|
||||
File.extname(@file_name).downcase
|
||||
end
|
||||
|
||||
# get file url
|
||||
def file_uri
|
||||
DocumentHelper.get_file_uri(@file_name, true)
|
||||
end
|
||||
|
||||
# get file uri for document server
|
||||
def file_uri_user
|
||||
File.absolute_path?(Rails.configuration.storagePath) ? download_url + "&dmode=emb" : DocumentHelper.get_file_uri(@file_name, false)
|
||||
config = ConfigurationManager.new
|
||||
File.absolute_path?(config.storage_path) ? download_url + "&dmode=emb" : DocumentHelper.get_file_uri(@file_name, false)
|
||||
end
|
||||
|
||||
# get document type from its name (word, cell or slide)
|
||||
@ -146,7 +144,7 @@ class FileModel
|
||||
:lang => @lang ? @lang : "en",
|
||||
:callbackUrl => callback_url, # absolute URL to the document storage service
|
||||
:coEditing => editorsmode.eql?("view") && @user.id.eql?("uid-0") ? {
|
||||
:mode => "strict",
|
||||
:mode => "strict",
|
||||
:change => false
|
||||
} : nil,
|
||||
:createUrl => !@user.id.eql?("uid-0") ? create_url : nil,
|
||||
@ -164,7 +162,7 @@ class FileModel
|
||||
},
|
||||
:customization => { # the parameters for the editor interface
|
||||
:about => true, # the About section display
|
||||
:comments => true,
|
||||
:comments => true,
|
||||
:feedback => true, # the Feedback & Support menu button display
|
||||
:forcesave => false, # adding the request for the forced file saving to the callback handler
|
||||
:submitForm => submitForm, # the Submit form button state
|
||||
@ -182,111 +180,6 @@ class FileModel
|
||||
return config
|
||||
end
|
||||
|
||||
# get document history
|
||||
def get_history
|
||||
file_name = @file_name
|
||||
file_ext = File.extname(file_name).downcase
|
||||
doc_key = key()
|
||||
doc_uri = file_uri()
|
||||
|
||||
hist_dir = DocumentHelper.history_dir(DocumentHelper.storage_path(@file_name, nil)) # get the path to the file history
|
||||
cur_ver = DocumentHelper.get_file_version(hist_dir) # get the file version
|
||||
|
||||
if (cur_ver > 0) # if file was modified
|
||||
hist = []
|
||||
histData = {}
|
||||
|
||||
for i in 1..cur_ver # run through all the file versions
|
||||
obj = {}
|
||||
dataObj = {}
|
||||
ver_dir = DocumentHelper.version_dir(hist_dir, i) # get the path to the given file version
|
||||
|
||||
# get document key
|
||||
cur_key = doc_key
|
||||
if (i != cur_ver)
|
||||
File.open(File.join(ver_dir, "key.txt"), 'r') do |file|
|
||||
cur_key = file.read()
|
||||
end
|
||||
end
|
||||
obj["key"] = cur_key
|
||||
obj["version"] = i
|
||||
|
||||
if (i == 1) # check if the version number is equal to 1
|
||||
if File.file?(File.join(hist_dir, "createdInfo.json")) # check if the createdInfo.json file with meta data exists
|
||||
File.open(File.join(hist_dir, "createdInfo.json"), 'r') do |file| # open it
|
||||
cr_info = JSON.parse(file.read()) # parse the file content
|
||||
|
||||
# write information about changes to the object
|
||||
obj["created"] = cr_info["created"]
|
||||
obj["user"] = {
|
||||
:id => cr_info["uid"],
|
||||
:name => cr_info["uname"]
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# get the history data from the previous file version and write key and url information about it
|
||||
dataObj["fileType"] = file_ext[1..file_ext.length]
|
||||
dataObj["key"] = cur_key
|
||||
dataObj["url"] = i == cur_ver ? doc_uri : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}")
|
||||
if is_enable_direct_url == true
|
||||
dataObj["directUrl"] = i == cur_ver ? download_url(false) : DocumentHelper.get_historypath_uri(file_name, i, "prev#{file_ext}", false)
|
||||
end
|
||||
dataObj["version"] = i
|
||||
|
||||
if (i > 1) # check if the version number is greater than 1
|
||||
changes = nil
|
||||
change = nil
|
||||
File.open(File.join(DocumentHelper.version_dir(hist_dir, i - 1), "changes.json"), 'r') do |file| # get the path to the changes.json file
|
||||
changes = JSON.parse(file.read()) # and parse its content
|
||||
end
|
||||
|
||||
change = changes["changes"][0]
|
||||
|
||||
# write information about changes to the object
|
||||
obj["changes"] = change ? changes["changes"] : nil
|
||||
obj["serverVersion"] = changes["serverVersion"]
|
||||
obj["created"] = change ? change["created"] : nil
|
||||
obj["user"] = change ? change["user"] : nil
|
||||
|
||||
prev = histData[(i - 2).to_s] # get the history data from the previous file version
|
||||
dataObj["previous"] = is_enable_direct_url == true ? { # write key and url information about previous file version with optional direct url
|
||||
:fileType => prev["fileType"],
|
||||
:key => prev["key"],
|
||||
:url => prev["url"],
|
||||
:directUrl => prev["directUrl"]
|
||||
} : {
|
||||
:fileType => prev["fileType"],
|
||||
:key => prev["key"],
|
||||
:url => prev["url"]
|
||||
}
|
||||
|
||||
# write the path to the diff.zip archive with differences in this file version
|
||||
dataObj["changesUrl"] = DocumentHelper.get_historypath_uri(file_name, i - 1, "diff.zip")
|
||||
end
|
||||
|
||||
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
|
||||
dataObj["token"] = JwtHelper.encode(dataObj) # encode a payload object into a token and write it to the data object
|
||||
end
|
||||
|
||||
hist.push(obj) # add object dictionary to the hist list
|
||||
histData[(i - 1).to_s] = dataObj # write data object information to the history data
|
||||
end
|
||||
|
||||
return {
|
||||
:hist => { # write history information about the current file version to the hist
|
||||
:currentVersion => cur_ver,
|
||||
:history => hist
|
||||
},
|
||||
:histData => histData
|
||||
}
|
||||
end
|
||||
|
||||
return nil
|
||||
|
||||
end
|
||||
|
||||
# get image information
|
||||
def get_insert_image
|
||||
insert_image = is_enable_direct_url == true ? {
|
||||
@ -319,7 +212,7 @@ class FileModel
|
||||
if JwtHelper.is_enabled # check if a secret key to generate token exists or not
|
||||
compare_file["token"] = JwtHelper.encode(compare_file) # encode a payload object into a token and write it to the compare_file object
|
||||
end
|
||||
|
||||
|
||||
return compare_file
|
||||
end
|
||||
|
||||
@ -351,4 +244,4 @@ class FileModel
|
||||
return @direct_url != nil && @direct_url == "true"
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@ -18,9 +18,9 @@ require 'jwt'
|
||||
|
||||
class JwtHelper
|
||||
|
||||
@jwt_secret = Rails.configuration.jwtSecret
|
||||
@token_use_for_request = Rails.configuration.token_use_for_request
|
||||
|
||||
@jwt_secret = ConfigurationManager.new.jwt_secret
|
||||
@token_use_for_request = ConfigurationManager.new.jwt_use_for_request
|
||||
|
||||
class << self
|
||||
# check if a secret key to generate token exists or not
|
||||
def is_enabled
|
||||
|
||||
60
web/documentserver-example/ruby/app/models/proxy.rb
Normal file
60
web/documentserver-example/ruby/app/models/proxy.rb
Normal file
@ -0,0 +1,60 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
require 'uri'
|
||||
|
||||
# The Proxy class provides interfaces that may be useful if a document-server
|
||||
# instance and an example instance communicate through a proxy server.
|
||||
class Proxy
|
||||
extend T::Sig
|
||||
|
||||
sig { params(configuration: ConfigurationManager).void }
|
||||
def initialize(configuration)
|
||||
@config = configuration
|
||||
end
|
||||
|
||||
# Resolves with a private document-server URI if the specified URI based on a
|
||||
# public document-server URI.
|
||||
sig { params(url: String).returns(URI::Generic) }
|
||||
def resolve_document_server_uri(url)
|
||||
uri = URI(url)
|
||||
|
||||
return uri unless equal_document_server_public_uri(uri)
|
||||
|
||||
swap_docuemnt_server_public_uri(uri)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
sig { params(uri: URI::Generic).returns(T::Boolean) }
|
||||
def equal_document_server_public_uri(uri)
|
||||
uri.scheme == @config.document_server_public_uri.scheme && \
|
||||
uri.host == @config.document_server_public_uri.host && \
|
||||
uri.port == @config.document_server_public_uri.port
|
||||
end
|
||||
|
||||
sig { params(uri: URI::Generic).returns(URI::Generic) }
|
||||
def swap_docuemnt_server_public_uri(uri)
|
||||
swaped_uri = uri
|
||||
swaped_uri.scheme = @config.document_server_private_uri.scheme
|
||||
swaped_uri.host = @config.document_server_private_uri.host
|
||||
swaped_uri.port = @config.document_server_private_uri.port
|
||||
swaped_uri
|
||||
end
|
||||
end
|
||||
@ -16,8 +16,8 @@
|
||||
|
||||
class ServiceConverter
|
||||
|
||||
@@convert_timeout = Rails.configuration.timeout # get the convertion timeout from the config
|
||||
@@document_converter_url = Rails.configuration.urlSite + Rails.configuration.urlConverter # get the converter url from the config
|
||||
@@convert_timeout = ConfigurationManager.new.convertation_timeout
|
||||
@@document_converter_url = ConfigurationManager.new.document_server_converter_uri.to_s
|
||||
|
||||
class << self
|
||||
|
||||
|
||||
@ -17,6 +17,7 @@
|
||||
require 'net/http'
|
||||
|
||||
class TrackHelper
|
||||
@@document_command_url = ConfigurationManager.new.document_server_command_uri.to_s
|
||||
|
||||
class << self
|
||||
|
||||
@ -60,8 +61,34 @@ class TrackHelper
|
||||
return file_data
|
||||
end
|
||||
|
||||
def resolve_file_data(file_data)
|
||||
config = ConfigurationManager.new
|
||||
proxy = Proxy.new(config)
|
||||
|
||||
url = file_data['url']
|
||||
file_data['url'] = proxy.resolve_document_server_uri(url).to_s if url
|
||||
|
||||
changesurl = file_data['changesurl']
|
||||
file_data['changesurl'] = proxy.resolve_document_server_uri(changesurl).to_s if changesurl
|
||||
|
||||
home = file_data['home']
|
||||
if home
|
||||
home_url = home['url']
|
||||
home['url'] = proxy.resolve_document_server_uri(home_url).to_s if home_url
|
||||
|
||||
home_changesurl = home['changesurl']
|
||||
home['changesurl'] = proxy.resolve_document_server_uri(home_changesurl).to_s if home_changesurl
|
||||
|
||||
file_data['home'] = home
|
||||
end
|
||||
|
||||
file_data
|
||||
end
|
||||
|
||||
# file saving process
|
||||
def process_save(file_data, file_name, user_address)
|
||||
def process_save(raw_file_data, file_name, user_address)
|
||||
file_data = resolve_file_data(raw_file_data)
|
||||
|
||||
download_uri = file_data['url']
|
||||
if download_uri.eql?(nil)
|
||||
saved = 1
|
||||
@ -211,8 +238,6 @@ class TrackHelper
|
||||
|
||||
# send the command request
|
||||
def command_request(method, key, meta = nil)
|
||||
document_command_url = Rails.configuration.urlSite + Rails.configuration.commandUrl # get the document command url
|
||||
|
||||
# create a payload object with the method and key
|
||||
payload = {
|
||||
:c => method,
|
||||
@ -226,10 +251,10 @@ class TrackHelper
|
||||
data = nil
|
||||
begin
|
||||
|
||||
uri = URI.parse(document_command_url) # parse the document command url
|
||||
uri = URI.parse(@@document_command_url) # parse the document command url
|
||||
http = Net::HTTP.new(uri.host, uri.port) # create a connection to the http server
|
||||
|
||||
DocumentHelper.verify_ssl(document_command_url, http)
|
||||
DocumentHelper.verify_ssl(@@document_command_url, http)
|
||||
|
||||
req = Net::HTTP::Post.new(uri.request_uri) # create the post request
|
||||
req.add_field("Content-Type", "application/json") # set headers
|
||||
|
||||
57
web/documentserver-example/ruby/app/proxy.rb
Normal file
57
web/documentserver-example/ruby/app/proxy.rb
Normal file
@ -0,0 +1,57 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
require 'uri'
|
||||
|
||||
require_relative 'models/configuration_manager'
|
||||
|
||||
class ProxyManager
|
||||
extend T::Sig
|
||||
|
||||
sig do
|
||||
params(
|
||||
config: ConfigurationManager,
|
||||
base_url: String,
|
||||
remote_ip: String,
|
||||
user_host: T.nilable(String)
|
||||
)
|
||||
.void
|
||||
end
|
||||
def initialize(
|
||||
config:,
|
||||
base_url:,
|
||||
remote_ip:,
|
||||
user_host: nil
|
||||
)
|
||||
@config = config
|
||||
@base_url = base_url
|
||||
@remote_ip = remote_ip
|
||||
@user_host = user_host
|
||||
end
|
||||
|
||||
sig { returns(URI::Generic) }
|
||||
def example_uri
|
||||
@config.example_uri || URI(@base_url)
|
||||
end
|
||||
|
||||
sig { returns(String) }
|
||||
def user_host
|
||||
(@user_host || @remote_ip).gsub(/[^0-9\-.a-zA-Z_=]/, '_')
|
||||
end
|
||||
end
|
||||
39
web/documentserver-example/ruby/app/response.rb
Normal file
39
web/documentserver-example/ruby/app/response.rb
Normal file
@ -0,0 +1,39 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
module ResponseError
|
||||
extend T::Sig
|
||||
|
||||
sig { params(error: String).void }
|
||||
def initialize(error)
|
||||
@error = error
|
||||
@success = false
|
||||
end
|
||||
|
||||
def to_json(*options)
|
||||
as_json.to_json(*options)
|
||||
end
|
||||
|
||||
def as_json(_ = {})
|
||||
{
|
||||
error: @error,
|
||||
success: @success
|
||||
}
|
||||
end
|
||||
end
|
||||
72
web/documentserver-example/ruby/app/storage.rb
Normal file
72
web/documentserver-example/ruby/app/storage.rb
Normal file
@ -0,0 +1,72 @@
|
||||
#
|
||||
# (c) Copyright Ascensio System SIA 2023
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
|
||||
# frozen_string_literal: true
|
||||
# typed: true
|
||||
|
||||
require 'pathname'
|
||||
require_relative 'models/configuration_manager'
|
||||
require_relative 'proxy'
|
||||
|
||||
# ```text
|
||||
# /application_directory
|
||||
# └─ storage_directory
|
||||
# └─ user_directory
|
||||
# └─ source_file
|
||||
#
|
||||
# /srv
|
||||
# └─ storage
|
||||
# └─ 172.19.0.1
|
||||
# └─ document.docx
|
||||
# ```
|
||||
class StorageManager
|
||||
extend T::Sig
|
||||
|
||||
sig do
|
||||
params(
|
||||
config: ConfigurationManager,
|
||||
proxy_manager: ProxyManager,
|
||||
source_basename: String
|
||||
)
|
||||
.void
|
||||
end
|
||||
def initialize(config:, proxy_manager:, source_basename:)
|
||||
@config = config
|
||||
@proxy_manager = proxy_manager
|
||||
@source_basename = source_basename
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def source_file
|
||||
user_directory.join(@source_basename)
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def user_directory
|
||||
directory = storage_directory.join(@proxy_manager.user_host)
|
||||
FileUtils.mkdir(directory) unless directory.exist?
|
||||
directory
|
||||
end
|
||||
|
||||
sig { returns(Pathname) }
|
||||
def storage_directory
|
||||
# TODO: move to the Configuration.
|
||||
path = Pathname.new(@config.storage_path)
|
||||
storage_path = path.absolute? ? path : Rails.root.join('public', path)
|
||||
FileUtils.mkdir(storage_path) unless storage_path.exist?
|
||||
storage_path
|
||||
end
|
||||
end
|
||||
@ -21,7 +21,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script src="<%= Rails.configuration.urlSite + Rails.configuration.urlApi %>"></script>
|
||||
<script src="<%= ConfigurationManager.new.document_server_api_uri.to_s %>"></script>
|
||||
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
@ -109,13 +109,67 @@
|
||||
// the user is trying to select document for comparing by clicking the Document from Storage button
|
||||
var onRequestCompareFile = function() {
|
||||
docEditor.setRevisedFile(<%= raw @file.get_compare_file.to_json %>); // select a document for comparing
|
||||
};
|
||||
};
|
||||
|
||||
// the user is trying to select recipients data by clicking the Mail merge button
|
||||
var onRequestMailMergeRecipients = function (event) {
|
||||
docEditor.setMailMergeRecipients(<%= raw @file.dataMailMergeRecipients.to_json %>); // insert recipient data for mail merge into the file
|
||||
};
|
||||
|
||||
function onRequestHistory() {
|
||||
const fileName = "<%= @file.file_name %>"
|
||||
// const directURL
|
||||
const request = new XMLHttpRequest()
|
||||
request.open("GET", `history/${fileName}`)
|
||||
request.send()
|
||||
request.onload = function () {
|
||||
response = JSON.parse(request.response)
|
||||
if (request.status != 200) {
|
||||
innerAlert(response.error)
|
||||
return
|
||||
}
|
||||
docEditor.refreshHistory(response)
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestHistoryData(event) {
|
||||
const fileName = "<%= @file.file_name %>"
|
||||
const version = event.data
|
||||
// const directURL
|
||||
const request = new XMLHttpRequest()
|
||||
request.open("GET", `history/${fileName}/${version}/data`)
|
||||
request.send()
|
||||
request.onload = function () {
|
||||
response = JSON.parse(request.response)
|
||||
if (request.status != 200) {
|
||||
innerAlert(response.error)
|
||||
return
|
||||
}
|
||||
docEditor.setHistoryData(response)
|
||||
}
|
||||
}
|
||||
|
||||
function onRequestHistoryClose() {
|
||||
document.location.reload()
|
||||
}
|
||||
|
||||
function onRequestRestore(event) {
|
||||
const fileName = "<%= @file.file_name %>"
|
||||
const userID = "<%= @file.user.id %>"
|
||||
const version = event.data.version
|
||||
const request = new XMLHttpRequest()
|
||||
request.open("PUT", `history/${fileName}/${version}/restore?user_id=${userID}`)
|
||||
request.send()
|
||||
request.onload = function () {
|
||||
if (request.status != 200) {
|
||||
response = JSON.parse(request.response)
|
||||
innerAlert(response.error)
|
||||
return
|
||||
}
|
||||
onRequestHistory()
|
||||
}
|
||||
}
|
||||
|
||||
var onRequestSaveAs = function (event) { // the user is trying to save file by clicking Save Copy as... button
|
||||
var title = event.data.title;
|
||||
var url = event.data.url;
|
||||
@ -152,7 +206,7 @@
|
||||
};
|
||||
|
||||
var onRequestReferenceData = function(event) { // user refresh external data source
|
||||
|
||||
|
||||
event.data.directUrl = !!config.document.directUrl;
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.open("POST", "reference");
|
||||
@ -179,30 +233,18 @@
|
||||
'onMetaChange': onMetaChange,
|
||||
'onRequestInsertImage': onRequestInsertImage,
|
||||
'onRequestCompareFile': onRequestCompareFile,
|
||||
'onRequestMailMergeRecipients': onRequestMailMergeRecipients,
|
||||
'onRequestMailMergeRecipients': onRequestMailMergeRecipients
|
||||
};
|
||||
|
||||
<%
|
||||
history = @file.get_history
|
||||
usersMentions = @file.get_users_mentions %>
|
||||
|
||||
if (config.editorConfig.user.id) {
|
||||
<% if history %>
|
||||
// the user is trying to show the document version history
|
||||
config.events['onRequestHistory'] = function () {
|
||||
docEditor.refreshHistory(<%= raw history[:hist].to_json %>); // show the document version history
|
||||
};
|
||||
// the user is trying to click the specific document version in the document version history
|
||||
config.events['onRequestHistoryData'] = function (event) {
|
||||
var ver = event.data;
|
||||
var histData = <%= raw history[:histData].to_json %>;
|
||||
docEditor.setHistoryData(histData[ver - 1]); // send the link to the document for viewing the version history
|
||||
};
|
||||
// the user is trying to go back to the document from viewing the document version history
|
||||
config.events['onRequestHistoryClose'] = function () {
|
||||
document.location.reload();
|
||||
};
|
||||
<% end %>
|
||||
config.events.onRequestHistory = onRequestHistory
|
||||
config.events.onRequestHistoryData = onRequestHistoryData
|
||||
config.events.onRequestHistoryClose = onRequestHistoryClose
|
||||
config.events.onRequestRestore = onRequestRestore
|
||||
|
||||
// add mentions for not anonymous users
|
||||
config.events['onRequestUsers'] = function () {
|
||||
docEditor.setUsers({ // set a list of users to mention in the comments
|
||||
@ -241,4 +283,4 @@
|
||||
window.attachEvent("load", сonnectEditor);
|
||||
}
|
||||
|
||||
</script>
|
||||
</script>
|
||||
|
||||
@ -75,7 +75,7 @@
|
||||
data-tooltip="Choose the language for ONLYOFFICE editors interface"
|
||||
src="assets/info.svg" />
|
||||
<select class="select-user" id="language">
|
||||
<% Rails.configuration.languages.each { |key, language|%>
|
||||
<% ConfigurationManager.new.languages.each { |key, language|%>
|
||||
<option value="<%=key %>"> <%=language %> </option>
|
||||
<% } %>
|
||||
</select>
|
||||
@ -304,7 +304,7 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<span id="loadScripts" data-docs="<%= Rails.configuration.urlSite + Rails.configuration.urlPreloader %>"></span>
|
||||
<span id="loadScripts" data-docs="<%= ConfigurationManager.new.document_server_preloader_uri.to_s %>"></span>
|
||||
|
||||
<footer>
|
||||
<div class="center">
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env ruby.exe
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
load Gem.bin_path('bundler', 'bundle')
|
||||
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env ruby.exe
|
||||
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
||||
require_relative '../config/boot'
|
||||
require 'rails/commands'
|
||||
@ -1,4 +0,0 @@
|
||||
#!/usr/bin/env ruby.exe
|
||||
require_relative '../config/boot'
|
||||
require 'rake'
|
||||
Rake.application.run
|
||||
@ -1,29 +0,0 @@
|
||||
#!/usr/bin/env ruby.exe
|
||||
require 'pathname'
|
||||
|
||||
# path to your application root.
|
||||
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
|
||||
|
||||
Dir.chdir APP_ROOT do
|
||||
# This script is a starting point to setup your application.
|
||||
# Add necessary setup steps to this file:
|
||||
|
||||
puts "== Installing dependencies =="
|
||||
system "gem install bundler --conservative"
|
||||
system "bundle check || bundle install"
|
||||
|
||||
# puts "\n== Copying sample files =="
|
||||
# unless File.exist?("config/database.yml")
|
||||
# system "cp config/database.yml.sample config/database.yml"
|
||||
# end
|
||||
|
||||
puts "\n== Preparing database =="
|
||||
system "bin/rake db:setup"
|
||||
|
||||
puts "\n== Removing old logs and tempfiles =="
|
||||
system "rm -f log/*"
|
||||
system "rm -rf tmp/cache"
|
||||
|
||||
puts "\n== Restarting application server =="
|
||||
system "touch tmp/restart.txt"
|
||||
end
|
||||
@ -1,15 +1,4 @@
|
||||
# This file is used by Rack-based servers to start the application.
|
||||
require_relative 'config/application'
|
||||
|
||||
require ::File.expand_path('../config/environment', __FILE__)
|
||||
Rails.application.initialize!
|
||||
run Rails.application
|
||||
|
||||
require 'rack/cors'
|
||||
use Rack::Cors do
|
||||
|
||||
allow do
|
||||
origins '*'
|
||||
resource '*',
|
||||
:headers => :any,
|
||||
:methods => [:get]
|
||||
end
|
||||
end
|
||||
@ -1,97 +1,106 @@
|
||||
require File.expand_path('../boot', __FILE__)
|
||||
# rubocop:disable Metrics/BlockLength
|
||||
|
||||
# Pick the frameworks you want:
|
||||
require "active_model/railtie"
|
||||
require "active_job/railtie"
|
||||
require "active_record/railtie"
|
||||
require "action_controller/railtie"
|
||||
require "action_mailer/railtie"
|
||||
require "action_view/railtie"
|
||||
require "sprockets/railtie"
|
||||
# require "rails/test_unit/railtie"
|
||||
require_relative 'boot'
|
||||
|
||||
require 'active_model/railtie'
|
||||
require 'action_controller/railtie'
|
||||
require 'action_view/railtie'
|
||||
require 'sprockets/railtie'
|
||||
|
||||
# Require the gems listed in Gemfile, including any gems
|
||||
# you've limited to :test, :development, or :production.
|
||||
Bundler.require(*Rails.groups)
|
||||
|
||||
module OnlineEditorsExampleRuby
|
||||
require_relative '../app/controllers/application_controller'
|
||||
require_relative '../app/history'
|
||||
|
||||
module Example
|
||||
class Application < Rails::Application
|
||||
# TODO: move to the Convifgutaion.
|
||||
# It needs to be moved to the Configuration, but it can't be done at the
|
||||
# moment because replacing it causes the application to crash.
|
||||
Rails.configuration.header = 'Authorization'
|
||||
|
||||
config.middleware.insert_before 0, Rack::Cors do
|
||||
allow do
|
||||
origins '*'
|
||||
resource '*',
|
||||
headers: :any,
|
||||
methods: [:get, :post, :patch, :delete, :put, :options]
|
||||
resource '*', headers: :any, methods: %i[get post patch delete put options]
|
||||
end
|
||||
end
|
||||
|
||||
Rails.configuration.version="1.5.1"
|
||||
config.action_controller.perform_caching = true
|
||||
config.active_support.deprecation = :log
|
||||
config.assets.debug = false
|
||||
config.assets.digest = true
|
||||
config.cache_classes = true
|
||||
config.consider_all_requests_local = true
|
||||
config.eager_load = true
|
||||
config.require_master_key = false
|
||||
config.secret_key_base = SecureRandom.uuid
|
||||
|
||||
Rails.configuration.fileSizeMax=5242880
|
||||
Rails.configuration.storagePath="app_data"
|
||||
Rails.configuration.timeout=120
|
||||
routes.append do
|
||||
root to: 'home#index'
|
||||
match '/convert', to: 'home#convert', via: 'post'
|
||||
match '/csv', to: 'home#csv', via: 'get'
|
||||
match '/download', to: 'home#download', via: 'get'
|
||||
match '/downloadhistory', to: 'home#downloadhistory', via: 'get'
|
||||
match '/editor', to: 'home#editor', via: 'get'
|
||||
match '/files', to: 'home#files', via: 'get'
|
||||
match '/index', to: 'home#index', via: 'get'
|
||||
match '/reference', to: 'home#reference', via: 'post'
|
||||
match '/remove', to: 'home#remove', via: 'get'
|
||||
match '/rename', to: 'home#rename', via: 'post'
|
||||
match '/restore', to: 'home#restore', via: 'put'
|
||||
match '/sample', to: 'home#sample', via: 'get'
|
||||
match '/saveas', to: 'home#saveas', via: 'post'
|
||||
match '/track', to: 'home#track', via: 'post'
|
||||
match '/upload', to: 'home#upload', via: 'post'
|
||||
|
||||
Rails.configuration.fillDocs=".docx|.oform"
|
||||
Rails.configuration.viewedDocs=".djvu|.oxps|.pdf|.xps"
|
||||
Rails.configuration.editedDocs=".csv|.docm|.docx|.docxf|.dotm|.dotx|.epub|.fb2|.html|.odp|.ods|.odt|.otp|.ots|.ott|.potm|.potx|.ppsm|.ppsx|.pptm|.pptx|.rtf|.txt|.xlsm|.xlsx|.xltm|.xltx"
|
||||
Rails.configuration.convertDocs=".doc|.dot|.dps|.dpt|.epub|.et|.ett|.fb2|.fodp|.fods|.fodt|.htm|.html|.mht|.mhtml|.odp|.ods|.odt|.otp|.ots|.ott|.pot|.pps|.ppt|.rtf|.stw|.sxc|.sxi|.sxw|.wps|.wpt|.xls|.xlsb|.xlt|.xml"
|
||||
file_basename_constraint = /[^\/]*/
|
||||
|
||||
Rails.configuration.urlSite="http://documentserver/"
|
||||
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 = ""
|
||||
Rails.configuration.header="Authorization"
|
||||
Rails.configuration.token_use_for_request=true
|
||||
|
||||
Rails.configuration.verify_peer_off = "true"
|
||||
|
||||
Rails.configuration.languages={
|
||||
'en' => 'English',
|
||||
'hy' => 'Armenian',
|
||||
'az' => 'Azerbaijani',
|
||||
'eu' => 'Basque',
|
||||
'be' => 'Belarusian',
|
||||
'bg' => 'Bulgarian',
|
||||
'ca' => 'Catalan',
|
||||
'zh' => 'Chinese (Simplified)',
|
||||
'zh-TW' => 'Chinese (Traditional)',
|
||||
'cs' => 'Czech',
|
||||
'da' => 'Danish',
|
||||
'nl' => 'Dutch',
|
||||
'fi' => 'Finnish',
|
||||
'fr' => 'French',
|
||||
'gl' => 'Galego',
|
||||
'de' => 'German',
|
||||
'el' => 'Greek',
|
||||
'hu' => 'Hungarian',
|
||||
'id' => 'Indonesian',
|
||||
'it' => 'Italian',
|
||||
'ja' => 'Japanese',
|
||||
'ko' => 'Korean',
|
||||
'lo' => 'Lao',
|
||||
'lv' => 'Latvian',
|
||||
'ms' => 'Malay (Malaysia)',
|
||||
'no' => 'Norwegian',
|
||||
'pl' => 'Polish',
|
||||
'pt' => 'Portuguese (Brazil)',
|
||||
'pt-PT' => 'Portuguese (Portugal)',
|
||||
'ro' => 'Romanian',
|
||||
'ru' => 'Russian',
|
||||
'si' => 'Sinhala (Sri Lanka)',
|
||||
'sk' => 'Slovak',
|
||||
'sl' => 'Slovenian',
|
||||
'es' => 'Spanish',
|
||||
'sv' => 'Swedish',
|
||||
'tr' => 'Turkish',
|
||||
'uk' => 'Ukrainian',
|
||||
'vi' => 'Vietnamese',
|
||||
'aa-AA' => 'Test Language'
|
||||
}
|
||||
get(
|
||||
'/history/:source_basename',
|
||||
to: HistoryController.action('history'),
|
||||
format: false,
|
||||
defaults: {
|
||||
format: 'html'
|
||||
},
|
||||
constraints: {
|
||||
source_basename: file_basename_constraint
|
||||
}
|
||||
)
|
||||
get(
|
||||
'/history/:source_basename/:version/data',
|
||||
to: HistoryController.action('data'),
|
||||
format: false,
|
||||
defaults: {
|
||||
format: 'html'
|
||||
},
|
||||
constraints: {
|
||||
source_basename: file_basename_constraint
|
||||
}
|
||||
)
|
||||
get(
|
||||
'/history/:source_basename/:version/download/:requested_basename',
|
||||
to: HistoryController.action('download'),
|
||||
format: false,
|
||||
defaults: {
|
||||
foramt: 'html'
|
||||
},
|
||||
constraints: {
|
||||
source_basename: file_basename_constraint,
|
||||
requested_basename: file_basename_constraint
|
||||
}
|
||||
)
|
||||
put(
|
||||
'/history/:source_basename/:version/restore',
|
||||
to: HistoryController.action('restore'),
|
||||
format: false,
|
||||
defaults: {
|
||||
foramt: 'html'
|
||||
},
|
||||
constraints: {
|
||||
source_basename: file_basename_constraint
|
||||
}
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -1,3 +1,3 @@
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
||||
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
|
||||
|
||||
require 'bundler/setup' # Set up gems listed in the Gemfile.
|
||||
require 'bundler/setup'
|
||||
|
||||
@ -1,25 +0,0 @@
|
||||
# SQLite version 3.x
|
||||
# gem install sqlite3
|
||||
#
|
||||
# Ensure the SQLite 3 gem is defined in your Gemfile
|
||||
# gem 'sqlite3'
|
||||
#
|
||||
default: &default
|
||||
adapter: sqlite3
|
||||
pool: 5
|
||||
timeout: 5000
|
||||
|
||||
development:
|
||||
<<: *default
|
||||
database: db/development.sqlite3
|
||||
|
||||
# Warning: The database defined as "test" will be erased and
|
||||
# re-generated from your development database when you run "rake".
|
||||
# Do not set this db to the same as development or production.
|
||||
test:
|
||||
<<: *default
|
||||
database: db/test.sqlite3
|
||||
|
||||
production:
|
||||
<<: *default
|
||||
database: db/production.sqlite3
|
||||
@ -1,5 +0,0 @@
|
||||
# Load the Rails application.
|
||||
require File.expand_path('../application', __FILE__)
|
||||
|
||||
# Initialize the Rails application.
|
||||
Rails.application.initialize!
|
||||
@ -1,41 +0,0 @@
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# In the development environment your application's code is reloaded on
|
||||
# every request. This slows down response time but is perfect for development
|
||||
# since you don't have to restart the web server when you make code changes.
|
||||
config.cache_classes = false
|
||||
|
||||
# Do not eager load code on boot.
|
||||
config.eager_load = false
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Don't care if the mailer can't send.
|
||||
config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Print deprecation notices to the Rails logger.
|
||||
config.active_support.deprecation = :log
|
||||
|
||||
# Raise an error on page load if there are pending migrations.
|
||||
config.active_record.migration_error = :page_load
|
||||
|
||||
# Debug mode disables concatenation and preprocessing of assets.
|
||||
# This option may cause significant delays in view rendering with a large
|
||||
# number of complex assets.
|
||||
config.assets.debug = true
|
||||
|
||||
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
|
||||
# yet still be able to expire them through the digest params.
|
||||
config.assets.digest = true
|
||||
|
||||
# Adds additional error checking when serving assets at runtime.
|
||||
# Checks for improperly declared sprockets dependencies.
|
||||
# Raises helpful error messages.
|
||||
config.assets.raise_runtime_errors = true
|
||||
|
||||
# Raises error for missing translations
|
||||
# config.action_view.raise_on_missing_translations = true
|
||||
end
|
||||
@ -1,79 +0,0 @@
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# Code is not reloaded between requests.
|
||||
config.cache_classes = true
|
||||
|
||||
# Eager load code on boot. This eager loads most of Rails and
|
||||
# your application in memory, allowing both threaded web servers
|
||||
# and those relying on copy on write to perform better.
|
||||
# Rake tasks automatically ignore this option for performance.
|
||||
config.eager_load = true
|
||||
|
||||
# Full error reports are disabled and caching is turned on.
|
||||
config.consider_all_requests_local = false
|
||||
config.action_controller.perform_caching = true
|
||||
|
||||
# Enable Rack::Cache to put a simple HTTP cache in front of your application
|
||||
# Add `rack-cache` to your Gemfile before enabling this.
|
||||
# For large-scale production use, consider using a caching reverse proxy like
|
||||
# NGINX, varnish or squid.
|
||||
# config.action_dispatch.rack_cache = true
|
||||
|
||||
# Disable serving static files from the `/public` folder by default since
|
||||
# Apache or NGINX already handles this.
|
||||
config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present?
|
||||
|
||||
# Compress JavaScripts and CSS.
|
||||
config.assets.js_compressor = :uglifier
|
||||
# config.assets.css_compressor = :sass
|
||||
|
||||
# Do not fallback to assets pipeline if a precompiled asset is missed.
|
||||
config.assets.compile = false
|
||||
|
||||
# Asset digests allow you to set far-future HTTP expiration dates on all assets,
|
||||
# yet still be able to expire them through the digest params.
|
||||
config.assets.digest = true
|
||||
|
||||
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
|
||||
|
||||
# Specifies the header that your server uses for sending files.
|
||||
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
|
||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
||||
|
||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||
# config.force_ssl = true
|
||||
|
||||
# Use the lowest log level to ensure availability of diagnostic information
|
||||
# when problems arise.
|
||||
config.log_level = :debug
|
||||
|
||||
# Prepend all log lines with the following tags.
|
||||
# config.log_tags = [ :subdomain, :uuid ]
|
||||
|
||||
# Use a different logger for distributed setups.
|
||||
# config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
|
||||
|
||||
# Use a different cache store in production.
|
||||
# config.cache_store = :mem_cache_store
|
||||
|
||||
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
|
||||
# config.action_controller.asset_host = 'http://assets.example.com'
|
||||
|
||||
# Ignore bad email addresses and do not raise email delivery errors.
|
||||
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
|
||||
# config.action_mailer.raise_delivery_errors = false
|
||||
|
||||
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
|
||||
# the I18n.default_locale when a translation cannot be found).
|
||||
config.i18n.fallbacks = true
|
||||
|
||||
# Send deprecation notices to registered listeners.
|
||||
config.active_support.deprecation = :notify
|
||||
|
||||
# Use default logging formatter so that PID and timestamp are not suppressed.
|
||||
config.log_formatter = ::Logger::Formatter.new
|
||||
|
||||
# Do not dump schema after migrations.
|
||||
config.active_record.dump_schema_after_migration = false
|
||||
end
|
||||
@ -1,42 +0,0 @@
|
||||
Rails.application.configure do
|
||||
# Settings specified here will take precedence over those in config/application.rb.
|
||||
|
||||
# The test environment is used exclusively to run your application's
|
||||
# test suite. You never need to work with it otherwise. Remember that
|
||||
# your test database is "scratch space" for the test suite and is wiped
|
||||
# and recreated between test runs. Don't rely on the data there!
|
||||
config.cache_classes = true
|
||||
|
||||
# Do not eager load code on boot. This avoids loading your whole application
|
||||
# just for the purpose of running a single test. If you are using a tool that
|
||||
# preloads Rails for running tests, you may have to set it to true.
|
||||
config.eager_load = false
|
||||
|
||||
# Configure static file server for tests with Cache-Control for performance.
|
||||
config.serve_static_files = true
|
||||
config.static_cache_control = 'public, max-age=3600'
|
||||
|
||||
# Show full error reports and disable caching.
|
||||
config.consider_all_requests_local = true
|
||||
config.action_controller.perform_caching = false
|
||||
|
||||
# Raise exceptions instead of rendering exception templates.
|
||||
config.action_dispatch.show_exceptions = false
|
||||
|
||||
# Disable request forgery protection in test environment.
|
||||
config.action_controller.allow_forgery_protection = false
|
||||
|
||||
# Tell Action Mailer not to deliver emails to the real world.
|
||||
# The :test delivery method accumulates sent emails in the
|
||||
# ActionMailer::Base.deliveries array.
|
||||
config.action_mailer.delivery_method = :test
|
||||
|
||||
# Randomize the order test cases are executed.
|
||||
config.active_support.test_order = :random
|
||||
|
||||
# Print deprecation notices to the stderr.
|
||||
config.active_support.deprecation = :stderr
|
||||
|
||||
# Raises error for missing translations
|
||||
# config.action_view.raise_on_missing_translations = true
|
||||
end
|
||||
@ -1,15 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Version of your assets, change this if you want to expire all your assets.
|
||||
Rails.application.config.assets.version = '1.0'
|
||||
Rails.application.config.assets.precompile += %w( editor.css )
|
||||
Rails.application.config.assets.precompile += %w( jquery-ui.css )
|
||||
Rails.application.config.assets.precompile += %w( stylesheet.css )
|
||||
Rails.application.config.assets.precompile += %w( media.css )
|
||||
|
||||
# Add additional assets to the asset load path
|
||||
# Rails.application.config.assets.paths << Emoji.images_path
|
||||
|
||||
# Precompile additional assets.
|
||||
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
|
||||
# Rails.application.config.assets.precompile += %w( search.js )
|
||||
@ -1,7 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
|
||||
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
|
||||
|
||||
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
|
||||
# Rails.backtrace_cleaner.remove_silencers!
|
||||
@ -1,3 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Rails.application.config.action_dispatch.cookies_serializer = :json
|
||||
@ -1,4 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Configure sensitive parameters which will be filtered from the log file.
|
||||
Rails.application.config.filter_parameters += [:password]
|
||||
@ -1,16 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new inflection rules using the following format. Inflections
|
||||
# are locale specific, and you may define rules for as many different
|
||||
# locales as you wish. All of these examples are active by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.plural /^(ox)$/i, '\1en'
|
||||
# inflect.singular /^(ox)en/i, '\1'
|
||||
# inflect.irregular 'person', 'people'
|
||||
# inflect.uncountable %w( fish sheep )
|
||||
# end
|
||||
|
||||
# These inflection rules are supported but not enabled by default:
|
||||
# ActiveSupport::Inflector.inflections(:en) do |inflect|
|
||||
# inflect.acronym 'RESTful'
|
||||
# end
|
||||
@ -1,4 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Add new mime types for use in respond_to blocks:
|
||||
# Mime::Type.register "text/richtext", :rtf
|
||||
@ -1,3 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
Rails.application.config.session_store :cookie_store, key: '_OnlineEditorsExampleRuby_session'
|
||||
@ -1,14 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# This file contains settings for ActionController::ParamsWrapper which
|
||||
# is enabled by default.
|
||||
|
||||
# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
|
||||
end
|
||||
|
||||
# To enable root element in JSON for ActiveRecord objects.
|
||||
# ActiveSupport.on_load(:active_record) do
|
||||
# self.include_root_in_json = true
|
||||
# end
|
||||
@ -1,23 +0,0 @@
|
||||
# Files in the config/locales directory are used for internationalization
|
||||
# and are automatically loaded by Rails. If you want to use locales other
|
||||
# than English, add the necessary files in this directory.
|
||||
#
|
||||
# To use the locales, use `I18n.t`:
|
||||
#
|
||||
# I18n.t 'hello'
|
||||
#
|
||||
# In views, this is aliased to just `t`:
|
||||
#
|
||||
# <%= t('hello') %>
|
||||
#
|
||||
# To use a different locale, set it with `I18n.locale`:
|
||||
#
|
||||
# I18n.locale = :es
|
||||
#
|
||||
# This would use the information in config/locales/es.yml.
|
||||
#
|
||||
# To learn more, please read the Rails Internationalization guide
|
||||
# available at http://guides.rubyonrails.org/i18n.html.
|
||||
|
||||
en:
|
||||
hello: "Hello world"
|
||||
@ -1,73 +0,0 @@
|
||||
Rails.application.routes.draw do
|
||||
root 'home#index'
|
||||
match '/index', to: 'home#index', via: 'get'
|
||||
match '/editor', to: 'home#editor', via: 'get'
|
||||
match '/sample', to: 'home#sample', via: 'get'
|
||||
match '/remove', to: 'home#remove', via: 'get'
|
||||
|
||||
match '/upload', to: 'home#upload', via: 'post'
|
||||
match '/download', to: 'home#download', via: 'get'
|
||||
match '/downloadhistory', to: 'home#downloadhistory', via: 'get'
|
||||
match '/convert', to: 'home#convert', via: 'post'
|
||||
match '/track', to: 'home#track', via: 'post'
|
||||
match '/csv', to: 'home#csv', via: 'get'
|
||||
match '/files', to: 'home#files', via: 'get'
|
||||
match '/saveas', to: 'home#saveas', via: 'post'
|
||||
match '/rename', to: 'home#rename', via: 'post'
|
||||
match '/reference', to: 'home#reference', via: 'post'
|
||||
|
||||
# The priority is based upon order of creation: first created -> highest priority.
|
||||
# See how all your routes lay out with "rake routes".
|
||||
|
||||
# You can have the root of your site routed with "root"
|
||||
# root 'welcome#index'
|
||||
|
||||
# Example of regular route:
|
||||
# get 'products/:id' => 'catalog#view'
|
||||
|
||||
# Example of named route that can be invoked with purchase_url(id: product.id)
|
||||
# get 'products/:id/purchase' => 'catalog#purchase', as: :purchase
|
||||
|
||||
# Example resource route (maps HTTP verbs to controller actions automatically):
|
||||
# resources :products
|
||||
|
||||
# Example resource route with options:
|
||||
# resources :products do
|
||||
# member do
|
||||
# get 'short'
|
||||
# post 'toggle'
|
||||
# end
|
||||
#
|
||||
# collection do
|
||||
# get 'sold'
|
||||
# end
|
||||
# end
|
||||
|
||||
# Example resource route with sub-resources:
|
||||
# resources :products do
|
||||
# resources :comments, :sales
|
||||
# resource :seller
|
||||
# end
|
||||
|
||||
# Example resource route with more complex sub-resources:
|
||||
# resources :products do
|
||||
# resources :comments
|
||||
# resources :sales do
|
||||
# get 'recent', on: :collection
|
||||
# end
|
||||
# end
|
||||
|
||||
# Example resource route with concerns:
|
||||
# concern :toggleable do
|
||||
# post 'toggle'
|
||||
# end
|
||||
# resources :posts, concerns: :toggleable
|
||||
# resources :photos, concerns: :toggleable
|
||||
|
||||
# Example resource route within a namespace:
|
||||
# namespace :admin do
|
||||
# # Directs /admin/products/* to Admin::ProductsController
|
||||
# # (app/controllers/admin/products_controller.rb)
|
||||
# resources :products
|
||||
# end
|
||||
end
|
||||
@ -1,22 +0,0 @@
|
||||
# Be sure to restart your server when you modify this file.
|
||||
|
||||
# Your secret key is used for verifying the integrity of signed cookies.
|
||||
# If you change this key, all old signed cookies will become invalid!
|
||||
|
||||
# Make sure the secret is at least 30 characters and all random,
|
||||
# no regular words or you'll be exposed to dictionary attacks.
|
||||
# You can use `rake secret` to generate a secure secret key.
|
||||
|
||||
# Make sure the secrets in this file are kept private
|
||||
# if you're sharing your code publicly.
|
||||
|
||||
development:
|
||||
secret_key_base: fadb8c51b54ebcb061791161d507fdaaa6df77e2ed6611101903bf48a20fffe0164a1fe9da16b5b400453de6b05dd46810de12ee468b3d695a4aa618801402a4
|
||||
|
||||
test:
|
||||
secret_key_base: 96b983c551091cb89dae1538233bbdba38f8ca742b61b2320fa7f9aa6a3f146bfda53da2c8cdf2001f66626826f8519eab4327a521d5485ab434f4241fe4d74f
|
||||
|
||||
# Do not keep production secrets in the repository,
|
||||
# instead read values from the environment.
|
||||
production:
|
||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||
@ -1,7 +0,0 @@
|
||||
# This file should contain all the record creation needed to seed the database with its default values.
|
||||
# The data can then be loaded with the rake db:seed (or created alongside the db with db:setup).
|
||||
#
|
||||
# Examples:
|
||||
#
|
||||
# cities = City.create([{ name: 'Chicago' }, { name: 'Copenhagen' }])
|
||||
# Mayor.create(name: 'Emanuel', city: cities.first)
|
||||
33
web/documentserver-example/ruby/docker-compose.yml
Normal file
33
web/documentserver-example/ruby/docker-compose.yml
Normal file
@ -0,0 +1,33 @@
|
||||
version: "3.8"
|
||||
|
||||
services:
|
||||
document-server:
|
||||
container_name: document-server
|
||||
image: onlyoffice/documentserver:7.3.3.50
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
- JWT_SECRET=your-256-bit-secret
|
||||
|
||||
example:
|
||||
container_name: example
|
||||
build:
|
||||
context: .
|
||||
target: example
|
||||
expose:
|
||||
- "80"
|
||||
environment:
|
||||
- DOCUMENT_SERVER_PRIVATE_URL=http://proxy:3000
|
||||
- DOCUMENT_SERVER_PUBLIC_URL=http://localhost:3000
|
||||
- EXAMPLE_URL=http://proxy:8080
|
||||
- JWT_SECRET=your-256-bit-secret
|
||||
- PORT=80
|
||||
|
||||
proxy:
|
||||
container_name: proxy
|
||||
build:
|
||||
context: .
|
||||
target: proxy
|
||||
ports:
|
||||
- "8080:8080"
|
||||
- "3000:3000"
|
||||
38
web/documentserver-example/ruby/proxy/nginx.conf
Normal file
38
web/documentserver-example/ruby/proxy/nginx.conf
Normal file
@ -0,0 +1,38 @@
|
||||
worker_processes auto;
|
||||
|
||||
events {
|
||||
worker_connections 512;
|
||||
}
|
||||
|
||||
http {
|
||||
include /etc/nginx/mime.types;
|
||||
|
||||
server {
|
||||
listen 8080;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://example;
|
||||
}
|
||||
}
|
||||
|
||||
server {
|
||||
listen 3000;
|
||||
server_name localhost;
|
||||
|
||||
location / {
|
||||
client_max_body_size 100m;
|
||||
proxy_http_version 1.1;
|
||||
proxy_pass http://document-server;
|
||||
proxy_redirect off;
|
||||
proxy_set_header Connection "upgrade";
|
||||
proxy_set_header Host $http_host;
|
||||
proxy_set_header Upgrade $http_upgrade;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Host $http_x_forwarded_host;
|
||||
proxy_set_header X-Forwarded-Proto $http_x_forwarded_proto;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user