rest-sinatra 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.3.3
1
+ 0.4.0
data/lib/rest-sinatra.rb CHANGED
@@ -20,6 +20,7 @@ module RestSinatra
20
20
 
21
21
  def _resource(name, resource_type, &block)
22
22
  config = evaluate_block(name, resource_type, &block)
23
+ config[:resource] = self
23
24
  validate(config)
24
25
  build_resource(config)
25
26
  config
@@ -30,13 +31,15 @@ module RestSinatra
30
31
  scope.extend(ResourceMethods)
31
32
  scope.instance_eval do
32
33
  @c = {
33
- :name => name,
34
- :resource_type => resource_type,
35
- :model => nil,
36
- :read_only => [],
37
- :permission => nil,
38
- :callbacks => {},
39
- :nested_resources => []
34
+ :name => name,
35
+ :resource_type => resource_type,
36
+ :model => nil,
37
+ :read_only => [],
38
+ :resource => nil,
39
+ :permission_to_view => nil,
40
+ :permission_to_modify => nil,
41
+ :callbacks => {},
42
+ :nested_resources => []
40
43
  }
41
44
  end
42
45
  scope.instance_eval(&block)
@@ -66,36 +69,51 @@ module RestSinatra
66
69
  end
67
70
 
68
71
  def build_parent_resource(config)
69
- callbacks = config[:callbacks]
70
- model = config[:model]
71
- name = config[:name]
72
- read_only = config[:read_only]
72
+ callbacks = config[:callbacks]
73
+ model = config[:model]
74
+ name = config[:name]
75
+ permission_to_view = config[:permission_to_view]
76
+ permission_to_modify = config[:permission_to_modify]
77
+ read_only = config[:read_only]
78
+ resource = config[:resource]
73
79
 
74
80
  get '/?' do
75
- require_at_least(:basic)
81
+ permission_check(
82
+ :default => :basic,
83
+ :override => permission_to_view
84
+ )
76
85
  validate_before_find_all(params, model)
77
- @documents = find_with_filters(params, model)
78
- @documents.render
86
+ documents = find_with_filters(params, model)
87
+ permitted = documents.select { |document| resource.permit_view?(@current_user, document) }
88
+ sanitized = permitted.map { |document| resource.sanitize(@current_user, document) }
89
+ sanitized.render
79
90
  end
80
91
 
81
92
  get '/:id/?' do |id|
82
- require_at_least(:basic)
93
+ permission_check(
94
+ :default => :basic,
95
+ :override => permission_to_view
96
+ )
83
97
  id = params.delete("id")
84
98
  validate_before_find_one(params, model)
85
- @document = find_document!(model, id)
86
- @document.render
99
+ document = find_document!(model, id)
100
+ unauthorized_api_key! unless resource.permit_view?(@current_user, document)
101
+ sanitized = resource.sanitize(@current_user, document)
102
+ sanitized.render
87
103
  end
88
104
 
89
105
  post '/?' do
90
- require_at_least(:curator)
106
+ permission_check(
107
+ :default => :admin,
108
+ :override => permission_to_modify
109
+ )
110
+ unauthorized_api_key! unless resource.permit_modify?(@current_user, nil)
91
111
  validate_before_create(params, model, read_only)
92
112
  callback(callbacks[:before_save])
93
113
  callback(callbacks[:before_create])
94
114
  @document = model.new(params)
95
- unless @document.valid?
96
- error 400, { "errors" => @document.errors.errors }.to_json
97
- end
98
- error 500, [].to_json unless @document.save
115
+ invalid_document! unless @document.valid?
116
+ internal_server_error! unless @document.save
99
117
  callback(callbacks[:after_create])
100
118
  callback(callbacks[:after_save])
101
119
  response.status = 201
@@ -104,25 +122,31 @@ module RestSinatra
104
122
  end
105
123
 
106
124
  put '/:id/?' do
