infopark_cloud_connector 7.0.2 → 7.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +8 -8
  2. data/app/controllers/rails_connector/objs_controller.rb +29 -37
  3. data/app/helpers/rails_connector/cms_asset_helper.rb +1 -1
  4. data/app/helpers/rails_connector/cms_tag_helper.rb +1 -1
  5. data/app/helpers/rails_connector/default_cms_routing_helper.rb +1 -3
  6. data/app/helpers/rails_connector/display_helper.rb +5 -1
  7. data/app/views/rails_connector/_editing_javascript.html.erb +3 -2
  8. data/config/ca-bundle.crt +2 -2
  9. data/config/routes.rb +3 -0
  10. data/lib/assets/fonts/infopark_icons-webfont.eot +0 -0
  11. data/lib/assets/fonts/infopark_icons-webfont.ttf +0 -0
  12. data/lib/assets/fonts/infopark_icons-webfont.woff +0 -0
  13. data/lib/assets/images/apple-touch-icon.jpg +0 -0
  14. data/lib/assets/images/favicon.ico +0 -0
  15. data/lib/assets/images/ip_logo.svg +50 -0
  16. data/lib/assets/javascripts/infopark_editing.js +903 -164
  17. data/lib/assets/stylesheets/infopark_editing.css +222 -271
  18. data/lib/infopark_cloud_connector.rb +0 -1
  19. data/lib/rails_connector/attribute_content.rb +25 -74
  20. data/lib/rails_connector/backend_error.rb +4 -0
  21. data/lib/rails_connector/basic_obj.rb +173 -20
  22. data/lib/rails_connector/basic_widget.rb +42 -1
  23. data/lib/rails_connector/blob.rb +1 -1
  24. data/lib/rails_connector/cache_middleware.rb +2 -2
  25. data/lib/rails_connector/cms_backend.rb +51 -33
  26. data/lib/rails_connector/cms_rest_api.rb +13 -8
  27. data/lib/rails_connector/cms_rest_api/attribute_serializer.rb +62 -0
  28. data/lib/rails_connector/cms_rest_api/blob_uploader.rb +18 -0
  29. data/lib/rails_connector/communication_error.rb +17 -0
  30. data/lib/rails_connector/configuration.rb +28 -0
  31. data/lib/rails_connector/connection_manager.rb +2 -2
  32. data/lib/rails_connector/content_conversion.rb +16 -62
  33. data/lib/rails_connector/content_service.rb +2 -2
  34. data/lib/rails_connector/engine.rb +2 -1
  35. data/lib/rails_connector/html_string.rb +0 -1
  36. data/lib/rails_connector/link.rb +41 -33
  37. data/lib/rails_connector/link_parser.rb +72 -0
  38. data/lib/rails_connector/migrations/migration_dsl.rb +13 -0
  39. data/lib/rails_connector/{backend_not_available.rb → network_error.rb} +1 -6
  40. data/lib/rails_connector/obj_data.rb +4 -0
  41. data/lib/rails_connector/obj_data_from_hash.rb +6 -0
  42. data/lib/rails_connector/obj_data_from_service.rb +37 -3
  43. data/lib/rails_connector/obj_params_parser.rb +50 -0
  44. data/lib/rails_connector/obj_search_builder.rb +62 -0
  45. data/lib/rails_connector/obj_search_enumerator.rb +60 -5
  46. data/lib/rails_connector/rate_limit_exceeded.rb +5 -0
  47. data/lib/rails_connector/revision.rb +9 -0
  48. data/lib/rails_connector/string_tagging.rb +1 -12
  49. data/lib/rails_connector/text_link.rb +52 -0
  50. data/lib/rails_connector/text_link_conversion.rb +50 -0
  51. data/lib/rails_connector/workspace.rb +125 -3
  52. data/lib/rails_connector/workspace_data_from_service.rb +30 -31
  53. data/lib/rails_connector/workspace_selection_middleware.rb +62 -20
  54. data/lib/tasks/cache.rake +2 -0
  55. data/lib/tasks/rails_connector/cache_garbage_collector_task.rb +98 -0
  56. metadata +24 -17
  57. data/lib/assets/images/ip_logo_app.png +0 -0
  58. data/lib/assets/images/ip_logo_app2x.png +0 -0
  59. data/lib/assets/images/irongrip.png +0 -0
  60. data/lib/rails_connector/link_resolvable.rb +0 -9
  61. data/lib/rails_connector/rack_middlewares.rb +0 -6
