carrierwave-aws 1.0.0.pre.rc.1 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: c592e2b5f772c89d14e60f354483bbd18f48b744
4
- data.tar.gz: bd4e6f6c44e26e9aab0b18c09d114633e8f43ae4
3
+ metadata.gz: 0daf2d106b4a0d27f423cfbaa8745fa019d5f840
4
+ data.tar.gz: 2213c9acca949bd4d1608a0fd08cbd96ed12b64b
5
5
  SHA512:
6
- metadata.gz: d174e6f20861ee37b5b536674c0cfc667b1e794048b4401fb6889e80cca88a66586d306702b96bae8213127de8cc7b8ec34dd424107d3316723d907c5da96f67
7
- data.tar.gz: 2b50f0def9160aa5255fe65f579c11c79f9c210e546f15ffd60ce6b60a4e6899462116f12cab04bdd703278103d3c6692fbe08f44d5916282d2477f36f42b3d6
6
+ metadata.gz: fa5b275f21820fb4fed97d1cd183a3f1ae909de304e1dd6616d64d4a047fa9d285b340a66fea9ad4a720df9ee6bf8e2ee3eb485277d58974fb22cde1b185ec7b
7
+ data.tar.gz: abffdcdca5ee8d72c7daf90f4e6fc9ee18df1b3c30cc4e0a4e692214ea02b851254449364155b1b020f4a205e3f1f6ea20cb20bef6f264cb92318ffa803ff9f2
@@ -1,8 +1,13 @@
1
+ sudo: false
1
2
  language: ruby
2
3
  rvm:
3
- - 2.1.5
4
- - 2.2.2
5
- script: bundle exec rspec spec
4
+ - 2.1.5
5
+ - 2.2.2
6
+ - ruby-head
7
+ matrix:
8
+ allow_failures:
9
+ - rvm: ruby-head
10
+ script: bundle exec rspec
6
11
  env:
7
12
  global:
8
13
  - secure: |-
@@ -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
@@ -1 +1,10 @@
1
- require "bundler/gem_tasks"
1
+ require 'bundler'
2
+ require 'bundler/gem_tasks'
3
+
4
+ Bundler.setup
5
+
6
+ require 'rspec/core/rake_task'
7
+
8
+ RSpec::Core::RakeTask.new(:spec)
9
+
10
+ task default: :spec
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.require_paths = ['lib']
18
18
 
19
19
  gem.add_dependency 'carrierwave', '~> 0.7'
20
- gem.add_dependency 'aws-sdk', '~> 2.0.47'
20
+ gem.add_dependency 'aws-sdk', '~> 2.0'
21
21
 
22
22
  gem.add_development_dependency 'rspec', '~> 3'
23
23
  end
@@ -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
@@ -1,5 +1,5 @@
1
1
  module Carrierwave
2
2
  module AWS
3
- VERSION = '1.0.0-rc.1'
3
+ VERSION = '1.0.0'
4
4
  end
5
5
  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 uploader.aws_acl.to_s != 'public-read'
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
- it 'defines aws specific storage options' do
5
- expect(described_class).to respond_to(:aws_attributes)
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
- described_class.configure do |config|
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')
@@ -5,8 +5,8 @@ def source_environment_file!
5
5
  return unless File.exists?('.env')
6
6
 
7
7
  File.readlines('.env').each do |line|
8
- values = line.split('=')
9
- ENV[values.first] = values.last.chomp
8
+ key, value = line.split('=')
9
+ ENV[key] = value.chomp
10
10
  end
11
11
  end
12
12
 
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.pre.rc.1
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-07-02 00:00:00.000000000 Z
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.47
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.47
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: 1.3.1
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