107
- require_at_least(:curator)
125
+ permission_check(
126
+ :default => :admin,
127
+ :override => permission_to_modify
128
+ )
108
129
  id = params.delete("id")
109
130
  @document = find_document!(model, id)
131
+ unauthorized_api_key! unless resource.permit_modify?(@current_user, @document)
110
132
  validate_before_update(params, model, read_only)
111
133
  callback(callbacks[:before_save])
112
134
  callback(callbacks[:before_update])
113
135
  @document = model.update(id, params)
114
- unless @document.valid?
115
- error 400, { "errors" => @document.errors.errors }.to_json
116
- end
136
+ invalid_document! unless @document.valid?
117
137
  callback(callbacks[:after_update])
118
138
  callback(callbacks[:after_save])
119
139
  @document.render
120
140
  end
121
141
 
122
142
  delete '/:id/?' do
123
- require_at_least(:curator)
143
+ permission_check(
144
+ :default => :admin,
145
+ :override => permission_to_modify
146
+ )
124
147
  id = params.delete("id")
125
148
  @document = find_document!(model, id)
149
+ unauthorized_api_key! unless resource.permit_modify?(@current_user, @document)
126
150
  callback(callbacks[:before_destroy])
127
151
  @document.destroy
128
152
  callback(callbacks[:after_destroy])
@@ -132,7 +156,7 @@ module RestSinatra
132
156
  helpers do
133
157
  def find_document!(model, id)
134
158
  document = model.find_by_id(id)
135
- error 404, [].to_json unless document
159
+ not_found! unless document
136
160
  document
137
161
  end
138
162
  end
@@ -151,44 +175,67 @@ module RestSinatra
151
175
  # klass : nested resource class
152
176
  # association : a method on the parent model that will return child models
153
177
  def build_nested_resource(klass, association, parent_config, child_config)
154
- callbacks = child_config[:callbacks]
155
- child_model = child_config[:model]
156
- child_name = child_config[:name]
157
- permission = child_config[:permission]
158
- read_only = child_config[:read_only]
178
+ callbacks = child_config[:callbacks]
179
+ child_model = child_config[:model]
180
+ child_name = child_config[:name]
181
+ child_resource = child_config[:resource]
182
+ permission_to_view = child_config[:permission_to_view]
183
+ permission_to_modify = child_config[:permission_to_modify]
184
+ read_only = child_config[:read_only]
159
185
 
160
186
  parent_model = parent_config[:model]
161
187
  parent_name = parent_config[:name]
188
+ parent_resource = parent_config[:resource]
162
189
 
163
190
  get "/:parent_id/#{child_name}/?" do
191
+ permission_check(
192
+ :default => :basic,
193
+ :override => permission_to_view
194
+ )
164
195
  parent_id = params.delete("parent_id")
165
- permission_check(:basic, permission, parent_id)
166
- @parent_document = find_parent!(parent_model, parent_id)
167
- all_child_documents = @parent_document.send(association)
196
+ parent_document = find_parent!(parent_model, parent_id)
197
+ unauthorized_api_key! unless parent_resource.permit_view?(@current_user, parent_document)
198
+ all_child_documents = parent_document.send(association)
168
199
  validate_before_find_all(params, child_model) # ?
169
- @child_documents = nested_find_with_filters(all_child_documents, params, parent_model)
170
- @child_documents.render
200
+ child_documents = nested_find_with_filters(all_child_documents, params, parent_model)
201
+ permitted = child_documents.select do |child_document|
202
+ child_resource.permit_view?(@current_user, child_document)
203
+ end
204
+ sanitized = permitted.map { |document| child_resource.sanitize(@current_user, document) }
205
+ sanitized.render
171
206
  end
172
207
 
173
208
  get "/:parent_id/#{child_name}/:child_id/?" do
209
+ permission_check(
210
+ :default => :basic,
211
+ :override => permission_to_view
212
+ )
174
213
  parent_id = params.delete("parent_id")
