rest-sinatra 0.3.3 → 0.4.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.
- 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
|