kojac 0.9.1 → 0.11.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.
- checksums.yaml +6 -14
- data/.gitignore +4 -0
- data/Gemfile +1 -1
- data/app/assets/javascripts/kojac.js +393 -125
- data/app/assets/javascripts/kojac_canjs.js +34 -34
- data/app/assets/javascripts/kojac_ember.js +110 -152
- data/app/controllers/{kojac_controller.rb → kojac_base_controller.rb} +18 -11
- data/app/policies/kojac_base_policy.rb +114 -0
- data/app/serializers/kojac_base_serializer.rb +35 -0
- data/kojac.gemspec +12 -10
- data/lib/kojac/app_serialize.rb +31 -29
- data/lib/kojac/concentric.rb +152 -0
- data/lib/kojac/kojac_policy.rb +70 -0
- data/lib/kojac/kojac_rails.rb +200 -49
- data/lib/kojac/version.rb +1 -1
- data/spec/can_cache_spec.js +19 -19
- data/spec/demo/.gitignore +16 -0
- data/spec/demo/.ruby-gemset +1 -0
- data/spec/demo/.ruby-version +1 -0
- data/spec/demo/Gemfile +59 -0
- data/spec/demo/Gemfile.lock +153 -0
- data/spec/demo/README.rdoc +15 -248
- data/spec/demo/Rakefile +25 -1
- data/spec/demo/app/{mailers/.gitkeep → assets/images/.keep} +0 -0
- data/spec/demo/app/assets/javascripts/application.js +3 -3
- data/spec/demo/app/controllers/application_controller.rb +6 -1
- data/spec/demo/app/{models/.gitkeep → controllers/concerns/.keep} +0 -0
- data/spec/demo/app/controllers/users_controller.rb +5 -0
- data/spec/demo/{lib/assets/.gitkeep → app/mailers/.keep} +0 -0
- data/spec/demo/{log/.gitkeep → app/models/.keep} +0 -0
- data/spec/demo/app/models/concerns/.keep +0 -0
- data/spec/demo/app/models/user.rb +36 -0
- data/spec/demo/app/policies/user_policy.rb +42 -0
- data/spec/demo/bin/bundle +3 -0
- data/spec/demo/bin/rails +4 -0
- data/spec/demo/bin/rake +4 -0
- data/spec/demo/config.ru +1 -1
- data/spec/demo/config/application.rb +14 -46
- data/spec/demo/config/application.yml +4 -0
- data/spec/demo/config/boot.rb +3 -9
- data/spec/demo/config/database.yml +6 -6
- data/spec/demo/config/environment.rb +4 -2
- data/spec/demo/config/environments/development.rb +11 -19
- data/spec/demo/config/environments/production.rb +40 -27
- data/spec/demo/config/environments/test.rb +13 -14
- data/spec/demo/config/initializers/concentric_config.rb +9 -0
- data/spec/demo/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/demo/config/initializers/inflections.rb +6 -5
- data/spec/demo/config/initializers/initialize_kojac.rb +16 -0
- data/spec/demo/config/initializers/secret_token.rb +7 -2
- data/spec/demo/config/initializers/session_store.rb +0 -5
- data/spec/demo/config/initializers/wrap_parameters.rb +6 -6
- data/spec/demo/config/locales/en.yml +20 -2
- data/spec/demo/config/routes.rb +24 -24
- data/spec/demo/db/migrate/20131212034312_add_user.rb +14 -0
- data/spec/demo/db/migrate/20140107085351_add_owner_id.rb +5 -0
- data/spec/demo/db/schema.rb +28 -0
- data/spec/demo/db/seeds.rb +7 -0
- data/spec/demo/lib/assets/.keep +0 -0
- data/spec/demo/lib/tasks/.keep +0 -0
- data/spec/demo/log/.keep +0 -0
- data/spec/demo/public/404.html +43 -11
- data/spec/demo/public/422.html +43 -11
- data/spec/demo/public/500.html +43 -11
- data/spec/demo/public/robots.txt +5 -0
- data/spec/demo/spec/controllers/allowed_fields_spec.rb +171 -0
- data/spec/demo/spec/factories/users.rb +9 -0
- data/spec/demo/spec/features/concentric_spec.rb +63 -0
- data/spec/demo/spec/features/serialization_spec.rb +86 -0
- data/spec/demo/spec/spec_helper.rb +133 -0
- data/spec/demo/spec/spec_utils.rb +42 -0
- data/spec/demo/vendor/assets/javascripts/.keep +0 -0
- data/spec/demo/vendor/assets/stylesheets/.keep +0 -0
- data/spec/ember_factory_spec.js +1 -1
- data/spec/ember_model_spec.js +13 -3
- data/spec/ember_tojsono_spec.js +105 -0
- data/spec/error_handling_spec.js +90 -0
- data/spec/external/underscore_plus.js +318 -9
- data/spec/kojac_caching_spec.js +3 -1
- data/spec/kojac_ember_cache_spec.js +9 -0
- data/spec/kojac_mock_spec.js +4 -4
- data/spec/kojac_operations_spec.js +4 -4
- data/spec/local_provider_spec.js +184 -0
- data/spec/model_ring_spec.rb +2 -2
- data/spec/operation_include_spec.js +2 -2
- data/spec/run.html +34 -24
- data/spec/type_conversion_spec.js +38 -0
- data/vendor/assets/javascripts/jstorage.js +950 -0
- metadata +115 -129
- data/Gemfile.lock +0 -157
- data/app/serializers/default_kojac_serializer.rb +0 -10
- data/lib/kojac/ring_strong_parameters.rb +0 -195
- data/spec/.DS_Store +0 -0
- data/spec/demo/script/rails +0 -6
- data/spec/external/.DS_Store +0 -0
data/lib/kojac/kojac_rails.rb
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
|
|
1
|
+
require 'pundit'
|
|
2
2
|
|
|
3
3
|
Kernel.class_eval do
|
|
4
4
|
def key_join(aResource,aId=nil,aAssoc=nil)
|
|
@@ -61,6 +61,39 @@ module KojacUtils
|
|
|
61
61
|
aValue
|
|
62
62
|
end
|
|
63
63
|
|
|
64
|
+
def timestamp
|
|
65
|
+
Time.now.to_ms
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def serializer_for(aObject)
|
|
69
|
+
return ::KojacBaseSerializer if aObject.is_a?(Hash)
|
|
70
|
+
return ::ActiveModel::ArraySerializer if aObject.respond_to?(:to_ary)
|
|
71
|
+
return ActiveModel::DefaultSerializer if KojacBaseSerializer::SERIALIZABLE_TYPES.include?(aObject.class)
|
|
72
|
+
return aObject.send(:active_model_serializer) if aObject.respond_to?(:active_model_serializer)
|
|
73
|
+
return aObject.class.send(:active_model_serializer) if aObject.class.respond_to?(:active_model_serializer)
|
|
74
|
+
if sz_class = ActiveModel::Serializer.serializer_for(aObject)
|
|
75
|
+
sz_class
|
|
76
|
+
else
|
|
77
|
+
aObject.respond_to?(:attributes) ? ::KojacBaseSerializer : ActiveModel::DefaultSerializer
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
def to_jsono(aObject,aOptions)
|
|
82
|
+
if aObject.is_a?(Hash) or aObject.respond_to? :attributes
|
|
83
|
+
serializer_for(aObject).new(aObject,aOptions).serializable_object
|
|
84
|
+
elsif aObject.respond_to?(:to_ary) && aObject.first # Array
|
|
85
|
+
item_sz = serializer_for(aObject.first)
|
|
86
|
+
ActiveModel::ArraySerializer.new(aObject,aOptions.merge(each_serializer: item_sz)).as_json(aOptions)
|
|
87
|
+
else
|
|
88
|
+
aObject.as_json(aOptions)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
def to_json(aObject,aOptions)
|
|
93
|
+
jsono = to_jsono(aObject,aOptions)
|
|
94
|
+
result = jsono.to_json
|
|
95
|
+
result
|
|
96
|
+
end
|
|
64
97
|
end
|
|
65
98
|
|
|
66
99
|
module Kojac
|
|
@@ -68,37 +101,99 @@ module Kojac
|
|
|
68
101
|
|
|
69
102
|
def self.included(aClass)
|
|
70
103
|
aClass.send :extend, ClassMethods
|
|
104
|
+
aClass.class_eval do
|
|
105
|
+
scope :by_key, ->(aKey,aOperation=nil) {
|
|
106
|
+
key = if respond_to?(:crack_key)
|
|
107
|
+
crack_key(aKey)
|
|
108
|
+
elsif aClass.respond_to?(:crack_key)
|
|
109
|
+
aClass.crack_key(aKey)
|
|
110
|
+
end
|
|
111
|
+
r = key[:resource]
|
|
112
|
+
id = key[:id]
|
|
113
|
+
a = key[:association]
|
|
114
|
+
if id
|
|
115
|
+
where(id: id)
|
|
116
|
+
else
|
|
117
|
+
where('1 = 1')
|
|
118
|
+
end
|
|
119
|
+
}
|
|
120
|
+
end
|
|
71
121
|
end
|
|
72
122
|
|
|
73
123
|
module ClassMethods
|
|
74
|
-
|
|
124
|
+
|
|
125
|
+
# used by pundit
|
|
126
|
+
def policy_class
|
|
127
|
+
"#{self}Policy".safe_constantize || KojacBasePolicy
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def create_policy(aCurrentUser,aOp=nil)
|
|
131
|
+
policy_class.new(aCurrentUser,self,aOp)
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
def active_model_serializer
|
|
135
|
+
"#{self}Serializer".safe_constantize || KojacBaseSerializer
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
def crack_key(aKey)
|
|
139
|
+
r,id,a = aKey.split_kojac_key
|
|
140
|
+
result = {}
|
|
141
|
+
result[:original] = aKey
|
|
142
|
+
result[:resource] = r if r
|
|
143
|
+
result[:id] = id if id
|
|
144
|
+
result[:association] = a if a
|
|
145
|
+
result
|
|
146
|
+
end
|
|
147
|
+
|
|
148
|
+
def load_by_key(aKey,aOperation=nil)
|
|
75
149
|
r,id,a = aKey.split_kojac_key
|
|
76
|
-
|
|
77
|
-
model = self.rescope(model,aContext) if self.respond_to? :rescope
|
|
150
|
+
rel = by_key(aKey)
|
|
78
151
|
if id
|
|
79
|
-
|
|
152
|
+
result = rel.first
|
|
153
|
+
result.prepare(aKey,aOperation) if result.respond_to? :prepare
|
|
80
154
|
else
|
|
81
|
-
|
|
155
|
+
result = rel.all
|
|
156
|
+
result.each do |item|
|
|
157
|
+
item.prepare(aKey,aOperation) if item.respond_to? :prepare
|
|
158
|
+
end
|
|
82
159
|
end
|
|
160
|
+
result
|
|
83
161
|
end
|
|
84
162
|
end
|
|
85
163
|
|
|
164
|
+
def unauthorized!(aMessage=nil)
|
|
165
|
+
raise ::Pundit::NotAuthorizedError, aMessage||"You are not authorized to perform this action"
|
|
166
|
+
end
|
|
167
|
+
|
|
86
168
|
def kojac_key
|
|
87
169
|
self.class.to_s.snake_case.pluralize+'__'+self.id.to_s
|
|
88
170
|
end
|
|
89
171
|
|
|
90
|
-
def update_permitted_attributes!(aChanges,
|
|
172
|
+
def update_permitted_attributes!(aChanges, aPolicy)
|
|
91
173
|
aChanges = KojacUtils.upgrade_hashes_to_params(aChanges)
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
174
|
+
p_fields = aPolicy.permitted_fields(:write)
|
|
175
|
+
unauthorized! if p_fields.empty?
|
|
176
|
+
p_fields = aChanges.permit(*p_fields)
|
|
177
|
+
if ::Rails::VERSION::MAJOR <= 3
|
|
178
|
+
assign_attributes(p_fields, :without_protection => true)
|
|
179
|
+
else
|
|
180
|
+
assign_attributes(p_fields)
|
|
181
|
+
end
|
|
95
182
|
save!
|
|
96
183
|
end
|
|
97
184
|
|
|
185
|
+
def as_json(options = nil)
|
|
186
|
+
super
|
|
187
|
+
end
|
|
188
|
+
|
|
98
189
|
end
|
|
99
190
|
end
|
|
100
191
|
|
|
101
192
|
module Kojac
|
|
193
|
+
|
|
194
|
+
class NotFoundError < StandardError
|
|
195
|
+
end
|
|
196
|
+
|
|
102
197
|
module ControllerOpMethods
|
|
103
198
|
|
|
104
199
|
def self.included(aClass)
|
|
@@ -128,27 +223,38 @@ module Kojac
|
|
|
128
223
|
self.class.to_s.chomp('Controller').snake_case
|
|
129
224
|
end
|
|
130
225
|
|
|
226
|
+
def kojac_current_user
|
|
227
|
+
self.current_user
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
def current_ring
|
|
231
|
+
kojac_current_user.try(:ring).to_i
|
|
232
|
+
end
|
|
233
|
+
|
|
131
234
|
def create_on_association(aItem,aAssoc,aValues,aRing)
|
|
132
|
-
raise "User does not have permission for create on #{aAssoc}" unless aItem.class.
|
|
235
|
+
raise "User does not have permission for create on #{aAssoc}" unless aItem.class.ring_can?(aRing,:create_on,aAssoc.to_sym)
|
|
133
236
|
|
|
134
237
|
return nil unless ma = aItem.class.reflect_on_association(aAssoc.to_sym)
|
|
135
238
|
a_model_class = ma.klass
|
|
239
|
+
policy = Kojac.policy!(kojac_current_user,a_model_class)
|
|
136
240
|
|
|
137
241
|
aValues = KojacUtils.upgrade_hashes_to_params(aValues || {})
|
|
138
242
|
|
|
139
243
|
case ma.macro
|
|
140
244
|
when :belongs_to
|
|
141
245
|
return nil if !aValues.is_a?(Hash)
|
|
142
|
-
fields = aValues.permit( *
|
|
246
|
+
fields = aValues.permit( *policy.permitted_fields(:write) )
|
|
247
|
+
a_model_class.write_op_filter(current_user,fields,aValues) if a_model_class.respond_to? :write_op_filter
|
|
143
248
|
return aItem.send("build_#{aAssoc}".to_sym,fields)
|
|
144
249
|
when :has_many
|
|
145
250
|
aValues = [aValues] if aValues.is_a?(Hash)
|
|
146
251
|
return nil unless aValues.is_a? Array
|
|
147
252
|
aValues.each do |v|
|
|
148
|
-
fields = v.permit( *
|
|
253
|
+
fields = v.permit( *policy.permitted_fields(:write) )
|
|
149
254
|
new_sub_item = nil
|
|
150
255
|
case ma.macro
|
|
151
256
|
when :has_many
|
|
257
|
+
a_model_class.write_op_filter(current_user,fields,aValues) if a_model_class.respond_to? :write_op_filter
|
|
152
258
|
new_sub_item = aItem.send(aAssoc.to_sym).create(fields)
|
|
153
259
|
else
|
|
154
260
|
raise "#{ma.macro} association unsupported in CREATE"
|
|
@@ -173,24 +279,26 @@ module Kojac
|
|
|
173
279
|
end
|
|
174
280
|
|
|
175
281
|
def create_op
|
|
176
|
-
ring =
|
|
282
|
+
ring = current_ring
|
|
177
283
|
op = params[:op]
|
|
178
284
|
options = op[:options] || {}
|
|
179
285
|
model_class = deduce_model_class
|
|
180
286
|
resource,id,assoc = op['key'].split_kojac_key
|
|
181
287
|
if assoc # create operation on an association eg. {verb: "CREATE", key: "order.items"}
|
|
182
|
-
raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}.#{assoc}" unless model_class.
|
|
288
|
+
raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}.#{assoc}" unless model_class.ring_can?(ring,:create_on,assoc.to_sym)
|
|
183
289
|
item = KojacUtils.model_for_key(key_join(resource,id))
|
|
184
290
|
ma = model_class.reflect_on_association(assoc.to_sym)
|
|
185
291
|
a_value = op[:value] # get data for this association, assume {}
|
|
186
292
|
raise "create multiple not yet implemented for associations" unless a_value.is_a?(Hash)
|
|
187
293
|
|
|
188
294
|
a_model_class = ma.klass
|
|
189
|
-
|
|
295
|
+
policy = Kojac.policy!(kojac_current_user,a_model_class)
|
|
296
|
+
p_fields = policy.permitted_fields(:write)
|
|
190
297
|
fields = a_value.permit( *p_fields )
|
|
191
298
|
new_sub_item = nil
|
|
192
299
|
case ma.macro
|
|
193
300
|
when :has_many
|
|
301
|
+
a_model_class.write_op_filter(current_user,fields,a_value) if a_model_class.respond_to? :write_op_filter
|
|
194
302
|
new_sub_item = item.send(assoc.to_sym).create(fields)
|
|
195
303
|
else
|
|
196
304
|
raise "#{ma.macro} association unsupported in CREATE"
|
|
@@ -198,15 +306,17 @@ module Kojac
|
|
|
198
306
|
result_key = op[:result_key] || new_sub_item.kojac_key
|
|
199
307
|
merge_model_into_results(new_sub_item)
|
|
200
308
|
else # create operation on a resource eg. {verb: "CREATE", key: "order_items"} but may have embedded association values
|
|
201
|
-
|
|
309
|
+
policy = Kojac.policy!(kojac_current_user,model_class)
|
|
310
|
+
p_fields = policy.permitted_fields(:write)
|
|
202
311
|
raise "User does not have permission for #{op[:verb]} operation on #{model_class.to_s}" unless model_class.ring_can?(:create,ring)
|
|
203
312
|
|
|
204
313
|
p_fields = op[:value].permit( *p_fields )
|
|
314
|
+
model_class.write_op_filter(current_user,p_fields,op[:value]) if model_class.respond_to? :write_op_filter
|
|
205
315
|
item = model_class.create!(p_fields)
|
|
206
316
|
|
|
207
317
|
options_include = options['include'] || []
|
|
208
318
|
included_assocs = []
|
|
209
|
-
p_assocs =
|
|
319
|
+
p_assocs = policy.permitted_associations(:write)
|
|
210
320
|
if p_assocs
|
|
211
321
|
p_assocs.each do |a|
|
|
212
322
|
next unless (a_value = op[:value][a]) || options_include.include?(a.to_s)
|
|
@@ -229,15 +339,16 @@ module Kojac
|
|
|
229
339
|
protected
|
|
230
340
|
|
|
231
341
|
def merge_model_into_results(aItem,aResultKey=nil,aOptions=nil)
|
|
232
|
-
ring =
|
|
233
|
-
aResultKey ||= aItem.kojac_key
|
|
342
|
+
ring = current_ring
|
|
343
|
+
aResultKey ||= aItem.g? :kojac_key
|
|
344
|
+
results[aResultKey] = (aItem && KojacUtils.to_jsono(aItem,scope: kojac_current_user))
|
|
345
|
+
return unless policy = Kojac.policy!(kojac_current_user,aItem)
|
|
234
346
|
aOptions ||= {}
|
|
235
|
-
results[aResultKey] = aItem.sanitized_hash(ring)
|
|
236
347
|
if included_assocs = aOptions[:include]
|
|
237
348
|
included_assocs = included_assocs.split(',') if included_assocs.is_a?(String)
|
|
238
349
|
included_assocs = [included_assocs] unless included_assocs.is_a?(Array)
|
|
239
350
|
included_assocs.map!(&:to_sym) if included_assocs.is_a?(Array)
|
|
240
|
-
p_assocs =
|
|
351
|
+
p_assocs = policy.permitted_associations(:read) # ***
|
|
241
352
|
use_assocs = p_assocs.delete_if do |a|
|
|
242
353
|
if included_assocs.include?(a) and ma = aItem.class.reflect_on_association(a)
|
|
243
354
|
![:belongs_to,:has_many].include?(ma.macro) # is supported association type
|
|
@@ -250,12 +361,12 @@ module Kojac
|
|
|
250
361
|
if a_contents.is_a? Array
|
|
251
362
|
contents_h = []
|
|
252
363
|
a_contents.each do |sub_item|
|
|
253
|
-
results[sub_item.kojac_key] =
|
|
364
|
+
results[sub_item.kojac_key] = KojacUtils.to_jsono(sub_item,scope: kojac_current_user)
|
|
254
365
|
#contents_h << sub_item.id
|
|
255
366
|
end
|
|
256
367
|
#results[aResultKey] = contents_h
|
|
257
368
|
else
|
|
258
|
-
results[a_contents.kojac_key] =
|
|
369
|
+
results[a_contents.kojac_key] = KojacUtils.to_jsono(a_contents,scope: kojac_current_user)
|
|
259
370
|
end
|
|
260
371
|
end
|
|
261
372
|
end
|
|
@@ -269,10 +380,12 @@ module Kojac
|
|
|
269
380
|
result_key = nil
|
|
270
381
|
resource,id = key.split '__'
|
|
271
382
|
model = deduce_model_class
|
|
272
|
-
|
|
383
|
+
scope = Kojac.policy_scope(current_user, model, op) || model
|
|
273
384
|
if id # item
|
|
274
|
-
if
|
|
275
|
-
item =
|
|
385
|
+
if scope
|
|
386
|
+
item = scope.load_by_key(key,op)
|
|
387
|
+
#item = item.first
|
|
388
|
+
#item.prepare(key,op) if item.respond_to? :prepare
|
|
276
389
|
result_key = op[:result_key] || (item && item.kojac_key) || op[:key]
|
|
277
390
|
merge_model_into_results(item,result_key,op[:options])
|
|
278
391
|
else
|
|
@@ -282,12 +395,23 @@ module Kojac
|
|
|
282
395
|
else # collection
|
|
283
396
|
result_key = op[:result_key] || op[:key]
|
|
284
397
|
results[result_key] = []
|
|
285
|
-
if
|
|
286
|
-
items =
|
|
287
|
-
items
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
398
|
+
if scope
|
|
399
|
+
items = scope.load_by_key(key,op)
|
|
400
|
+
#items = scope.by_key(key,op)
|
|
401
|
+
#items = items.all
|
|
402
|
+
items.each do |item|
|
|
403
|
+
item.prepare(key,op) if item.respond_to? :prepare
|
|
404
|
+
end
|
|
405
|
+
if op[:options] and op[:options][:atomise]==false
|
|
406
|
+
items_json = []
|
|
407
|
+
items_json = items.map {|i| KojacUtils.to_jsono(i,scope: kojac_current_user) }
|
|
408
|
+
results[result_key] = items_json
|
|
409
|
+
else
|
|
410
|
+
items.each do |m|
|
|
411
|
+
item_key = m.kojac_key
|
|
412
|
+
results[result_key] << item_key.split_kojac_key[1]
|
|
413
|
+
merge_model_into_results(m,item_key,op[:options])
|
|
414
|
+
end
|
|
291
415
|
end
|
|
292
416
|
end
|
|
293
417
|
end
|
|
@@ -301,39 +425,40 @@ module Kojac
|
|
|
301
425
|
|
|
302
426
|
def update_op
|
|
303
427
|
result = nil
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
ring = current_user.try(:ring)
|
|
428
|
+
ring = current_ring
|
|
307
429
|
op = params[:op]
|
|
308
430
|
result_key = nil
|
|
309
|
-
|
|
431
|
+
model = deduce_model_class
|
|
432
|
+
scope = Kojac.policy_scope(current_user, model, op) || model
|
|
433
|
+
|
|
434
|
+
if self.item = scope.load_by_key(op[:key],op)
|
|
310
435
|
|
|
311
436
|
run_callbacks :update_op do
|
|
312
|
-
|
|
437
|
+
policy = Kojac.policy!(kojac_current_user,item,op)
|
|
438
|
+
item.update_permitted_attributes!(op[:value], policy)
|
|
313
439
|
|
|
314
|
-
associations =
|
|
440
|
+
associations = policy.permitted_associations(:write)
|
|
315
441
|
associations.each do |k|
|
|
316
442
|
next unless assoc = model.reflect_on_association(k)
|
|
317
443
|
next unless op[:value][k]
|
|
318
444
|
case assoc.macro
|
|
319
445
|
when :belongs_to
|
|
320
446
|
if leaf = (item.send(k) || item.send("build_#{k}".to_sym))
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
#leaf.assign_attributes(permitted_fields, :without_protection => true)
|
|
324
|
-
#leaf.save!
|
|
325
|
-
leaf.update_permitted_attributes!(op[:value][k], ring)
|
|
447
|
+
policy = Kojac.policy!(kojac_current_user,leaf)
|
|
448
|
+
leaf.update_permitted_attributes!(op[:value][k], policy)
|
|
326
449
|
end
|
|
327
450
|
end
|
|
328
451
|
end
|
|
329
452
|
|
|
330
453
|
result_key = item.kojac_key
|
|
331
|
-
results[result_key] = item
|
|
454
|
+
#results[result_key] = item
|
|
455
|
+
merge_model_into_results(item,result_key,op[:options])
|
|
332
456
|
|
|
333
457
|
associations.each do |a|
|
|
334
458
|
next unless assoc_item = item.send(a)
|
|
335
459
|
next unless key = assoc_item.respond_to?(:kojac_key) && assoc_item.kojac_key
|
|
336
|
-
results[key] = assoc_item
|
|
460
|
+
#results[key] = assoc_item
|
|
461
|
+
merge_model_into_results(assoc_item,key)
|
|
337
462
|
end
|
|
338
463
|
end
|
|
339
464
|
end
|
|
@@ -346,7 +471,7 @@ module Kojac
|
|
|
346
471
|
end
|
|
347
472
|
|
|
348
473
|
def destroy_op
|
|
349
|
-
ring =
|
|
474
|
+
ring = current_ring
|
|
350
475
|
op = params[:op]
|
|
351
476
|
result_key = op[:result_key] || op[:key]
|
|
352
477
|
item = KojacUtils.model_for_key(op[:key])
|
|
@@ -365,7 +490,7 @@ module Kojac
|
|
|
365
490
|
#end
|
|
366
491
|
|
|
367
492
|
def add_op
|
|
368
|
-
ring =
|
|
493
|
+
ring = current_ring
|
|
369
494
|
op = params[:op]
|
|
370
495
|
model = deduce_model_class
|
|
371
496
|
raise "ADD only supports associated collections at present eg order.items" unless op[:key].index('.')
|
|
@@ -398,7 +523,7 @@ module Kojac
|
|
|
398
523
|
end
|
|
399
524
|
|
|
400
525
|
def remove_op
|
|
401
|
-
ring =
|
|
526
|
+
ring = current_ring
|
|
402
527
|
op = params[:op]
|
|
403
528
|
model = deduce_model_class
|
|
404
529
|
raise "REMOVE only supports associated collections at present eg order.items" unless op[:key].key_assoc
|
|
@@ -430,5 +555,31 @@ module Kojac
|
|
|
430
555
|
results: results
|
|
431
556
|
}
|
|
432
557
|
end
|
|
558
|
+
|
|
559
|
+
def execute_op
|
|
560
|
+
op = params[:op]
|
|
561
|
+
resource,action = op[:key].split_kojac_key
|
|
562
|
+
raise "action not given" unless action.is_a? String
|
|
563
|
+
action = "execute_#{action}"
|
|
564
|
+
raise "action #{action} not implemented on #{resource}" unless respond_to? action.to_sym
|
|
565
|
+
result = send(action.to_sym,op)
|
|
566
|
+
if op[:error]
|
|
567
|
+
{
|
|
568
|
+
key: op[:key],
|
|
569
|
+
verb: op[:verb],
|
|
570
|
+
error: op[:error]
|
|
571
|
+
}
|
|
572
|
+
else
|
|
573
|
+
result_key = op[:result_key] || op[:key]
|
|
574
|
+
results = op[:results] || {} # look at op[:results][result_key]. If empty, fill with returned value from action
|
|
575
|
+
results[result_key] = KojacUtils.to_jsono(result,scope: kojac_current_user) unless results.has_key? result_key
|
|
576
|
+
{
|
|
577
|
+
key: op[:key],
|
|
578
|
+
verb: op[:verb],
|
|
579
|
+
result_key: result_key,
|
|
580
|
+
results: results
|
|
581
|
+
}
|
|
582
|
+
end
|
|
583
|
+
end
|
|
433
584
|
end
|
|
434
585
|
end
|
data/lib/kojac/version.rb
CHANGED
data/spec/can_cache_spec.js
CHANGED
|
@@ -40,8 +40,8 @@ describe("Kojac.CanCache Specs", function() {
|
|
|
40
40
|
});
|
|
41
41
|
|
|
42
42
|
it("Expose bug in can.Observe when setting attribute with another can.Observe", function() {
|
|
43
|
-
var cache = new
|
|
44
|
-
var cs1 = new
|
|
43
|
+
var cache = new Kojac.CanCache({});
|
|
44
|
+
var cs1 = new Kojac.CanCache({});
|
|
45
45
|
var cont1 = {cur_super_43: cs1};
|
|
46
46
|
|
|
47
47
|
var cs2 = new can.Observe({});
|
|
@@ -66,22 +66,22 @@ describe("Kojac.CanCache Specs", function() {
|
|
|
66
66
|
expect(Kojac.Utils.interpretKeys(['a','b','c'])).toEqual(['a','b','c']);
|
|
67
67
|
});
|
|
68
68
|
|
|
69
|
-
it("kojac.cacheHasKeys", function() {
|
|
70
|
-
expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(false);
|
|
71
|
-
this.cache.a = 1;
|
|
72
|
-
expect(this.kojac.cacheHasKeys(['a'])).toBe(true);
|
|
73
|
-
expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(false);
|
|
74
|
-
this.cache.b = null;
|
|
75
|
-
this.cache.c = 'hello';
|
|
76
|
-
expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(true);
|
|
77
|
-
});
|
|
78
|
-
|
|
79
|
-
it("kojac.cacheValues", function() {
|
|
80
|
-
expect(this.kojac.cacheValues(['a','b','c'])).toEqual([undefined,undefined,undefined]);
|
|
81
|
-
this.cache.a = 1;
|
|
82
|
-
this.cache.b = null;
|
|
83
|
-
this.cache.c = 'hello';
|
|
84
|
-
expect(this.kojac.cacheValues(['a','b','c'])).toEqual([1,null,'hello']);
|
|
85
|
-
});
|
|
69
|
+
// it("kojac.cacheHasKeys", function() {
|
|
70
|
+
// expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(false);
|
|
71
|
+
// this.cache.a = 1;
|
|
72
|
+
// expect(this.kojac.cacheHasKeys(['a'])).toBe(true);
|
|
73
|
+
// expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(false);
|
|
74
|
+
// this.cache.b = null;
|
|
75
|
+
// this.cache.c = 'hello';
|
|
76
|
+
// expect(this.kojac.cacheHasKeys(['a','b','c'])).toBe(true);
|
|
77
|
+
// });
|
|
78
|
+
//
|
|
79
|
+
// it("kojac.cacheValues", function() {
|
|
80
|
+
// expect(this.kojac.cacheValues(['a','b','c'])).toEqual([undefined,undefined,undefined]);
|
|
81
|
+
// this.cache.a = 1;
|
|
82
|
+
// this.cache.b = null;
|
|
83
|
+
// this.cache.c = 'hello';
|
|
84
|
+
// expect(this.kojac.cacheValues(['a','b','c'])).toEqual([1,null,'hello']);
|
|
85
|
+
// });
|
|
86
86
|
|
|
87
87
|
});
|