@@ -88,7 +88,7 @@ class ContentService
88
88
  begin
89
89
  sleep delay.next_sleep_time(e.retry_after)
90
90
  rescue MaxSleepTimeReached
91
- raise BackendNotAvailable.new('rate limit exceeded', 429)
91
+ raise ::RailsConnector::RateLimitExceeded.new('rate limit exceeded', 429)
92
92
  end
93
93
  retry
94
94
  end
@@ -109,7 +109,7 @@ class ContentService
109
109
  elsif response.code == "429"
110
110
  raise RateLimitExceeded.new(response["Retry-After"])
111
111
  else
112
- raise BackendNotAvailable.new("Server responded with status code #{response.code}", response.code)
112
+ raise NetworkError.new("Server responded with status code #{response.code}", response.code)
113
113
  end
114
114
  end
115
115
 
@@ -50,7 +50,8 @@ module ::RailsConnector
50
50
  config.autoload_paths += paths['lib'].to_a
51
51
  config.autoload_once_paths += paths['lib'].to_a
52
52
 
53
- RailsConnector.rack_middlewares.each { |middleware| config.app_middleware.use middleware }
53
+ config.app_middleware.use "RailsConnector::CacheMiddleware"
54
+ config.app_middleware.use "RailsConnector::WorkspaceSelectionMiddleware"
54
55
  end
55
56
  end
56
57
 
@@ -2,7 +2,6 @@ module RailsConnector
2
2
 
3
3
  # Include this module in order to tag the string as one with HTML content
4
4
  module HtmlString
5
- include LinkResolvable
6
5
  # Returns whether the String contains HTML (default to true, overrides String.html?).
7
6
  def html?
8
7
  true
@@ -6,6 +6,16 @@ module RailsConnector
6
6
 
7
7
  extend ActiveModel::Naming
8
8
 
9
+ # Parses a url and returns a {Link} object. Determines internal urls based on the given
10
+ # +hostname+ and +port+.
11
+ # @api public
12
+ # @param [String] url
13
+ # @param host [String] the hostname of internal urls
14
+ # @param port [String] the port of internal urls
15
+ def self.parse(url, host, port)
16
+ LinkParser.new(host, port).parse(url)
17
+ end
18
+
9
19
  # Create a new link obj
10
20
  # @api public
11
21
  # @param [Hash] link_data
@@ -92,33 +102,14 @@ module RailsConnector
92
102
  @link_data[:fragment] = value
93
103
  end
94
104
 
95
- # Returns the browser window or browser frame to be used as a target for this link.
96
- # Example: Links that should be opened in a new window will return "_blank" as their target.
97
- # @api public
98
105
  def target
99
106
  @link_data[:target]
100
107
  end
101
108
 
102
- # Set the browser window or browser frame to be used as a target for this link.
103
- # Example: Links that should be opened in a new window will return "_blank" as their target.
104
- # @api public
105
- # @param value [String] the target of the link
106
109
  def target=(value)
107
110
  @link_data[:target] = value
108
111
  end
109
112
 
110
- def id
111
- @link_data[:link_id]
112
- end
113
-
114
- def tag_name
115
- @link_data[:tag_name]
116
- end
117
-
118
- def tag_name=(value)
119
- @link_data[:tag_name] = value
120
- end
121
-
122
113
  # Returns the file extension (e.g. zip, pdf) of this link's (internal or external) target.
123
114
  # Returns an empty string if the file extension is can not be determined.
124
115
  # @api public
@@ -171,10 +162,6 @@ module RailsConnector
171
162
  external? || (obj && obj.active?)
172
163
  end
173
164
 
174
- def external_prefix?
175
- nil != (url =~ /\s?external:/)
176
- end
177
-
178
165
  def resolved?
179
166
  external? || !obj.nil?
180
167
  end
@@ -188,14 +175,6 @@ module RailsConnector
188
175
  obj
