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 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