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,151 @@
1
+ $(document).ready(function() {
2
+
3
+ $form = $('form.tryForm')
4
+
5
+ // Get all fields which will be added as headers
6
+ var headerFields = $('input.headerField', $form)
7
+
8
+ // Add stored values to header fields
9
+ if(typeof(Storage) !== "undefined") {
10
+ headerFields.each(function() {
11
+ $field = $(this)
12
+ $field.val(localStorage.getItem("header__" + $(this).attr('name')))
13
+ })
14
+
15
+ }
16
+
17
+
18
+ //
19
+ // Form submission
20
+ //
21
+ $form.on('submit', function() {
22
+
23
+ // Gets values used to make up the URL which should be
24
+ // requested for this request.
25
+ var host = $("input[name=host]", $(this)).val()
26
+ var version = $("input[name=version]", $(this)).val()
27
+ var controller = $("input[name=controller]", $(this)).val()
28
+ var action = $("input[name=action]", $(this)).val()
29
+ var url = host + "/api/" + version + "/" + controller + "/" + action
30
+ // Get the output box ready for use
31
+ var outputBox = $('.tryForm__output', $(this))
32
+ // Create a hash fo all parameters which will be submitted
33
+ var parameters = {}
34
+ $('input.paramField').each(function(){
35
+ $this = $(this)
36
+ value = $this.val()
37
+ type = $this.data('type')
38
+ name = $this.attr('name')
39
+ if(value.length) {
40
+ if(type == 'Integer') {
41
+ parameters[name] = parseInt(value);
42
+ } else if (type == "Hash" || type == "Array") {
43
+ parameters[name] = JSON.parse(value);
44
+ } else {
45
+ parameters[name] = value;
46
+ }
47
+ }
48
+ });
49
+
50
+ // Include/exclude full attributes as needed
51
+ var fullAttrsCheckbox = $('#full_attrs')
52
+ if(fullAttrsCheckbox.length) {
53
+ parameters['_full'] = !!fullAttrsCheckbox.prop('checked')
54
+ }
55
+
56
+ // Include/exclude expansions
57
+ var expansionCheckboxes = $('.tryForm__expansions')
58
+ if(expansionCheckboxes.length) {
59
+ parameters['_expansions'] = []
60
+ expansionCheckboxes.each(function() {
61
+ $this = $(this)
62
+ name = $(this).attr('name')
63
+ if($(this).prop('checked')) {
64
+ parameters['_expansions'].push(name)
65
+ }
66
+ })
67
+ }
68
+
69
+ // Make the AJAX request
70
+ $.ajax({
71
+ url: url,
72
+ method: 'POST',
73
+ contentType: 'application/json',
74
+ data: JSON.stringify(parameters),
75
+ beforeSend: function(xhr) {
76
+ // Add any headers which have been added
77
+ headerFields.each(function() {
78
+ $field = $(this)
79
+ name = $field.attr('name')
80
+ value = $field.val()
81
+ if(typeof(Storage) !== "undefined") {
82
+ localStorage.setItem("header__" + name, value)
83
+ }
84
+ if(value.length) {
85
+ xhr.setRequestHeader(name, $field.val())
86
+ }
87
+ })
88
+ },
89
+ success: function(data) {
90
+ // Success means that we got a 200 OK which means we can be pretty
91
+ // sure that we've got a moonrope response.
92
+ if(data.status == "success") {
93
+ outputBox.addClass('tryForm__output--success').removeClass('tryForm__output--error')
94
+ } else {
95
+ outputBox.addClass('tryForm__output--error').removeClass('tryForm__output--success')
96
+ }
97
+ outputBox.text(JSON.stringify(data, null, 4))
98
+ outputBox.show()
99
+ },
100
+ error: function() {
101
+ // Errors which occurr aren't very well reported at the moment.
102
+ // They should be.
103
+ outputBox.show()
104
+ outputBox.text("Failed to make request.")
105
+ outputBox.addClass('tryForm__output--error').removeClass('tryForm__output--success')
106
+ }
107
+ })
108
+ return false
109
+ });
110
+
111
+ //
112
+ // Open the try form
113
+ //
114
+ $('p.tryFormActivate a').on('click', function() {
115
+ $form = $('form.tryForm')
116
+ $parent = $(this).parents('p')
117
+ $form.show('fast')
118
+ $parent.hide()
119
+ return false
120
+ });
121
+
122
+ //
123
+ // Close the try form
124
+ //
125
+ $('button.tryFormCancel').on('click', function() {
126
+ $form = $('form.tryForm')
127
+ $parent = $('p.tryFormActivate')
128
+ $form.hide()
129
+ $parent.show()
130
+ return false
131
+ });
132
+
133
+ // http://stackoverflow.com/questions/8100770/auto-scaling-inputtype-text-to-width-of-value
134
+ // http://jsfiddle.net/MqM76/217/
135
+ $.fn.textWidth = function(text, font) {
136
+ if (!$.fn.textWidth.fakeEl) $.fn.textWidth.fakeEl = $('<span>').hide().appendTo(document.body);
137
+ $.fn.textWidth.fakeEl.text(text || this.val() || this.text()).css('font', font || this.css('font'));
138
+ return $.fn.textWidth.fakeEl.width();
139
+ };
140
+
141
+ // Automatically ensure that the size for the header inputs is
142
+ // correct
143
+ function resizeInput() {
144
+ $this = $(this)
145
+ $this.css('width', $this.textWidth() + "px")
146
+ $this.attr('size', $this.val().length)
147
+ }
148
+
149
+ $('form.tryForm .tryForm__header input').on('input', resizeInput).trigger('input')
150
+
151
+ });
@@ -0,0 +1,191 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Authentication - 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="active">
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
+
47
+
48
+ <h1>Authentication</h1>
49
+
50
+
51
+ <p class='text'>
52
+ To authenticate to the API, you need to pass an appropriate API token with your
53
+ request. To find out how to obtain an API token, please refer to the Authentication
54
+ API documentaton which outlines the available methods available for this.
55
+
56
+ </p>
57
+
58
+ <h2>Authentication Headers</h2>
59
+ <p class='text'>
60
+ The following headers are used to identify yourself to the API client. These should be
61
+ sent as standard HTTP headers with any API request.
62
+ </p>
63
+ <table class='table paramTable'>
64
+ <thead>
65
+ <tr>
66
+ <th width="60%">Header</th>
67
+ <th width="40%">Example</th>
68
+ </tr>
69
+ </thead>
70
+
71
+ <tr>
72
+ <td>
73
+ <p>
74
+ <span class='paramTable__name'>X-Auth-Application</span>
75
+ </p>
76
+
77
+ <p class='paramTable__description'>The API application which is generated by us and provided to you.</p>
78
+
79
+ </td>
80
+ <td>abc123abc123abc123 </td>
81
+ </tr>
82
+
83
+ <tr>
84
+ <td>
85
+ <p>
86
+ <span class='paramTable__name'>X-Auth-Token</span>
87
+ </p>
88
+
89
+ <p class='paramTable__description'>The API token for the user you wish to authenticate as.</p>
90
+
91
+ </td>
92
+ <td>abc123abc123abc123 </td>
93
+ </tr>
94
+
95
+ </table>
96
+
97
+ <h2>Errors</h2>
98
+ <p class='text'>
99
+ The errors listed below may be raised if any issues occur when verifying your
100
+ identity with the API.
101
+ </p>
102
+
103
+ <table class='table errorsTable'>
104
+ <thead>
105
+ <tr>
106
+ <th width="60%">Error</th>
107
+ <th width="40%">Attributes</th>
108
+ </tr>
109
+ </thead>
110
+
111
+ <tr>
112
+ <td>
113
+ <p>
114
+ <span class='paramTable__name'>InvalidApplicationToken</span>
115
+
116
+ <p class='paramTable__description'>The application token provided in X-Auth-Application is not valid.</p>
117
+
118
+ </p>
119
+ </td>
120
+ <td>
121
+
122
+ <ul class='errorAttributeList'>
123
+
124
+ <li>
125
+ <p class='errorAttributeList__name'>token</p>
126
+ <p class='errorAttributeList__desc'>The token used to find the application</p>
127
+ </li>
128
+
129
+ </ul>
130
+
131
+ </td>
132
+ </tr>
133
+
134
+ <tr>
135
+ <td>
136
+ <p>
137
+ <span class='paramTable__name'>InvalidAuthToken</span>
138
+
139
+ <p class='paramTable__description'>The auth token provided in X-Auth-Token is not valid.</p>
140
+
141
+ </p>
142
+ </td>
143
+ <td>
144
+
145
+ <ul class='errorAttributeList'>
146
+
147
+ <li>
148
+ <p class='errorAttributeList__name'>token</p>
149
+ <p class='errorAttributeList__desc'>The token that was used</p>
150
+ </li>
151
+
152
+ </ul>
153
+
154
+ </td>
155
+ </tr>
156
+
157
+ <tr>
158
+ <td>
159
+ <p>
160
+ <span class='paramTable__name'>ExpiredAuthToken</span>
161
+
162
+ <p class='paramTable__description'>The auth token provided in X-Auth-Token has expired.</p>
163
+
164
+ </p>
165
+ </td>
166
+ <td>
167
+
168
+ <ul class='errorAttributeList'>
169
+
170
+ <li>
171
+ <p class='errorAttributeList__name'>expired_at</p>
172
+ <p class='errorAttributeList__desc'>The time the token expired</p>
173
+ </li>
174
+
175
+ </ul>
176
+
177
+ </td>
178
+ </tr>
179
+
180
+ </table>
181
+
182
+
183
+
184
+ </section>
185
+ <footer class='footer'>
186
+ <p>Generated by Moonrope at 12:43 on Monday 22 February 2016 for d3c499</p>
187
+ </footer>
188
+ <script src='https://code.jquery.com/jquery-1.12.0.min.js'></script>
189
+ <script src='../assets/try.js'></script>
190
+ </body>
191
+ </html>
@@ -0,0 +1,144 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>version - Meta API - 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="active">
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
+
47
+ <h1>version</h1>
48
+
49
+ <p class='text'>Return the current software version</p>
50
+
51
+
52
+ <p class='tryFormActivate'><a class='tryFormActivate__button' href='#'>Try this request in your browser</a></p>
53
+ <form class='tryForm'>
54
+ <input type='hidden' name='controller' value='meta'>
55
+ <input type='hidden' name='action' value='version'>
56
+ <div class='tryForm__header'>
57
+ <input type='text' id='host' name='host' value=''>
58
+ /api/
59
+ <input type='text' id='version' name='version' value='v1' class='v'>
60
+ /meta/version
61
+ </div>
62
+
63
+
64
+ <p class='tryForm__heading'>Headers</p>
65
+ <table class='tryForm__table'>
66
+
67
+ <tr>
68
+ <td width="50%"><code>X-Auth-Application</code></td>
69
+ <td width="50%"><input type='text' class='tryForm__tableField headerField' name='X-Auth-Application'></td>
70
+ </tr>
71
+
72
+ <tr>
73
+ <td width="50%"><code>X-Auth-Token</code></td>
74
+ <td width="50%"><input type='text' class='tryForm__tableField headerField' name='X-Auth-Token'></td>
75
+ </tr>
76
+
77
+ </table>
78
+
79
+
80
+
81
+
82
+
83
+
84
+ <p class='tryForm__button'>
85
+ <button class='tryForm__buttonLink' type='submit'>Make this request</button>
86
+ <button class='tryForm__buttonLink tryFormCancel' type='button'>Cancel</button>
87
+ </p>
88
+
89
+ <pre class='tryForm__output'>The request output will be shown here...</pre>
90
+ </form>
91
+
92
+
93
+
94
+
95
+ <h2>URL</h2>
96
+ <p class='apiURLFull'><span>/api/v1/</span>meta/version</p>
97
+
98
+
99
+
100
+
101
+ <h2>Access</h2>
102
+ <p class='text'>
103
+ Must be authenticated with a valid user API token.
104
+
105
+ If not authorised, a <code>NotAuthenticated</code> error will be returned.
106
+
107
+ </p>
108
+
109
+
110
+
111
+
112
+ <h2>Parameters</h2>
113
+
114
+ <p><em>This action doesn't support any parameters.</em></p>
115
+
116
+
117
+
118
+
119
+ <h2>Errors</h2>
120
+
121
+
122
+ <p><em>There are no action-specific errors which can be raised.</em></p>
123
+
124
+
125
+
126
+ <h2>Response Data</h2>
127
+
128
+ <p class='text'>
129
+ This action will return a String.
130
+ </p>
131
+
132
+ <pre class='code'>v1.2.3</pre>
133
+
134
+
135
+
136
+
137
+ </section>
138
+ <footer class='footer'>
139
+ <p>Generated by Moonrope at 12:43 on Monday 22 February 2016 for d3c499</p>
140
+ </footer>
141
+ <script src='https://code.jquery.com/jquery-1.12.0.min.js'></script>
142
+ <script src='../../assets/try.js'></script>
143
+ </body>
144
+ </html>
@@ -0,0 +1,73 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <title>Meta API - 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="active">
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>Meta API</h1>
47
+
48
+ <p class='text'> The meta API provides you with access to information about the API itself.
49
+ </p>
50
+
51
+ <h2>Action</h2>
52
+ <p class='text'>
53
+ The following actions are available. Choose from the list below
54
+ to view full details of how to access them.
55
+ </p>
56
+ <ul class='standardList'>
57
+
58
+ <li>
59
+ <a class='link' href='../controllers/meta/version.html'>version</a>
60
+ <p class='apiURL'><span>/api/v1/</span><b>meta/version</b></p>
61
+ <p class='meta'>Return the current software version</p>
62
+ </li>
63
+
64
+ </ul>
65
+
66
+ </section>
67
+ <footer class='footer'>
68
+ <p>Generated by Moonrope at 12:43 on Monday 22 February 2016 for d3c499</p>
69
+ </footer>
70
+ <script src='https://code.jquery.com/jquery-1.12.0.min.js'></script>
71
+ <script src='../assets/try.js'></script>
72
+ </body>
73
+ </html>