carrierwave-azure_rm 0.0.3 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +41 -0
- data/README.md +20 -0
- data/carrierwave-azure_rm.gemspec +1 -1
- data/lib/carrierwave-azure_rm.rb +5 -0
- data/lib/carrierwave/azure_rm/version.rb +1 -1
- data/lib/carrierwave/storage/azure_rm.rb +44 -6
- data/spec/carrierwave-azure_spec.rb +10 -0
- data/spec/carrierwave/storage/azure_file_spec.rb +8 -2
- data/spec/carrierwave/storage/azure_spec.rb +24 -0
- metadata +6 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0b3dce327bd64abd1f7e58c353cf1894b0ce85b8
|
4
|
+
data.tar.gz: 7e8bee6a2a1d9d6c7082c73656721cea4cc60a97
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a630896782125313caab539709844c13a38f14fa825ab648e0108218b080709e1b887f37ec14dcf3b02fccc4568c449face8914a79e3c3d7e06cd471dfb158a1
|
7
|
+
data.tar.gz: 5b5aabd4d024ec70063410df71fa694f4cbc1abc712cdbf5c9618cb4a124b47d071255cffcdfb4e477368bbee4749ffd681abcdf4b74a8c4786f36e8e3fa85c8
|
data/CHANGELOG.md
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# Change Log
|
2
|
+
|
3
|
+
## [v0.1.0](https://github.com/nooulaif/carrierwave-azure_rm/tree/v0.1.0) (2017-04-24)
|
4
|
+
[Full Changelog](https://github.com/nooulaif/carrierwave-azure_rm/compare/v0.0.3...v0.1.0)
|
5
|
+
|
6
|
+
**Merged pull requests:**
|
7
|
+
|
8
|
+
- Feature/private blobs [\#2](https://github.com/nooulaif/carrierwave-azure_rm/pull/2) ([stestaub](https://github.com/stestaub))
|
9
|
+
|
10
|
+
**Implemented enhancements:**
|
11
|
+
|
12
|
+
- Updated [azure-storage](https://rubygems.org/gems/azure-storage) to version 0.12.1.preview
|
13
|
+
|
14
|
+
## [v0.0.3](https://github.com/nooulaif/carrierwave-azure_rm/tree/v0.0.3) (2017-03-25)
|
15
|
+
[Full Changelog](https://github.com/nooulaif/carrierwave-azure_rm/compare/v0.0.2...v0.0.3)
|
16
|
+
|
17
|
+
**Merged pull requests:**
|
18
|
+
|
19
|
+
- Feature properties without content [\#1](https://github.com/nooulaif/carrierwave-azure_rm/pull/1) ([stestaub](https://github.com/stestaub))
|
20
|
+
|
21
|
+
**Implemented enhancements:**
|
22
|
+
|
23
|
+
- Updated [azure-storage](https://rubygems.org/gems/azure-storage) to version 0.12.0.preview
|
24
|
+
|
25
|
+
## [v0.0.2](https://github.com/nooulaif/carrierwave-azure_rm/tree/v0.0.2) (2016-07-26)
|
26
|
+
[Full Changelog](https://github.com/nooulaif/carrierwave-azure_rm/compare/v0.0.1...v0.0.2)
|
27
|
+
|
28
|
+
**Fixed bugs:**
|
29
|
+
|
30
|
+
- Fixed 'exists?' method
|
31
|
+
|
32
|
+
## [v0.0.1](https://github.com/nooulaif/carrierwave-azure_rm/tree/v0.0.1) (2016-07-25)
|
33
|
+
[Full Changelog](https://github.com/nooulaif/carrierwave-azure_rm/compare/v0.0.1.preview...v0.0.1)
|
34
|
+
|
35
|
+
**Fixed bugs:**
|
36
|
+
|
37
|
+
- Ensure container exists in `store!` method
|
38
|
+
|
39
|
+
## [v0.0.1.preview](https://github.com/nooulaif/carrierwave-azure_rm/tree/v0.0.1.preview) (2016-07-25)
|
40
|
+
|
41
|
+
- Initial commit
|
data/README.md
CHANGED
@@ -40,6 +40,26 @@ class ExampleUploader < CarrierWave::Uploader::Base
|
|
40
40
|
end
|
41
41
|
```
|
42
42
|
|
43
|
+
## Private blobs
|
44
|
+
If your container access policy is set to private, carrierwave-azure_rm can automatically
|
45
|
+
return signed urls on the files. Enable auto_sign in the configuration:
|
46
|
+
|
47
|
+
```ruby
|
48
|
+
config.auto_sign_urls = true
|
49
|
+
config.token_expire_after = 3600 # optional - Set the expire time of the url to 3600 seconds. Default is 1800 seconds
|
50
|
+
```
|
51
|
+
|
52
|
+
If you wish a newly created container to be initialized with a specific access_level you can set the following in
|
53
|
+
your config:
|
54
|
+
|
55
|
+
```ruby
|
56
|
+
config.public_access_level = 'private' # optional - possible values are blob, private, container
|
57
|
+
```
|
58
|
+
|
59
|
+
This config is only required if your container does not exist and you want it to be configured automatically.
|
60
|
+
|
61
|
+
[Manage access to blobs](https://docs.microsoft.com/en-us/azure/storage/storage-manage-access-to-resources)
|
62
|
+
|
43
63
|
## Issues
|
44
64
|
If you have any problems with or questions about this image, please contact me through a [GitHub issue](https://github.com/nooulaif/carrierwave-azure_rm/issues).
|
45
65
|
|
@@ -17,7 +17,7 @@ Gem::Specification.new do |gem|
|
|
17
17
|
gem.require_paths = ['lib']
|
18
18
|
|
19
19
|
gem.add_dependency 'carrierwave'
|
20
|
-
gem.add_dependency 'azure-storage', '~> 0.12.
|
20
|
+
gem.add_dependency 'azure-storage', '~> 0.12.1.preview'
|
21
21
|
|
22
22
|
gem.add_development_dependency 'rake'
|
23
23
|
gem.add_development_dependency 'rspec', '~> 3'
|
data/lib/carrierwave-azure_rm.rb
CHANGED
@@ -7,8 +7,13 @@ class CarrierWave::Uploader::Base
|
|
7
7
|
add_config :azure_storage_access_key
|
8
8
|
add_config :azure_storage_blob_host
|
9
9
|
add_config :azure_container
|
10
|
+
add_config :public_access_level
|
11
|
+
add_config :auto_sign_urls
|
12
|
+
add_config :token_expire_after
|
10
13
|
|
11
14
|
configure do |config|
|
15
|
+
config.public_access_level = 'blob'
|
16
|
+
config.token_expire_after = 1800
|
12
17
|
config.storage_engines[:azure_rm] = 'CarrierWave::Storage::AzureRM'
|
13
18
|
end
|
14
19
|
end
|
@@ -4,13 +4,13 @@ module CarrierWave
|
|
4
4
|
module Storage
|
5
5
|
class AzureRM < Abstract
|
6
6
|
def store!(file)
|
7
|
-
azure_file = CarrierWave::Storage::AzureRM::File.new(uploader, connection, uploader.store_path)
|
7
|
+
azure_file = CarrierWave::Storage::AzureRM::File.new(uploader, connection, uploader.store_path, signer)
|
8
8
|
azure_file.store!(file)
|
9
9
|
azure_file
|
10
10
|
end
|
11
11
|
|
12
12
|
def retrieve!(identifer)
|
13
|
-
CarrierWave::Storage::AzureRM::File.new(uploader, connection, uploader.store_path(identifer))
|
13
|
+
CarrierWave::Storage::AzureRM::File.new(uploader, connection, uploader.store_path(identifer), signer)
|
14
14
|
end
|
15
15
|
|
16
16
|
def connection
|
@@ -22,19 +22,34 @@ module CarrierWave
|
|
22
22
|
end
|
23
23
|
end
|
24
24
|
|
25
|
+
def signer
|
26
|
+
@signer ||= begin
|
27
|
+
::Azure::Storage::Core::Auth::SharedAccessSignature.new
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
25
31
|
class File
|
26
32
|
attr_reader :path
|
27
33
|
|
28
|
-
def initialize(uploader, connection, path)
|
34
|
+
def initialize(uploader, connection, path, signer = nil)
|
29
35
|
@uploader = uploader
|
30
36
|
@connection = connection
|
37
|
+
@signer = signer
|
31
38
|
@path = path
|
32
39
|
end
|
33
40
|
|
34
41
|
def ensure_container_exists(name)
|
35
42
|
unless @connection.list_containers.any? { |c| c.name == name }
|
36
|
-
@connection.create_container(name,
|
43
|
+
@connection.create_container(name, access_level_option)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
def access_level
|
48
|
+
unless @public_access_level
|
49
|
+
container, signed_identifiers = @connection.get_container_acl(@uploader.send("azure_container"))
|
50
|
+
@public_access_level = container.public_access_level || 'private' # when container access level is private, it returns nil
|
37
51
|
end
|
52
|
+
@public_access_level
|
38
53
|
end
|
39
54
|
|
40
55
|
def store!(file)
|
@@ -62,7 +77,15 @@ module CarrierWave
|
|
62
77
|
if @uploader.asset_host
|
63
78
|
"#{@uploader.asset_host}/#{path}"
|
64
79
|
else
|
65
|
-
@connection.generate_uri(path)
|
80
|
+
uri = @connection.generate_uri(path)
|
81
|
+
if sign_url?(options)
|
82
|
+
@signer.signed_uri(uri, false, { permissions: 'r',
|
83
|
+
resource: 'b',
|
84
|
+
start: 1.minute.ago.utc.iso8601,
|
85
|
+
expiry: expires_at}).to_s
|
86
|
+
else
|
87
|
+
uri.to_s
|
88
|
+
end
|
66
89
|
end
|
67
90
|
end
|
68
91
|
|
@@ -88,7 +111,7 @@ module CarrierWave
|
|
88
111
|
end
|
89
112
|
|
90
113
|
def filename
|
91
|
-
URI.decode(url).gsub(/.*\/(.*?$)/, '\1')
|
114
|
+
URI.decode(url(skip_signing: true)).gsub(/.*\/(.*?$)/, '\1')
|
92
115
|
end
|
93
116
|
|
94
117
|
def extension
|
@@ -106,6 +129,21 @@ module CarrierWave
|
|
106
129
|
|
107
130
|
private
|
108
131
|
|
132
|
+
def access_level_option
|
133
|
+
lvl = @uploader.public_access_level
|
134
|
+
raise "Invalid Access level #{lvl}." unless %w(private blob container).include? lvl
|
135
|
+
lvl == 'private' ? {} : { :public_access_level => lvl }
|
136
|
+
end
|
137
|
+
|
138
|
+
def expires_at
|
139
|
+
expiry = Time.now + @uploader.token_expire_after
|
140
|
+
expiry.utc.iso8601
|
141
|
+
end
|
142
|
+
|
143
|
+
def sign_url?(options)
|
144
|
+
@uploader.auto_sign_urls && !options[:skip_signing] && access_level == 'private'
|
145
|
+
end
|
146
|
+
|
109
147
|
def blob
|
110
148
|
load_blob if @blob.nil?
|
111
149
|
@blob
|
@@ -10,5 +10,15 @@ describe CarrierWave::Uploader::Base do
|
|
10
10
|
is_expected.to respond_to(:azure_storage_access_key)
|
11
11
|
is_expected.to respond_to(:azure_storage_blob_host)
|
12
12
|
is_expected.to respond_to(:azure_container)
|
13
|
+
is_expected.to respond_to(:auto_sign_urls)
|
14
|
+
is_expected.to respond_to(:token_expire_after)
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'should have public_access_level blob by default' do
|
18
|
+
expect(described_class.public_access_level).to eq 'blob'
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'should have set token_expire_after to 30 minutes' do
|
22
|
+
expect(described_class.token_expire_after).to eq 30*60
|
13
23
|
end
|
14
24
|
end
|
@@ -13,11 +13,17 @@ describe CarrierWave::Storage::AzureRM::File do
|
|
13
13
|
allow(uploader).to receive(:azure_container).and_return('test')
|
14
14
|
end
|
15
15
|
|
16
|
-
subject { CarrierWave::Storage::AzureRM::File.new(uploader, storage.connection, 'dummy.txt').url }
|
16
|
+
subject { CarrierWave::Storage::AzureRM::File.new(uploader, storage.connection, 'dummy.txt', storage.signer).url }
|
17
17
|
|
18
18
|
context 'with storage_blob_host' do
|
19
19
|
before do
|
20
|
+
# This must be first!
|
20
21
|
allow(uploader).to receive(:azure_storage_blob_host).and_return('http://example.com')
|
22
|
+
|
23
|
+
# automatic resolving won't work for non existent url
|
24
|
+
struct = Struct.new('Container', :public_access_level).new
|
25
|
+
struct.public_access_level = 'blob'
|
26
|
+
allow(storage.connection).to receive(:get_container_acl).and_return(struct)
|
21
27
|
end
|
22
28
|
|
23
29
|
it 'should return on asset_host' do
|
@@ -41,7 +47,7 @@ describe CarrierWave::Storage::AzureRM::File do
|
|
41
47
|
allow(storage.connection).to receive(:get_blob).and_return(nil)
|
42
48
|
end
|
43
49
|
|
44
|
-
subject { CarrierWave::Storage::AzureRM::File.new(uploader, storage.connection, 'dummy.txt').exists? }
|
50
|
+
subject { CarrierWave::Storage::AzureRM::File.new(uploader, storage.connection, 'dummy.txt', storage.signer).exists? }
|
45
51
|
|
46
52
|
context 'when blob file does not exist' do
|
47
53
|
it 'should return false' do
|
@@ -68,11 +68,35 @@ describe CarrierWave::Storage::AzureRM do
|
|
68
68
|
it_should_behave_like 'an expected return value' do
|
69
69
|
subject { stored_file }
|
70
70
|
end
|
71
|
+
|
72
|
+
context 'private container' do
|
73
|
+
before {
|
74
|
+
allow(uploader).to receive(:public_access_level).and_return('private')
|
75
|
+
allow(uploader).to receive(:azure_container).and_return('carrerwaveprivate')
|
76
|
+
allow(uploader).to receive(:auto_sign_urls).and_return(true)
|
77
|
+
}
|
78
|
+
|
79
|
+
it_should_behave_like 'an expected return value' do
|
80
|
+
subject { stored_file }
|
81
|
+
end
|
82
|
+
end
|
71
83
|
end
|
72
84
|
|
73
85
|
describe '#retrieve' do
|
74
86
|
it_should_behave_like 'an expected return value' do
|
75
87
|
subject { retrieved_file }
|
76
88
|
end
|
89
|
+
|
90
|
+
context 'private container' do
|
91
|
+
before {
|
92
|
+
allow(uploader).to receive(:public_access_level).and_return('private')
|
93
|
+
allow(uploader).to receive(:azure_container).and_return('carrerwaveprivate')
|
94
|
+
allow(uploader).to receive(:auto_sign_urls).and_return(true)
|
95
|
+
}
|
96
|
+
|
97
|
+
it_should_behave_like 'an expected return value' do
|
98
|
+
subject { retrieved_file }
|
99
|
+
end
|
100
|
+
end
|
77
101
|
end
|
78
102
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: carrierwave-azure_rm
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nooulaif
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-
|
11
|
+
date: 2017-04-24 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: 0.12.
|
33
|
+
version: 0.12.1.preview
|
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: 0.12.
|
40
|
+
version: 0.12.1.preview
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: rake
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
@@ -75,6 +75,7 @@ extra_rdoc_files: []
|
|
75
75
|
files:
|
76
76
|
- ".gitignore"
|
77
77
|
- ".rspec"
|
78
|
+
- CHANGELOG.md
|
78
79
|
- Gemfile
|
79
80
|
- LICENSE
|
80
81
|
- README.md
|
@@ -108,7 +109,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
108
109
|
version: '0'
|
109
110
|
requirements: []
|
110
111
|
rubyforge_project:
|
111
|
-
rubygems_version: 2.
|
112
|
+
rubygems_version: 2.6.8
|
112
113
|
signing_key:
|
113
114
|
specification_version: 4
|
114
115
|
summary: Microsoft Azure Storage blob support for CarrierWave
|