scrivito_sdk 0.12.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +5 -0
  3. data/README +6 -0
  4. data/app/controllers/cms_controller.rb +7 -0
  5. data/app/controllers/scrivito/blobs_controller.rb +10 -0
  6. data/app/controllers/scrivito/default_cms_controller.rb +61 -0
  7. data/app/controllers/scrivito/objs_controller.rb +200 -0
  8. data/app/controllers/scrivito/tasks_controller.rb +11 -0
  9. data/app/controllers/scrivito/webservice_controller.rb +36 -0
  10. data/app/controllers/scrivito/workspaces_controller.rb +41 -0
  11. data/app/helpers/cms_helper.rb +7 -0
  12. data/app/helpers/cms_routing_helper.rb +7 -0
  13. data/app/helpers/scrivito/cms_asset_helper.rb +103 -0
  14. data/app/helpers/scrivito/cms_tag_helper.rb +231 -0
  15. data/app/helpers/scrivito/default_cms_helper.rb +21 -0
  16. data/app/helpers/scrivito/default_cms_routing_helper.rb +130 -0
  17. data/app/helpers/scrivito/display_helper.rb +71 -0
  18. data/app/helpers/scrivito/editing_helper.rb +26 -0
  19. data/app/helpers/scrivito/layout_helper.rb +28 -0
  20. data/app/models/named_link.rb +2 -0
  21. data/app/views/cms/_index.html.erb +7 -0
  22. data/app/views/cms/index.html.erb +1 -0
  23. data/app/views/scrivito/_editing_javascript.html.erb +7 -0
  24. data/app/views/scrivito/default_cms/show_widget.html.erb +1 -0
  25. data/app/views/scrivito/objs/copy_widget.html.erb +1 -0
  26. data/app/views/scrivito/objs/create_widget.html.erb +1 -0
  27. data/app/views/scrivito/widget_thumbnail.html.erb +9 -0
  28. data/config/ca-bundle.crt +3509 -0
  29. data/config/cms_routes.rb +17 -0
  30. data/config/locales/de.scrivito.errors.yml +7 -0
  31. data/config/locales/de.scrivito.lib.yml +6 -0
  32. data/config/locales/de.scrivito.models.yml +6 -0
  33. data/config/locales/en.scrivito.errors.yml +7 -0
  34. data/config/locales/en.scrivito.lib.yml +6 -0
  35. data/config/locales/en.scrivito.models.yml +6 -0
  36. data/config/routes.rb +37 -0
  37. data/lib/assets/images/180x120.gif +0 -0
  38. data/lib/assets/images/scrivito/image_placeholder.png +0 -0
  39. data/lib/assets/javascripts/scrivito_editing.js +14642 -0
  40. data/lib/assets/stylesheets/scrivito.css +180 -0
  41. data/lib/assets/stylesheets/scrivito_editing.css +2213 -0
  42. data/lib/generators/cms/migration/USAGE +9 -0
  43. data/lib/generators/cms/migration/migration_generator.rb +21 -0
  44. data/lib/generators/cms/migration/templates/migration.erb +10 -0
  45. data/lib/obj.rb +3 -0
  46. data/lib/scrivito/access_denied.rb +6 -0
  47. data/lib/scrivito/attribute_content.rb +194 -0
  48. data/lib/scrivito/backend_error.rb +4 -0
  49. data/lib/scrivito/basic_obj.rb +840 -0
  50. data/lib/scrivito/basic_widget.rb +238 -0
  51. data/lib/scrivito/blob.rb +48 -0
  52. data/lib/scrivito/cache.rb +41 -0
  53. data/lib/scrivito/cache_garbage_collector.rb +83 -0
  54. data/lib/scrivito/cache_middleware.rb +17 -0
  55. data/lib/scrivito/client_config.rb +62 -0
  56. data/lib/scrivito/client_error.rb +12 -0
  57. data/lib/scrivito/cms_accessible.rb +30 -0
  58. data/lib/scrivito/cms_backend.rb +238 -0
  59. data/lib/scrivito/cms_cache_storage.rb +51 -0
  60. data/lib/scrivito/cms_dispatch_controller.rb +46 -0
  61. data/lib/scrivito/cms_env.rb +63 -0
  62. data/lib/scrivito/cms_field_tag.rb +112 -0
  63. data/lib/scrivito/cms_rest_api.rb +151 -0
  64. data/lib/scrivito/cms_rest_api/attribute_serializer.rb +98 -0
  65. data/lib/scrivito/cms_rest_api/blob_uploader.rb +18 -0
  66. data/lib/scrivito/cms_rest_api/widget_extractor.rb +42 -0
  67. data/lib/scrivito/cms_test_request.rb +23 -0
  68. data/lib/scrivito/communication_error.rb +17 -0
  69. data/lib/scrivito/comparison.rb +67 -0
  70. data/lib/scrivito/configuration.rb +221 -0
  71. data/lib/scrivito/connection_manager.rb +100 -0
  72. data/lib/scrivito/content_conversion.rb +43 -0
  73. data/lib/scrivito/content_service.rb +118 -0
  74. data/lib/scrivito/content_state.rb +109 -0
  75. data/lib/scrivito/content_state_caching.rb +47 -0
  76. data/lib/scrivito/content_state_visitor.rb +19 -0
  77. data/lib/scrivito/controller_runtime.rb +35 -0
  78. data/lib/scrivito/date_attribute.rb +16 -0
  79. data/lib/scrivito/deprecation.rb +21 -0
  80. data/lib/scrivito/diff.rb +110 -0
  81. data/lib/scrivito/editing_context.rb +106 -0
  82. data/lib/scrivito/editing_context_middleware.rb +60 -0
  83. data/lib/scrivito/engine.rb +65 -0
  84. data/lib/scrivito/errors.rb +11 -0
  85. data/lib/scrivito/html_string.rb +18 -0
  86. data/lib/scrivito/link.rb +187 -0
  87. data/lib/scrivito/link_parser.rb +81 -0
  88. data/lib/scrivito/log_subscriber.rb +29 -0
  89. data/lib/scrivito/migration.rb +2 -0
  90. data/lib/scrivito/migrations.rb +12 -0
  91. data/lib/scrivito/migrations/cms_backend.rb +94 -0
  92. data/lib/scrivito/migrations/installer.rb +45 -0
  93. data/lib/scrivito/migrations/migration.rb +93 -0
  94. data/lib/scrivito/migrations/migration_dsl.rb +143 -0
  95. data/lib/scrivito/migrations/migration_store.rb +23 -0
  96. data/lib/scrivito/migrations/migrator.rb +135 -0
  97. data/lib/scrivito/migrations/workspace_lock.rb +39 -0
  98. data/lib/scrivito/model_identity.rb +13 -0
  99. data/lib/scrivito/modification.rb +8 -0
  100. data/lib/scrivito/named_link.rb +75 -0
  101. data/lib/scrivito/network_error.rb +11 -0
  102. data/lib/scrivito/obj_data.rb +140 -0
  103. data/lib/scrivito/obj_data_from_hash.rb +31 -0
  104. data/lib/scrivito/obj_data_from_service.rb +84 -0
  105. data/lib/scrivito/obj_params_parser.rb +61 -0
  106. data/lib/scrivito/obj_search_builder.rb +62 -0
  107. data/lib/scrivito/obj_search_enumerator.rb +374 -0
  108. data/lib/scrivito/rate_limit_exceeded.rb +5 -0
  109. data/lib/scrivito/revision.rb +9 -0
  110. data/lib/scrivito/string_tagging.rb +18 -0
  111. data/lib/scrivito/text_link.rb +52 -0
  112. data/lib/scrivito/text_link_conversion.rb +52 -0
  113. data/lib/scrivito/type_computer.rb +34 -0
  114. data/lib/scrivito/widget_field_params.rb +61 -0
  115. data/lib/scrivito/widget_garbage_collection.rb +97 -0
  116. data/lib/scrivito/workspace.rb +222 -0
  117. data/lib/scrivito/workspace_data_from_service.rb +80 -0
  118. data/lib/scrivito/workspace_selection_middleware.rb +23 -0
  119. data/lib/scrivito_sdk.rb +19 -0
  120. data/lib/tasks/cache.rake +12 -0
  121. data/lib/tasks/migration.rake +35 -0
  122. data/lib/widget.rb +3 -0
  123. metadata +291 -0
