browse-everything 1.6.0 → 1.6.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
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: faa729e0e6ae6d2ae76c0c9364b44017d689bbb89153b3c1e98bde8c17fa1427
|
|
4
|
+
data.tar.gz: 7a29fe7df1a1dd5bdd309e23e4edc22af28d3fb618bceaf01d852537d37fdb3b
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 4a97f843dafad43ddb8a58cf30f663d586dcdecaec0ba1fde64f38c2189c6a3c731d9fd0e1c9c39437ce63f8ad294ded4befac02d651b9de2063eedf3b13311b
|
|
7
|
+
data.tar.gz: 487830c4ba65dbd1810774a87fef7ecd4202e805a4153bbfdb4c333e9c833afdcfaab24de26e285c198e2bc29d1ea944f387bf1011cb21c76e697da88a23e2d3
|
data/Gemfile
CHANGED
|
@@ -25,6 +25,12 @@ end
|
|
|
25
25
|
|
|
26
26
|
ENV['RAILS_VERSION'] ||= "8.0.0"
|
|
27
27
|
|
|
28
|
+
# json 3 dropped the quirks_mode option that ActiveSupport before 8.1 passes
|
|
29
|
+
# when encoding, so Hash#to_json raises ArgumentError under it.
|
|
30
|
+
if ENV['RAILS_VERSION'] != 'edge' && Gem::Version.new(ENV['RAILS_VERSION']) < Gem::Version.new('8.1')
|
|
31
|
+
gem 'json', '< 3'
|
|
32
|
+
end
|
|
33
|
+
|
|
28
34
|
if ENV['RAILS_VERSION']
|
|
29
35
|
if ENV['RAILS_VERSION'] == 'edge'
|
|
30
36
|
gem 'rails', github: 'rails/rails'
|
|
@@ -323,7 +323,12 @@ $(function () {
|
|
|
323
323
|
|
|
324
324
|
$(document).on('click', 'button.ev-submit', function (event) {
|
|
325
325
|
event.preventDefault();
|
|
326
|
-
|
|
326
|
+
// button('loading') is Bootstrap 3's button plugin. When jQuery UI's
|
|
327
|
+
// button widget owns $.fn.button instead, it throws on the call and the
|
|
328
|
+
// selection is never submitted. startWait() disables the button either way.
|
|
329
|
+
if ($.fn.button && $.fn.button.Constructor) {
|
|
330
|
+
$(this).button('loading');
|
|
331
|
+
}
|
|
327
332
|
startWait();
|
|
328
333
|
$('form.ev-submit-form').append(Array.from(selected_files.values()));
|
|
329
334
|
var main_form = $(this).closest('form');
|
|
@@ -55,17 +55,19 @@ module BrowseEverything
|
|
|
55
55
|
def link_for(path)
|
|
56
56
|
obj = bucket.object(full_path(path))
|
|
57
57
|
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
expires: (config[:expires_in] if config[:response_type] == :signed_url)
|
|
61
|
-
}.compact
|
|
62
|
-
|
|
63
|
-
url = case config[:response_type].to_sym
|
|
58
|
+
response_type = config[:response_type].to_sym
|
|
59
|
+
url = case response_type
|
|
64
60
|
when :signed_url then obj.presigned_url(:get, expires_in: config[:expires_in])
|
|
65
61
|
when :public_url then obj.public_url
|
|
66
62
|
when :s3_uri then "s3://#{obj.bucket_name}/#{obj.key}"
|
|
67
63
|
end
|
|
68
64
|
|
|
65
|
+
extras = {
|
|
66
|
+
file_name: File.basename(path),
|
|
67
|
+
file_size: object_size(obj),
|
|
68
|
+
expires: (signed_url_expiry(url) if response_type == :signed_url)
|
|
69
|
+
}.compact
|
|
70
|
+
|
|
69
71
|
[url, extras]
|
|
70
72
|
end
|
|
71
73
|
|
|
@@ -79,6 +81,26 @@ module BrowseEverything
|
|
|
79
81
|
|
|
80
82
|
private
|
|
81
83
|
|
|
84
|
+
# The size is a convenience for consumers, so credentials that can list
|
|
85
|
+
# but not read an object (enough for an :s3_uri link) leave it out
|
|
86
|
+
# rather than fail the link.
|
|
87
|
+
def object_size(obj)
|
|
88
|
+
obj.content_length
|
|
89
|
+
rescue Aws::S3::Errors::ServiceError, Seahorse::Client::NetworkingError
|
|
90
|
+
nil
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# Retriever#retrieve parses `expires` as a time, so send when the link
|
|
94
|
+
# expires, as the Box and Google Drive drivers do. It is read from the
|
|
95
|
+
# signed URL itself because the SDK can sign for less than expires_in,
|
|
96
|
+
# for example when the signing credentials are temporary.
|
|
97
|
+
def signed_url_expiry(url)
|
|
98
|
+
params = Rack::Utils.parse_query(URI(url).query)
|
|
99
|
+
return unless params['X-Amz-Date'] && params['X-Amz-Expires']
|
|
100
|
+
|
|
101
|
+
Time.strptime(params['X-Amz-Date'], '%Y%m%dT%H%M%S%z') + params['X-Amz-Expires'].to_i
|
|
102
|
+
end
|
|
103
|
+
|
|
82
104
|
def strip(path)
|
|
83
105
|
path.sub %r{^/?(.+?)/?$}, '\1'
|
|
84
106
|
end
|
|
@@ -134,28 +134,68 @@ describe BrowseEverything::Driver::S3 do
|
|
|
134
134
|
context 'when retrieving the link for an asset' do
|
|
135
135
|
subject { contents[2] }
|
|
136
136
|
|
|
137
|
+
let(:signed_at) { Time.now.utc.change(usec: 0) }
|
|
138
|
+
let(:presigned_url) do
|
|
139
|
+
"https://s3.amazonaws.com/presigned_url?X-Amz-Date=#{signed_at.strftime('%Y%m%dT%H%M%SZ')}&X-Amz-Expires=3600"
|
|
140
|
+
end
|
|
141
|
+
|
|
137
142
|
before do
|
|
138
143
|
object = instance_double(Aws::S3::Object)
|
|
139
|
-
allow(object).to receive(:presigned_url).and_return(
|
|
144
|
+
allow(object).to receive(:presigned_url).and_return(presigned_url)
|
|
140
145
|
allow(object).to receive(:public_url).and_return('https://s3.amazonaws.com/public_url')
|
|
141
146
|
allow(object).to receive(:bucket_name).and_return('s3.bucket')
|
|
142
147
|
allow(object).to receive(:key).and_return('foo/quux.png')
|
|
148
|
+
allow(object).to receive(:content_length).and_return(1_511_860)
|
|
143
149
|
allow(provider.bucket).to receive(:object).and_return(object)
|
|
144
150
|
end
|
|
145
151
|
|
|
146
152
|
it ':signed_url' do
|
|
147
153
|
provider.config[:response_type] = :signed_url
|
|
148
|
-
expect(provider.link_for('foo/quux.png')).to eq [
|
|
154
|
+
expect(provider.link_for('foo/quux.png')).to eq [presigned_url, { file_name: 'quux.png', file_size: 1_511_860, expires: signed_at + 3600 }]
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
it ':signed_url reports the lifetime the URL was signed for, not expires_in' do
|
|
158
|
+
provider.config[:response_type] = :signed_url
|
|
159
|
+
provider.config[:expires_in] = 14400
|
|
160
|
+
expect(provider.link_for('foo/quux.png').last[:expires]).to eq signed_at + 3600
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
it ':signed_url configured as a string still sends the expiry' do
|
|
164
|
+
provider.config[:response_type] = 'signed_url'
|
|
165
|
+
expect(provider.link_for('foo/quux.png').last[:expires]).to eq signed_at + 3600
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
[Aws::S3::Errors::Forbidden.new(nil, 'Forbidden'), Seahorse::Client::NetworkingError.new(Errno::ECONNRESET.new)].each do |error|
|
|
169
|
+
it "leaves out the size when reading it raises #{error.class}" do
|
|
170
|
+
provider.config[:response_type] = :s3_uri
|
|
171
|
+
allow(provider.bucket.object('foo/quux.png')).to receive(:content_length).and_raise(error)
|
|
172
|
+
expect(provider.link_for('foo/quux.png')).to eq ['s3://s3.bucket/foo/quux.png', { file_name: 'quux.png' }]
|
|
173
|
+
end
|
|
174
|
+
end
|
|
175
|
+
|
|
176
|
+
it ':s3_uri keeps a key that is not a valid URI' do
|
|
177
|
+
provider.config[:response_type] = :s3_uri
|
|
178
|
+
allow(provider.bucket.object('foo/quux.png')).to receive(:key).and_return('foo/résumé file.pdf')
|
|
179
|
+
expect(provider.link_for('foo/quux.png').first).to eq 's3://s3.bucket/foo/résumé file.pdf'
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
it ':signed_url gives an expiry the retriever accepts' do
|
|
183
|
+
provider.config[:response_type] = :signed_url
|
|
184
|
+
url, extras = provider.link_for('foo/quux.png')
|
|
185
|
+
spec = { 'url' => url, 'expires' => extras[:expires].to_s, 'file_size' => extras[:file_size] }
|
|
186
|
+
retriever = BrowseEverything::Retriever.new
|
|
187
|
+
allow(retriever).to receive(:retrieve_http)
|
|
188
|
+
expect { retriever.retrieve(spec) }.not_to raise_error
|
|
149
189
|
end
|
|
150
190
|
|
|
151
191
|
it ':public_url' do
|
|
152
192
|
provider.config[:response_type] = :public_url
|
|
153
|
-
expect(provider.link_for('foo/quux.png')).to eq ['https://s3.amazonaws.com/public_url', { file_name: 'quux.png' }]
|
|
193
|
+
expect(provider.link_for('foo/quux.png')).to eq ['https://s3.amazonaws.com/public_url', { file_name: 'quux.png', file_size: 1_511_860 }]
|
|
154
194
|
end
|
|
155
195
|
|
|
156
196
|
it ':s3_uri' do
|
|
157
197
|
provider.config[:response_type] = :s3_uri
|
|
158
|
-
expect(provider.link_for('foo/quux.png')).to eq ['s3://s3.bucket/foo/quux.png', { file_name: 'quux.png' }]
|
|
198
|
+
expect(provider.link_for('foo/quux.png')).to eq ['s3://s3.bucket/foo/quux.png', { file_name: 'quux.png', file_size: 1_511_860 }]
|
|
159
199
|
end
|
|
160
200
|
end
|
|
161
201
|
end
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: browse-everything
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 1.6.
|
|
4
|
+
version: 1.6.1
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Carolyn Cole
|
|
@@ -629,7 +629,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
629
629
|
- !ruby/object:Gem::Version
|
|
630
630
|
version: '0'
|
|
631
631
|
requirements: []
|
|
632
|
-
rubygems_version:
|
|
632
|
+
rubygems_version: 4.0.22
|
|
633
633
|
specification_version: 4
|
|
634
634
|
summary: AJAX/Rails engine file browser for cloud storage services
|
|
635
635
|
test_files:
|