moonrope 2.0.1 → 2.0.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile.lock +6 -6
- data/lib/moonrope/base.rb +26 -0
- data/lib/moonrope/rack_middleware.rb +29 -14
- data/lib/moonrope/request.rb +8 -0
- data/lib/moonrope/structure.rb +2 -2
- data/lib/moonrope/structure_attribute.rb +1 -1
- data/lib/moonrope/version.rb +1 -1
- data/moonrope.gemspec +2 -2
- data/templates/basic/_action_form.erb +1 -1
- data/test/tests/rack_middleware_test.rb +14 -0
- data/test/tests/structures_test.rb +8 -0
- metadata +11 -30
- data/html/assets/lock.svg +0 -3
- data/html/assets/reset.css +0 -101
- data/html/assets/style.css +0 -348
- data/html/assets/tool.svg +0 -4
- data/html/assets/try.js +0 -151
- data/html/authenticators/default.html +0 -191
- data/html/controllers/meta.html +0 -73
- data/html/controllers/meta/version.html +0 -144
- data/html/controllers/users.html +0 -93
- data/html/controllers/users/create.html +0 -341
- data/html/controllers/users/list.html +0 -348
- data/html/controllers/users/show.html +0 -261
- data/html/controllers/users/update.html +0 -387
- data/html/index.html +0 -166
- data/html/moonrope.txt +0 -0
- data/html/structures/pet.html +0 -176
- data/html/structures/user.html +0 -338
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: e34dcc98aecf5558f04b21b81aeb19c419597a21d7c736363ed681a322feee06
|
4
|
+
data.tar.gz: b4ad2c14aed545aefa3be780e8d0e778c75d0828d3426ebc022a3d540a05e023
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7395cad7eb23fe964de419d8daf4cfb9fbf4009160dd51e8bec84fe278301be830e822da463ddd139d02c47c0ca805f51d1273777419151a65c1b3168bc68ee0
|
7
|
+
data.tar.gz: 3bbd5d843bf9f608057374c147f056e4a16e1afa2f2928cc2bf99de51e1d274a59317d8524827150e7ffad00a5b208a9efa3edf9ebd037d25935fe596bf00925
|
data/Gemfile.lock
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
moonrope (2.0.
|
4
|
+
moonrope (2.0.2)
|
5
5
|
deep_merge (~> 1.0)
|
6
|
-
json
|
6
|
+
json
|
7
7
|
rack (>= 1.4)
|
8
8
|
|
9
9
|
GEM
|
10
10
|
remote: https://rubygems.org/
|
11
11
|
specs:
|
12
|
-
deep_merge (1.
|
12
|
+
deep_merge (1.2.1)
|
13
13
|
diff-lcs (1.2.5)
|
14
|
-
json (
|
14
|
+
json (2.3.1)
|
15
15
|
rack (1.5.2)
|
16
16
|
rack-test (0.6.3)
|
17
17
|
rack (>= 1.0)
|
@@ -35,7 +35,7 @@ PLATFORMS
|
|
35
35
|
DEPENDENCIES
|
36
36
|
moonrope!
|
37
37
|
rack-test (~> 0)
|
38
|
-
rake
|
38
|
+
rake
|
39
39
|
rspec
|
40
40
|
rspec-core
|
41
41
|
rspec-expectations
|
@@ -44,4 +44,4 @@ DEPENDENCIES
|
|
44
44
|
yard (~> 0.8)
|
45
45
|
|
46
46
|
BUNDLED WITH
|
47
|
-
1.
|
47
|
+
1.17.2
|
data/lib/moonrope/base.rb
CHANGED
@@ -48,6 +48,9 @@ module Moonrope
|
|
48
48
|
# @return [Proc] a proc to execute before every request
|
49
49
|
attr_accessor :on_request
|
50
50
|
|
51
|
+
# @return [Boolean] is SSL forced?
|
52
|
+
attr_accessor :force_ssl
|
53
|
+
|
51
54
|
#
|
52
55
|
# Initialize a new instance of the Moonrope::Base
|
53
56
|
#
|
@@ -68,6 +71,7 @@ module Moonrope
|
|
68
71
|
@environment = other.environment
|
69
72
|
@load_directories = other.load_directories
|
70
73
|
@on_request = other.on_request
|
74
|
+
other.request_callbacks.each { |block| self.register_request_callback(&block) }
|
71
75
|
other.request_error_callbacks.each { |block| self.register_request_error_callback(&block) }
|
72
76
|
other.external_errors.each { |error, block| self.register_external_error(error, &block) }
|
73
77
|
end
|
@@ -231,5 +235,27 @@ module Moonrope
|
|
231
235
|
@request_error_callbacks ||= []
|
232
236
|
end
|
233
237
|
|
238
|
+
#
|
239
|
+
# Set a block which will be executed whenever a request is received by moonrope.
|
240
|
+
#
|
241
|
+
#
|
242
|
+
def register_request_callback(&block)
|
243
|
+
request_callbacks << block
|
244
|
+
end
|
245
|
+
|
246
|
+
#
|
247
|
+
# Return an array of request callbacks
|
248
|
+
#
|
249
|
+
def request_callbacks
|
250
|
+
@request_callbacks ||= []
|
251
|
+
end
|
252
|
+
|
253
|
+
#
|
254
|
+
# Should SSL be forced?
|
255
|
+
#
|
256
|
+
def force_ssl?
|
257
|
+
@force_ssl || false
|
258
|
+
end
|
259
|
+
|
234
260
|
end
|
235
261
|
end
|
@@ -52,27 +52,33 @@ module Moonrope
|
|
52
52
|
# Reload if needed
|
53
53
|
#
|
54
54
|
if @options[:reload_on_each_request]
|
55
|
-
base = @base.copy
|
55
|
+
@base = @base.copy
|
56
56
|
begin
|
57
|
-
base.load
|
57
|
+
@base.load
|
58
58
|
rescue => e
|
59
|
-
return generate_error_triplet(@base, e, global_headers)
|
59
|
+
return generate_error_triplet(@base, nil, e, global_headers)
|
60
60
|
end
|
61
|
-
else
|
62
|
-
base = @base
|
63
61
|
end
|
64
62
|
|
65
63
|
#
|
66
|
-
#
|
64
|
+
# Create a new request object
|
67
65
|
#
|
68
|
-
|
69
|
-
|
66
|
+
request = base.request(env, $1)
|
67
|
+
|
68
|
+
#
|
69
|
+
# If force SSL is enabled, don't allow requests to proceed if they're
|
70
|
+
# not SSL
|
71
|
+
#
|
72
|
+
if base.force_ssl? && !request.ssl?
|
73
|
+
return [400, global_headers, [{:status => 'http-not-supported', :message => "Non-secure HTTP connections are not supported. Requests should be made using https:// rather than http://."}.to_json]]
|
70
74
|
end
|
71
75
|
|
72
76
|
#
|
73
|
-
#
|
77
|
+
# Call the on request block if one has been defined for the base.
|
74
78
|
#
|
75
|
-
|
79
|
+
if base.on_request.is_a?(Proc)
|
80
|
+
base.on_request.call(base, env)
|
81
|
+
end
|
76
82
|
|
77
83
|
#
|
78
84
|
# Check the request is valid
|
@@ -87,13 +93,22 @@ module Moonrope
|
|
87
93
|
begin
|
88
94
|
result = request.execute
|
89
95
|
json = result.to_json
|
90
|
-
|
96
|
+
|
91
97
|
global_headers['Content-Length'] = json.bytesize.to_s
|
92
|
-
|
98
|
+
headers = global_headers.merge(result.headers)
|
99
|
+
Moonrope.logger.info "[#{Time.now.utc.strftime("%Y-%m-%d %H:%M:%S")}] controller=#{request.controller.name} action=#{request.action.name} status=#{result.status} time=#{result.time} ip=#{request.ip} size=#{json.bytesize}"
|
100
|
+
|
101
|
+
base.request_callbacks.each do |callback|
|
102
|
+
# Call each request callback and provide the request, the result
|
103
|
+
# and the raw that's being returned to the user.
|
104
|
+
callback.call(request, result, json, headers)
|
105
|
+
end
|
106
|
+
|
107
|
+
[200, headers, [json]]
|
93
108
|
rescue JSON::ParserError => e
|
94
109
|
[400, global_headers, [{:status => 'invalid-json', :details => e.message}.to_json]]
|
95
110
|
rescue => e
|
96
|
-
generate_error_triplet(base, e, global_headers)
|
111
|
+
generate_error_triplet(base, request, e, global_headers)
|
97
112
|
end
|
98
113
|
|
99
114
|
else
|
@@ -105,7 +120,7 @@ module Moonrope
|
|
105
120
|
end
|
106
121
|
end
|
107
122
|
|
108
|
-
def generate_error_triplet(base, exception, headers = {})
|
123
|
+
def generate_error_triplet(base, request, exception, headers = {})
|
109
124
|
Moonrope.logger.info exception.class
|
110
125
|
Moonrope.logger.info exception.message
|
111
126
|
Moonrope.logger.info exception.backtrace.join("\n")
|
data/lib/moonrope/request.rb
CHANGED
data/lib/moonrope/structure.rb
CHANGED
@@ -95,7 +95,7 @@ module Moonrope
|
|
95
95
|
if options[:expansions].is_a?(Array)
|
96
96
|
expansions_to_include = options[:expansions].each_with_object({}) do |expan, hash|
|
97
97
|
if expan.is_a?(Symbol) || expan.is_a?(String)
|
98
|
-
hash[expan.to_sym] =
|
98
|
+
hash[expan.to_sym] = nil
|
99
99
|
elsif expan.is_a?(Hash)
|
100
100
|
hash[expan.first.first.to_sym] = expan.first.last
|
101
101
|
end
|
@@ -233,7 +233,7 @@ module Moonrope
|
|
233
233
|
# hash value as appropriate.
|
234
234
|
if structure = self.base.structure(attribute.structure)
|
235
235
|
structure_opts = options[:structure_opts] || attribute.structure_opts || {}
|
236
|
-
if value.respond_to?(:map)
|
236
|
+
if value.is_a?(Enumerable) && value.respond_to?(:map)
|
237
237
|
value.map do |v|
|
238
238
|
structure.hash(v, structure_opts.merge(:request => environment.request))
|
239
239
|
end
|
data/lib/moonrope/version.rb
CHANGED
data/moonrope.gemspec
CHANGED
@@ -14,8 +14,8 @@ Gem::Specification.new do |s|
|
|
14
14
|
s.files = Dir["**/*"]
|
15
15
|
s.bindir = "bin"
|
16
16
|
s.executables << 'moonrope'
|
17
|
-
s.add_dependency "json"
|
17
|
+
s.add_dependency "json"
|
18
18
|
s.add_dependency "rack", ">= 1.4"
|
19
19
|
s.add_dependency "deep_merge", "~> 1.0"
|
20
|
-
s.add_development_dependency "rake"
|
20
|
+
s.add_development_dependency "rake"
|
21
21
|
end
|
@@ -6,7 +6,7 @@
|
|
6
6
|
<div class='tryForm__header'>
|
7
7
|
<input type='text' id='host' name='host' value='<%= host %>'>
|
8
8
|
/api/
|
9
|
-
<input type='text' id='version' name='version' value='
|
9
|
+
<input type='text' id='version' name='version' value='<%= version %>' class='v'>
|
10
10
|
/<%= controller.name %>/<%= action.name %>
|
11
11
|
</div>
|
12
12
|
|
@@ -107,6 +107,20 @@ class RackMiddlewareTest < Test::Unit::TestCase
|
|
107
107
|
assert_equal 2, request_count
|
108
108
|
end
|
109
109
|
|
110
|
+
def test_force_ssl
|
111
|
+
begin
|
112
|
+
app.base.force_ssl = true
|
113
|
+
get "/api/v1/users/list"
|
114
|
+
assert_equal 400, last_response.status
|
115
|
+
assert response_json = JSON.parse(last_response.body)
|
116
|
+
assert_equal 'http-not-supported', response_json['status']
|
117
|
+
|
118
|
+
get "/api/v1/users/list", {}, {'HTTPS' => 'on'}
|
119
|
+
assert_equal 200, last_response.status
|
120
|
+
ensure
|
121
|
+
app.base.force_ssl = false
|
122
|
+
end
|
123
|
+
end
|
110
124
|
|
111
125
|
private
|
112
126
|
|
@@ -160,6 +160,14 @@ class StructuresTest < Test::Unit::TestCase
|
|
160
160
|
assert_equal 'Fido', hash[:animals][0][:name]
|
161
161
|
assert_equal 'Boris', hash[:animals][1][:name]
|
162
162
|
assert_equal 'Black', hash[:animals][1][:hair_color]
|
163
|
+
|
164
|
+
# a full user hash with named extensions
|
165
|
+
hash = base.structure(:user).hash(user, :full => true, :expansions => [:animals])
|
166
|
+
# arrays
|
167
|
+
assert_equal Array, hash[:animals].class
|
168
|
+
assert_equal 'Fido', hash[:animals][0][:name]
|
169
|
+
assert_equal 'Boris', hash[:animals][1][:name]
|
170
|
+
assert_equal 'Black', hash[:animals][1][:hair_color]
|
163
171
|
end
|
164
172
|
|
165
173
|
def test_ifs
|
metadata
CHANGED
@@ -1,29 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: moonrope
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.
|
4
|
+
version: 2.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Adam Cooke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2020-12-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
|
-
- - "
|
17
|
+
- - ">="
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: '
|
19
|
+
version: '0'
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
22
22
|
version_requirements: !ruby/object:Gem::Requirement
|
23
23
|
requirements:
|
24
|
-
- - "
|
24
|
+
- - ">="
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: '
|
26
|
+
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
name: rack
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -56,16 +56,16 @@ dependencies:
|
|
56
56
|
name: rake
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
58
58
|
requirements:
|
59
|
-
- - "
|
59
|
+
- - ">="
|
60
60
|
- !ruby/object:Gem::Version
|
61
|
-
version: '
|
61
|
+
version: '0'
|
62
62
|
type: :development
|
63
63
|
prerelease: false
|
64
64
|
version_requirements: !ruby/object:Gem::Requirement
|
65
65
|
requirements:
|
66
|
-
- - "
|
66
|
+
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: '
|
68
|
+
version: '0'
|
69
69
|
description: A full library allowing you to create sexy DSLs to define your RPC-like
|
70
70
|
APIs.
|
71
71
|
email:
|
@@ -91,23 +91,6 @@ files:
|
|
91
91
|
- example/controllers/users_controller.rb
|
92
92
|
- example/structures/pet_structure.rb
|
93
93
|
- example/structures/user_structure.rb
|
94
|
-
- html/assets/lock.svg
|
95
|
-
- html/assets/reset.css
|
96
|
-
- html/assets/style.css
|
97
|
-
- html/assets/tool.svg
|
98
|
-
- html/assets/try.js
|
99
|
-
- html/authenticators/default.html
|
100
|
-
- html/controllers/meta.html
|
101
|
-
- html/controllers/meta/version.html
|
102
|
-
- html/controllers/users.html
|
103
|
-
- html/controllers/users/create.html
|
104
|
-
- html/controllers/users/list.html
|
105
|
-
- html/controllers/users/show.html
|
106
|
-
- html/controllers/users/update.html
|
107
|
-
- html/index.html
|
108
|
-
- html/moonrope.txt
|
109
|
-
- html/structures/pet.html
|
110
|
-
- html/structures/user.html
|
111
94
|
- lib/moonrope.rb
|
112
95
|
- lib/moonrope/action.rb
|
113
96
|
- lib/moonrope/action_result.rb
|
@@ -191,10 +174,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
174
|
- !ruby/object:Gem::Version
|
192
175
|
version: '0'
|
193
176
|
requirements: []
|
194
|
-
|
195
|
-
rubygems_version: 2.5.1
|
177
|
+
rubygems_version: 3.0.3
|
196
178
|
signing_key:
|
197
179
|
specification_version: 4
|
198
180
|
summary: An API server DSL.
|
199
181
|
test_files: []
|
200
|
-
has_rdoc:
|
data/html/assets/lock.svg
DELETED
data/html/assets/reset.css
DELETED
@@ -1,101 +0,0 @@
|
|
1
|
-
html, body, body div, span, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, abbr, address, cite, code, del, dfn, em, img, ins, kbd, q, samp, small, strong, sub, sup, var, b, i, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, figure, footer, header, hgroup, menu, nav, section, time, mark, audio, video {
|
2
|
-
margin: 0;
|
3
|
-
padding: 0;
|
4
|
-
border: 0;
|
5
|
-
outline: 0;
|
6
|
-
font-size: 100%;
|
7
|
-
letter-spacing:0;
|
8
|
-
vertical-align: baseline;
|
9
|
-
background: transparent;
|
10
|
-
font-weight:inherit;
|
11
|
-
}
|
12
|
-
|
13
|
-
* {
|
14
|
-
-webkit-box-sizing: border-box;
|
15
|
-
-moz-box-sizing: border-box;
|
16
|
-
box-sizing: border-box;
|
17
|
-
}
|
18
|
-
u { text-decoration: none;}
|
19
|
-
b { font-weight:normal;}
|
20
|
-
article, aside, figure, footer, header, hgroup, nav, section {display: block;}
|
21
|
-
|
22
|
-
object,embed {max-width: 100%;}
|
23
|
-
ul {list-style: none;}
|
24
|
-
blockquote, q {quotes: none;}
|
25
|
-
b,strong { font-weight:bold;}
|
26
|
-
blockquote:before, blockquote:after, q:before, q:after {content: ''; content: none;}
|
27
|
-
|
28
|
-
a {margin: 0; padding: 0; font-size: 100%; vertical-align: baseline; background: transparent;}
|
29
|
-
|
30
|
-
del {text-decoration: line-through;}
|
31
|
-
|
32
|
-
abbr[title], dfn[title] {border-bottom: 1px dotted #000; cursor: help;}
|
33
|
-
|
34
|
-
/* tables still need cellspacing="0" in the markup */
|
35
|
-
table {border-collapse: collapse; border-spacing: 0;}
|
36
|
-
mark { color:inherit;}
|
37
|
-
|
38
|
-
hr {display: block; height: 1px; border: 0; border-top: 1px solid #ccc; margin: 1em 0; padding: 0;}
|
39
|
-
|
40
|
-
input, select {vertical-align: middle;}
|
41
|
-
|
42
|
-
pre {
|
43
|
-
white-space: pre; /* CSS2 */
|
44
|
-
white-space: pre-wrap; /* CSS 2.1 */
|
45
|
-
white-space: pre-line; /* CSS 3 (and 2.1 as well, actually) */
|
46
|
-
word-wrap: break-word; /* IE */
|
47
|
-
}
|
48
|
-
|
49
|
-
input[type="radio"] {vertical-align: text-bottom;}
|
50
|
-
input[type="checkbox"] {vertical-align: bottom; *vertical-align: baseline;}
|
51
|
-
.ie6 input {vertical-align: text-bottom;}
|
52
|
-
|
53
|
-
select, input, textarea {font: 99% sans-serif;}
|
54
|
-
|
55
|
-
table {font-size: inherit; font: 100%;}
|
56
|
-
|
57
|
-
/* Accessible focus treatment
|
58
|
-
people.opera.com/patrickl/experiments/keyboard/test */
|
59
|
-
a:hover, a:active {outline: none;}
|
60
|
-
|
61
|
-
small {font-size: 85%;}
|
62
|
-
|
63
|
-
strong, th {font-weight: bold;}
|
64
|
-
|
65
|
-
td, td img {vertical-align: top;}
|
66
|
-
|
67
|
-
/* Make sure sup and sub don't screw with your line-heights
|
68
|
-
gist.github.com/413930 */
|
69
|
-
sub, sup {font-size: 75%; line-height: 0; position: relative;}
|
70
|
-
sup {top: -0.5em;}
|
71
|
-
sub {bottom: -0.25em;}
|
72
|
-
|
73
|
-
/* standardize any monospaced elements */
|
74
|
-
pre, code, kbd, samp {font-family: monospace, sans-serif;}
|
75
|
-
|
76
|
-
/* hand cursor on clickable elements */
|
77
|
-
.clickable,
|
78
|
-
label,
|
79
|
-
input[type=button],
|
80
|
-
input[type=submit],
|
81
|
-
button {cursor: pointer;}
|
82
|
-
|
83
|
-
/* Webkit browsers add a 2px margin outside the chrome of form elements */
|
84
|
-
button, input, select, textarea {margin: 0;}
|
85
|
-
|
86
|
-
/* make buttons play nice in IE */
|
87
|
-
button {width: auto; overflow: visible;}
|
88
|
-
|
89
|
-
/* scale images in IE7 more attractively */
|
90
|
-
.ie7 img {-ms-interpolation-mode: bicubic;}
|
91
|
-
|
92
|
-
/* prevent BG image flicker upon hover */
|
93
|
-
.ie6 html {filter: expression(document.execCommand("BackgroundImageCache", false, true));}
|
94
|
-
|
95
|
-
/* let's clear some floats */
|
96
|
-
.clearfix:before, .clearfix:after { content: "\0020"; display: block; height: 0; overflow: hidden; }
|
97
|
-
.clearfix:after { clear: both; }
|
98
|
-
.clearfix { zoom: 1; }
|
99
|
-
|
100
|
-
select, input, textarea, a { outline: none;}
|
101
|
-
a { color:inherit;}
|