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 +1 -1
- data/lib/rest-sinatra.rb +118 -60
- data/rest-sinatra.gemspec +2 -2
- data/spec/unit/helpers/sources.rb +3 -0
- data/spec/unit/posts_and_comments_spec.rb +8 -0
- data/spec/unit/sources_spec.rb +4 -0
- metadata +2 -2
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
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
|
34
|
-
:resource_type
|
35
|
-
:model
|
36
|
-
:read_only
|
37
|
-
:
|
38
|
-
:
|
39
|
-
:
|
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
|
70
|
-
model
|
71
|
-
name
|
72
|
-
|
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
|
-
|
81
|
+
permission_check(
|
82
|
+
:default => :basic,
|
83
|
+
:override => permission_to_view
|
84
|
+
)
|
76
85
|
validate_before_find_all(params, model)
|
77
|
-
|
78
|
-
|
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
|
-
|
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
|
-
|
86
|
-
@document
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
155
|
-
child_model
|
156
|
-
child_name
|
157
|
-
|
158
|
-
|
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
|
-
|
166
|
-
|
167
|
-
all_child_documents =
|
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
|
-
|
170
|
-
|
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
|
-
|
179
|
-
@
|
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
|
-
|
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
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
273
|
-
raise "permission already declared" if @c[:
|
274
|
-
@c[:
|
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.
|
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-
|
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 = [
|
@@ -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
|
data/spec/unit/sources_spec.rb
CHANGED
@@ -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.
|
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-
|
12
|
+
date: 2009-10-14 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|