hobo 0.8.3 → 0.8.4
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +330 -0
- data/Manifest +12 -4
- data/Rakefile +4 -6
- data/dryml_generators/rapid/cards.dryml.erb +5 -1
- data/dryml_generators/rapid/forms.dryml.erb +8 -10
- data/dryml_generators/rapid/pages.dryml.erb +65 -36
- data/hobo.gemspec +28 -15
- data/lib/active_record/association_collection.rb +3 -22
- data/lib/hobo.rb +25 -258
- data/lib/hobo/accessible_associations.rb +131 -0
- data/lib/hobo/authentication_support.rb +15 -9
- data/lib/hobo/composite_model.rb +1 -1
- data/lib/hobo/controller.rb +7 -8
- data/lib/hobo/dryml.rb +9 -10
- data/lib/hobo/dryml/dryml_builder.rb +7 -1
- data/lib/hobo/dryml/dryml_doc.rb +161 -0
- data/lib/hobo/dryml/dryml_generator.rb +18 -9
- data/lib/hobo/dryml/part_context.rb +76 -42
- data/lib/hobo/dryml/tag_parameters.rb +1 -0
- data/lib/hobo/dryml/taglib.rb +2 -1
- data/lib/hobo/dryml/template.rb +39 -29
- data/lib/hobo/dryml/template_environment.rb +79 -37
- data/lib/hobo/dryml/template_handler.rb +66 -21
- data/lib/hobo/guest.rb +2 -10
- data/lib/hobo/hobo_helper.rb +125 -53
- data/lib/hobo/include_in_save.rb +0 -1
- data/lib/hobo/lifecycles.rb +54 -24
- data/lib/hobo/lifecycles/actions.rb +95 -31
- data/lib/hobo/lifecycles/creator.rb +18 -23
- data/lib/hobo/lifecycles/lifecycle.rb +86 -62
- data/lib/hobo/lifecycles/state.rb +1 -2
- data/lib/hobo/lifecycles/transition.rb +22 -28
- data/lib/hobo/model.rb +64 -176
- data/lib/hobo/model_controller.rb +67 -54
- data/lib/hobo/model_router.rb +5 -2
- data/lib/hobo/permissions.rb +397 -0
- data/lib/hobo/permissions/associations.rb +167 -0
- data/lib/hobo/scopes.rb +15 -38
- data/lib/hobo/scopes/association_proxy_extensions.rb +15 -5
- data/lib/hobo/scopes/automatic_scopes.rb +43 -18
- data/lib/hobo/scopes/named_scope_extensions.rb +2 -2
- data/lib/hobo/user.rb +10 -4
- data/lib/hobo/user_controller.rb +6 -5
- data/lib/hobo/view_hints.rb +58 -0
- data/rails_generators/hobo/hobo_generator.rb +7 -3
- data/rails_generators/hobo/templates/guest.rb +1 -13
- data/rails_generators/hobo_front_controller/hobo_front_controller_generator.rb +1 -1
- data/rails_generators/hobo_model/hobo_model_generator.rb +4 -2
- data/rails_generators/hobo_model/templates/hints.rb +4 -0
- data/rails_generators/hobo_model/templates/model.rb +8 -8
- data/rails_generators/hobo_model_controller/hobo_model_controller_generator.rb +10 -0
- data/rails_generators/hobo_model_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_rapid/templates/hobo-rapid.js +91 -56
- data/rails_generators/hobo_rapid/templates/lowpro.js +15 -15
- data/rails_generators/hobo_rapid/templates/reset.css +36 -3
- data/rails_generators/hobo_rapid/templates/themes/clean/public/stylesheets/clean.css +13 -17
- data/rails_generators/hobo_user_controller/templates/controller.rb +1 -1
- data/rails_generators/hobo_user_model/templates/model.rb +18 -16
- data/taglibs/core.dryml +60 -18
- data/taglibs/rapid.dryml +8 -401
- data/taglibs/rapid_core.dryml +586 -0
- data/taglibs/rapid_document_tags.dryml +28 -10
- data/taglibs/rapid_editing.dryml +92 -55
- data/taglibs/rapid_forms.dryml +406 -87
- data/taglibs/rapid_generics.dryml +1 -1
- data/taglibs/rapid_navigation.dryml +2 -1
- data/taglibs/rapid_pages.dryml +7 -16
- data/taglibs/rapid_plus.dryml +39 -14
- data/taglibs/rapid_support.dryml +1 -1
- data/taglibs/rapid_user_pages.dryml +14 -4
- data/tasks/{generate_tag_reference.rb → generate_tag_reference.rake} +49 -18
- data/tasks/hobo_tasks.rake +16 -0
- data/test/permissions/models/models.rb +134 -0
- data/test/permissions/models/schema.rb +55 -0
- data/test/permissions/models/test.sqlite3 +0 -0
- data/test/permissions/test_permissions.rb +436 -0
- metadata +27 -14
- data/lib/hobo/mass_assignment.rb +0 -64
- data/rails_generators/hobo/templates/patch_routing.rb +0 -30
- data/uninstall.rb +0 -1
@@ -90,21 +90,27 @@ module Hobo
|
|
90
90
|
# When called with before_filter :login_from_cookie will check for an :auth_token
|
91
91
|
# cookie and log the user back in if apropriate
|
92
92
|
def login_from_cookie
|
93
|
-
|
94
|
-
|
95
|
-
user_model = token[:user_model].constantize
|
96
|
-
user = user_model.find_by_remember_token(token)
|
97
|
-
if user && user.remember_token?
|
93
|
+
if (user = authenticated_user_from_cookie)
|
98
94
|
user.remember_me
|
99
|
-
current_user = user
|
95
|
+
self.current_user = user
|
100
96
|
create_auth_cookie
|
101
97
|
end
|
102
98
|
end
|
99
|
+
|
100
|
+
|
101
|
+
def authenticated_user_from_cookie
|
102
|
+
!logged_in? and
|
103
|
+
cookie = cookies[:auth_token] and
|
104
|
+
(token, model_name = cookie.split) and
|
105
|
+
user_model = model_name.constantize rescue nil and
|
106
|
+
user = user_model.find_by_remember_token(token) and
|
107
|
+
user.remember_token? and
|
108
|
+
user
|
109
|
+
end
|
103
110
|
|
104
111
|
def create_auth_cookie
|
105
|
-
cookies[:auth_token] = { :value => current_user.remember_token ,
|
106
|
-
:expires => current_user.remember_token_expires_at
|
107
|
-
:user_model => current_user.model }
|
112
|
+
cookies[:auth_token] = { :value => "#{current_user.remember_token} #{current_user.class.name}",
|
113
|
+
:expires => current_user.remember_token_expires_at }
|
108
114
|
end
|
109
115
|
|
110
116
|
private
|
data/lib/hobo/composite_model.rb
CHANGED
data/lib/hobo/controller.rb
CHANGED
@@ -15,6 +15,7 @@ module Hobo
|
|
15
15
|
def included_in_class(klass)
|
16
16
|
klass.extend(ClassMethods)
|
17
17
|
klass.class_eval do
|
18
|
+
before_filter :login_from_cookie
|
18
19
|
alias_method_chain :redirect_to, :object_url
|
19
20
|
around_filter do |controller, action|
|
20
21
|
Thread.current['Hobo::current_controller'] = controller
|
@@ -66,11 +67,10 @@ module Hobo
|
|
66
67
|
|
67
68
|
def hobo_ajax_response(*args)
|
68
69
|
results = args.extract_options!
|
69
|
-
this = args.first || @this
|
70
70
|
page_path = params[:page_path]
|
71
71
|
r = params[:render]
|
72
72
|
if r
|
73
|
-
ajax_update_response(
|
73
|
+
ajax_update_response(page_path, r.values, results)
|
74
74
|
true
|
75
75
|
else
|
76
76
|
false
|
@@ -78,8 +78,8 @@ module Hobo
|
|
78
78
|
end
|
79
79
|
|
80
80
|
|
81
|
-
def ajax_update_response(
|
82
|
-
|
81
|
+
def ajax_update_response(page_path, render_specs, results={})
|
82
|
+
@template.send(:_evaluate_assigns_and_ivars)
|
83
83
|
renderer = Hobo::Dryml.page_renderer(@template, [], page_path) if page_path
|
84
84
|
|
85
85
|
render :update do |page|
|
@@ -89,12 +89,11 @@ module Hobo
|
|
89
89
|
dom_id = spec[:id]
|
90
90
|
|
91
91
|
if spec[:part_context]
|
92
|
-
|
93
|
-
part_content = renderer.call_part(dom_id, part_name, part_this, *locals)
|
92
|
+
part_content = renderer.refresh_part(spec[:part_context], session, dom_id)
|
94
93
|
page.call(function, dom_id, part_content)
|
95
94
|
elsif spec[:result]
|
96
95
|
result = results[spec[:result].to_sym]
|
97
|
-
page.call(function,
|
96
|
+
page.call(function, dom_id, result)
|
98
97
|
else
|
99
98
|
# spec didn't specify any action :-/
|
100
99
|
end
|
@@ -168,7 +167,7 @@ end
|
|
168
167
|
class ActionController::Base
|
169
168
|
|
170
169
|
def home_page
|
171
|
-
|
170
|
+
base_url
|
172
171
|
end
|
173
172
|
|
174
173
|
end
|
data/lib/hobo/dryml.rb
CHANGED
@@ -58,12 +58,12 @@ module Hobo
|
|
58
58
|
end
|
59
59
|
|
60
60
|
|
61
|
-
def page_renderer_for_template(view, template)
|
62
|
-
page_renderer(view, template.
|
61
|
+
def page_renderer_for_template(view, local_names, template)
|
62
|
+
page_renderer(view, local_names, template.path_without_extension, template.filename)
|
63
63
|
end
|
64
64
|
|
65
65
|
|
66
|
-
def page_renderer(view, local_names=[], page=nil)
|
66
|
+
def page_renderer(view, local_names=[], page=nil, filename=nil)
|
67
67
|
if RAILS_ENV == "development"
|
68
68
|
clear_cache
|
69
69
|
Taglib.clear_cache
|
@@ -79,16 +79,15 @@ module Hobo
|
|
79
79
|
make_renderer_class("", page, local_names, DEFAULT_IMPORTS, included_taglibs)
|
80
80
|
@tag_page_renderer_classes[controller_class.name].new(page, view)
|
81
81
|
else
|
82
|
-
|
83
|
-
|
84
|
-
mtime = File.mtime(template_path)
|
82
|
+
filename ||= view._pick_template(page + ".dryml").filename
|
83
|
+
mtime = File.mtime(filename)
|
85
84
|
renderer_class = @renderer_classes[page]
|
86
85
|
|
87
86
|
# do we need to recompile?
|
88
|
-
if (!renderer_class
|
89
|
-
(local_names - renderer_class.compiled_local_names).any?
|
87
|
+
if (!renderer_class || # nothing cached?
|
88
|
+
(local_names - renderer_class.compiled_local_names).any? || # any new local names?
|
90
89
|
renderer_class.load_time < mtime) # cache out of date?
|
91
|
-
renderer_class = make_renderer_class(File.read(
|
90
|
+
renderer_class = make_renderer_class(File.read(filename), filename, local_names,
|
92
91
|
DEFAULT_IMPORTS, included_taglibs)
|
93
92
|
renderer_class.load_time = mtime
|
94
93
|
@renderer_classes[page] = renderer_class
|
@@ -106,7 +105,7 @@ module Hobo
|
|
106
105
|
|
107
106
|
|
108
107
|
def controller_taglibs(controller_class)
|
109
|
-
|
108
|
+
controller_class.try.included_taglibs || []
|
110
109
|
end
|
111
110
|
|
112
111
|
|
@@ -62,7 +62,13 @@ module Hobo::Dryml
|
|
62
62
|
# Strip off "_erbout = ''" from the beginning and "; _erbout"
|
63
63
|
# from the end, because we do things differently around
|
64
64
|
# here. (_erbout is defined as a method)
|
65
|
-
|
65
|
+
trim_mode = if defined?(ActionView::TemplateHandlers::ERB.erb_trim_mode)
|
66
|
+
ActionView::TemplateHandlers::ERB.erb_trim_mode
|
67
|
+
else
|
68
|
+
ActionView::Base.erb_trim_mode
|
69
|
+
end
|
70
|
+
|
71
|
+
ERB.new(erb_src, nil, trim_mode).src[("_erbout = '';").length..-("; _erbout".length)]
|
66
72
|
end
|
67
73
|
|
68
74
|
|
@@ -0,0 +1,161 @@
|
|
1
|
+
require 'rexml/xpath'
|
2
|
+
|
3
|
+
module Hobo
|
4
|
+
|
5
|
+
module Dryml
|
6
|
+
|
7
|
+
# DrymlDoc provides the facility to parse a directory tree of DRYML taglibs, building a collection of objects that provide metadata
|
8
|
+
module DrymlDoc
|
9
|
+
|
10
|
+
def self.load_taglibs(directory, taglib_class=DrymlDoc::Taglib)
|
11
|
+
dryml_files = Dir["#{directory}/**/*.dryml"]
|
12
|
+
|
13
|
+
dryml_files.map { |f| taglib_class.new(directory, f) }
|
14
|
+
end
|
15
|
+
|
16
|
+
class Taglib
|
17
|
+
|
18
|
+
def initialize(home, filename)
|
19
|
+
@name = filename.sub(/.dryml$/, '')[home.length+1..-1]
|
20
|
+
@doc = Hobo::Dryml::Parser::Document.new(File.read(filename), filename)
|
21
|
+
parse_tag_defs
|
22
|
+
end
|
23
|
+
|
24
|
+
attr_reader :name, :doc, :tag_defs
|
25
|
+
|
26
|
+
def comment
|
27
|
+
first_node = doc[0][0]
|
28
|
+
doc.restore_erb_scriptlets(first_node.to_s.strip) if first_node.is_a?(REXML::Comment)
|
29
|
+
end
|
30
|
+
|
31
|
+
def comment_html
|
32
|
+
Maruku.new(comment).to_html
|
33
|
+
end
|
34
|
+
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def tagdef_class
|
39
|
+
self.class.parent.const_get('TagDef')
|
40
|
+
end
|
41
|
+
|
42
|
+
def parse_tag_defs
|
43
|
+
@tag_defs = []
|
44
|
+
REXML::XPath.match(doc, '/*/*[@tag]').each { |node| @tag_defs << tagdef_class.new(self, node) }
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
class TagDef
|
50
|
+
|
51
|
+
def initialize(taglib, node)
|
52
|
+
@taglib = taglib
|
53
|
+
@node = node
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :taglib, :node
|
57
|
+
delegate :doc, :to => :taglib
|
58
|
+
|
59
|
+
|
60
|
+
def name
|
61
|
+
node.attributes['tag']
|
62
|
+
end
|
63
|
+
|
64
|
+
def source
|
65
|
+
doc.restore_erb_scriptlets(node.to_s).strip
|
66
|
+
end
|
67
|
+
|
68
|
+
# The contents of the XML comment, if any, immediately above the tag definition
|
69
|
+
def comment
|
70
|
+
@comment ||= begin
|
71
|
+
space = node.previous_sibling and
|
72
|
+
space.to_s.blank? && space.to_s.count("\n") == 1 and
|
73
|
+
comment_node = space.previous_sibling
|
74
|
+
|
75
|
+
if comment_node.is_a?(REXML::Comment)
|
76
|
+
doc.restore_erb_scriptlets(comment_node.to_s.strip)
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
|
82
|
+
def comment_intro
|
83
|
+
comment && comment =~ /(.*?)^#/m ? $1 : comment
|
84
|
+
end
|
85
|
+
|
86
|
+
|
87
|
+
def comment_rest
|
88
|
+
comment && comment[comment_intro.length..-1]
|
89
|
+
end
|
90
|
+
|
91
|
+
%w(comment comment_intro comment_rest).each do |m|
|
92
|
+
class_eval "def #{m}_html; Maruku.new(#{m}).to_html.gsub(/&/, '&'); end"
|
93
|
+
end
|
94
|
+
|
95
|
+
def comment_html
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
def no_doc?
|
100
|
+
comment =~ /^nodoc\b/
|
101
|
+
end
|
102
|
+
|
103
|
+
# An array of the arrtibute names defined by this tag
|
104
|
+
def attributes
|
105
|
+
(node.attributes['attrs'] || "").split(/\s*,\s*/).where_not.blank?
|
106
|
+
end
|
107
|
+
|
108
|
+
|
109
|
+
# Returns a recursive array srtucture, where each item in the array is a pair: [parameter_name, sub_parameters]
|
110
|
+
# (sub-parameters is the same kind of structure)
|
111
|
+
def parameters(element=node)
|
112
|
+
result = []
|
113
|
+
element.elements.each do |e|
|
114
|
+
if (p = e.attributes['param'])
|
115
|
+
param_name = p == "&true" ? e.name : p
|
116
|
+
result << [param_name, parameters(e)]
|
117
|
+
else
|
118
|
+
result.concat(parameters(e))
|
119
|
+
end
|
120
|
+
end
|
121
|
+
result
|
122
|
+
end
|
123
|
+
|
124
|
+
|
125
|
+
# Is this the base definition of a polymorphic tag
|
126
|
+
def polymorphic?
|
127
|
+
node.attributes['polymorphic'].present?
|
128
|
+
end
|
129
|
+
|
130
|
+
# Is this an <extend>?
|
131
|
+
def extension?
|
132
|
+
node.name == "extend"
|
133
|
+
end
|
134
|
+
|
135
|
+
|
136
|
+
# The definition's 'for' attribute
|
137
|
+
def for_type
|
138
|
+
node.attributes['for']
|
139
|
+
end
|
140
|
+
|
141
|
+
|
142
|
+
# The name of the tag, if any, that this definition merges its parameters into
|
143
|
+
# That is, the tag with 'merge' or 'merge-params' declared
|
144
|
+
def merge_params
|
145
|
+
REXML::XPath.first(node, ".//*[@merge|@merge-params]")._?.name
|
146
|
+
end
|
147
|
+
|
148
|
+
# The name of the tag, if any, that this definition merges its attributes into
|
149
|
+
# That is, the tag with 'merge' or 'merge-attrs' declared
|
150
|
+
def merge_attrs
|
151
|
+
REXML::XPath.first(node, ".//*[@merge|@merge-attrs]")._?.name
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
end
|
158
|
+
|
159
|
+
end
|
160
|
+
|
161
|
+
end
|
@@ -13,6 +13,7 @@ module Hobo
|
|
13
13
|
HEADER = "<!-- AUTOMATICALLY GENERATED FILE - DO NOT EDIT -->\n\n"
|
14
14
|
|
15
15
|
def self.run
|
16
|
+
return if RAILS_ENV == "production"
|
16
17
|
@generator ||= DrymlGenerator.new
|
17
18
|
@generator.run
|
18
19
|
end
|
@@ -137,15 +138,6 @@ module Hobo
|
|
137
138
|
end
|
138
139
|
|
139
140
|
|
140
|
-
def primary_collection_name(klass=model)
|
141
|
-
dependent_collection_names = klass.reflections.values.select do |refl|
|
142
|
-
refl.macro == :has_many && refl.options[:dependent]
|
143
|
-
end.*.name
|
144
|
-
|
145
|
-
(dependent_collection_names - through_collection_names(klass)).first
|
146
|
-
end
|
147
|
-
|
148
|
-
|
149
141
|
def through_collection_names(klass=model)
|
150
142
|
klass.reflections.values.select do |refl|
|
151
143
|
refl.macro == :has_many && refl.options[:through]
|
@@ -199,6 +191,23 @@ module Hobo
|
|
199
191
|
end
|
200
192
|
|
201
193
|
|
194
|
+
def creators
|
195
|
+
defined?(model::Lifecycle) ? model::Lifecycle.publishable_creators : []
|
196
|
+
end
|
197
|
+
|
198
|
+
def transitions
|
199
|
+
defined?(model::Lifecycle) ? model::Lifecycle.publishable_transitions : []
|
200
|
+
end
|
201
|
+
|
202
|
+
def creator_names
|
203
|
+
creators.map { |c| c.name.to_s }
|
204
|
+
end
|
205
|
+
|
206
|
+
def transition_names
|
207
|
+
transitions.map { |t| t.name.to_s }.uniq
|
208
|
+
end
|
209
|
+
|
210
|
+
|
202
211
|
def a_or_an(word)
|
203
212
|
(word =~ /^[aeiou]/i ? "an " : "a ") + word
|
204
213
|
end
|
@@ -7,7 +7,7 @@ module Hobo
|
|
7
7
|
|
8
8
|
class TamperedWithPartContext < StandardError; end
|
9
9
|
|
10
|
-
class
|
10
|
+
class TypedId < String; end
|
11
11
|
|
12
12
|
class << self
|
13
13
|
attr_accessor :secret, :digest
|
@@ -23,75 +23,109 @@ module Hobo
|
|
23
23
|
"hoboParts['#{dom_id}'] = (#{code});\n"
|
24
24
|
end.join
|
25
25
|
end
|
26
|
-
|
27
|
-
|
28
|
-
def
|
29
|
-
@part_name = part_name
|
30
|
-
@this_id = this_id
|
31
|
-
@locals = locals.map { |l| pre_marshal(l) }
|
32
|
-
end
|
33
|
-
|
34
|
-
|
35
|
-
def pre_marshal(x)
|
26
|
+
|
27
|
+
|
28
|
+
def self.pre_marshal(x)
|
36
29
|
if x.is_a?(ActiveRecord::Base) && x.respond_to?(:typed_id)
|
37
|
-
|
30
|
+
TypedId.new(x.typed_id)
|
38
31
|
else
|
39
32
|
x
|
40
33
|
end
|
41
34
|
end
|
42
35
|
|
43
36
|
|
37
|
+
def self.for_call(part_name, environment, locals)
|
38
|
+
new do |c|
|
39
|
+
c.part_name = part_name
|
40
|
+
c.locals = locals.map { |l| pre_marshal(l) }
|
41
|
+
c.this_id = environment.typed_id
|
42
|
+
c.form_field_path = environment.form_field_path
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
def self.for_refresh(encoded_context, page_this, session)
|
48
|
+
new do |c|
|
49
|
+
c.unmarshal(encoded_context, page_this, session)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
def initialize
|
55
|
+
yield self
|
56
|
+
end
|
57
|
+
|
58
|
+
attr_accessor :part_name, :locals, :this, :this_field, :this_id, :form_field_path
|
59
|
+
|
60
|
+
|
44
61
|
def marshal(session)
|
45
62
|
context = [@part_name, @this_id, @locals]
|
63
|
+
context << form_field_path if form_field_path
|
46
64
|
data = Base64.encode64(Marshal.dump(context)).strip
|
47
|
-
digest =
|
65
|
+
digest = generate_digest(data, session)
|
48
66
|
"#{data}--#{digest}"
|
49
67
|
end
|
50
68
|
|
51
69
|
|
52
|
-
|
70
|
+
# Unmarshal part context to a hash and verify its integrity.
|
71
|
+
def unmarshal(client_store, page_this, session)
|
72
|
+
data, digest = CGI.unescape(client_store).strip.split('--')
|
53
73
|
|
54
|
-
|
55
|
-
def generate_digest(data, session)
|
56
|
-
secret = self.secret || ActionController::Base.cached_session_options.first[:secret]
|
57
|
-
key = secret.respond_to?(:call) ? secret.call(session) : secret
|
58
|
-
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(digest), key, data)
|
59
|
-
end
|
74
|
+
raise TamperedWithPartContext unless digest == generate_digest(data, session)
|
60
75
|
|
76
|
+
context = Marshal.load(Base64.decode64(data))
|
77
|
+
|
78
|
+
part_name, this_id, locals, form_field_path = context
|
61
79
|
|
62
|
-
|
63
|
-
|
64
|
-
|
80
|
+
RAILS_DEFAULT_LOGGER.info "Call part: #{part_name}. this-id = #{this_id}, locals = #{locals.inspect}"
|
81
|
+
RAILS_DEFAULT_LOGGER.info " : form_field_path = #{form_field_path.inspect}" if form_field_path
|
82
|
+
|
83
|
+
self.part_name = part_name
|
84
|
+
self.this_id = this_id
|
85
|
+
self.locals = restore_locals(locals)
|
86
|
+
self.form_field_path = form_field_path
|
87
|
+
|
88
|
+
parse_this_id(page_this)
|
89
|
+
end
|
65
90
|
|
66
|
-
raise TamperedWithPartContext unless digest == generate_digest(data, session)
|
67
91
|
|
68
|
-
|
69
|
-
|
92
|
+
# Generate the HMAC keyed message digest. Uses SHA1 by default.
|
93
|
+
def generate_digest(data, session)
|
94
|
+
secret = self.class.secret || ActionController::Base.cached_session_options.first[:secret]
|
95
|
+
key = secret.respond_to?(:call) ? secret.call(session) : secret
|
96
|
+
OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(self.class.digest), key, data)
|
97
|
+
end
|
70
98
|
|
71
|
-
[part_name, restore_part_this(this_id, this), restore_locals(locals)]
|
72
|
-
end
|
73
99
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
100
|
+
|
101
|
+
def parse_this_id(page_this)
|
102
|
+
if this_id == "this"
|
103
|
+
self.this = page_this
|
104
|
+
elsif this_id =~ /^this:(.*)/
|
105
|
+
self.this = page_this
|
106
|
+
self.this_field = $1
|
107
|
+
elsif this_id == "nil"
|
108
|
+
nil
|
109
|
+
else
|
110
|
+
parts = this_id.split(':')
|
111
|
+
if parts.length == 3
|
112
|
+
self.this = Hobo::Model.find_by_typed_id("#{parts[0]}:#{parts[1]}")
|
113
|
+
self.this_field = parts[2]
|
79
114
|
else
|
80
|
-
Hobo.
|
115
|
+
self.this = Hobo::Model.find_by_typed_id(this_id)
|
81
116
|
end
|
82
117
|
end
|
118
|
+
end
|
83
119
|
|
84
120
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
end
|
121
|
+
def restore_locals(locals)
|
122
|
+
locals.map do |l|
|
123
|
+
if l.is_a?(TypedId)
|
124
|
+
Hobo::Model.find_by_typed_id(this_id)
|
125
|
+
else
|
126
|
+
l
|
92
127
|
end
|
93
128
|
end
|
94
|
-
|
95
129
|
end
|
96
130
|
|
97
131
|
end
|