the_garage 2.6.1 → 2.8.1
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.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/app/assets/javascripts/garage/docs/console.js +103 -0
- data/app/controllers/garage/docs/resources_controller.rb +1 -1
- data/lib/garage/docs/engine.rb +1 -2
- data/lib/garage/restful_actions.rb +6 -1
- data/lib/garage/strategy/access_token.rb +2 -1
- data/lib/garage/strategy/auth_server.rb +16 -4
- data/lib/garage/version.rb +1 -1
- metadata +9 -37
- data/app/assets/javascripts/garage/docs/console.js.coffee +0 -84
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b48c2510bfd1fe5926e9fdd4adac78374bb9ed83b46db0b9202e1b6028645974
|
|
4
|
+
data.tar.gz: 1d92f344d618e25f1eef2d7e7778edaa4f3e2a0e1f236a19d476b19a893fc012
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 063d9f1cdf9744ec2fb4d18f6697e44f390bccc259a8c4ff36839992732e4578916ef1691949c8dc8f67872de161bd97e12c049dbd69b81fd5b5e599c8f4faae
|
|
7
|
+
data.tar.gz: e76b35e33c9332afbe6ff7b16ec6b96c23e41c9bd85605e58e2532729e4389ca6090599a32ad67c9e45d8e6c03fade453d8d3e861f87445be45ae30c0b5f53cb
|
data/README.md
CHANGED
|
@@ -153,7 +153,7 @@ Then configure auth server strategy:
|
|
|
153
153
|
|
|
154
154
|
The OAuth server must response a json with following structure.
|
|
155
155
|
|
|
156
|
-
- `token`(string) - OAuth access token value.
|
|
156
|
+
- `token` (string, null) - OAuth access token value.
|
|
157
157
|
- `token_type` (string) - OAuth access token value. i.e. `bearer` type.
|
|
158
158
|
- `scope` (string) - OAuth scopes separated by spaces. i.e. `public read_user`.
|
|
159
159
|
- `application_id` (integer) - OAuth application id of the access token.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
jQuery(function(){
|
|
2
|
+
$(".get-oauth-token").colorbox({
|
|
3
|
+
transition: "none",
|
|
4
|
+
href: "#oauth-dialog",
|
|
5
|
+
inline: true
|
|
6
|
+
});
|
|
7
|
+
|
|
8
|
+
$(".modal-close").click(function(ev) {
|
|
9
|
+
$.colorbox.close();
|
|
10
|
+
ev.preventDefault();
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
var addNewParamField = function(container) {
|
|
14
|
+
const nextId = "parameter-" + $('.parameter', container).length;
|
|
15
|
+
const copy = $('.template .parameter').clone().attr('id', nextId);
|
|
16
|
+
$('.close-field', copy).click(ev => $('#' + nextId).detach());
|
|
17
|
+
$('.add-field', copy).click(ev => addNewParamField(container));
|
|
18
|
+
copy.show().appendTo(container);
|
|
19
|
+
};
|
|
20
|
+
|
|
21
|
+
const buildData = function(container) {
|
|
22
|
+
const data = {};
|
|
23
|
+
$('.parameter', container).each(function(index) {
|
|
24
|
+
const name = $('.name', this).val();
|
|
25
|
+
const value = $('.value', this).val();
|
|
26
|
+
return data[name] = value;
|
|
27
|
+
});
|
|
28
|
+
return data;
|
|
29
|
+
};
|
|
30
|
+
|
|
31
|
+
$('.console #method').change(function(ev) {
|
|
32
|
+
if (($(this).val() === 'POST') || ($(this).val() === 'PUT')) {
|
|
33
|
+
if ($('.parameters .parameter').length === 0) {
|
|
34
|
+
addNewParamField($('.parameters'));
|
|
35
|
+
}
|
|
36
|
+
} else {
|
|
37
|
+
$('.parameters').empty();
|
|
38
|
+
}
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
const buildHyperlinks = function(json) {
|
|
42
|
+
const html = $('<div/>').text(json).html().replace(/"href": "(\/.*?)"/g, "\"href\": \"<a>$1</a>\"");
|
|
43
|
+
const dom = $(`<div>${html}</div>`);
|
|
44
|
+
$('a', dom).each(function(i) {
|
|
45
|
+
return $(this).attr('href', `${location.pathname}?location=${encodeURIComponent($(this).text())}&method=GET`);
|
|
46
|
+
});
|
|
47
|
+
return dom.html();
|
|
48
|
+
};
|
|
49
|
+
|
|
50
|
+
$('.console .send-request').click(function(ev) {
|
|
51
|
+
$('#api-headers').text('');
|
|
52
|
+
$('#api-response').text('');
|
|
53
|
+
|
|
54
|
+
console.log(buildData($('.parameters')));
|
|
55
|
+
$.ajax({
|
|
56
|
+
type: $('#method').val(),
|
|
57
|
+
url: $('#base').val() + $('#location').val(),
|
|
58
|
+
headers: {'Authorization': 'Bearer ' + $('#access_token').val()},
|
|
59
|
+
cache: false,
|
|
60
|
+
data: buildData($('.parameters')),
|
|
61
|
+
dataType: 'json',
|
|
62
|
+
complete() {
|
|
63
|
+
const queryString = $.param({'location': $('#location').val(), 'method': $('#method').val()});
|
|
64
|
+
const newFullpath = `${location.pathname}?${queryString}`;
|
|
65
|
+
history.pushState('', '', newFullpath);
|
|
66
|
+
$("#oauth-dialog #return_to").val(newFullpath);
|
|
67
|
+
},
|
|
68
|
+
success(data, textStatus, xhr) {
|
|
69
|
+
$('#api-headers').text(`${xhr.status} ${xhr.statusText}\n` + xhr.getAllResponseHeaders());
|
|
70
|
+
$('#api-response').html(buildHyperlinks(JSON.stringify(data, undefined, 2)));
|
|
71
|
+
},
|
|
72
|
+
error(xhr, textStatus, error) {
|
|
73
|
+
$('#api-headers').text(`${xhr.status} ${xhr.statusText}\n` + xhr.getAllResponseHeaders());
|
|
74
|
+
$('#api-response').text(xhr.responseText);
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
ev.preventDefault();
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
if (($('.console #token').val() !== '') && ($('.console #location').val() !== '') && ($('.console #method').val() === 'GET')) {
|
|
81
|
+
$('.send-request').click();
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if ($('.oauth-callback-redirect').size() > 0) {
|
|
85
|
+
const token = window.location.hash.match(/\#access_token=(\w+)/)[1];
|
|
86
|
+
if (token) {
|
|
87
|
+
$('#access_token').val(token);
|
|
88
|
+
$('form.oauth-callback-redirect').submit();
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
$('#oauth-dialog .token-scope-check-all').click(function(ev) {
|
|
93
|
+
$('.token-scope-checkbox').prop('checked', this.checked);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
return $('#oauth-dialog .token-scope-checkbox').click(function(ev) {
|
|
97
|
+
if ($('.token-scope-checkbox:not(:checked)').length === 0) {
|
|
98
|
+
$('.token-scope-check-all').prop('checked', true);
|
|
99
|
+
} else if (!this.checked) {
|
|
100
|
+
$('.token-scope-check-all').prop('checked', false);
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
});
|
|
@@ -86,7 +86,7 @@ class Garage::Docs::ResourcesController < Garage::ApplicationController
|
|
|
86
86
|
def require_console_application
|
|
87
87
|
@app = console_application
|
|
88
88
|
if @app[:uid].blank? || @app[:secret].blank?
|
|
89
|
-
render(
|
|
89
|
+
render(plain: 'Configuration for console application is missing.', status: :forbidden)
|
|
90
90
|
end
|
|
91
91
|
end
|
|
92
92
|
|
data/lib/garage/docs/engine.rb
CHANGED
|
@@ -228,7 +228,12 @@ module Garage
|
|
|
228
228
|
end
|
|
229
229
|
|
|
230
230
|
def location
|
|
231
|
-
|
|
231
|
+
if @resource.try(:respond_to?, :id)
|
|
232
|
+
hash = { action: :show, id: @resource.id }
|
|
233
|
+
url_for(hash)
|
|
234
|
+
hash
|
|
235
|
+
end
|
|
236
|
+
rescue ActionController::UrlGenerationError
|
|
232
237
|
end
|
|
233
238
|
end
|
|
234
239
|
end
|
|
@@ -58,10 +58,8 @@ module Garage
|
|
|
58
58
|
|
|
59
59
|
def fetch
|
|
60
60
|
if has_any_valid_credentials?
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
else
|
|
64
|
-
fetch_without_cache
|
|
61
|
+
fetch_access_token&.tap do |access_token|
|
|
62
|
+
access_token.token ||= token_string
|
|
65
63
|
end
|
|
66
64
|
else
|
|
67
65
|
nil
|
|
@@ -144,6 +142,14 @@ module Garage
|
|
|
144
142
|
@bearer_token ||= @request.authorization.try {|o| o.slice(/\ABearer\s+(.+)\z/, 1) }
|
|
145
143
|
end
|
|
146
144
|
|
|
145
|
+
def fetch_access_token
|
|
146
|
+
if has_cacheable_credentials?
|
|
147
|
+
fetch_with_cache
|
|
148
|
+
else
|
|
149
|
+
fetch_without_cache
|
|
150
|
+
end
|
|
151
|
+
end
|
|
152
|
+
|
|
147
153
|
def fetch_with_cache
|
|
148
154
|
Cache.with_cache("garage_gem/token_cache/#{Garage::VERSION}/#{bearer_token}") do
|
|
149
155
|
fetch_without_cache
|
|
@@ -162,6 +168,12 @@ module Garage
|
|
|
162
168
|
end
|
|
163
169
|
end
|
|
164
170
|
end
|
|
171
|
+
|
|
172
|
+
def token_string
|
|
173
|
+
bearer_token.presence ||
|
|
174
|
+
@request.params[:access_token].presence ||
|
|
175
|
+
@request.params[:bearer_token].presence
|
|
176
|
+
end
|
|
165
177
|
end
|
|
166
178
|
|
|
167
179
|
class Response
|
data/lib/garage/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: the_garage
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 2.
|
|
4
|
+
version: 2.8.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Tatsuhiko Miyagawa
|
|
8
|
-
autorequire:
|
|
8
|
+
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date:
|
|
11
|
+
date: 2022-04-05 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: rails
|
|
@@ -16,14 +16,14 @@ dependencies:
|
|
|
16
16
|
requirements:
|
|
17
17
|
- - ">="
|
|
18
18
|
- !ruby/object:Gem::Version
|
|
19
|
-
version: 4.
|
|
19
|
+
version: 4.2.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: 4.
|
|
26
|
+
version: 4.2.0
|
|
27
27
|
- !ruby/object:Gem::Dependency
|
|
28
28
|
name: rack-accept-default
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -123,21 +123,7 @@ dependencies:
|
|
|
123
123
|
- !ruby/object:Gem::Version
|
|
124
124
|
version: '0'
|
|
125
125
|
- !ruby/object:Gem::Dependency
|
|
126
|
-
name:
|
|
127
|
-
requirement: !ruby/object:Gem::Requirement
|
|
128
|
-
requirements:
|
|
129
|
-
- - ">="
|
|
130
|
-
- !ruby/object:Gem::Version
|
|
131
|
-
version: '0'
|
|
132
|
-
type: :runtime
|
|
133
|
-
prerelease: false
|
|
134
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
-
requirements:
|
|
136
|
-
- - ">="
|
|
137
|
-
- !ruby/object:Gem::Version
|
|
138
|
-
version: '0'
|
|
139
|
-
- !ruby/object:Gem::Dependency
|
|
140
|
-
name: coffee-rails
|
|
126
|
+
name: sassc-rails
|
|
141
127
|
requirement: !ruby/object:Gem::Requirement
|
|
142
128
|
requirements:
|
|
143
129
|
- - ">="
|
|
@@ -164,20 +150,6 @@ dependencies:
|
|
|
164
150
|
- - ">="
|
|
165
151
|
- !ruby/object:Gem::Version
|
|
166
152
|
version: 2.0.0
|
|
167
|
-
- !ruby/object:Gem::Dependency
|
|
168
|
-
name: appraisal
|
|
169
|
-
requirement: !ruby/object:Gem::Requirement
|
|
170
|
-
requirements:
|
|
171
|
-
- - ">="
|
|
172
|
-
- !ruby/object:Gem::Version
|
|
173
|
-
version: '0'
|
|
174
|
-
type: :development
|
|
175
|
-
prerelease: false
|
|
176
|
-
version_requirements: !ruby/object:Gem::Requirement
|
|
177
|
-
requirements:
|
|
178
|
-
- - ">="
|
|
179
|
-
- !ruby/object:Gem::Version
|
|
180
|
-
version: '0'
|
|
181
153
|
description: Garage extends your RESTful, Hypermedia APIs as a Platform
|
|
182
154
|
email:
|
|
183
155
|
- miyagawa@bulknews.net
|
|
@@ -189,7 +161,7 @@ files:
|
|
|
189
161
|
- README.md
|
|
190
162
|
- Rakefile
|
|
191
163
|
- app/assets/javascripts/garage/application.js
|
|
192
|
-
- app/assets/javascripts/garage/docs/console.js
|
|
164
|
+
- app/assets/javascripts/garage/docs/console.js
|
|
193
165
|
- app/assets/javascripts/garage/docs/jquery.colorbox.js
|
|
194
166
|
- app/assets/stylesheets/garage/application.css
|
|
195
167
|
- app/assets/stylesheets/garage/colorbox.scss
|
|
@@ -255,7 +227,7 @@ homepage: https://github.com/cookpad/garage
|
|
|
255
227
|
licenses:
|
|
256
228
|
- MIT
|
|
257
229
|
metadata: {}
|
|
258
|
-
post_install_message:
|
|
230
|
+
post_install_message:
|
|
259
231
|
rdoc_options: []
|
|
260
232
|
require_paths:
|
|
261
233
|
- lib
|
|
@@ -271,7 +243,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
271
243
|
version: '0'
|
|
272
244
|
requirements: []
|
|
273
245
|
rubygems_version: 3.1.4
|
|
274
|
-
signing_key:
|
|
246
|
+
signing_key:
|
|
275
247
|
specification_version: 4
|
|
276
248
|
summary: Garage Platform Engine
|
|
277
249
|
test_files: []
|
|
@@ -1,84 +0,0 @@
|
|
|
1
|
-
jQuery ()->
|
|
2
|
-
$(".get-oauth-token").colorbox(
|
|
3
|
-
transition: "none"
|
|
4
|
-
href: "#oauth-dialog"
|
|
5
|
-
inline: true
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
$(".modal-close").click (ev) ->
|
|
9
|
-
$.colorbox.close()
|
|
10
|
-
ev.preventDefault()
|
|
11
|
-
|
|
12
|
-
addNewParamField = (container) ->
|
|
13
|
-
nextId = "parameter-" + $('.parameter', container).length
|
|
14
|
-
copy = $('.template .parameter').clone().attr('id', nextId)
|
|
15
|
-
$('.close-field', copy).click (ev) ->
|
|
16
|
-
$('#' + nextId).detach()
|
|
17
|
-
$('.add-field', copy).click (ev) ->
|
|
18
|
-
addNewParamField(container)
|
|
19
|
-
copy.show().appendTo(container)
|
|
20
|
-
|
|
21
|
-
buildData = (container) ->
|
|
22
|
-
data = {}
|
|
23
|
-
$('.parameter', container).each (index) ->
|
|
24
|
-
name = $('.name', this).val()
|
|
25
|
-
value = $('.value', this).val()
|
|
26
|
-
data[name] = value
|
|
27
|
-
data
|
|
28
|
-
|
|
29
|
-
$('.console #method').change (ev) ->
|
|
30
|
-
if $(this).val() == 'POST' or $(this).val() == 'PUT'
|
|
31
|
-
if $('.parameters .parameter').length == 0
|
|
32
|
-
addNewParamField($('.parameters'))
|
|
33
|
-
else
|
|
34
|
-
$('.parameters').empty()
|
|
35
|
-
|
|
36
|
-
buildHyperlinks = (json) ->
|
|
37
|
-
html = $('<div/>').text(json).html().replace /"href": "(\/.*?)"/g, "\"href\": \"<a>$1</a>\""
|
|
38
|
-
dom = $("<div>#{html}</div>")
|
|
39
|
-
$('a', dom).each (i) ->
|
|
40
|
-
$(this).attr('href', "#{location.pathname}?location=#{encodeURIComponent($(this).text())}&method=GET")
|
|
41
|
-
dom.html()
|
|
42
|
-
|
|
43
|
-
$('.console .send-request').click (ev) ->
|
|
44
|
-
$('#api-headers').text ''
|
|
45
|
-
$('#api-response').text ''
|
|
46
|
-
|
|
47
|
-
console.log buildData($('.parameters'))
|
|
48
|
-
$.ajax
|
|
49
|
-
type: $('#method').val(),
|
|
50
|
-
url: $('#base').val() + $('#location').val(),
|
|
51
|
-
headers: {'Authorization': 'Bearer ' + $('#access_token').val()},
|
|
52
|
-
cache: false,
|
|
53
|
-
data: buildData($('.parameters')),
|
|
54
|
-
dataType: 'json',
|
|
55
|
-
complete: ->
|
|
56
|
-
queryString = $.param({'location': $('#location').val(), 'method': $('#method').val()})
|
|
57
|
-
newFullpath = "#{location.pathname}?#{queryString}"
|
|
58
|
-
history.pushState('', '', newFullpath)
|
|
59
|
-
$("#oauth-dialog #return_to").val(newFullpath)
|
|
60
|
-
success: (data, textStatus, xhr) ->
|
|
61
|
-
$('#api-headers').text("#{xhr.status} #{xhr.statusText}\n" + xhr.getAllResponseHeaders())
|
|
62
|
-
$('#api-response').html buildHyperlinks(JSON.stringify(data, undefined, 2))
|
|
63
|
-
error: (xhr, textStatus, error) ->
|
|
64
|
-
$('#api-headers').text("#{xhr.status} #{xhr.statusText}\n" + xhr.getAllResponseHeaders())
|
|
65
|
-
$('#api-response').text xhr.responseText
|
|
66
|
-
ev.preventDefault()
|
|
67
|
-
|
|
68
|
-
if $('.console #token').val() != '' && $('.console #location').val() != '' && $('.console #method').val() == 'GET'
|
|
69
|
-
$('.send-request').click()
|
|
70
|
-
|
|
71
|
-
if $('.oauth-callback-redirect').size() > 0
|
|
72
|
-
token = window.location.hash.match(/\#access_token=(\w+)/)[1]
|
|
73
|
-
if token
|
|
74
|
-
$('#access_token').val(token)
|
|
75
|
-
$('form.oauth-callback-redirect').submit()
|
|
76
|
-
|
|
77
|
-
$('#oauth-dialog .token-scope-check-all').click (ev) ->
|
|
78
|
-
$('.token-scope-checkbox').prop('checked', this.checked)
|
|
79
|
-
|
|
80
|
-
$('#oauth-dialog .token-scope-checkbox').click (ev) ->
|
|
81
|
-
if $('.token-scope-checkbox:not(:checked)').length == 0
|
|
82
|
-
$('.token-scope-check-all').prop('checked', true)
|
|
83
|
-
else if not this.checked
|
|
84
|
-
$('.token-scope-check-all').prop('checked', false)
|