189
176
  end
190
177
 
191
- def html_attribute_snippet
192
- parts = []
193
- parts << %{alt="#{title}"} if tag_name == 'img' || tag_name == 'input'
194
- parts << %{title="#{title}"} if (tag_name == 'a' || tag_name == 'link') && title.present?
195
- parts << %{target="#{target}"} if target.present?
196
- parts.join(' ')
197
- end
198
-
199
178
  def query_and_fragment
200
179
  str = ''
201
180
  str << "?#{query}" if query.present?
@@ -207,9 +186,38 @@ module RailsConnector
207
186
  "objid:#{obj.id}"
208
187
  end
209
188
 
210
- def external_url
211
- external_prefix? ? url.gsub(/external:/, '').strip : url
189
+ def to_cms_api_html_url
190
+ if internal?
191
+ "#{internal_url}#{query_and_fragment}"
192
+ else
193
+ begin
194
+ parsed = Addressable::URI.parse(url)
195
+ rescue Addressable::URI::InvalidURIError
196
+ return url
197
+ end
198
+
199
+ if parsed.relative? && parsed.path.present?
200
+ "external:#{url}"
201
+ else
202
+ url
203
+ end
204
+ end
212
205
  end
213
206
 
207
+ def to_cms_api_linklist_params
208
+ params = {}
209
+
210
+ if internal?
211
+ params[:obj_id] = obj.id
212
+ params[:title] = title if title
213
+ params[:query] = query if query
214
+ params[:fragment] = fragment if fragment
215
+ else
216
+ params[:url] = url
217
+ params[:title] = title if title
218
+ end
219
+
220
+ params
221
+ end
214
222
  end
215
223
  end
@@ -0,0 +1,72 @@
1
+ require 'addressable/uri'
2
+
3
+ module RailsConnector
4
+ class LinkParser
5
+ def initialize(host, port)
6
+ @host = host
7
+ @port = port
8
+ end
9
+
10
+ def parse(url)
11
+ uri = Addressable::URI.parse(url)
12
+ link_params = {}
13
+
14
+ if obj = find_obj(uri)
15
+ link_params[:obj] = obj
16
+ else
17
+ if application_uri?(uri)
18
+ uri.path = '/' unless uri.path.present?
19
+ uri.port = nil
20
+ uri.host = nil
21
+ uri.scheme = nil
22
+ end
23
+
24
+ link_params[:url] = uri.to_s
25
+ end
26
+
27
+ link_params[:query] = uri.query
28
+ link_params[:fragment] = uri.fragment
29
+
30
+ Link.new(link_params)
31
+ rescue Addressable::URI::InvalidURIError
32
+ Link.new(url: url)
33
+ end
34
+
35
+ private
36
+
37
+ def application_uri?(uri)
38
+ uri.absolute? && internal_uri?(uri) || uri.relative? && uri.path.present?
39
+ end
40
+
41
+ def internal_uri?(uri)
42
+ if uri.port.present?
43
+ uri.host == @host && uri.port == Integer(@port)
44
+ else
45
+ uri.host == @host
46
+ end
47
+ end
48
+
49
+ def find_obj(uri)
50
+ return nil unless application_uri?(uri) && application_route?(uri)
51
+
52
+ route_params = route(uri)
53
+
54
+ if id = route_params[:id]
55
+ Obj.find(id)
56
+ elsif permalink = route_params[:permalink]
57
+ Obj.find_by_permalink(permalink)
58
+ end
59
+ rescue RailsConnector::ResourceNotFound
60
+ end
61
+
62
+ def application_route?(uri)
63
+ route_params = route(uri)
64
+ route_params && route_params[:controller] == 'rails_connector/cms_dispatch'
65
+ end
66
+
67
+ def route(uri)
68
+ Rails.application.routes.recognize_path(uri.to_s, method: :get)
69
+ rescue ActionController::RoutingError
70
+ end
71
+ end
72
+ end
@@ -84,7 +84,11 @@ module RailsConnector
84
84
  #
85
85
  # @return nothing
86
86
  # @api public
87
+ #
88
+ # @deprecated use {BasicObj.create Obj.create} instead
87
89
  def create_obj(attributes = {})
