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
@@ -1,3 +1,5 @@
1
+ require 'moonrope/dsl/structure_dsl'
2
+
1
3
  module Moonrope
2
4
  class Structure
3
5
 
@@ -22,6 +24,9 @@ module Moonrope
22
24
  # @return [Hash] attributes which should be included in this structure
23
25
  attr_reader :attributes
24
26
 
27
+ # @return [Bool] should this structure be documented
28
+ attr_accessor :doc
29
+
25
30
  #
26
31
  # Initialize a new structure
27
32
  #
@@ -37,6 +42,15 @@ module Moonrope
37
42
  @dsl.instance_eval(&block) if block_given?
38
43
  end
39
44
 
45
+ #
46
+ # Return details for the given attribute
47
+ #
48
+ def attribute(name)
49
+ @attributes[:basic].select { |p| p.name == name }.first ||
50
+ @attributes[:full].select { |p| p.name == name }.first ||
51
+ @attributes[:expansion].select { |p| p.name == name }.first
52
+ end
53
+
40
54
  #
41
55
  # Return a hash for this struture
42
56
  #
@@ -46,7 +60,7 @@ module Moonrope
46
60
  #
47
61
  def hash(object, options = {})
48
62
  # Set up an environment
49
- environment = EvalEnvironment.new(base, options[:request], :o => object)
63
+ environment = EvalEnvironment.new(base, options[:request], options[:request] ? options[:request].action : nil, :o => object)
50
64
 
51
65
  # Set a new hash
52
66
  hash = Hash.new
@@ -83,7 +97,7 @@ module Moonrope
83
97
  # Add the expansions
84
98
  expansions.each do |name, expansion|
85
99
  next if options[:expansions].is_a?(Array) && !options[:expansions].include?(name.to_sym)
86
- next unless expansion[:conditions].all? { |condition| environment.instance_eval(&condition) }
100
+ next unless check_conditions(environment, expansion[:conditions])
87
101
  DeepMerge.deep_merge!({name.to_sym => environment.instance_eval(&expansion[:block])}, hash)
88
102
  end
89
103
  end
@@ -92,8 +106,59 @@ module Moonrope
92
106
  hash
93
107
  end
94
108
 
109
+ #
110
+ # Return an array of all expansions which are available on this structure
111
+ #
112
+ def all_expansions
113
+ @attributes[:expansion].map(&:name) + expansions.keys
114
+ end
115
+
116
+ #
117
+ # Return the description for a given condition hash
118
+ #
119
+ def description_for_condition(condition)
120
+ if condition[:authenticator] && condition[:access_rule]
121
+ if authenticator = base.authenticators[condition[:authenticator]]
122
+ if access_rule = authenticator.rules[condition[:access_rule]]
123
+ access_rule[:description]
124
+ end
125
+ end
126
+ else
127
+ condition[:description]
128
+ end
129
+ end
130
+
95
131
  private
96
132
 
133
+ #
134
+ # Call all conditions provided and return whether they pass or not
135
+ #
136
+ def check_conditions(environment, conditions)
137
+ conditions.each do |condition|
138
+ if condition[:block]
139
+ unless environment.instance_eval(&condition[:block])
140
+ return false
141
+ end
142
+ elsif condition[:authenticator] && condition[:access_rule]
143
+ if authenticator = base.authenticators[condition[:authenticator]]
144
+ if access_rule = authenticator.rules[condition[:access_rule]]
145
+ # If we have an authenticator and access rule, use the access rule
146
+ # block with this environment to determine if we should include the
147
+ # given block or not.
148
+ unless environment.instance_exec(self, &access_rule[:block])
149
+ return false
150
+ end
151
+ else
152
+ raise Moonrope::Errors::MissingAccessRule, "The rule '#{condition[:access_rule]}' was not found on '#{authenticator.name}' authenticator"
153
+ end
154
+ else
155
+ raise Moonrope::Errors::MissingAuthenticator, "The authentication '#{condition[:authenticator]}' was not found"
156
+ end
157
+ end
158
+ end
159
+ true
160
+ end
161
+
97
162
  #
98
163
  # Return a returnable hash for a given set of structured fields.
99
164
  #
@@ -103,14 +168,7 @@ module Moonrope
103
168
  attributes.each do |attribute|
104
169
 
105
170
  unless attribute.conditions.empty?
106
- matched = false
107
- attribute.conditions.each do |condition|
108
- if !environment.instance_eval(&condition)
109
- matched = true
110
- break
111
- end
112
- end
113
- if matched
171
+ unless check_conditions(environment, attribute.conditions)
114
172
  # Skip this item because a condition didn't evaluate
