moonrope 1.4.1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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