175
- permission_check(:basic, permission, parent_id)
176
214
  child_id = params.delete("child_id")
177
215
  validate_before_find_one(params, child_model) # ?
178
- @parent_document, @child_document = find_documents!(parent_model, parent_id, association, child_id)
179
- @child_document.render
216
+ parent_document = find_parent!(parent_model, parent_id)
217
+ unauthorized_api_key! unless parent_resource.permit_view?(@current_user, parent_document)
218
+ child_document = find_child!(parent_document, association, child_id)
219
+ unauthorized_api_key! unless child_resource.permit_view?(@current_user, child_document)
220
+ sanitized = child_resource.sanitize(@current_user, child_document)
221
+ sanitized.render
180
222
  end
181
223
 
182
224
  post "/:parent_id/#{child_name}/?" do
225
+ permission_check(
226
+ :default => :admin,
227
+ :override => permission_to_modify
228
+ )
183
229
  parent_id = params.delete("parent_id")
184
- permission_check(:curator, permission, parent_id)
185
230
  @parent_document = find_parent!(parent_model, parent_id)
231
+ unauthorized_api_key! unless parent_resource.permit_modify?(@current_user, @parent_document)
232
+ unauthorized_api_key! unless child_resource.permit_modify?(@current_user, nil)
186
233
  validate_before_create(params, child_model, read_only)
187
234
  callback(callbacks[:before_save])
188
235
  callback(callbacks[:before_create])
189
236
  @child_document = child_model.new(params)
190
237
  @parent_document.send(association) << @child_document
191
- error 500, [].to_json unless @parent_document.save
238
+ internal_server_error! unless @parent_document.save
192
239
  callback(callbacks[:after_create])
193
240
  callback(callbacks[:after_save])
194
241
  response.status = 201
@@ -199,52 +246,58 @@ module RestSinatra
199
246
  end
200
247
 
201
248
  put "/:parent_id/#{child_name}/:child_id/?" do
249
+ permission_check(
250
+ :default => :admin,
251
+ :override => permission_to_modify
252
+ )
202
253
  parent_id = params.delete("parent_id")
203
- permission_check(:curator, permission, parent_id)
204
254
  child_id = params.delete("child_id")
205
- @parent_document, @child_document = find_documents!(parent_model, parent_id, association, child_id)
255
+ @parent_document = find_parent!(parent_model, parent_id)
256
+ unauthorized_api_key! unless parent_resource.permit_modify?(@current_user, @parent_document)
257
+ @child_document = find_child!(@parent_document, association, child_id)
258
+ unauthorized_api_key! unless child_resource.permit_modify?(@current_user, @child_document)
206
259
  validate_before_update(params, child_model, read_only)
207
260
  callback(callbacks[:before_save])
208
261
  callback(callbacks[:before_update])
209
262
  @child_document.attributes = params
210
263
  child_index = @parent_document.send(association).index(@child_document)
211
264
  @parent_document.send(association)[child_index] = @child_document
212
- error 500, [].to_json unless @parent_document.save
265
+ internal_server_error! unless @parent_document.save
213
266
  callback(callbacks[:after_update])
214
267
  callback(callbacks[:after_save])
215
268
  @child_document.render
216
269
  end
217
270
 
218
271
  delete "/:parent_id/#{child_name}/:child_id/?" do
272
+ permission_check(
273
+ :default => :admin,
274
+ :override => permission_to_modify
275
+ )
219
276
  parent_id = params.delete("parent_id")
220
- permission_check(:curator, permission, parent_id)
221
277
  child_id = params.delete("child_id")
222
- @parent_document, @child_document = find_documents!(parent_model, parent_id, association, child_id)
278
+ @parent_document = find_parent!(parent_model, parent_id)
279
+ unauthorized_api_key! unless parent_resource.permit_modify?(@current_user, @parent_document)
280
+ @child_document = find_child!(@parent_document, association, child_id)
281
+ unauthorized_api_key! unless child_resource.permit_modify?(@current_user, @child_document)
223
282
  callback(callbacks[:before_destroy])