115
173
  # to true.
116
174
  next
@@ -146,7 +204,12 @@ module Moonrope
146
204
  # Return a value for a structured field.
147
205
  #
148
206
  def value_for_attribute(object, environment, attribute)
149
- value = object.send(attribute.source_attribute)
207
+ if attribute.source_attribute.is_a?(Proc)
208
+ value = environment.instance_eval(&attribute.source_attribute)
209
+ else
210
+ value = object.send(attribute.source_attribute)
211
+ end
212
+
150
213
  if value && attribute.structure
151
214
  # If a structure is required, lookup the desired structure and set the
152
215
  # hash value as appropriate.
@@ -11,6 +11,7 @@ module Moonrope
11
11
  attr_accessor :structure_opts
12
12
  attr_accessor :value
13
13
  attr_accessor :example
14
+ attr_accessor :doc
14
15
 
15
16
  def initialize(type, name)
16
17
  @type = type
@@ -23,5 +24,19 @@ module Moonrope
23
24
  @source_attribute || @name
24
25
  end
25
26
 
27
+ def name_with_groups
28
+ ([groups] + [name]).flatten.compact.join('.')
29
+ end
30
+
31
+ def example
32
+ @example ||= begin
33
+ if value_type == :timestamp
34
+ "2016-12-25 09:42:00 +0000"
35
+ elsif value_type == :boolean
36
+ "false"
37
+ end
38
+ end
39
+ end
40
+
26
41
  end
27
42
  end
@@ -1,3 +1,3 @@
1
1
  module Moonrope
2
- VERSION = '1.4.1'
2
+ VERSION = '2.0.0'
3
3
  end
data/lib/moonrope.rb CHANGED
@@ -11,7 +11,8 @@ require 'moonrope/dsl/base_dsl'
11
11
  require 'moonrope/dsl/action_dsl'
12
12
  require 'moonrope/dsl/controller_dsl'
13
13
  require 'moonrope/dsl/structure_dsl'
14
-
14
+ require 'moonrope/dsl/authenticator_dsl'
15
+ require 'moonrope/authenticator'
15
16
  require 'moonrope/errors'
16
17
  require 'moonrope/eval_helpers'
17
18
  require 'moonrope/eval_environment'
@@ -26,13 +27,13 @@ require 'moonrope/version'
26
27
  require 'moonrope/railtie' if defined?(Rails)
27
28
 
28
29
  module Moonrope
29
-
30
+
30
31
  class << self
31
32
  attr_accessor :logger
32
-
33
+
33
34
  def logger
34
35
  @logger ||= Logger.new(STDOUT)
35
36
  end
36
37
  end
37
-
38
+
38
39
  end
data/moonrope.gemspec ADDED
@@ -0,0 +1,21 @@
1
+ $:.push File.expand_path("../lib", __FILE__)
2
+
3
+ require "moonrope/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "moonrope"
7
+ s.version = Moonrope::VERSION
8
+ s.authors = ["Adam Cooke"]
9
+ s.email = ["adam@atechmedia.com"]
10
+ s.homepage = "http://adamcooke.io"
11
+ s.licenses = ['MIT']
12
+ s.summary = "An API server DSL."
13
+ s.description = "A full library allowing you to create sexy DSLs to define your RPC-like APIs."
14
+ s.files = Dir["**/*"]
15
+ s.bindir = "bin"
16
+ s.executables << 'moonrope'
17
+ s.add_dependency "json", "~> 1.7"
18
+ s.add_dependency "rack", ">= 1.4"
19
+ s.add_dependency "deep_merge", "~> 1.0"
20
+ s.add_development_dependency "rake", '~> 10.3'
21
+ end
@@ -0,0 +1,32 @@
1
+ $:.unshift(File.expand_path(File.join('..', 'lib')))
2
+
3
+ RSpec.configure do |config|
4
+ config.color = true
5
+ config.expect_with :rspec do |expectations|
6
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
7
+ end
8
+ end
9
+
10
+ class FakeRequest
11
+
12
+ def initialize(options = {})
13
+ @options = options
14
+ end
15
+
16
+ def params
17
+ @params ||= Moonrope::ParamSet.new(@options[:params] || {})
18
+ end
19
+
20
+ def version
21
+ @options[:version]
22
+ end
23
+
24
+ def identity
25
+ @options[:identity]
26
+ end
27
+
28
+ def action
29
+ nil
30
+ end
31
+
32
+ end