moonrope 1.4.1 → 2.0.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 +4 -4
- data/Gemfile +9 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENCE +20 -0
- data/README.md +24 -0
- data/bin/moonrope +28 -0
- data/docs/authentication.md +114 -0
- data/docs/controllers.md +106 -0
- data/docs/exceptions.md +27 -0
- data/docs/introduction.md +29 -0
- data/docs/structures.md +214 -0
- data/example/authentication.rb +50 -0
- data/example/controllers/meta_controller.rb +14 -0
- data/example/controllers/users_controller.rb +92 -0
- data/example/structures/pet_structure.rb +12 -0
- data/example/structures/user_structure.rb +35 -0
- data/html/assets/lock.svg +3 -0
- data/html/assets/reset.css +101 -0
- data/html/assets/style.css +348 -0
- data/html/assets/tool.svg +4 -0
- data/html/assets/try.js +151 -0
- data/html/authenticators/default.html +191 -0
- data/html/controllers/meta/version.html +144 -0
- data/html/controllers/meta.html +73 -0
- data/html/controllers/users/create.html +341 -0
- data/html/controllers/users/list.html +348 -0
- data/html/controllers/users/show.html +261 -0
- data/html/controllers/users/update.html +387 -0
- data/html/controllers/users.html +93 -0
- data/html/index.html +166 -0
- data/html/moonrope.txt +0 -0
- data/html/structures/pet.html +176 -0
- data/html/structures/user.html +338 -0
- data/lib/moonrope/action.rb +165 -37
- data/lib/moonrope/authenticator.rb +39 -0
- data/lib/moonrope/base.rb +24 -6
- data/lib/moonrope/controller.rb +4 -2
- data/lib/moonrope/doc_context.rb +94 -0
- data/lib/moonrope/doc_server.rb +123 -0
- data/lib/moonrope/dsl/action_dsl.rb +159 -9
- data/lib/moonrope/dsl/authenticator_dsl.rb +31 -0
- data/lib/moonrope/dsl/base_dsl.rb +21 -18
- data/lib/moonrope/dsl/controller_dsl.rb +60 -9
- data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
- data/lib/moonrope/dsl/structure_dsl.rb +27 -2
- data/lib/moonrope/errors.rb +3 -0
- data/lib/moonrope/eval_environment.rb +82 -3
- data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
- data/lib/moonrope/eval_helpers.rb +28 -5
- data/lib/moonrope/guard.rb +35 -0
- data/lib/moonrope/html_generator.rb +65 -0
- data/lib/moonrope/param_set.rb +11 -1
- data/lib/moonrope/rack_middleware.rb +1 -1
- data/lib/moonrope/railtie.rb +31 -14
- data/lib/moonrope/request.rb +25 -14
- data/lib/moonrope/structure.rb +74 -11
- data/lib/moonrope/structure_attribute.rb +15 -0
- data/lib/moonrope/version.rb +1 -1
- data/lib/moonrope.rb +5 -4
- data/moonrope.gemspec +21 -0
- data/spec/spec_helper.rb +32 -0
- data/spec/specs/action_spec.rb +455 -0
- data/spec/specs/base_spec.rb +29 -0
- data/spec/specs/controller_spec.rb +31 -0
- data/spec/specs/param_set_spec.rb +31 -0
- data/templates/basic/_action_form.erb +77 -0
- data/templates/basic/_errors_table.erb +32 -0
- data/templates/basic/_structure_attributes_list.erb +55 -0
- data/templates/basic/action.erb +168 -0
- data/templates/basic/assets/lock.svg +3 -0
- data/templates/basic/assets/reset.css +101 -0
- data/templates/basic/assets/style.css +348 -0
- data/templates/basic/assets/tool.svg +4 -0
- data/templates/basic/assets/try.js +151 -0
- data/templates/basic/authenticator.erb +51 -0
- data/templates/basic/controller.erb +20 -0
- data/templates/basic/index.erb +114 -0
- data/templates/basic/layout.erb +46 -0
- data/templates/basic/structure.erb +23 -0
- data/test/test_helper.rb +81 -0
- data/test/tests/action_access_test.rb +63 -0
- data/test/tests/actions_test.rb +524 -0
- data/test/tests/authenticators_test.rb +87 -0
- data/test/tests/base_test.rb +35 -0
- data/test/tests/controllers_test.rb +49 -0
- data/test/tests/eval_environment_test.rb +136 -0
- data/test/tests/evel_helpers_test.rb +60 -0
- data/test/tests/examples_test.rb +11 -0
- data/test/tests/helpers_test.rb +97 -0
- data/test/tests/param_set_test.rb +44 -0
- data/test/tests/rack_middleware_test.rb +109 -0
- data/test/tests/request_test.rb +232 -0
- data/test/tests/structures_param_extensions_test.rb +159 -0
- data/test/tests/structures_test.rb +335 -0
- metadata +82 -48
@@ -0,0 +1,338 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html>
|
3
|
+
<head>
|
4
|
+
<title>User Structure - API Documentation</title>
|
5
|
+
<link href='https://fonts.googleapis.com/css?family=Lato:400,700,900' rel='stylesheet' type='text/css'>
|
6
|
+
<link href='https://fonts.googleapis.com/css?family=Droid+Sans+Mono' rel='stylesheet' type='text/css'>
|
7
|
+
<link rel="stylesheet" href="../assets/reset.css">
|
8
|
+
<link rel="stylesheet" href="../assets/style.css">
|
9
|
+
</head>
|
10
|
+
<body>
|
11
|
+
<section class='sidebarBackground'></section>
|
12
|
+
<section class="sidebar">
|
13
|
+
<nav>
|
14
|
+
<ul>
|
15
|
+
<li>
|
16
|
+
<a href='../index.html' class="">
|
17
|
+
Home
|
18
|
+
</a>
|
19
|
+
</li>
|
20
|
+
|
21
|
+
<li>
|
22
|
+
<a href='../authenticators/default.html' class="">
|
23
|
+
Authentication
|
24
|
+
</a>
|
25
|
+
</li>
|
26
|
+
|
27
|
+
|
28
|
+
<li>
|
29
|
+
<a href='../controllers/meta.html' class="">
|
30
|
+
Meta API
|
31
|
+
</a>
|
32
|
+
</li>
|
33
|
+
|
34
|
+
<li>
|
35
|
+
<a href='../controllers/users.html' class="">
|
36
|
+
Users API
|
37
|
+
</a>
|
38
|
+
</li>
|
39
|
+
|
40
|
+
</ul>
|
41
|
+
</nav>
|
42
|
+
</section>
|
43
|
+
<section class='content'>
|
44
|
+
|
45
|
+
|
46
|
+
<h1>User Structure</h1>
|
47
|
+
|
48
|
+
<h2>Base Attributes</h2>
|
49
|
+
<table class='table paramTable'>
|
50
|
+
<thead>
|
51
|
+
<tr>
|
52
|
+
<th width="45%">Attribute</th>
|
53
|
+
<th width="20%">Type</th>
|
54
|
+
<th width="35%">Example</th>
|
55
|
+
</tr>
|
56
|
+
</thead>
|
57
|
+
|
58
|
+
<tr>
|
59
|
+
<td>
|
60
|
+
<p>
|
61
|
+
<span class='paramTable__name'>id</span>
|
62
|
+
</p>
|
63
|
+
|
64
|
+
<p class='paramTable__description'>The user's internal system ID</p>
|
65
|
+
|
66
|
+
|
67
|
+
|
68
|
+
|
69
|
+
</td>
|
70
|
+
<td>Integer</td>
|
71
|
+
<td>
|
72
|
+
|
73
|
+
123
|
74
|
+
|
75
|
+
</td>
|
76
|
+
</tr>
|
77
|
+
|
78
|
+
<tr>
|
79
|
+
<td>
|
80
|
+
<p>
|
81
|
+
<span class='paramTable__name'>username</span>
|
82
|
+
</p>
|
83
|
+
|
84
|
+
<p class='paramTable__description'>The user's unique username</p>
|
85
|
+
|
86
|
+
|
87
|
+
|
88
|
+
|
89
|
+
</td>
|
90
|
+
<td>String</td>
|
91
|
+
<td>
|
92
|
+
|
93
|
+
adamcooke
|
94
|
+
|
95
|
+
</td>
|
96
|
+
</tr>
|
97
|
+
|
98
|
+
<tr>
|
99
|
+
<td>
|
100
|
+
<p>
|
101
|
+
<span class='paramTable__name'>name.first</span>
|
102
|
+
</p>
|
103
|
+
|
104
|
+
<p class='paramTable__description'>The user's first name</p>
|
105
|
+
|
106
|
+
|
107
|
+
|
108
|
+
|
109
|
+
</td>
|
110
|
+
<td>String</td>
|
111
|
+
<td>
|
112
|
+
|
113
|
+
Adam
|
114
|
+
|
115
|
+
</td>
|
116
|
+
</tr>
|
117
|
+
|
118
|
+
<tr>
|
119
|
+
<td>
|
120
|
+
<p>
|
121
|
+
<span class='paramTable__name'>name.last</span>
|
122
|
+
</p>
|
123
|
+
|
124
|
+
<p class='paramTable__description'>The user's last name</p>
|
125
|
+
|
126
|
+
|
127
|
+
|
128
|
+
|
129
|
+
</td>
|
130
|
+
<td>String</td>
|
131
|
+
<td>
|
132
|
+
|
133
|
+
Cooke
|
134
|
+
|
135
|
+
</td>
|
136
|
+
</tr>
|
137
|
+
|
138
|
+
|
139
|
+
|
140
|
+
</table>
|
141
|
+
|
142
|
+
|
143
|
+
|
144
|
+
|
145
|
+
<h2>Extended Attributes</h2>
|
146
|
+
<table class='table paramTable'>
|
147
|
+
<thead>
|
148
|
+
<tr>
|
149
|
+
<th width="45%">Attribute</th>
|
150
|
+
<th width="20%">Type</th>
|
151
|
+
<th width="35%">Example</th>
|
152
|
+
</tr>
|
153
|
+
</thead>
|
154
|
+
|
155
|
+
<tr>
|
156
|
+
<td>
|
157
|
+
<p>
|
158
|
+
<span class='paramTable__name'>admin</span>
|
159
|
+
</p>
|
160
|
+
|
161
|
+
<p class='paramTable__description'>Is this user an administrator?</p>
|
162
|
+
|
163
|
+
|
164
|
+
|
165
|
+
|
166
|
+
</td>
|
167
|
+
<td>Boolean</td>
|
168
|
+
<td>
|
169
|
+
|
170
|
+
false
|
171
|
+
|
172
|
+
</td>
|
173
|
+
</tr>
|
174
|
+
|
175
|
+
<tr>
|
176
|
+
<td>
|
177
|
+
<p>
|
178
|
+
<span class='paramTable__name'>created_at</span>
|
179
|
+
</p>
|
180
|
+
|
181
|
+
<p class='paramTable__description'>The timestamp the user was created</p>
|
182
|
+
|
183
|
+
|
184
|
+
|
185
|
+
|
186
|
+
</td>
|
187
|
+
<td>Timestamp</td>
|
188
|
+
<td>
|
189
|
+
|
190
|
+
2016-12-25 09:42:00 +0000
|
191
|
+
|
192
|
+
</td>
|
193
|
+
</tr>
|
194
|
+
|
195
|
+
<tr>
|
196
|
+
<td>
|
197
|
+
<p>
|
198
|
+
<span class='paramTable__name'>updated_at</span>
|
199
|
+
</p>
|
200
|
+
|
201
|
+
<p class='paramTable__description'>The timestamp the user was updated</p>
|
202
|
+
|
203
|
+
|
204
|
+
|
205
|
+
|
206
|
+
</td>
|
207
|
+
<td>Timestamp</td>
|
208
|
+
<td>
|
209
|
+
|
210
|
+
2016-12-25 09:42:00 +0000
|
211
|
+
|
212
|
+
</td>
|
213
|
+
</tr>
|
214
|
+
|
215
|
+
<tr>
|
216
|
+
<td>
|
217
|
+
<p>
|
218
|
+
<span class='paramTable__name'>support_pin</span>
|
219
|
+
</p>
|
220
|
+
|
221
|
+
<p class='paramTable__description'>The PIN this user needs to use to access support</p>
|
222
|
+
|
223
|
+
|
224
|
+
|
225
|
+
|
226
|
+
<ul class='paramTable__restrictedList'>
|
227
|
+
|
228
|
+
<li>Can only be accessed by API users with admin access</li>
|
229
|
+
|
230
|
+
</ul>
|
231
|
+
|
232
|
+
</td>
|
233
|
+
<td>String</td>
|
234
|
+
<td>
|
235
|
+
|
236
|
+
4953
|
237
|
+
|
238
|
+
</td>
|
239
|
+
</tr>
|
240
|
+
|
241
|
+
<tr>
|
242
|
+
<td>
|
243
|
+
<p>
|
244
|
+
<span class='paramTable__name'>mask</span>
|
245
|
+
</p>
|
246
|
+
|
247
|
+
<p class='paramTable__description'>The unique mask that represents this user</p>
|
248
|
+
|
249
|
+
|
250
|
+
|
251
|
+
|
252
|
+
<ul class='paramTable__restrictedList'>
|
253
|
+
|
254
|
+
<li>Must not be authenticated (no auth headers provided).</li>
|
255
|
+
|
256
|
+
</ul>
|
257
|
+
|
258
|
+
</td>
|
259
|
+
<td>String</td>
|
260
|
+
<td>
|
261
|
+
|
262
|
+
abc123abc123
|
263
|
+
|
264
|
+
</td>
|
265
|
+
</tr>
|
266
|
+
|
267
|
+
|
268
|
+
|
269
|
+
</table>
|
270
|
+
|
271
|
+
|
272
|
+
|
273
|
+
|
274
|
+
<h2>Expansions</h2>
|
275
|
+
<p class='text'>
|
276
|
+
Expansions are embedded structures of other objects that are related to the structure
|
277
|
+
that you're viewing. Which expansions are returned by a specific action are shown on that
|
278
|
+
action's documentation however some actions allow you to choose which expansions are
|
279
|
+
returned.
|
280
|
+
</p>
|
281
|
+
<table class='table paramTable'>
|
282
|
+
<thead>
|
283
|
+
<tr>
|
284
|
+
<th width="45%">Attribute</th>
|
285
|
+
<th width="20%">Type</th>
|
286
|
+
<th width="35%">Example</th>
|
287
|
+
</tr>
|
288
|
+
</thead>
|
289
|
+
|
290
|
+
<tr>
|
291
|
+
<td>
|
292
|
+
<p>
|
293
|
+
<span class='paramTable__name'>pets</span>
|
294
|
+
</p>
|
295
|
+
|
296
|
+
<p class='paramTable__description'>All pets that belong to this user</p>
|
297
|
+
|
298
|
+
|
299
|
+
|
300
|
+
|
301
|
+
</td>
|
302
|
+
<td>Array</td>
|
303
|
+
<td>
|
304
|
+
|
305
|
+
<a class='link' href="../structures/pet.html">Pet structure</a>
|
306
|
+
|
307
|
+
</td>
|
308
|
+
</tr>
|
309
|
+
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
<tr>
|
314
|
+
<td>
|
315
|
+
<p>
|
316
|
+
<span class='paramTable__name'>balance</span>
|
317
|
+
</p>
|
318
|
+
|
319
|
+
<p class='paramTable__description'>The user's balance</p>
|
320
|
+
|
321
|
+
</td>
|
322
|
+
<td>Float</td>
|
323
|
+
<td>12.5</td>
|
324
|
+
</tr>
|
325
|
+
|
326
|
+
|
327
|
+
</table>
|
328
|
+
|
329
|
+
|
330
|
+
|
331
|
+
</section>
|
332
|
+
<footer class='footer'>
|
333
|
+
<p>Generated by Moonrope at 12:43 on Monday 22 February 2016 for d3c499</p>
|
334
|
+
</footer>
|
335
|
+
<script src='https://code.jquery.com/jquery-1.12.0.min.js'></script>
|
336
|
+
<script src='../assets/try.js'></script>
|
337
|
+
</body>
|
338
|
+
</html>
|
data/lib/moonrope/action.rb
CHANGED
@@ -1,3 +1,6 @@
|
|
1
|
+
require 'moonrope/dsl/action_dsl'
|
2
|
+
require 'moonrope/action_result'
|
3
|
+
|
1
4
|
module Moonrope
|
2
5
|
class Action
|
3
6
|
|
@@ -13,14 +16,35 @@ module Moonrope
|
|
13
16
|
# @return [Hash] the params available for the action
|
14
17
|
attr_reader :params
|
15
18
|
|
19
|
+
# @return [String] the title of the action
|
20
|
+
attr_accessor :title
|
21
|
+
|
16
22
|
# @return [String] the description of the action
|
17
23
|
attr_accessor :description
|
18
24
|
|
19
|
-
# @return [
|
20
|
-
attr_accessor :
|
25
|
+
# @return [Array] the actual action blocks for the action
|
26
|
+
attr_accessor :actions
|
27
|
+
|
28
|
+
# @return [Symbol] the name of the authenticator for this action
|
29
|
+
attr_accessor :authenticator
|
30
|
+
|
31
|
+
# @return [Symbol] the name of the access rule for this action
|
32
|
+
attr_accessor :access_rule
|
33
|
+
|
34
|
+
# @return [Hash] the errors which can be retuend by this action
|
35
|
+
attr_accessor :errors
|
36
|
+
|
37
|
+
# @return [Hash] details of what will be returned on success
|
38
|
+
attr_accessor :returns
|
39
|
+
|
40
|
+
# @return [Bool] whether or not the action should be documented
|
41
|
+
attr_accessor :doc
|
42
|
+
|
43
|
+
# @return [Array] additional traits that have been applied to this action
|
44
|
+
attr_reader :traits
|
21
45
|
|
22
|
-
# @return [
|
23
|
-
|
46
|
+
# @return [Hash] a hash of filters that are applied
|
47
|
+
attr_reader :filters
|
24
48
|
|
25
49
|
#
|
26
50
|
# Initialize a new action
|
@@ -33,6 +57,10 @@ module Moonrope
|
|
33
57
|
@controller = controller
|
34
58
|
@name = name
|
35
59
|
@params = {}
|
60
|
+
@errors = {}
|
61
|
+
@traits = []
|
62
|
+
@actions = []
|
63
|
+
@filters = {}
|
36
64
|
@dsl = Moonrope::DSL::ActionDSL.new(self)
|
37
65
|
@dsl.instance_eval(&block) if block_given?
|
38
66
|
end
|
@@ -49,6 +77,32 @@ module Moonrope
|
|
49
77
|
end
|
50
78
|
end
|
51
79
|
|
80
|
+
#
|
81
|
+
# Return the authenticator that should be used when executing this action
|
82
|
+
#
|
83
|
+
# @return [Moonrope::Authenticator]
|
84
|
+
#
|
85
|
+
def authenticator_to_use
|
86
|
+
@authenticator_to_use ||= begin
|
87
|
+
if @authenticator
|
88
|
+
@controller.base.authenticators[@authenticator] || :not_found
|
89
|
+
elsif @controller.authenticator
|
90
|
+
@controller.base.authenticators[@controller.authenticator] || :not_found
|
91
|
+
else
|
92
|
+
@controller.base.authenticators[:default] || :none
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Return the access rule to use for this action#
|
99
|
+
#
|
100
|
+
# @return [Symbol]
|
101
|
+
#
|
102
|
+
def access_rule_to_use
|
103
|
+
@access_rule_to_use ||= access_rule || @controller.access_rule || :default
|
104
|
+
end
|
105
|
+
|
52
106
|
#
|
53
107
|
# Execute a block of code and catch approprite Moonrope errors and return
|
54
108
|
# a result.
|
@@ -86,7 +140,7 @@ module Moonrope
|
|
86
140
|
if request.is_a?(EvalEnvironment)
|
87
141
|
eval_environment = request
|
88
142
|
else
|
89
|
-
eval_environment = EvalEnvironment.new(@controller.base, request)
|
143
|
+
eval_environment = EvalEnvironment.new(@controller.base, request, self)
|
90
144
|
end
|
91
145
|
|
92
146
|
#
|
@@ -95,12 +149,6 @@ module Moonrope
|
|
95
149
|
#
|
96
150
|
eval_environment.default_params = self.default_params
|
97
151
|
|
98
|
-
#
|
99
|
-
# Set the current action to the eval environment so it knows what action
|
100
|
-
# invoked this.
|
101
|
-
#
|
102
|
-
eval_environment.action = self
|
103
|
-
|
104
152
|
convert_errors_to_action_result do
|
105
153
|
#
|
106
154
|
# Validate the parameters
|
@@ -115,7 +163,10 @@ module Moonrope
|
|
115
163
|
end
|
116
164
|
|
117
165
|
# Run the actual action
|
118
|
-
response =
|
166
|
+
response = nil
|
167
|
+
actions.each do |action|
|
168
|
+
response = eval_environment.instance_exec(response, &action)
|
169
|
+
end
|
119
170
|
|
120
171
|
# Calculate the length of time this request takes
|
121
172
|
time_to_run = Time.now - start_time
|
@@ -144,34 +195,25 @@ module Moonrope
|
|
144
195
|
if request.is_a?(EvalEnvironment)
|
145
196
|
eval_environment = request
|
146
197
|
else
|
147
|
-
eval_environment = EvalEnvironment.new(@controller.base, request)
|
198
|
+
eval_environment = EvalEnvironment.new(@controller.base, request, self)
|
148
199
|
end
|
149
200
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
# If there's no authentication object, access is permitted otherwise
|
154
|
-
# we'll do the normal testing.
|
155
|
-
if access_condition.is_a?(Proc)
|
156
|
-
!!eval_environment.instance_exec(self, &access_condition)
|
157
|
-
elsif access_condition.is_a?(Symbol)
|
158
|
-
!!(eval_environment.auth.respond_to?(access_condition) && eval_environment.auth.send(access_condition))
|
159
|
-
elsif access_condition.is_a?(Hash) && access_condition[:must_be] && access_condition[:with]
|
160
|
-
!!(eval_environment.auth.is_a?(access_condition[:must_be]) &&
|
161
|
-
eval_environment.auth.respond_to?(access_condition[:with]) &&
|
162
|
-
eval_environment.auth.send(access_condition[:with])
|
163
|
-
)
|
164
|
-
elsif access_condition.is_a?(Hash) && access_condition[:must_be]
|
165
|
-
!!(eval_environment.auth.is_a?(access_condition[:must_be]))
|
166
|
-
elsif access_condition == true
|
167
|
-
true
|
201
|
+
if authenticator_to_use.is_a?(Moonrope::Authenticator)
|
202
|
+
if rule = authenticator_to_use.rules[access_rule_to_use]
|
203
|
+
eval_environment.instance_exec(self, &rule[:block]) == true
|
168
204
|
else
|
169
|
-
|
205
|
+
if access_rule_to_use == :default
|
206
|
+
# The default rule on any authenticator will allow everything so we
|
207
|
+
# don't need to worry about this not being defined.
|
208
|
+
true
|
209
|
+
else
|
210
|
+
# If an access rule that doesn't exist has been requested, we will
|
211
|
+
# raise an internal error.
|
212
|
+
raise Moonrope::Errors::MissingAccessRule, "The rule '#{access_rule_to_use}' was not found on '#{authenticator_to_use.name}' authenticator"
|
213
|
+
end
|
170
214
|
end
|
171
215
|
else
|
172
|
-
|
173
|
-
# depends on whether or not an access condition has been defined or not.
|
174
|
-
!access_condition
|
216
|
+
true
|
175
217
|
end
|
176
218
|
end
|
177
219
|
|
@@ -191,12 +233,98 @@ module Moonrope
|
|
191
233
|
raise Moonrope::Errors::ParameterError, "`#{name}` parameter is invalid"
|
192
234
|
end
|
193
235
|
|
194
|
-
if value[:
|
195
|
-
raise Moonrope::Errors::ParameterError, "`#{name}`
|
236
|
+
if value[:options].is_a?(Array) && param_set[name] && !value[:options].include?(param_set[name])
|
237
|
+
raise Moonrope::Errors::ParameterError, "`#{name}` must be one of #{value[:options].join(', ')}"
|
238
|
+
end
|
239
|
+
|
240
|
+
if value[:type] && param_set[name]
|
241
|
+
if value[:type] == :boolean
|
242
|
+
if BOOLEAN_VALUES.include?(param_set[name])
|
243
|
+
param_set._set_value(name, TRUE_LIKE_VALUES.include?(param_set[name]))
|
244
|
+
else
|
245
|
+
raise Moonrope::Errors::ParameterError, "`#{name}` should be a boolean value"
|
246
|
+
end
|
247
|
+
elsif value[:type].is_a?(Symbol) || value[:type].is_a?(String)
|
248
|
+
# Value is a symbol, nothing to do.
|
249
|
+
elsif !param_set[name].is_a?(value[:type])
|
250
|
+
raise Moonrope::Errors::ParameterError, "`#{name}` should be a `#{value[:type]}` but is a `#{param_set[name].class}`"
|
251
|
+
end
|
196
252
|
end
|
197
253
|
end
|
198
254
|
true
|
199
255
|
end
|
200
256
|
|
257
|
+
TRUE_LIKE_VALUES = ['true', '1', 1, true]
|
258
|
+
FALSE_LIKE_VALUES = ['false', '0', 0, false]
|
259
|
+
BOOLEAN_VALUES = TRUE_LIKE_VALUES + FALSE_LIKE_VALUES
|
260
|
+
|
261
|
+
#
|
262
|
+
# Does this action allow the user to include/exclude full attributes when
|
263
|
+
# calling this action?
|
264
|
+
#
|
265
|
+
def can_change_full?
|
266
|
+
if returns && opts = returns[:structure_opts]
|
267
|
+
opts[:paramable] == true ||
|
268
|
+
(opts[:paramable].is_a?(Hash) && opts[:paramable].has_key?(:full))
|
269
|
+
else
|
270
|
+
false
|
271
|
+
end
|
272
|
+
end
|
273
|
+
|
274
|
+
#
|
275
|
+
# Does this action include full attributes by default?
|
276
|
+
#
|
277
|
+
def includes_full_attributes?
|
278
|
+
if returns && opts = returns[:structure_opts]
|
279
|
+
(opts[:paramable].is_a?(Hash) && opts[:paramable][:full] == true) ||
|
280
|
+
opts[:full] == true
|
281
|
+
else
|
282
|
+
false
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
#
|
287
|
+
# Does this action allow the user to include/exclude expansions when calling
|
288
|
+
# this action?
|
289
|
+
#
|
290
|
+
def can_change_expansions?
|
291
|
+
if returns && opts = returns[:structure_opts]
|
292
|
+
opts[:paramable] == true ||
|
293
|
+
(opts[:paramable].is_a?(Hash) && opts[:paramable].has_key?(:expansions))
|
294
|
+
else
|
295
|
+
false
|
296
|
+
end
|
297
|
+
end
|
298
|
+
|
299
|
+
#
|
300
|
+
# Does this action include full attributes by default?
|
301
|
+
#
|
302
|
+
def includes_expansion?(expansion)
|
303
|
+
if returns && opts = returns[:structure_opts]
|
304
|
+
(opts[:paramable].is_a?(Hash) && opts[:paramable][:expansions] == true) ||
|
305
|
+
opts[:expansions] == true ||
|
306
|
+
(opts[:paramable].is_a?(Hash) && opts[:paramable][:expansions].is_a?(Array) && opts[:paramable][:expansions].include?(expansion)) ||
|
307
|
+
(opts[:expansions].is_a?(Array) && opts[:expansions].include?(expansion))
|
308
|
+
else
|
309
|
+
false
|
310
|
+
end
|
311
|
+
end
|
312
|
+
|
313
|
+
#
|
314
|
+
# Which expansions is the user permitted to include/exclude when calling this
|
315
|
+
# action.
|
316
|
+
#
|
317
|
+
def available_expansions
|
318
|
+
if returns && (structure = returns[:structure]) && can_change_expansions?
|
319
|
+
if returns[:structure_opts][:paramable].is_a?(Hash) && returns[:structure_opts][:paramable][:expansions].is_a?(Array)
|
320
|
+
returns[:structure_opts][:paramable][:expansions]
|
321
|
+
else
|
322
|
+
@controller.base.structure(structure).all_expansions
|
323
|
+
end
|
324
|
+
else
|
325
|
+
[]
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
201
329
|
end
|
202
330
|
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'moonrope/dsl/authenticator_dsl'
|
2
|
+
|
3
|
+
module Moonrope
|
4
|
+
class Authenticator
|
5
|
+
|
6
|
+
def initialize(name, &block)
|
7
|
+
@name = name
|
8
|
+
@headers = {}
|
9
|
+
@errors = {}
|
10
|
+
@rules = {}
|
11
|
+
if block_given?
|
12
|
+
dsl = Moonrope::DSL::AuthenticatorDSL.new(self)
|
13
|
+
dsl.instance_eval(&block)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
# @return [Symbol] the name of the authenticator
|
18
|
+
attr_reader :name
|
19
|
+
|
20
|
+
# @return [String] the description for the authenticator
|
21
|
+
attr_accessor :description
|
22
|
+
|
23
|
+
# @return [Proc] the lookup block
|
24
|
+
attr_accessor :lookup
|
25
|
+
|
26
|
+
# @return [Hash] the headers that this authenticator uses
|
27
|
+
attr_reader :headers
|
28
|
+
|
29
|
+
# @return [Hash] the errors this authenticator can raise
|
30
|
+
attr_reader :errors
|
31
|
+
|
32
|
+
# @return [Hash] the rules this authenticator provides
|
33
|
+
attr_reader :rules
|
34
|
+
|
35
|
+
# @return [Bool] whether or not the action should be documented
|
36
|
+
attr_accessor :doc
|
37
|
+
|
38
|
+
end
|
39
|
+
end
|
data/lib/moonrope/base.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'moonrope/dsl/base_dsl'
|
2
|
+
|
1
3
|
module Moonrope
|
2
4
|
class Base
|
3
5
|
|
@@ -14,6 +16,11 @@ module Moonrope
|
|
14
16
|
api
|
15
17
|
end
|
16
18
|
|
19
|
+
class << self
|
20
|
+
# @return [Moonrope::Base] return a global instance
|
21
|
+
attr_accessor :instance
|
22
|
+
end
|
23
|
+
|
17
24
|
# @return [Array] the array of defined structures
|
18
25
|
attr_reader :structures
|
19
26
|
|
@@ -26,11 +33,11 @@ module Moonrope
|
|
26
33
|
# @return [Moonrope::DSL::BaseDSL] the base DSL
|
27
34
|
attr_accessor :dsl
|
28
35
|
|
29
|
-
# @return [
|
30
|
-
attr_accessor :
|
36
|
+
# @return [Hash] authenticators
|
37
|
+
attr_accessor :authenticators
|
31
38
|
|
32
|
-
# @return [
|
33
|
-
attr_accessor :
|
39
|
+
# @return [Hash] global shared actions
|
40
|
+
attr_accessor :shared_actions
|
34
41
|
|
35
42
|
# @return [Array] the array of directories to load from (if relevant)
|
36
43
|
attr_accessor :load_directories
|
@@ -61,7 +68,8 @@ module Moonrope
|
|
61
68
|
@structures = []
|
62
69
|
@controllers = []
|
63
70
|
@helpers = @helpers.is_a?(Array) ? @helpers.select { |h| h.options[:unloadable] == false } : []
|
64
|
-
@
|
71
|
+
@authenticators = {}
|
72
|
+
@shared_actions = {}
|
65
73
|
@default_access = nil
|
66
74
|
end
|
67
75
|
|
@@ -92,7 +100,17 @@ module Moonrope
|
|
92
100
|
#
|
93
101
|
def load_directory(directory)
|
94
102
|
if File.exist?(directory)
|
95
|
-
|
103
|
+
@loaded_files = []
|
104
|
+
Dir[
|
105
|
+
"#{directory}/structures/**/*.rb",
|
106
|
+
"#{directory}/shared_actions/**/*.rb",
|
107
|
+
"#{directory}/controllers/**/*.rb",
|
108
|
+
"#{directory}/helpers/**/*.rb",
|
109
|
+
"#{directory}/authenticators/**/*.rb",
|
110
|
+
"#{directory}/*.rb",
|
111
|
+
].each do |filename|
|
112
|
+
next if @loaded_files.include?(filename)
|
113
|
+
@loaded_files << filename
|
96
114
|
self.dsl.instance_eval(File.read(filename), filename)
|
97
115
|
end
|
98
116
|
true
|