infopark_fiona_connector 6.9.4 → 7.0.1.5.2.3.rc4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/app/assets/images/admin/minus.gif +0 -0
- data/app/assets/images/bg80.png +0 -0
- data/app/assets/images/edit.png +0 -0
- data/app/assets/images/icons/mm_generic.png +0 -0
- data/app/assets/images/icons/mm_menu.png +0 -0
- data/app/assets/javascripts/editmarker.js +240 -0
- data/app/assets/javascripts/infopark_rails_connector.js.erb +0 -0
- data/app/assets/stylesheets/editmarker.css +70 -0
- data/app/assets/stylesheets/infopark_rails_connector.css.erb +0 -0
- data/app/controllers/cms_controller.rb +7 -0
- data/app/controllers/rails_connector/default_cms_controller.rb +43 -0
- data/app/helpers/cms_helper.rb +7 -0
- data/app/helpers/cms_routing_helper.rb +7 -0
- data/app/helpers/rails_connector/cms_asset_helper.rb +2 -1
- data/app/helpers/rails_connector/default_cms_helper.rb +23 -0
- data/app/helpers/rails_connector/default_cms_routing_helper.rb +120 -0
- data/app/helpers/rails_connector/display_helper.rb +5 -5
- data/app/helpers/rails_connector/layout_helper.rb +29 -0
- data/app/helpers/rails_connector/marker_helper.rb +1 -3
- data/app/helpers/rails_connector/table_of_contents_helper.rb +22 -0
- data/app/models/named_link.rb +2 -0
- data/app/views/cms/_index.html.erb +7 -0
- data/app/views/cms/index.html.erb +1 -0
- data/app/views/errors/403_forbidden.html.erb +3 -0
- data/app/views/errors/410_gone.html.erb +7 -0
- data/config/cms_routes.rb +17 -0
- data/config/locales/de.rails_connector.errors.yml +11 -0
- data/config/locales/de.rails_connector.lib.yml +6 -0
- data/config/locales/de.rails_connector.views.yml +9 -0
- data/config/locales/en.rails_connector.errors.yml +10 -0
- data/config/locales/en.rails_connector.lib.yml +6 -0
- data/config/locales/en.rails_connector.views.yml +9 -0
- data/lib/gem_dependencies.rb +67 -0
- data/lib/infopark_fiona_connector.rb +26 -3
- data/lib/meta_eager_loader.rb +1 -0
- data/lib/obj.rb +3 -0
- data/lib/rails_connector/attr_dict.rb +31 -16
- data/lib/rails_connector/attribute.rb +96 -0
- data/lib/rails_connector/authenticable.rb +30 -0
- data/lib/rails_connector/basic_obj.rb +82 -95
- data/lib/rails_connector/blob.rb +14 -6
- data/lib/rails_connector/blob_mapping.rb +16 -0
- data/lib/rails_connector/blob_mysql.rb +1 -1
- data/lib/rails_connector/blob_oracle.rb +1 -1
- data/lib/rails_connector/channel.rb +19 -0
- data/lib/rails_connector/cms_accessible.rb +112 -0
- data/lib/rails_connector/cms_base_model.rb +9 -0
- data/lib/rails_connector/cms_dispatch_controller.rb +46 -0
- data/lib/rails_connector/cms_env.rb +68 -0
- data/lib/rails_connector/cms_test_request.rb +8 -0
- data/lib/rails_connector/configuration.rb +3 -1
- data/lib/rails_connector/content.rb +11 -0
- data/lib/rails_connector/core_extensions.rb +1 -0
- data/lib/rails_connector/core_extensions/time.rb +18 -0
- data/lib/rails_connector/date_attribute.rb +1 -1
- data/lib/rails_connector/engine.rb +68 -0
- data/lib/rails_connector/fiona_datetime.rb +14 -0
- data/lib/rails_connector/html_string.rb +19 -0
- data/lib/rails_connector/job.rb +13 -0
- data/lib/rails_connector/link_list.rb +32 -0
- data/lib/rails_connector/link_resolvable.rb +9 -0
- data/lib/rails_connector/markdown_string.rb +19 -0
- data/lib/rails_connector/meta.rb +148 -0
- data/lib/rails_connector/meta/eager_loader.rb +82 -0
- data/lib/rails_connector/named_link.rb +16 -1
- data/lib/rails_connector/news.rb +7 -3
- data/lib/rails_connector/obj_class.rb +140 -0
- data/lib/rails_connector/obj_class_attr.rb +5 -0
- data/lib/rails_connector/object_with_meta_data.rb +18 -0
- data/lib/rails_connector/rack_middlewares.rb +1 -2
- data/lib/rails_connector/string_tagging.rb +29 -0
- data/lib/version.rb +7 -0
- metadata +168 -42
- data/README +0 -5
@@ -0,0 +1,30 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
module Authenticable
|
3
|
+
def self.included(mod)
|
4
|
+
%w(logged_in? admin? current_user).each do |method_name|
|
5
|
+
unless instance_method_defined?(mod, method_name)
|
6
|
+
mod.class_eval do
|
7
|
+
private
|
8
|
+
define_method(method_name, InstanceMethods.method(method_name).to_proc)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
mod.send(:helper_method, method_name)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
module InstanceMethods
|
17
|
+
def self.logged_in?; false; end
|
18
|
+
def self.admin?; false; end
|
19
|
+
def self.current_user; nil; end
|
20
|
+
end
|
21
|
+
|
22
|
+
private
|
23
|
+
|
24
|
+
def self.instance_method_defined?(mod, method_name)
|
25
|
+
(
|
26
|
+
mod.instance_methods + mod.protected_instance_methods + mod.private_instance_methods
|
27
|
+
).map(&:to_s).include?(method_name)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "json"
|
2
2
|
require 'openssl'
|
3
|
+
require 'rails_connector/fiona_datetime'
|
3
4
|
|
4
5
|
module RailsConnector
|
5
6
|
|
@@ -9,14 +10,23 @@ module RailsConnector
|
|
9
10
|
# [parent] the Obj of which this one is a child - nil for the root object
|
10
11
|
# @api public
|
11
12
|
class BasicObj < CmsBaseModel
|
13
|
+
include RailsConnector::Meta
|
14
|
+
|
12
15
|
CRYPT_KEY = "\xd7\x28\x9c\x63\xd6\x29\xdf\x20\xcd\x32\xcf\x30\xcf\x30\xcf\x30\xdf\x20\xb6\x49"\
|
13
16
|
"\x91\x6e\x99\x66\x90\x6f\x8f\x70\x9e\x61\x8d\x72\x94\x6b\xdf\x20\xbe\x41\xb8\x47\xc4\x3b"\
|
14
17
|
"\xdf\x20\xbd\x42\x9a\x65\x8d\x72\x93\x6c\x96\x69\x91\x6e".freeze
|
15
18
|
|
16
|
-
|
19
|
+
PREDEFINED_ATTRIBUTES = %w(blob body title channels sort_key1 sort_type1 sort_key2 sort_type2
|
20
|
+
sort_key3 sort_type3 sort_order).freeze
|
21
|
+
|
17
22
|
|
18
23
|
self.store_full_sti_class = false
|
19
24
|
|
25
|
+
def self.inherited(subclass)
|
26
|
+
super
|
27
|
+
subclass.delegate_attributes
|
28
|
+
end
|
29
|
+
|
20
30
|
def self.configure_for_content(which)
|
21
31
|
case which
|
22
32
|
when :released then configure_column_information("objs", true)
|
@@ -36,10 +46,59 @@ module RailsConnector
|
|
36
46
|
self.inheritance_column = "obj_class"
|
37
47
|
|
38
48
|
@@use_cached_permissions = use_cached_permissions
|
49
|
+
descendants.each do |klass|
|
50
|
+
klass.reset_table_name
|
51
|
+
klass.initialize_attributes
|
52
|
+
end
|
53
|
+
|
54
|
+
RailsConnector::Meta::EagerLoader.instance.obj_classes.each do |class_name, obj_class|
|
55
|
+
next unless obj_class
|
56
|
+
|
57
|
+
if class_name =~ /^[A-Z]/
|
58
|
+
klass = class_name.safe_constantize
|
59
|
+
next unless klass
|
60
|
+
if klass < RailsConnector::BasicObj
|
61
|
+
klass.initialize_attributes
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
def self.initialize_attributes
|
68
|
+
PREDEFINED_ATTRIBUTES.each do |attribute|
|
69
|
+
self.send(:define_attribute, attribute, ActiveRecord::Type::String.new)
|
70
|
+
end
|
71
|
+
|
72
|
+
return if obj_class_definition.blank?
|
73
|
+
|
74
|
+
obj_class_definition.custom_attributes.each_key do |attribute|
|
75
|
+
self.send(:define_attribute, attribute, ActiveRecord::Type::String.new)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
def self.delegate_attributes
|
80
|
+
PREDEFINED_ATTRIBUTES.each do |attribute|
|
81
|
+
delegate attribute, to: :attr_dict
|
82
|
+
end
|
83
|
+
|
84
|
+
return if obj_class_definition.blank?
|
85
|
+
|
86
|
+
obj_class_definition.custom_attributes.each_key do |attribute|
|
87
|
+
delegate attribute, to: :attr_dict
|
88
|
+
end
|
39
89
|
end
|
40
90
|
|
41
|
-
|
42
|
-
|
91
|
+
attribute :last_changed, :fiona_datetime
|
92
|
+
attribute :valid_from, :fiona_datetime
|
93
|
+
attribute :valid_until, :fiona_datetime
|
94
|
+
attribute :suppress_export, :boolean
|
95
|
+
attribute :is_edited, :boolean
|
96
|
+
attribute :is_released, :boolean
|
97
|
+
|
98
|
+
delegate :sort_keys, to: :attr_dict
|
99
|
+
delegate :body_data_path, to: :attr_dict
|
100
|
+
delegate :empty?, to: :attr_dict
|
101
|
+
delegate :text_links, to: :attr_dict
|
43
102
|
|
44
103
|
# Patch to avoid a type_condition being added by ActiveRecord::Base.add_conditions! for Obj.find(params):
|
45
104
|
def self.descends_from_active_record?
|
@@ -65,6 +124,11 @@ module RailsConnector
|
|
65
124
|
# We don't cache types at all here.
|
66
125
|
end
|
67
126
|
|
127
|
+
def self.reset_reflections
|
128
|
+
has_many :children, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
|
129
|
+
belongs_to :parent, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
|
130
|
+
end
|
131
|
+
|
68
132
|
# @api public
|
69
133
|
def permissions
|
70
134
|
@@use_cached_permissions ? attr_dict.permissions : arel_permissions
|
@@ -101,12 +165,6 @@ module RailsConnector
|
|
101
165
|
@@homepage_id = nil
|
102
166
|
end
|
103
167
|
|
104
|
-
# returns the obj's permalink.
|
105
|
-
# @api public
|
106
|
-
def permalink
|
107
|
-
self[:permalink]
|
108
|
-
end
|
109
|
-
|
110
168
|
# This method determines the controller that should be invoked when the Obj is requested.
|
111
169
|
# By default a controller matching the Obj's obj_class will be used.
|
112
170
|
# If the controller does not exist, the CmsController will be used as a fallback.
|
@@ -208,13 +266,13 @@ module RailsConnector
|
|
208
266
|
# and edited? will always return false in this case.
|
209
267
|
# @api public
|
210
268
|
def edited?
|
211
|
-
|
269
|
+
is_edited
|
212
270
|
end
|
213
271
|
|
214
272
|
# Returns true if this object has released content
|
215
273
|
# @api public
|
216
274
|
def released?
|
217
|
-
|
275
|
+
is_released
|
218
276
|
end
|
219
277
|
|
220
278
|
# Returns true if the Obj is suppressed.
|
@@ -223,7 +281,7 @@ module RailsConnector
|
|
223
281
|
# as a standalone web page.
|
224
282
|
# @api public
|
225
283
|
def suppressed?
|
226
|
-
suppress_export
|
284
|
+
suppress_export
|
227
285
|
end
|
228
286
|
|
229
287
|
# Returns true if the export of the object is not suppressed and the content is active?
|
@@ -253,16 +311,14 @@ module RailsConnector
|
|
253
311
|
def root?
|
254
312
|
parent_obj_id.nil?
|
255
313
|
end
|
256
|
-
|
257
|
-
has_many :children, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
|
258
|
-
belongs_to :parent, :class_name => 'Obj', :foreign_key => 'parent_obj_id'
|
314
|
+
#
|
259
315
|
|
260
316
|
# Returns a list of exportable? children excluding the binary? ones unless :all is specfied.
|
261
317
|
# This is mainly used for navigations.
|
262
318
|
# @api public
|
263
319
|
def toclist(*args)
|
264
320
|
return [] unless publication?
|
265
|
-
toclist = children.
|
321
|
+
toclist = children.to_a.select{ |toc| toc.exportable? }
|
266
322
|
toclist = toclist.reject { |toc| toc.binary? } unless args.include?(:all)
|
267
323
|
toclist
|
268
324
|
end
|
@@ -300,18 +356,6 @@ module RailsConnector
|
|
300
356
|
return self.sort_order == "descending" ? sorted_list.reverse : sorted_list
|
301
357
|
end
|
302
358
|
|
303
|
-
def sort_key1
|
304
|
-
self[:sort_key1]
|
305
|
-
end
|
306
|
-
|
307
|
-
def sort_key2
|
308
|
-
self[:sort_key2]
|
309
|
-
end
|
310
|
-
|
311
|
-
def sort_key3
|
312
|
-
self[:sort_key3]
|
313
|
-
end
|
314
|
-
|
315
359
|
# Returns an Array of all the ancestor objects, starting at the root and ending at this object's parent.
|
316
360
|
# @api public
|
317
361
|
def ancestors
|
@@ -336,26 +380,17 @@ module RailsConnector
|
|
336
380
|
# Passing an invalid key will not raise an error, but return nil.
|
337
381
|
# @api public
|
338
382
|
def [](key)
|
339
|
-
|
340
|
-
|
383
|
+
if has_attribute?(key)
|
384
|
+
begin
|
385
|
+
if attr_dict.respond_to?(key)
|
386
|
+
return attr_dict.send(key)
|
387
|
+
end
|
341
388
|
|
342
|
-
|
343
|
-
|
344
|
-
|
345
|
-
return as_date(super(key))
|
346
|
-
else
|
347
|
-
return super(key)
|
389
|
+
read_attribute(key)
|
390
|
+
rescue NoMethodError
|
391
|
+
nil
|
348
392
|
end
|
349
393
|
end
|
350
|
-
|
351
|
-
# Unknown Obj attributes are delegated to the corresponding instance of AttrDict.
|
352
|
-
begin
|
353
|
-
return (attr_dict.send key)
|
354
|
-
rescue NoMethodError
|
355
|
-
end
|
356
|
-
|
357
|
-
# fallback
|
358
|
-
return nil
|
359
394
|
end
|
360
395
|
|
361
396
|
# Reloads the attributes of this object from the database, invalidates custom attributes
|
@@ -384,9 +419,7 @@ module RailsConnector
|
|
384
419
|
# for binary Objs body_length equals the file size
|
385
420
|
# for non-binary Objs body_length equals the number of characters in the body (main content)
|
386
421
|
# @api public
|
387
|
-
|
388
|
-
attr_dict.body_length
|
389
|
-
end
|
422
|
+
delegate :body_length, to: :attr_dict
|
390
423
|
|
391
424
|
# Override this method to provide an external url
|
392
425
|
# where the content (the body) of this Obj can be downloaded.
|
@@ -462,27 +495,6 @@ module RailsConnector
|
|
462
495
|
rslt
|
463
496
|
end
|
464
497
|
|
465
|
-
# @api public
|
466
|
-
def last_changed
|
467
|
-
self[:last_changed]
|
468
|
-
end
|
469
|
-
|
470
|
-
# @api public
|
471
|
-
def valid_from
|
472
|
-
self[:valid_from]
|
473
|
-
end
|
474
|
-
|
475
|
-
# @api public
|
476
|
-
def valid_until
|
477
|
-
self[:valid_until]
|
478
|
-
end
|
479
|
-
|
480
|
-
# deprecated, use file_extension instead
|
481
|
-
def content_type
|
482
|
-
logger.warn "DEPRECATION WARNING: Obj#content_type is deprecated, use file_extension instead"
|
483
|
-
file_extension
|
484
|
-
end
|
485
|
-
|
486
498
|
# Returns the MIME-type as determined from the file_extension - see MIME::Types
|
487
499
|
# @api public
|
488
500
|
def mime_type
|
@@ -503,30 +515,6 @@ module RailsConnector
|
|
503
515
|
|
504
516
|
private
|
505
517
|
|
506
|
-
def as_date(value)
|
507
|
-
DateAttribute.parse(value) unless value.nil?
|
508
|
-
end
|
509
|
-
|
510
|
-
# Forwards any unknown method call to a corresponding instance
|
511
|
-
# of AttrDict and thus provides access to object fields, i.e. content.
|
512
|
-
#
|
513
|
-
# In case of an invalid method call, an error is raised.
|
514
|
-
#
|
515
|
-
# Hint: Use [] instead to suppress error messages.
|
516
|
-
def method_missing(method_id, *args)
|
517
|
-
super
|
518
|
-
rescue NoMethodError, NameError
|
519
|
-
# prevent infinite recursion when calling "attr_*" below,
|
520
|
-
# since rails checks the absence of an "_attr_*" method internally
|
521
|
-
raise if %w(_attr_dict _attr_defs _attr_values).include?(method_id.to_s)
|
522
|
-
|
523
|
-
if attr_dict.respond_to?(method_id)
|
524
|
-
attr_dict.send method_id, *args
|
525
|
-
else
|
526
|
-
raise
|
527
|
-
end
|
528
|
-
end
|
529
|
-
|
530
518
|
def fiona_fields
|
531
519
|
@fiona_fields ||=
|
532
520
|
['name', 'obj_class', 'workflow', 'suppressexport', 'permalink'].inject({}) do |all,field|
|
@@ -566,7 +554,7 @@ module RailsConnector
|
|
566
554
|
|
567
555
|
def self.try_type
|
568
556
|
result = yield
|
569
|
-
result if
|
557
|
+
result if result < CmsBaseModel
|
570
558
|
rescue NameError, ActiveRecord::ActiveRecordError
|
571
559
|
nil
|
572
560
|
end
|
@@ -574,4 +562,3 @@ module RailsConnector
|
|
574
562
|
end
|
575
563
|
|
576
564
|
end
|
577
|
-
|
data/lib/rails_connector/blob.rb
CHANGED
@@ -7,13 +7,13 @@ module RailsConnector
|
|
7
7
|
|
8
8
|
class << self
|
9
9
|
# Does not retrieve the column blob_data.
|
10
|
-
def find_with_excluded_blob_data(
|
11
|
-
|
12
|
-
args.last[:select] = 'blob_name, blob_length'
|
13
|
-
find_without_excluded_blob_data(*args)
|
10
|
+
def find_with_excluded_blob_data(primary_key)
|
11
|
+
select(:blob_name, :blob_length).find(primary_key)
|
14
12
|
end
|
15
13
|
|
16
|
-
|
14
|
+
alias_method :find_without_excluded_blob_data, :find
|
15
|
+
alias_method :find, :find_with_excluded_blob_data
|
16
|
+
|
17
17
|
end
|
18
18
|
|
19
19
|
def length
|
@@ -25,7 +25,7 @@ module RailsConnector
|
|
25
25
|
end
|
26
26
|
|
27
27
|
def path_of_stored_data(use_cached_file_if_older_than = Time.now)
|
28
|
-
store_data if !File.exists?(path) ||
|
28
|
+
store_data if !File.exists?(path) || file_size_differs? || stale?(use_cached_file_if_older_than)
|
29
29
|
path
|
30
30
|
end
|
31
31
|
|
@@ -65,6 +65,14 @@ module RailsConnector
|
|
65
65
|
File.open(tmp_file, "wb", &block)
|
66
66
|
File.rename(tmp_file, path)
|
67
67
|
end
|
68
|
+
|
69
|
+
def stale?(time)
|
70
|
+
time > File.mtime(path)
|
71
|
+
end
|
72
|
+
|
73
|
+
def file_size_differs?
|
74
|
+
blob_length != File.stat(path).size
|
75
|
+
end
|
68
76
|
end
|
69
77
|
|
70
78
|
end
|
@@ -0,0 +1,16 @@
|
|
1
|
+
# -*- encoding : utf-8 -*-
|
2
|
+
module RailsConnector
|
3
|
+
class BlobMapping < CmsBaseModel
|
4
|
+
def self.exists?
|
5
|
+
self.table_exists?
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.get_fingerprint(name)
|
9
|
+
find_by_blob_name(name).fingerprint
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.get_fingerprint_map(blob_names)
|
13
|
+
Hash[self.where(:blob_name => blob_names).select([:blob_name, :fingerprint]).map {|b| [b.blob_name, b.fingerprint] }]
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
@@ -13,7 +13,7 @@ module RailsConnector
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def fetch_into_file(file)
|
16
|
-
mysql2_client = connection.
|
16
|
+
mysql2_client = self.class.connection.raw_connection
|
17
17
|
ActiveRecord::Base.logger.debug "Streaming blob from MySQL2 into #{file.path}"
|
18
18
|
|
19
19
|
table_name = mysql2_client.escape(self.class.table_name)
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
class Channel < CmsBaseModel
|
3
|
+
self.primary_key = "channel_name"
|
4
|
+
|
5
|
+
def self.table_name
|
6
|
+
"#{table_name_prefix}" "channels"
|
7
|
+
end
|
8
|
+
|
9
|
+
has_many :news, :class_name => 'RailsConnector::News', :foreign_key => 'channel_name'
|
10
|
+
has_many :active_news,
|
11
|
+
lambda { where(['valid_from <= :now AND valid_until >= :now', {:now => Time.now.to_s(:number)}]) },
|
12
|
+
:class_name => 'RailsConnector::News', :foreign_key => 'channel_name'
|
13
|
+
|
14
|
+
has_many :objects, :through => :news
|
15
|
+
|
16
|
+
scope :with_prefix, -> (prefix) {where(["channel_name LIKE ?", "#{prefix}%"])}
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
module RailsConnector
|
2
|
+
|
3
|
+
# @api public
|
4
|
+
module CmsAccessible
|
5
|
+
|
6
|
+
protected
|
7
|
+
|
8
|
+
# Filter method to load a CMS object.
|
9
|
+
#
|
10
|
+
# To require the loading for all actions, use this in your controllers:
|
11
|
+
# before_action :load_object
|
12
|
+
def load_object
|
13
|
+
CmsEnv.new(request.env).load
|
14
|
+
loaded_obj = request.env[CmsEnv::OBJ_ENV_KEY]
|
15
|
+
raise loaded_obj if loaded_obj.is_a?(StandardError)
|
16
|
+
@obj = loaded_obj
|
17
|
+
end
|
18
|
+
|
19
|
+
# Filter method to check if the already loaded object is active. If it is
|
20
|
+
# not, a 410 Gone error message will be generate (by calling render_obj_error).
|
21
|
+
#
|
22
|
+
# To require the check for all actions, use this in your controllers:
|
23
|
+
# before_action :load_object
|
24
|
+
# before_action :ensure_object_is_active
|
25
|
+
def ensure_object_is_active
|
26
|
+
unless @obj.active?
|
27
|
+
@valid_from = @obj.valid_from
|
28
|
+
@valid_until = @obj.valid_until
|
29
|
+
@obj = nil
|
30
|
+
render_obj_error(410, "gone")
|
31
|
+
end
|
32
|
+
return true
|
33
|
+
end
|
34
|
+
|
35
|
+
# Filter method to check if access to the loaded object is permitted. If it is
|
36
|
+
# not, a 403 Forbidden error message will be generated (by calling render_obj_error)
|
37
|
+
#
|
38
|
+
# To require the check for all actions, use this in your controllers:
|
39
|
+
# before_action :load_object
|
40
|
+
# before_action :ensure_object_is_permitted
|
41
|
+
def ensure_object_is_permitted
|
42
|
+
unless is_permitted(@obj)
|
43
|
+
@obj = nil
|
44
|
+
render_obj_error(403, "forbidden")
|
45
|
+
end
|
46
|
+
return true
|
47
|
+
end
|
48
|
+
|
49
|
+
# This method is called when rendering an error caused by either {ensure_object_is_permitted}
|
50
|
+
# or {ensure_object_is_active} before filter. It renders an error template located in
|
51
|
+
# "errors/*.html.erb" with given HTTP status and content type "text/html" and with no layout.
|
52
|
+
# Overwrite this method to change the error page.
|
53
|
+
# @api public
|
54
|
+
def render_obj_error(status, name)
|
55
|
+
force_html_format
|
56
|
+
render(
|
57
|
+
:template => "errors/#{status}_#{name}",
|
58
|
+
:layout => false,
|
59
|
+
:status => status,
|
60
|
+
:content_type => Mime[:html]
|
61
|
+
)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Enforce "html" as template format.
|
65
|
+
# @api public
|
66
|
+
def force_html_format
|
67
|
+
request.format = :html
|
68
|
+
end
|
69
|
+
|
70
|
+
# Inclusion hook to make is_permitted available as helper method.
|
71
|
+
def self.included(base)
|
72
|
+
base.__send__ :helper_method, :is_permitted
|
73
|
+
end
|
74
|
+
|
75
|
+
# Helper method to check live permissions
|
76
|
+
def is_permitted(obj)
|
77
|
+
obj.permitted_for_user?(current_user)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Filter method which sets the header 'X-Robots-Tag: unavailable_after'
|
81
|
+
# to the valid_until date of the current object.
|
82
|
+
def set_google_expire_header
|
83
|
+
if @obj && (date = @obj.valid_until)
|
84
|
+
headers['X-Robots-Tag: unavailable_after'] = date.rfc822
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
# Deliver the obj's body as response by file or data.
|
89
|
+
# May respond with status 304 if a If-Modified-Since header is found.
|
90
|
+
# @api public
|
91
|
+
def deliver_file
|
92
|
+
if @obj.body_data_url
|
93
|
+
redirect_to enforce_protocol_from_request(@obj.body_data_url)
|
94
|
+
elsif stale?(:last_modified => @obj.last_changed.utc)
|
95
|
+
mime_type = @obj.mime_type
|
96
|
+
mime_type += '; charset=utf-8' if mime_type =~ /^text\//
|
97
|
+
|
98
|
+
if (filepath = @obj.body_data_path).present?
|
99
|
+
send_file(File.expand_path(filepath), {
|
100
|
+
:type => mime_type,
|
101
|
+
:filename => @obj.filename,
|
102
|
+
:disposition => 'inline',
|
103
|
+
})
|
104
|
+
else
|
105
|
+
# generics should send its body, empty files should be delivered as
|
106
|
+
# empty files - and not lead to an application error
|
107
|
+
send_data @obj.body || '', :type => mime_type, :filename => @obj.filename, :disposition => 'inline'
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|