224
283
  @parent_document.send(association).delete(@child_document)
225
284
  callback(callbacks[:after_destroy])
226
- error 500, [].to_json unless @parent_document.save
285
+ internal_server_error! unless @parent_document.save
227
286
  { "id" => child_id }.to_json
228
287
  end
229
288
 
230
289
  helpers do
231
290
  def find_parent!(parent_model, parent_id)
232
291
  parent_document = parent_model.find_by_id(parent_id)
233
- error 404, [].to_json unless parent_document
292
+ not_found! unless parent_document
234
293
  parent_document
235
294
  end
236
295
 
237
296
  def find_child!(parent_document, association, child_id)
238
297
  child_document = parent_document.send(association).detect { |x| x.id == child_id }
239
- error 404, [].to_json unless child_document
298
+ not_found! unless child_document
240
299
  child_document
241
300
  end
242
-
243
- def find_documents!(parent_model, parent_id, association, child_id)
244
- parent_document = find_parent!(parent_model, parent_id)
245
- child_document = find_child!(parent_document, association, child_id)
246
- [parent_document, child_document]
247
- end
248
301
  end
249
302
  end
250
303
 
@@ -269,9 +322,14 @@ module RestSinatra
269
322
  @c[:read_only] << attribute
270
323
  end
271
324
 
272
- def permission(level)
273
- raise "permission already declared" if @c[:permission]
274
- @c[:permission] = level
325
+ def permission_to_view(level)
326
+ raise "permission already declared" if @c[:permission_to_view]
327
+ @c[:permission_to_view] = level
328
+ end
329
+
330
+ def permission_to_modify(level)
331
+ raise "permission already declared" if @c[:permission_to_modify]
332
+ @c[:permission_to_modify] = level
275
333
  end
276
334
 
277
335
  def callback(name, &block)
data/rest-sinatra.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{rest-sinatra}
8
- s.version = "0.3.3"
8
+ s.version = "0.4.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["David James"]
12
- s.date = %q{2009-10-11}
12
+ s.date = %q{2009-10-14}
13
13
  s.description = %q{Provides a DSL for making RESTful Sinatra actions with MongoMapper models.}
14
14
  s.email = %q{djames@sunlightfoundation.com}
15
15
  s.extra_rdoc_files = [
@@ -8,5 +8,8 @@ class Sources
8
8
 
9
9
  @r = resource "sources" do
10
10
  model Source
11
+
12
+ permission_to_view :basic
13
+ permission_to_modify :owner
11
14
  end
12
15
  end
@@ -17,6 +17,10 @@ describe "Posts" do
17
17
  @config[:model].should == Post
18
18
  end
19
19
 
20
+ it "resource should be Posts" do
21
+ @config[:resource].should == Posts
22
+ end
23
+
20
24
  it "read_only should be correct" do
21
25
  @config[:read_only].should == [:created_at, :updated_at]
22
26
  end
@@ -133,6 +137,10 @@ describe "Comments" do
133
137
  @config[:model].should == Comment
134
138
  end
135
139
 
140
+ it "model should be Comments" do
141
+ @config[:resource].should == Comments
142
+ end
143
+
136
144
  it "read_only should be correct" do
137
145
  @config[:read_only].should == [:created_at]
138
146
  end
@@ -15,6 +15,10 @@ describe "Sources" do
15
15
  it "model should be Source" do
16
16
  @config[:model].should == Source
17
17
  end
18
+
19
+ it "resource should be Sources" do
20
+ @config[:resource].should == Sources
21
+ end
18
22
 
19
23
  it "read_only should be empty" do
20
24
  @config[:read_only].should == []
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rest-sinatra
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.3
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - David James
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-10-11 00:00:00 -04:00
12
+ date: 2009-10-14 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency