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.
Files changed (95) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +9 -0
  3. data/Gemfile.lock +47 -0
  4. data/MIT-LICENCE +20 -0
  5. data/README.md +24 -0
  6. data/bin/moonrope +28 -0
  7. data/docs/authentication.md +114 -0
  8. data/docs/controllers.md +106 -0
  9. data/docs/exceptions.md +27 -0
  10. data/docs/introduction.md +29 -0
  11. data/docs/structures.md +214 -0
  12. data/example/authentication.rb +50 -0
  13. data/example/controllers/meta_controller.rb +14 -0
  14. data/example/controllers/users_controller.rb +92 -0
  15. data/example/structures/pet_structure.rb +12 -0
  16. data/example/structures/user_structure.rb +35 -0
  17. data/html/assets/lock.svg +3 -0
  18. data/html/assets/reset.css +101 -0
  19. data/html/assets/style.css +348 -0
  20. data/html/assets/tool.svg +4 -0
  21. data/html/assets/try.js +151 -0
  22. data/html/authenticators/default.html +191 -0
  23. data/html/controllers/meta/version.html +144 -0
  24. data/html/controllers/meta.html +73 -0
  25. data/html/controllers/users/create.html +341 -0
  26. data/html/controllers/users/list.html +348 -0
  27. data/html/controllers/users/show.html +261 -0
  28. data/html/controllers/users/update.html +387 -0
  29. data/html/controllers/users.html +93 -0
  30. data/html/index.html +166 -0
  31. data/html/moonrope.txt +0 -0
  32. data/html/structures/pet.html +176 -0
  33. data/html/structures/user.html +338 -0
  34. data/lib/moonrope/action.rb +165 -37
  35. data/lib/moonrope/authenticator.rb +39 -0
  36. data/lib/moonrope/base.rb +24 -6
  37. data/lib/moonrope/controller.rb +4 -2
  38. data/lib/moonrope/doc_context.rb +94 -0
  39. data/lib/moonrope/doc_server.rb +123 -0
  40. data/lib/moonrope/dsl/action_dsl.rb +159 -9
  41. data/lib/moonrope/dsl/authenticator_dsl.rb +31 -0
  42. data/lib/moonrope/dsl/base_dsl.rb +21 -18
  43. data/lib/moonrope/dsl/controller_dsl.rb +60 -9
  44. data/lib/moonrope/dsl/filterable_dsl.rb +27 -0
  45. data/lib/moonrope/dsl/structure_dsl.rb +27 -2
  46. data/lib/moonrope/errors.rb +3 -0
  47. data/lib/moonrope/eval_environment.rb +82 -3
  48. data/lib/moonrope/eval_helpers/filter_helper.rb +82 -0
  49. data/lib/moonrope/eval_helpers.rb +28 -5
  50. data/lib/moonrope/guard.rb +35 -0
  51. data/lib/moonrope/html_generator.rb +65 -0
  52. data/lib/moonrope/param_set.rb +11 -1
  53. data/lib/moonrope/rack_middleware.rb +1 -1
  54. data/lib/moonrope/railtie.rb +31 -14
  55. data/lib/moonrope/request.rb +25 -14
  56. data/lib/moonrope/structure.rb +74 -11
  57. data/lib/moonrope/structure_attribute.rb +15 -0
  58. data/lib/moonrope/version.rb +1 -1
  59. data/lib/moonrope.rb +5 -4
  60. data/moonrope.gemspec +21 -0
  61. data/spec/spec_helper.rb +32 -0
  62. data/spec/specs/action_spec.rb +455 -0
  63. data/spec/specs/base_spec.rb +29 -0
  64. data/spec/specs/controller_spec.rb +31 -0
  65. data/spec/specs/param_set_spec.rb +31 -0
  66. data/templates/basic/_action_form.erb +77 -0
  67. data/templates/basic/_errors_table.erb +32 -0
  68. data/templates/basic/_structure_attributes_list.erb +55 -0
  69. data/templates/basic/action.erb +168 -0
  70. data/templates/basic/assets/lock.svg +3 -0
  71. data/templates/basic/assets/reset.css +101 -0
  72. data/templates/basic/assets/style.css +348 -0
  73. data/templates/basic/assets/tool.svg +4 -0
  74. data/templates/basic/assets/try.js +151 -0
  75. data/templates/basic/authenticator.erb +51 -0
  76. data/templates/basic/controller.erb +20 -0
  77. data/templates/basic/index.erb +114 -0
  78. data/templates/basic/layout.erb +46 -0
  79. data/templates/basic/structure.erb +23 -0
  80. data/test/test_helper.rb +81 -0
  81. data/test/tests/action_access_test.rb +63 -0
  82. data/test/tests/actions_test.rb +524 -0
  83. data/test/tests/authenticators_test.rb +87 -0
  84. data/test/tests/base_test.rb +35 -0
  85. data/test/tests/controllers_test.rb +49 -0
  86. data/test/tests/eval_environment_test.rb +136 -0
  87. data/test/tests/evel_helpers_test.rb +60 -0
  88. data/test/tests/examples_test.rb +11 -0
  89. data/test/tests/helpers_test.rb +97 -0
  90. data/test/tests/param_set_test.rb +44 -0
  91. data/test/tests/rack_middleware_test.rb +109 -0
  92. data/test/tests/request_test.rb +232 -0
  93. data/test/tests/structures_param_extensions_test.rb +159 -0
  94. data/test/tests/structures_test.rb +335 -0
  95. 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>
@@ -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 [Proc] the access check condition for the action
20
- attr_accessor :access
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 [Proc] the action for the action
23
- attr_accessor :action
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 = eval_environment.instance_eval(&action)
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
- access_condition = self.access || @controller.access || @controller.base.default_access
151
-
152
- if eval_environment.auth
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
- false
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
- # No authentication object is available to test with. The result here
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[:type] && param_set[name] && !param_set[name].is_a?(value[:type])
195
- raise Moonrope::Errors::ParameterError, "`#{name}` should be a `#{value[:type]}` but is a `#{param_set[name].class}`"
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 [Proc] the authentictor
30
- attr_accessor :authenticator
36
+ # @return [Hash] authenticators
37
+ attr_accessor :authenticators
31
38
 
32
- # @return [Proc] the default access condition
33
- attr_accessor :default_access
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
- @authenticator = nil
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
- Dir["#{directory}/**/*.rb"].each do |filename|
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