carrierwave-aws 1.0.0.pre.rc.1 → 1.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.
- checksums.yaml +4 -4
- data/.travis.yml +8 -3
- data/CHANGELOG.md +7 -0
- data/README.md +4 -0
- data/Rakefile +10 -1
- data/carrierwave-aws.gemspec +1 -1
- data/lib/carrierwave-aws.rb +57 -1
- data/lib/carrierwave/aws/version.rb +1 -1
- data/lib/carrierwave/storage/aws_file.rb +11 -1
- data/spec/carrierwave-aws_spec.rb +130 -3
- data/spec/carrierwave/storage/aws_file_spec.rb +11 -0
- data/spec/features/storing_files_spec.rb +4 -0
- data/spec/spec_helper.rb +2 -2
- metadata +7 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0daf2d106b4a0d27f423cfbaa8745fa019d5f840
|
4
|
+
data.tar.gz: 2213c9acca949bd4d1608a0fd08cbd96ed12b64b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: fa5b275f21820fb4fed97d1cd183a3f1ae909de304e1dd6616d64d4a047fa9d285b340a66fea9ad4a720df9ee6bf8e2ee3eb485277d58974fb22cde1b185ec7b
|
7
|
+
data.tar.gz: abffdcdca5ee8d72c7daf90f4e6fc9ee18df1b3c30cc4e0a4e692214ea02b851254449364155b1b020f4a205e3f1f6ea20cb20bef6f264cb92318ffa803ff9f2
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
## Version 1.0.0 2015-09-18
|
2
|
+
|
3
|
+
* Added: ACL options are verified when they are set, and coerced into usable
|
4
|
+
values when possible.
|
5
|
+
* Added: Specify an `aws_signer` lambda for use signing authenticated content
|
6
|
+
served through services like CloudFront.
|
7
|
+
|
1
8
|
## Version 1.0.0-rc.1 2015-07-02
|
2
9
|
|
3
10
|
* Continues where 0.6.0 left off. This wraps AWS-SDK v2 and all of the breaking
|
data/README.md
CHANGED
@@ -58,6 +58,10 @@ CarrierWave.configure do |config|
|
|
58
58
|
secret_access_key: ENV.fetch('AWS_SECRET_ACCESS_KEY'),
|
59
59
|
region: ENV.fetch('AWS_REGION') # Required
|
60
60
|
}
|
61
|
+
|
62
|
+
# Optional: Signing of download urls, e.g. for serving private
|
63
|
+
# content through CloudFront.
|
64
|
+
config.aws_signer = -> (unsigned_url, options) { Aws::CF::Signer.sign_url unsigned_url, options }
|
61
65
|
end
|
62
66
|
```
|
63
67
|
|
data/Rakefile
CHANGED
data/carrierwave-aws.gemspec
CHANGED
data/lib/carrierwave-aws.rb
CHANGED
@@ -6,15 +6,71 @@ require 'carrierwave/storage/aws_options'
|
|
6
6
|
require 'carrierwave/support/uri_filename'
|
7
7
|
|
8
8
|
class CarrierWave::Uploader::Base
|
9
|
+
ACCEPTED_ACL = %w[
|
10
|
+
private
|
11
|
+
public-read
|
12
|
+
public-read-write
|
13
|
+
authenticated-read
|
14
|
+
bucket-owner-read
|
15
|
+
bucket-owner-full-control
|
16
|
+
].freeze
|
17
|
+
|
18
|
+
ConfigurationError = Class.new(StandardError)
|
19
|
+
|
9
20
|
add_config :aws_attributes
|
10
21
|
add_config :aws_authenticated_url_expiration
|
11
22
|
add_config :aws_credentials
|
12
23
|
add_config :aws_bucket
|
13
|
-
add_config :aws_acl
|
14
24
|
add_config :aws_read_options
|
15
25
|
add_config :aws_write_options
|
26
|
+
add_config :aws_acl
|
27
|
+
add_config :aws_signer
|
16
28
|
|
17
29
|
configure do |config|
|
18
30
|
config.storage_engines[:aws] = 'CarrierWave::Storage::AWS'
|
19
31
|
end
|
32
|
+
|
33
|
+
def self.aws_acl=(acl)
|
34
|
+
@aws_acl = normalized_acl(acl)
|
35
|
+
end
|
36
|
+
|
37
|
+
def self.normalized_acl(acl)
|
38
|
+
normalized = acl.to_s.downcase.sub('_', '-')
|
39
|
+
|
40
|
+
unless ACCEPTED_ACL.include?(normalized)
|
41
|
+
raise ConfigurationError.new("Invalid ACL option: #{normalized}")
|
42
|
+
end
|
43
|
+
|
44
|
+
normalized
|
45
|
+
end
|
46
|
+
|
47
|
+
def self.aws_signer(value = nil)
|
48
|
+
self.aws_signer = value if value
|
49
|
+
|
50
|
+
if instance_variable_defined?('@aws_signer')
|
51
|
+
@aws_signer
|
52
|
+
elsif superclass.respond_to? :aws_signer
|
53
|
+
superclass.aws_signer
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.aws_signer=(signer)
|
58
|
+
@aws_signer = validated_signer(signer)
|
59
|
+
end
|
60
|
+
|
61
|
+
def self.validated_signer(signer)
|
62
|
+
unless signer.nil? || signer.instance_of?(Proc) && signer.arity == 2
|
63
|
+
raise ConfigurationError.new("Invalid signer option. Signer proc has to respond to '.call(unsigned_url, options)'")
|
64
|
+
end
|
65
|
+
|
66
|
+
signer
|
67
|
+
end
|
68
|
+
|
69
|
+
def aws_acl=(acl)
|
70
|
+
@aws_acl = self.class.normalized_acl(acl)
|
71
|
+
end
|
72
|
+
|
73
|
+
def aws_signer
|
74
|
+
instance_variable_defined?('@aws_signer') ? @aws_signer : self.class.aws_signer
|
75
|
+
end
|
20
76
|
end
|
@@ -60,6 +60,10 @@ module CarrierWave
|
|
60
60
|
bucket.object(new_path).copy_from(copy_source: "#{bucket.name}/#{file.key}")
|
61
61
|
end
|
62
62
|
|
63
|
+
def signed_url(options = {})
|
64
|
+
signer.call(public_url, options)
|
65
|
+
end
|
66
|
+
|
63
67
|
def authenticated_url(options = {})
|
64
68
|
file.presigned_url(:get, aws_options.expiration_options(options))
|
65
69
|
end
|
@@ -73,7 +77,9 @@ module CarrierWave
|
|
73
77
|
end
|
74
78
|
|
75
79
|
def url(options = {})
|
76
|
-
if
|
80
|
+
if signer
|
81
|
+
signed_url(options)
|
82
|
+
elsif uploader.aws_acl.to_s != 'public-read'
|
77
83
|
authenticated_url(options)
|
78
84
|
else
|
79
85
|
public_url
|
@@ -85,6 +91,10 @@ module CarrierWave
|
|
85
91
|
def bucket
|
86
92
|
@bucket ||= connection.bucket(uploader.aws_bucket)
|
87
93
|
end
|
94
|
+
|
95
|
+
def signer
|
96
|
+
uploader.aws_signer
|
97
|
+
end
|
88
98
|
end
|
89
99
|
end
|
90
100
|
end
|
@@ -1,13 +1,140 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe CarrierWave::Uploader::Base do
|
4
|
-
|
5
|
-
|
4
|
+
let(:uploader) do
|
5
|
+
Class.new(CarrierWave::Uploader::Base)
|
6
|
+
end
|
7
|
+
|
8
|
+
let(:derived_uploader) do
|
9
|
+
Class.new(uploader)
|
6
10
|
end
|
7
11
|
|
8
12
|
it 'inserts aws as a known storage engine' do
|
9
|
-
|
13
|
+
uploader.configure do |config|
|
10
14
|
expect(config.storage_engines).to have_key(:aws)
|
11
15
|
end
|
12
16
|
end
|
17
|
+
|
18
|
+
it 'defines aws specific storage options' do
|
19
|
+
expect(uploader).to respond_to(:aws_attributes)
|
20
|
+
end
|
21
|
+
|
22
|
+
describe '#aws_acl' do
|
23
|
+
it 'allows known acess control values' do
|
24
|
+
expect {
|
25
|
+
uploader.aws_acl = 'private'
|
26
|
+
uploader.aws_acl = 'public-read'
|
27
|
+
uploader.aws_acl = 'authenticated-read'
|
28
|
+
}.not_to raise_exception
|
29
|
+
end
|
30
|
+
|
31
|
+
it 'does not allow unknown control values' do
|
32
|
+
expect {
|
33
|
+
uploader.aws_acl = 'everybody'
|
34
|
+
}.to raise_exception(CarrierWave::Uploader::Base::ConfigurationError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'normalizes the set value' do
|
38
|
+
uploader.aws_acl = :'public-read'
|
39
|
+
expect(uploader.aws_acl).to eq('public-read')
|
40
|
+
|
41
|
+
uploader.aws_acl = 'PUBLIC_READ'
|
42
|
+
expect(uploader.aws_acl).to eq('public-read')
|
43
|
+
end
|
44
|
+
|
45
|
+
it 'can be overridden on an instance level' do
|
46
|
+
instance = uploader.new
|
47
|
+
|
48
|
+
uploader.aws_acl = 'private'
|
49
|
+
instance.aws_acl = 'public-read'
|
50
|
+
|
51
|
+
expect(uploader.aws_acl).to eq('private')
|
52
|
+
expect(instance.aws_acl).to eq('public-read')
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'can be looked up from superclass' do
|
56
|
+
uploader.aws_acl = 'private'
|
57
|
+
instance = derived_uploader.new
|
58
|
+
|
59
|
+
expect(derived_uploader.aws_acl).to eq('private')
|
60
|
+
expect(instance.aws_acl).to eq('private')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'can be overridden on a class level' do
|
64
|
+
uploader.aws_acl = 'public-read'
|
65
|
+
derived_uploader.aws_acl = 'private'
|
66
|
+
|
67
|
+
base = uploader.new
|
68
|
+
expect(base.aws_acl).to eq('public-read')
|
69
|
+
|
70
|
+
instance = derived_uploader.new
|
71
|
+
expect(instance.aws_acl).to eq('private')
|
72
|
+
end
|
73
|
+
|
74
|
+
it 'can be set with the configure block' do
|
75
|
+
uploader.configure do |config|
|
76
|
+
config.aws_acl = 'public-read'
|
77
|
+
end
|
78
|
+
|
79
|
+
expect(uploader.aws_acl).to eq('public-read')
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
describe '#aws_signer' do
|
84
|
+
let(:signer_proc) { -> (unsigned_url, options) { } }
|
85
|
+
let(:other_signer) { -> (unsigned_url, options) { } }
|
86
|
+
|
87
|
+
it 'allows proper signer object' do
|
88
|
+
expect { uploader.aws_signer = signer_proc }.not_to raise_exception
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'does not allow signer with unknown api' do
|
92
|
+
signer_proc = -> (unsigned_url) { }
|
93
|
+
|
94
|
+
expect { uploader.aws_signer = signer_proc }.to raise_exception(CarrierWave::Uploader::Base::ConfigurationError)
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'can be overridden on an instance level' do
|
98
|
+
instance = uploader.new
|
99
|
+
|
100
|
+
uploader.aws_signer = signer_proc
|
101
|
+
instance.aws_signer = other_signer
|
102
|
+
|
103
|
+
expect(uploader.aws_signer).to eql(signer_proc)
|
104
|
+
expect(instance.aws_signer).to eql(other_signer)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'can be overridden on a class level' do
|
108
|
+
uploader.aws_signer = signer_proc
|
109
|
+
derived_uploader.aws_signer = other_signer
|
110
|
+
|
111
|
+
base = uploader.new
|
112
|
+
expect(base.aws_signer).to eq(signer_proc)
|
113
|
+
|
114
|
+
instance = derived_uploader.new
|
115
|
+
expect(instance.aws_signer).to eql(other_signer)
|
116
|
+
end
|
117
|
+
|
118
|
+
it 'can be looked up from superclass' do
|
119
|
+
uploader.aws_signer = signer_proc
|
120
|
+
instance = derived_uploader.new
|
121
|
+
|
122
|
+
expect(derived_uploader.aws_signer).to eq(signer_proc)
|
123
|
+
expect(instance.aws_signer).to eql(signer_proc)
|
124
|
+
end
|
125
|
+
|
126
|
+
it 'can be set with the configure block' do
|
127
|
+
uploader.configure do |config|
|
128
|
+
config.aws_signer = signer_proc
|
129
|
+
end
|
130
|
+
|
131
|
+
expect(uploader.aws_signer).to eql(signer_proc)
|
132
|
+
end
|
133
|
+
|
134
|
+
it 'can be set when passed as argument to the class getter method' do
|
135
|
+
uploader.aws_signer signer_proc
|
136
|
+
|
137
|
+
expect(uploader.aws_signer).to eql(signer_proc)
|
138
|
+
end
|
139
|
+
end
|
13
140
|
end
|
@@ -12,6 +12,7 @@ describe CarrierWave::Storage::AWSFile do
|
|
12
12
|
aws_acl: :'public-read',
|
13
13
|
aws_attributes: {},
|
14
14
|
asset_host: nil,
|
15
|
+
aws_signer: nil,
|
15
16
|
aws_read_options: { encryption_key: 'abc' },
|
16
17
|
aws_write_options: { encryption_key: 'def' }
|
17
18
|
)
|
@@ -62,6 +63,16 @@ describe CarrierWave::Storage::AWSFile do
|
|
62
63
|
aws_file.url
|
63
64
|
end
|
64
65
|
|
66
|
+
it 'requests an signed url if url signing is configured' do
|
67
|
+
signature = 'Signature=QWERTZ&Key-Pair-Id=XYZ'
|
68
|
+
cloudfront_signer = -> (unsigned_url, options) { [unsigned_url, signature].join('?') }
|
69
|
+
|
70
|
+
allow(uploader).to receive(:aws_signer) { cloudfront_signer }
|
71
|
+
expect(file).to receive(:public_url) { 'http://example.com' }
|
72
|
+
|
73
|
+
expect(aws_file.url).to eq "http://example.com?#{signature}"
|
74
|
+
end
|
75
|
+
|
65
76
|
it 'uses the asset_host and file path if asset_host is set' do
|
66
77
|
allow(uploader).to receive(:aws_acl) { :'public-read' }
|
67
78
|
allow(uploader).to receive(:asset_host) { 'http://example.com' }
|
@@ -4,6 +4,10 @@ describe 'Storing Files', type: :feature do
|
|
4
4
|
let(:image) { File.open('spec/fixtures/image.png', 'r') }
|
5
5
|
let(:instance) { FeatureUploader.new }
|
6
6
|
|
7
|
+
before do
|
8
|
+
instance.aws_acl = 'public-read'
|
9
|
+
end
|
10
|
+
|
7
11
|
it 'uploads the file to the configured bucket' do
|
8
12
|
instance.store!(image)
|
9
13
|
instance.retrieve_from_store!('image.png')
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-aws
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Parker Selbert
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-18 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: carrierwave
|
@@ -30,14 +30,14 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - "~>"
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 2.0
|
33
|
+
version: '2.0'
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - "~>"
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 2.0
|
40
|
+
version: '2.0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rspec
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -98,12 +98,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
98
98
|
version: '0'
|
99
99
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
100
100
|
requirements:
|
101
|
-
- - "
|
101
|
+
- - ">="
|
102
102
|
- !ruby/object:Gem::Version
|
103
|
-
version:
|
103
|
+
version: '0'
|
104
104
|
requirements: []
|
105
105
|
rubyforge_project:
|
106
|
-
rubygems_version: 2.4.5
|
106
|
+
rubygems_version: 2.4.5.1
|
107
107
|
signing_key:
|
108
108
|
specification_version: 4
|
109
109
|
summary: A slimmer alternative to using Fog for S3 support in CarrierWave
|