90
+ Deprecation.warn_method('create_obj', 'Obj.create')
91
+
88
92
  endpoint = "workspaces/#{Workspace.current.id}/objs"
89
93
 
90
94
  CmsRestApi.post(endpoint, obj: attributes)
@@ -117,7 +121,11 @@ module RailsConnector
117
121
  #
118
122
  # @return nothing
119
123
  # @api public
124
+ #
125
+ # @deprecated use {BasicObj#destroy Obj#destroy} instead
120
126
  def delete_obj(id)
127
+ Deprecation.warn_method('delete_obj', 'Obj#destroy')
128
+
121
129
  endpoint = "workspaces/#{Workspace.current.id}/objs/#{id}"
122
130
 
123
131
  CmsRestApi.delete(endpoint)
@@ -166,7 +174,10 @@ module RailsConnector
166
174
  #
167
175
  # @return nothing
168
176
  # @api public
177
+ #
178
+ # @deprecated use {BasicObj#update Obj#update} instead
169
179
  def update_obj(id, attributes = {})
180
+ Deprecation.warn_method('update_obj', 'Obj#update')
170
181
  endpoint = "workspaces/#{Workspace.current.id}/objs/#{id}"
171
182
 
172
183
  CmsRestApi.put(endpoint, obj: attributes)
@@ -202,7 +213,9 @@ module RailsConnector
202
213
  #
203
214
  # @return The blob of the uploaded file that can be stored on a CMS object.
204
215
  # @api public
216
+ # @deprecated use {BasicObj.create Obj.create} or {BasicObj#update Obj#update} instead
205
217
  def upload_file(file)
218
+ Deprecation.warn_method("upload_file", "Obj.create or Obj#update")
206
219
  upload_permission = RailsConnector::CmsRestApi.get('blobs/upload_permission')
207
220
 
208
221
  fields = upload_permission['fields'].map { |name, value| [name, value] }
@@ -1,16 +1,11 @@
1
1
  module RailsConnector
2
2
 
3
- class BackendNotAvailable < StandardError
3
+ class NetworkError < RailsConnector::CommunicationError
4
4
  attr_reader :http_code
5
5
 
6
6
  def self.from_socket_error(socket_error)
7
7
  new(socket_error.message, 503)
8
8
  end
9
-
10
- def initialize(message, http_code)
11
- @http_code = http_code.to_i
12
- super(message)
13
- end
14
9
  end
15
10
 
16
11
  end
@@ -17,6 +17,10 @@ module RailsConnector
17
17
  raise "implement in subclass"
18
18
  end
19
19
 
20
+ def all_custom_attributes
21
+ raise "implement in subclass"
22
+ end
23
+
20
24
  private
21
25
 
22
26
  def type_of_internal(key)
@@ -14,6 +14,12 @@ module RailsConnector
14
14
  @hash.has_key?(name)
15
15
  end
16
16
 
17
+ def all_custom_attributes
18
+ @hash.select do |attribute_name, _|
19
+ has_custom_attribute?(attribute_name)
20
+ end.keys
21
+ end
22
+
17
23
  end
18
24
 
19
25
  end
@@ -17,10 +17,16 @@ module RailsConnector
17
17
  else
18
18
  raise RailsConnectorError.new("Illegal attribute name #{attribute_name}")
19
19
  end
20
- elsif value_and_type.length == 1
21
- [value_and_type.first, type_of_internal(attribute_name)]
22
20
  else
23
- value_and_type
21
+ raw_value = value_and_type.first
22
+ type =
23
+ if value_and_type.length == 1
24
+ type_of_internal(attribute_name)
25
+ else
26
+ value_and_type[1]
27
+ end
28
+
29
+ [convert_value(raw_value, type), type]
24
30
  end
25
31
  end
26
32
 
@@ -28,8 +34,35 @@ module RailsConnector
28
34
  is_custom_attribute?(attribute_name) && !!@data[attribute_name]
29
35
  end
30
36
 
37
+ def all_custom_attributes
38
+ @data.select do |attribute_name, _|
39
+ has_custom_attribute?(attribute_name)
40
+ end.keys
41
+ end
42
+
31
43
  private