@@ -0,0 +1,17 @@
1
+ module Scrivito
2
+
3
+ class CommunicationError < StandardError
4
+ attr_reader :http_code, :message
5
+
6
+ def initialize(message, http_code)
7
+ @http_code = http_code.to_i
8
+ @message = message
9
+ end
10
+
11
+ def to_s
12
+ "HTTP-Response-Code: #{self.http_code}, Body: \"#{self.message}\""
13
+ end
14
+
15
+ end
16
+
17
+ end
@@ -0,0 +1,67 @@
1
+ module Scrivito
2
+
3
+ class Comparison < Struct.new(:revision, :inverse, :diff_mode)
4
+
5
+ alias :inverse? :inverse
6
+
7
+ def active?
8
+ !!revision
9
+ end
10
+
11
+ def modification(content)
12
+ return nil unless revision
13
+
14
+ convert_modification(content.modification(revision))
15
+ end
16
+
17
+ def modification_for_attribute(content, field_name)
18
+ return nil unless revision
19
+
20
+ convert_modification(
21
+ content.modification_for_attribute(field_name, revision)
22
+ )
23
+ end
24
+
25
+ def diff_for(content, field_name)
26
+ return nil unless revision
27
+
28
+ current_value = content[field_name]
29
+ compare_value = value_of(content, field_name)
30
+
31
+ return nil if current_value == compare_value
32
+
33
+ field_type = content.type_of_attribute(field_name)
34
+
35
+ if inverse?
36
+ old, new = current_value, compare_value
37
+ else
38
+ old, new = compare_value, current_value
39
+ end
40
+
41
+ Scrivito::Diff.for(diff_mode, field_type, old, new)
42
+ end
43
+
44
+ private
45
+
46
+ def value_of(content, field_name)
47
+ compare_content = content.in_revision(revision)
48
+ compare_content && compare_content[field_name]
49
+ end
50
+
51
+ def convert_modification(modification)
52
+ if inverse?
53
+ case modification
54
+ when Modification::NEW
55
+ Modification::DELETED
56
+ when Modification::DELETED
57
+ Modification::NEW
58
+ else
59
+ modification
60
+ end
61
+ else
62
+ modification
63
+ end
64
+ end
65
+ end
66
+
67
+ end
@@ -0,0 +1,221 @@
1
+ require 'scrivito/blob'
2
+
3
+ module Scrivito
4
+ #
5
+ # Configures the Scrivito SDK.
6
+ # The configuration keys +tenant+ and +api_key+ _must_ be provided.
7
+ #
8
+ # @example
9
+ # Scrivito.configure do |config|
10
+ # config.tenant = 'my-tenant-name'
11
+ # config.api_key = 'secret'
12
+ # end
13
+ #
14
+ # @api public
15
+ #
16
+ def self.configure
17
+ yield ::Scrivito::Configuration
18
+ end
19
+
20
+ #
21
+ # @api public
22
+ #
23
+ class Configuration
24
+ #
25
+ # Default path of a CA certification file in PEM format.
26
+ #
27
+ # @api public
28
+ #
29
+ DEFAULT_CA_FILE = File.expand_path('../../../config/ca-bundle.crt', __FILE__)
30
+
31
+ class << self
32
+ # Determine if current visitor is permitted to edit content.
33
+ attr_accessor :editing_auth_callback
34
+
35
+ # Configure a callback to be invoked when the Scrivito SDK determines,
36
+ # if current visitor is permitted to edit content.
37
+ # Default is <code>false</code>.
38
+ #
39
+ # Example Usage:
40
+ # Scrivito::Configuation.editing_auth do |env|
41
+ # request = Rack::Request.new(env)
42
+ # # return truey if current visitor is permitted to edit content, falsy otherwise
43
+ # end
44
+ # @api public
45
+ def editing_auth(&block)
46
+ if block.respond_to?(:arity) && block.arity == 1
47
+ self.editing_auth_callback = block
48
+ else
49
+ raise ArgumentError, 'editing_auth should have only one attribute!'
50
+ end
51
+ end
52
+
53
+ # TODO: Legacy compatiblity. Remove when DisplayHelper gets removed.
54
+ def editor_interface_enabled?
55
+ false
56
+ end
57
+
58
+ # The +Scrivito+ makes heavy use of filesystem caching.
59
+ # Use this method to configure the directory that should be used to store cached data.
60
+ # By default, +RAILS_ROOT/tmp/scrivito_cache+ will be used.
61
+ # @param path [String] Path to directory that should be used to store cached data.
62
+ # @example Configure +Scrivito+ to store its cache under +/tmp/my_cache+.
63
+ # Scrivito::Configuration.cache_path = '/tmp/my_cache'
64
+ # @api public
65
+ def cache_path=(path)
66
+ CmsCacheStorage.backend_cache = ActiveSupport::Cache::FileStore.new(path)
67
+ end
68
+
69
+ #
70
+ # Sets the tenant name.
71
+ # This configuration key _must_ be provided.
72
+ #
73
+ # @api public
74
+ #
75
+ def tenant=(tenant_name)
76
+ @endpoint_uri = nil
77
+ @tenant = tenant_name
78
+ end
79
+
80
+ #
81
+ # Sets the API key.
82
+ # This configuration key _must_ be provided.
83
+ #
84
+ # @api public
85
+ #
86
+ attr_writer :api_key
87
+
88
+ #
89
+ # Sets the API endpoint URL.
90
+ # This configuration key is optional.
91
+ # Default is +'api.scrival.com'+.
92
+ # If no schema is provided HTTPS is assumed.
93
+ #
94
+ # @api public
95
+ #
96
+ attr_writer :endpoint
97
+
98
+ #
99
+ # Gets the path of a CA certification file in PEM format.
100
+ #
101
+ # @return [String]
102
+ # @api public
103
+ #
104
+ attr_reader :ca_file
105
+
106
+ # Sets path of a CA certification file in PEM format.
107
+ # The file can contain several CA certificates.
108
+ # Certifications will be used for endpoint peer verification of various scrivito services
109
+ # e.g. Content Read Service.
110
+ # @api public
111
+ def ca_file=(path)
112
+ File.read(path) if path # Try to read the given file and fail if it doesn't exist or is not readable.
113
+ @ca_file = path
114
+ end
115
+
116
+ def to_prepare
117
+ unless Rails.configuration.cache_classes
118
+ NamedLink.reset_cache
119
+ BasicObj.reset_type_computer!
120
+ BasicWidget.reset_type_computer!
121
+ ::ApplicationController.__send__(:helper, :cms)
122
+ end
123
+ end
124
+
125
+ def configure_cms_database
126
+ end
127
+
128
+ def tenant
129
+ assert_key_present(:tenant)
130
+ @tenant
131
+ end
132
+
133
+ def api_key
134
+ assert_key_present(:api_key)
135
+ @api_key
136
+ end
137
+
138
+ def endpoint
139
+ assert_key_present(:endpoint)
140
+ @endpoint
141
+ end
142
+
143
+ def endpoint_uri
144
+ @endpoint_uri ||= calculate_endpoint_uri
145
+ end
146
+
147
+ def set_defaults!
148
+ self.ca_file = DEFAULT_CA_FILE
149
+ self.editing_auth { |env| false }
150
+ self.endpoint = 'api.scrival.com'
151
+ end
152
+
153
+ attr_accessor :choose_homepage_callback
154
+
155
+ # Configure a callback to be invoked when the Scrivito SDK delivers the homepage.
156
+ # The given callback will receive the rack env
157
+ # and must return an {BasicObj Obj} to be used as the homepage.
158
+ # If no callback is configured, {BasicObj.homepage Obj.homepage} will be used as the default.
159
+ # @api public
160
+ def choose_homepage(&block)
161
+ self.choose_homepage_callback = block
162
+ end
163
+
164
+ def cms_routes(*args)
165
+ raise <<-EOS.gsub(/\s+/, ' ')
166
+ Calling Scrivito::Configuration.cms_routes is not needed anymore.
167
+ Please remove it from config/routes.rb
168
+ EOS
169
+ end
170
+
171
+ def use_x_sendfile=(value)
172
+ raise 'Configuration.use_x_sendfile is now available as Rails configuration:'\
173
+ ' config.action_dispatch.x_sendfile_header = "X-Sendfile"'
174
+ end
175
+
176
+ def obj_formats
177
+ @obj_formats ||= {
178
+ '_changes_list' => proc do |obj|
179
+ {
180
+ id: obj.id,
181
+ obj_class_name: obj.obj_class_name,
182
+ description_for_editor: obj.description_for_editor,
183
+ modification: obj.modification,
184
+ has_conflict: obj.has_conflict?,
185
+ last_changed: obj.last_changed.utc.iso8601,
186
+ is_binary: obj.binary?,
187
+ }
188
+ end
189
+ }
190
+ end
191
+
192
+ def register_obj_format(name, &block)
193
+ if name.start_with? '_'
194
+ raise InvalidFormatNameError.new('Format names starting with underscore are not allowed.')
195
+ else
196
+ obj_formats[name] = block
197
+ end
198
+ end
199
+
200
+ private
201
+
202
+ def assert_key_present(key)
203
+ if instance_variable_get("@#{key}").nil?
204
+ raise "Missing required configuration key '#{key}'."
205
+ end
206
+ end
207
+
208
+ def calculate_endpoint_uri
209
+ url = endpoint
210
+ url = "https://#{url}" unless url.match(/^http/)
211
+ url = "#{url}/tenants/#{tenant}"
212
+ URI.parse(url)
213
+ end
214
+ end
215
+
216
+ self.set_defaults!
217
+ end
218
+
219
+ class InvalidFormatNameError < StandardError
220
+ end
221
+ end
@@ -0,0 +1,100 @@
1
+ module Scrivito
2
+ class ConnectionManager
3
+ SOCKET_ERRORS = [
4
+ EOFError,
5
+ Errno::ECONNABORTED,
6
+ Errno::ECONNREFUSED,
7
+ Errno::ECONNRESET,
8
+ Errno::EINVAL,
9
+ Errno::EPIPE,
10
+ Errno::ETIMEDOUT,
11
+ IOError,
12
+ SocketError,
13
+ Timeout::Error,
14
+ ].freeze
15
+
16
+ DEFAULT_TIMEOUT = 10.freeze
17
+
18
+ attr_reader :uri
19
+
20
+ class << self
21
+ def instance
22
+ @instance ||= new(Configuration.endpoint_uri)
23
+ end
24
+
25
+ # For test purpose only.
26
+ def reset_instance!
27
+ @instance = nil
28
+ end
29
+ end
30
+
31
+ def initialize(uri)
32
+ @uri = uri
33
+ end
34
+
35
+ def request(request, timeout=DEFAULT_TIMEOUT)
36
+ request['User-Agent'] = user_agent
37
+ ensure_started(timeout)
38
+
39
+ begin
40
+ connection.request(request)
41
+ rescue *SOCKET_ERRORS => e
42
+ ensure_finished
43
+ raise NetworkError.from_socket_error(e)
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ attr_accessor :connection
50
+
51
+ def ensure_started(timeout)
52
+ if @connection && @connection.started?
53
+ configure_timeout(@connection, timeout)
54
+ else
55
+ conn = Net::HTTP.new(uri.host, uri.port)
56
+ if uri.scheme == 'https'
57
+ conn.use_ssl = true
58
+ conn.verify_mode = OpenSSL::SSL::VERIFY_PEER
59
+ conn.ca_file = Scrivito::Configuration.ca_file
60
+ end
61
+ configure_timeout(conn, timeout)
62
+ retry_twice_on_socket_error do
63
+ conn.start
64
+ end
65
+ @connection = conn
66
+ end
67
+ end
68
+
69
+ def ensure_finished
70
+ @connection.finish if @connection && @connection.started?
71
+ @connection = nil
72
+ end
73
+
74
+ def retry_twice_on_socket_error
75
+ attempt = 0
76
+ begin
77
+ yield
78
+ rescue *SOCKET_ERRORS => e
79
+ raise NetworkError.from_socket_error(e) if attempt == 2
80
+ attempt += 1
81
+ retry
82
+ end
83
+ end
84
+
85
+ def configure_timeout(connection, timeout)
86
+ connection.open_timeout = timeout
87
+ connection.read_timeout = timeout
88
+ connection.ssl_timeout = timeout
89
+ end
90
+
91
+ def user_agent
92
+ @user_agent ||= (
93
+ gem_info = Gem.loaded_specs["scrivito_sdk"]
94
+ if gem_info
95
+ "#{gem_info.name}-#{gem_info.version}"
96
+ end
97
+ )
98
+ end
99
+ end
100
+ end
@@ -0,0 +1,43 @@
1
+ require 'nokogiri'
2
+
3
+ module Scrivito
4
+
5
+ class ContentConversion
6
+ def self.convert_html_links(input, request_host, request_port)
7
+ doc = Nokogiri::HTML.parse("<div class='internal_jump_point'>#{input}</div>")
8
+
9
+ doc.css('body a').each do |a_tag|
10
+ if href = a_tag.attributes['href']
11
+ link = Link.parse(href.value, request_host, request_port)
12
+ href.value = link.to_cms_api_html_url
13
+ end
14
+ end
15
+
16
+ doc.css('body img').each do |img_tag|
17
+ if src = img_tag.attributes['src']
18
+ link = Link.parse(src.value, request_host, request_port)
19
+ src.value = link.to_cms_api_html_url
20
+ end
21
+ end
22
+
23
+ new_html = doc.css('body div.internal_jump_point').inner_html
24
+
25
+ nbsp = Nokogiri::HTML("&nbsp;").text
26
+ new_html.gsub(nbsp, "&nbsp;")
27
+ end
28
+
29
+ def self.convert_linklist_urls(linklist, request_host, request_port)
30
+ linklist.map do |link_data|
31
+ if link_data.has_key?(:url)
32
+ link_data.delete(:obj_id)
33
+ url = link_data.delete(:url)
34
+ link = Link.parse(url, request_host, request_port)
35
+ link_data.merge!(link.to_cms_api_linklist_params)
36
+ end
37
+
38
+ link_data
39
+ end
40
+ end
41
+ end
42
+
43
+ end