32
44
 
45
+ def convert_value(value, type)
46
+ if type == "html"
47
+ text_links_conversion.convert(value)
48
+ else
49
+ value
50
+ end
51
+ end
52
+
53
+ def text_links_conversion
54
+ @text_links_conversion = TextLinkConversion.new(text_links_map)
55
+ end
56
+
57
+ def text_links_map
58
+ text_links = @data["_text_links"]
59
+ return nil unless text_links
60
+
61
+ text_links.first.each_with_object({}) do |link, map|
62
+ map[link["link_id"]] = TextLink.new(link)
63
+ end
64
+ end
65
+
33
66
  def value_and_type_of_widget_pool
34
67
  [value_of_widget_pool, nil]
35
68
  end
@@ -52,6 +85,7 @@ module RailsConnector
52
85
 
53
86
  internal_key_list = %w[
54
87
  last_changed
88
+ modification
55
89
  permalink
56
90
  sort_key1
57
91
  sort_key2
@@ -0,0 +1,50 @@
1
+ module RailsConnector
2
+ class ObjParamsParser
3
+ def initialize(host, port)
4
+ @host = host
5
+ @port = port
6
+ end
7
+
8
+ def parse(obj, params)
9
+ raise "Required parameter 'obj' is missing." unless params.present?
10
+ raise "Parameter 'obj' is not a hash." unless params.is_a?(Hash)
11
+
12
+ if obj
13
+ convert_params(params, obj)
14
+
15
+ if widget_pool_params = params['_widget_pool']
16
+ convert_widget_pool_params(widget_pool_params, obj)
17
+ end
18
+ end
19
+
20
+ params
21
+ end
22
+
23
+ private
24
+
25
+ def convert_widget_pool_params(widget_pool_params, obj)
26
+ widget_pool_params.each_pair do |widget_id, widget_params|
27
+ widget = obj.widget_from_pool(widget_id)
28
+
29
+ if widget_params.present?
30
+ convert_params(widget_params, widget)
31
+ end
32
+ end
33
+ end
34
+
35
+ def convert_params(params, obj)
36
+ params.each do |key, value|
37
+ type = obj.type_of_attribute(key.to_s)
38
+
39
+ params[key] = case type
40
+ when 'html'
41
+ ContentConversion.convert_html_links(value, @host, @port)
42
+ when 'linklist'
43
+ ContentConversion.convert_linklist_urls(value, @host, @port)
44
+ else
45
+ value
46
+ end
47
+ end
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,62 @@
1
+ module RailsConnector
2
+
3
+ class ObjSearchBuilder < Struct.new(:query)
4
+
5
+ def build
6
+ reset_enumerator
7
+
8
+ set_predicates
9
+ set_offset
10
+ set_order
11
+ set_batch_size
12
+ set_format
13
+ set_include_deleted
14
+
15
+ enumerator
16
+ end
17
+
18
+ private
19
+
20
+ def reset_enumerator
21
+ @enumerator = nil
22
+ end
23
+
24
+ def enumerator
25
+ @enumerator ||= ObjSearchEnumerator.new(nil)
26
+ end
27
+
28
+ def set_predicates
29
+ query[:predicates].each do |p|
30
+ if p[:negate]
31
+ enumerator.and_not(p[:field], p[:operator], p[:value])
32
+ else
33
+ enumerator.and(p[:field], p[:operator], p[:value], p[:boost])
34
+ end
35
+ end
36
+ end
37
+
38
+ def set_offset
39
+ enumerator.offset(query[:offset].to_i) if query[:offset]
40
+ end
41
+
42
+ def set_order
43
+ enumerator.order(query[:order]) if query[:order]
44
+ enumerator.reverse_order if query[:reverse_order]
45
+ end
46
+
47
+ def set_batch_size
48
+ enumerator.batch_size(query[:batch_size]) if query[:batch_size]
49
+ end
50
+
51
+ def set_format
52
+ enumerator.format(query[:format]) if query[:format]
53
+ end
54
+
55
+ def set_include_deleted
56
+ enumerator.include_deleted if query[:include_deleted]
57
+ end
58
+
59
+ end
60
+
61
+ end
62
+