paperclip-azure-storage 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: c343cc5f38fe90088c4a79456704487216ff247a96ab662bb89746a0ce0b998f
4
+ data.tar.gz: fe1ef1ba0d3c222a3b9d39efc47f5c71f0694154a475abe144953581da1152f9
5
+ SHA512:
6
+ metadata.gz: fd844d3e4a077ae7120a58edc7432ff5bd09d3ce668ccd2020847af559c43686dd8fb5a3e71ed090caf8b822fef4abd6ca063450beea64abc14c8abb257978fe
7
+ data.tar.gz: ecbc10ff245e0df92acc55fcd56428c1b22904919fbcb0627ac26e68050cf8ef380daa70e830503e7326c0e2bf071538b4c3c785cca9410d429dde33b4c8ab1e
@@ -0,0 +1,29 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ tags: [ 'v*' ]
6
+
7
+ jobs:
8
+ build:
9
+ name: Build + Publish
10
+ runs-on: ubuntu-latest
11
+ permissions:
12
+ contents: read
13
+ packages: write
14
+ steps:
15
+ - uses: actions/checkout@v2
16
+ - name: Set up Ruby 2.5
17
+ uses: actions/setup-ruby@v1
18
+ with:
19
+ ruby-version: 2.5
20
+ - name: Publish
21
+ run: |
22
+ mkdir -p $HOME/.gem
23
+ touch $HOME/.gem/credentials
24
+ chmod 0600 $HOME/.gem/credentials
25
+ printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
26
+ gem build *.gemspec
27
+ gem push *.gem
28
+ env:
29
+ GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
@@ -0,0 +1,23 @@
1
+ name: Ruby Gem
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - main
7
+ pull_request:
8
+
9
+ jobs:
10
+ build:
11
+ name: Review
12
+ runs-on: ubuntu-20.04
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby 2.5
16
+ uses: actions/setup-ruby@v1
17
+ with:
18
+ ruby-version: 2.5
19
+ - name: Run rspec
20
+ run: |
21
+ gem install bundler --version=1.17.3
22
+ bundle install
23
+ rspec
data/.gitignore ADDED
@@ -0,0 +1,2 @@
1
+ .idea
2
+ *.gem
data/.ruby-gemset ADDED
@@ -0,0 +1 @@
1
+ paperclip-azure-storage
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.5.0
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ source "https://rubygems.org"
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,104 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ paperclip-azure-storage (0.1.5)
5
+ azure-storage-blob (>= 1.0.0, < 3.0.0)
6
+ paperclip (>= 5.1.0, < 7.0.0)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activemodel (6.1.4.1)
12
+ activesupport (= 6.1.4.1)
13
+ activerecord (6.1.4.1)
14
+ activemodel (= 6.1.4.1)
15
+ activesupport (= 6.1.4.1)
16
+ activesupport (6.1.4.1)
17
+ concurrent-ruby (~> 1.0, >= 1.0.2)
18
+ i18n (>= 1.6, < 2)
19
+ minitest (>= 5.1)
20
+ tzinfo (~> 2.0)
21
+ zeitwerk (~> 2.3)
22
+ addressable (2.8.0)
23
+ public_suffix (>= 2.0.2, < 5.0)
24
+ azure-core (0.1.15)
25
+ faraday (~> 0.9)
26
+ faraday_middleware (~> 0.10)
27
+ nokogiri (~> 1.6)
28
+ azure-storage-blob (1.1.0)
29
+ azure-core (~> 0.1.13)
30
+ azure-storage-common (~> 1.0)
31
+ nokogiri (~> 1.6, >= 1.6.8)
32
+ azure-storage-common (1.1.0)
33
+ azure-core (~> 0.1.13)
34
+ nokogiri (~> 1.6, >= 1.6.8)
35
+ climate_control (0.2.0)
36
+ concurrent-ruby (1.1.9)
37
+ crack (0.4.5)
38
+ rexml
39
+ diff-lcs (1.4.4)
40
+ faraday (0.17.4)
41
+ multipart-post (>= 1.2, < 3)
42
+ faraday_middleware (0.14.0)
43
+ faraday (>= 0.7.4, < 1.0)
44
+ hashdiff (1.0.1)
45
+ i18n (1.8.10)
46
+ concurrent-ruby (~> 1.0)
47
+ mime-types (3.3.1)
48
+ mime-types-data (~> 3.2015)
49
+ mime-types-data (3.2021.0901)
50
+ mimemagic (0.3.10)
51
+ nokogiri (~> 1)
52
+ rake
53
+ mini_portile2 (2.6.1)
54
+ minitest (5.14.4)
55
+ multipart-post (2.1.1)
56
+ nokogiri (1.12.5)
57
+ mini_portile2 (~> 2.6.1)
58
+ racc (~> 1.4)
59
+ paperclip (6.1.0)
60
+ activemodel (>= 4.2.0)
61
+ activesupport (>= 4.2.0)
62
+ mime-types
63
+ mimemagic (~> 0.3.0)
64
+ terrapin (~> 0.6.0)
65
+ public_suffix (4.0.6)
66
+ racc (1.6.0)
67
+ rake (13.0.6)
68
+ rexml (3.2.5)
69
+ rspec (3.10.0)
70
+ rspec-core (~> 3.10.0)
71
+ rspec-expectations (~> 3.10.0)
72
+ rspec-mocks (~> 3.10.0)
73
+ rspec-core (3.10.1)
74
+ rspec-support (~> 3.10.0)
75
+ rspec-expectations (3.10.1)
76
+ diff-lcs (>= 1.2.0, < 2.0)
77
+ rspec-support (~> 3.10.0)
78
+ rspec-mocks (3.10.2)
79
+ diff-lcs (>= 1.2.0, < 2.0)
80
+ rspec-support (~> 3.10.0)
81
+ rspec-support (3.10.2)
82
+ sqlite3 (1.4.2)
83
+ terrapin (0.6.0)
84
+ climate_control (>= 0.0.3, < 1.0)
85
+ tzinfo (2.0.4)
86
+ concurrent-ruby (~> 1.0)
87
+ webmock (3.14.0)
88
+ addressable (>= 2.8.0)
89
+ crack (>= 0.3.2)
90
+ hashdiff (>= 0.4.0, < 2.0.0)
91
+ zeitwerk (2.5.1)
92
+
93
+ PLATFORMS
94
+ ruby
95
+
96
+ DEPENDENCIES
97
+ activerecord (~> 6.1)
98
+ paperclip-azure-storage!
99
+ rspec (~> 3.10)
100
+ sqlite3 (~> 1.4)
101
+ webmock (~> 3.14)
102
+
103
+ BUNDLED WITH
104
+ 1.17.3
data/LICENSE.md ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2021 Irsyad Rizaldi
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,33 @@
1
+ # Paperclip Azure Storage
2
+ ## Description
3
+ `paperclip-azure-storage` is a [paperclip](https://github.com/thoughtbot/paperclip) adapter for azure storage.
4
+
5
+ The difference between this and other azure adapter, such as [paperclip-azure](https://github.com/supportify/paperclip-azure),
6
+ was the ability to use [service principal](https://docs.microsoft.com/en-us/azure/active-directory/develop/app-objects-and-service-principals)
7
+ as the authentication method.
8
+
9
+ ## Getting Started
10
+ 1. Add `paperclip-azure-storage` on `Gemfile`
11
+ ```ruby
12
+ gem 'paperclip-azure-storage'
13
+ ```
14
+ 2. Configure `paperclip`
15
+ ```ruby
16
+ require 'paperclip-azure-storage'
17
+
18
+ Paperclip::DataUriAdapter.register
19
+
20
+ Paperclip::Attachment.default_options[:storage] = :azure_storage
21
+ Paperclip::Attachment.default_options[:tenant_id] = 'c881ddef-bf33-4574-a43b-1876a94c940a'
22
+ Paperclip::Attachment.default_options[:client_id] = 'e35cf4da-b3cd-4722-9923-deed0bf41a37'
23
+ Paperclip::Attachment.default_options[:client_secret] = 'J@NcRfUjXn2r5u7x!A%D*G-KaPdSgVkY'
24
+ Paperclip::Attachment.default_options[:resource] = 'https://mystorage.blob.core.windows.net'
25
+ Paperclip::Attachment.default_options[:storage_name] = 'mystorage'
26
+ Paperclip::Attachment.default_options[:container] = 'mycontainer'
27
+ ```
28
+ 3. Upload & access your image
29
+ ```ruby
30
+ image_content = '<some-image>'
31
+ model = model_class.create!(image: image_content) # upload image to azure
32
+ model.image.azure_url # get azure image url
33
+ ```
@@ -0,0 +1,112 @@
1
+ module Paperclip
2
+ module Storage
3
+ module AzureStorage
4
+ def self.extended(_base)
5
+ require 'azure/storage/blob'
6
+ require 'azure/storage/common'
7
+ end
8
+
9
+ def exists?(style_name = default_style)
10
+ container = @options[:container]
11
+ storage_client.list_blobs(
12
+ container,
13
+ prefix: path(style_name),
14
+ max_results: 1,
15
+ timeout: 60
16
+ ).present?
17
+ end
18
+
19
+ def flush_writes
20
+ container = @options[:container]
21
+ @queued_for_write.each do |style_name, file|
22
+ storage_client.create_block_blob(
23
+ container,
24
+ path(style_name),
25
+ file.read,
26
+ timeout: 60,
27
+ content_type: file.content_type,
28
+ content_length: file.size
29
+ )
30
+ end
31
+
32
+ after_flush_writes
33
+ @queued_for_write = {}
34
+ end
35
+
36
+ def flush_deletes
37
+ container = @options[:container]
38
+ @queued_for_delete.each { |path| storage_client.delete_blob(container, path, timeout: 60) }
39
+
40
+ @queued_for_delete = []
41
+ end
42
+
43
+ def copy_to_local_file(style, local_dest_path)
44
+ container = @options[:container]
45
+ _blob, content = storage_client.get_blob(container, path(style), timeout: 60)
46
+ ::File.open(local_dest_path, 'wb') { |local_file| local_file.write(content) }
47
+ end
48
+
49
+ def azure_url(style_name = default_style)
50
+ "#{@options[:resource]}/#{@options[:container]}/#{path(style_name)}".squeeze('/')
51
+ end
52
+
53
+ private
54
+
55
+ def storage_client
56
+ renew_expired_token
57
+ @storage_client ||= create_storage_client
58
+ end
59
+
60
+ def renew_expired_token
61
+ expired = @expires_on.present? && Time.now.to_i >= @expires_on.to_i
62
+ return unless expired
63
+
64
+ @access_token, @expires_on = create_access_token
65
+ @token_credential.renew_token(@access_token)
66
+ end
67
+
68
+ def create_storage_client
69
+ storage_name = @options[:storage_name]
70
+ @access_token, @expires_on = create_access_token
71
+ @token_credential = ::Azure::Storage::Common::Core::TokenCredential.new(@access_token)
72
+ token_signer = ::Azure::Storage::Common::Core::Auth::TokenSigner.new(@token_credential)
73
+ ::Azure::Storage::Blob::BlobService.new(storage_account_name: storage_name, signer: token_signer)
74
+ end
75
+
76
+ def create_access_token
77
+ tenant_id = @options[:tenant_id]
78
+ client_id = @options[:client_id]
79
+ client_secret = @options[:client_secret]
80
+ resource = @options[:resource]
81
+ grant_type = 'client_credentials'
82
+
83
+ requested_at = Time.now.to_i
84
+ response = faraday_client.post("#{tenant_id}/oauth2/token") do |request|
85
+ request.headers['Content-Type'] = 'application/x-www-form-urlencoded'
86
+ request.headers['Accept'] = 'application/json'
87
+ request_payload = {
88
+ client_id: client_id,
89
+ client_secret: client_secret,
90
+ resource: resource,
91
+ grant_type: grant_type
92
+ }
93
+ request.body = URI.encode_www_form(request_payload)
94
+ end
95
+
96
+ access_token = response.body['access_token']
97
+ expires_on = requested_at + response.body['expires_in'].to_i
98
+
99
+ [access_token, expires_on]
100
+ end
101
+
102
+ def faraday_client
103
+ @faraday_client ||= Faraday.new('https://login.microsoftonline.com') do |client|
104
+ client.request :retry
105
+ client.response :json
106
+ client.response :raise_error
107
+ client.adapter :net_http
108
+ end
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1 @@
1
+ require_relative 'paperclip/storage/azure_storage'
@@ -0,0 +1,26 @@
1
+ Gem::Specification.new do |s|
2
+ s.name = 'paperclip-azure-storage'
3
+ s.version = '0.1.5'
4
+ s.licenses = ['MIT']
5
+ s.summary = "Paperclip Adapter for Azure Storage"
6
+ s.description = 'paperclip-azure-storage is a paperclip adapter for azure storage that use service principal authentication'
7
+ s.authors = ["Irsyad Rizaldi"]
8
+ s.email = 'irsyad.rizaldi97@gmail.com'
9
+ s.homepage = 'https://github.com/dadangeuy/paperclip-azure-storage'
10
+ s.metadata = { "source_code_uri" => "https://github.com/dadangeuy/paperclip-azure-storage" }
11
+
12
+ s.files = `git ls-files`.split("\n")
13
+ s.test_files = `git ls-files -- {spec,features}/*`.split("\n")
14
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
15
+ s.require_paths = ['lib']
16
+
17
+ s.required_ruby_version = ">= 2.5.0"
18
+
19
+ s.add_dependency 'azure-storage-blob', '>= 1.0.0', '< 3.0.0'
20
+ s.add_dependency 'paperclip', '>= 5.1.0', '< 7.0.0'
21
+
22
+ s.add_development_dependency 'activerecord', '~> 6.1'
23
+ s.add_development_dependency 'rspec', '~> 3.10'
24
+ s.add_development_dependency 'sqlite3', '~>1.4'
25
+ s.add_development_dependency 'webmock', '~> 3.14'
26
+ end
@@ -0,0 +1,58 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <EnumerationResults ContainerName="https://myaccount.blob.core.windows.net/mycontainer">
3
+ <MaxResults>4</MaxResults>
4
+ <Blobs>
5
+ <Blob>
6
+ <Name>blob1.txt</Name>
7
+ <Url>https://myaccount.blob.core.windows.net/mycontainer/blob1.txt</Url>
8
+ <Properties>
9
+ <Last-Modified>Sun, 27 Sep 2009 18:41:57 GMT</Last-Modified>
10
+ <Etag>0x8CAE7D55D050B8B</Etag>
11
+ <Content-Length>8</Content-Length>
12
+ <Content-Type>text/html</Content-Type>
13
+ <Content-Encoding/>
14
+ <Content-Language>en-US</Content-Language>
15
+ <Content-MD5/>
16
+ <Cache-Control>no-cache</Cache-Control>
17
+ <BlobType>BlockBlob</BlobType>
18
+ <LeaseStatus>unlocked</LeaseStatus>
19
+ </Properties>
20
+ </Blob>
21
+ <Blob>
22
+ <Name>blob2.txt</Name>
23
+ <Url>https://myaccount.blob.core.windows.net/mycontainer/blob2.txt</Url>
24
+ <Properties>
25
+ <Last-Modified>Sun, 27 Sep 2009 12:18:50 GMT</Last-Modified>
26
+ <Etag>0x8CAE7D55CF6C339</Etag>
27
+ <Content-Length>100</Content-Length>
28
+ <Content-Type>text/html</Content-Type>
29
+ <Content-Encoding/>
30
+ <Content-Language>en-US</Content-Language>
31
+ <Content-MD5/>
32
+ <Cache-Control>no-cache</Cache-Control>
33
+ <BlobType>BlockBlob</BlobType>
34
+ <LeaseStatus>unlocked</LeaseStatus>
35
+ </Properties>
36
+ </Blob>
37
+ <BlobPrefix>
38
+ <Name>myfolder/</Name>
39
+ </BlobPrefix>
40
+ <Blob>
41
+ <Name>newblob1.txt</Name>
42
+ <Url>https://myaccount.blob.core.windows.net/mycontainer/newblob1.txt</Url>
43
+ <Properties>
44
+ <Last-Modified>Sun, 27 Sep 2009 16:31:57 GMT</Last-Modified>
45
+ <Etag>0x8CAE7D55CF6C339</Etag>
46
+ <Content-Length>25</Content-Length>
47
+ <Content-Type>text/html</Content-Type>
48
+ <Content-Encoding/>
49
+ <Content-Language>en-US</Content-Language>
50
+ <Content-MD5/>
51
+ <Cache-Control>no-cache</Cache-Control>
52
+ <BlobType>BlockBlob</BlobType>
53
+ <LeaseStatus>unlocked</LeaseStatus>
54
+ </Properties>
55
+ </Blob>
56
+ </Blobs>
57
+ <NextMarker>newblob2.txt</NextMarker>
58
+ </EnumerationResults>
@@ -0,0 +1,135 @@
1
+ require './spec/spec_helper'
2
+
3
+ class MockPaperclip < ActiveRecord::Base
4
+ include Paperclip::Glue
5
+
6
+ has_attached_file(
7
+ :image,
8
+ path: 'img/missions/:reversed_path/:style/:filename',
9
+ url: 'img/missions/:reversed_path/:style/:filename',
10
+ storage: :azure_storage,
11
+ tenant_id: 'tenant-id',
12
+ client_id: 'client-id',
13
+ resource: 'resource',
14
+ storage_name: 'storage-name',
15
+ container: 'container'
16
+ )
17
+ validates_attachment_content_type :image, content_type: /\Aimage/
18
+ end
19
+
20
+ describe 'AzureStorage' do
21
+ before(:all, 'create mock table') do
22
+ MockPaperclip.connection.create_table(MockPaperclip.table_name, force: true) do |table|
23
+ table.column :image_content_type, :string
24
+ table.column :image_file_name, :string
25
+ table.column :image_file_size, :integer
26
+ table.column :image_updated_at, :datetime
27
+ table.column :image_fingerprint, :string
28
+ end
29
+ end
30
+
31
+ before 'mock login' do
32
+ method = :post
33
+ uri = %r{https://login.microsoftonline.com/.+/oauth2/token}
34
+ status = 200
35
+ body = {
36
+ token_type: 'Bearer',
37
+ expires_in: '3599',
38
+ ext_expires_in: '3599',
39
+ expires_on: '1634195094',
40
+ not_before: '1634191194',
41
+ resource: 'resource',
42
+ access_token: 'access_token'
43
+ }.to_json
44
+ headers = { 'Content-Type': 'application/json' }
45
+
46
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
47
+ end
48
+
49
+ before 'mock create_block_blob' do
50
+ method = :put
51
+ uri = %r{https://[a-z-]+.blob.core.windows.net/container/.+}
52
+ status = 201
53
+ body = ''
54
+ headers = {}
55
+
56
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
57
+ end
58
+
59
+ before 'mock list_blobs' do
60
+ method = :get
61
+ uri = %r{https://[a-z-]+.blob.core.windows.net/container\?}
62
+ status = 200
63
+ body = File.read('./spec/fixtures/list_blobs.xml')
64
+
65
+ headers = {}
66
+
67
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
68
+ end
69
+
70
+ before 'mock get_blob' do
71
+ method = :get
72
+ uri = %r{https://storage-name.blob.core.windows.net/container/.+}
73
+ status = 200
74
+ body = image
75
+ headers = {}
76
+
77
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
78
+ end
79
+
80
+ before 'mock delete_blob' do
81
+ method = :delete
82
+ uri = %r{https://[a-z-]+.blob.core.windows.net/container/.+}
83
+ status = 202
84
+ body = ''
85
+ headers = {}
86
+
87
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
88
+ end
89
+
90
+ let(:image) { 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7' }
91
+
92
+ describe 'upload image' do
93
+ subject { MockPaperclip.create(image: image) }
94
+
95
+ it 'success' do
96
+ expect { subject }.not_to raise_error
97
+ end
98
+
99
+ describe '500 response' do
100
+ before 'mock create_block_blob' do
101
+ method = :put
102
+ uri = %r{https://[a-z-]+.blob.core.windows.net/container/.+}
103
+ status = 500
104
+ body = ''
105
+ headers = {}
106
+
107
+ stub_request(method, uri).to_return(status: status, body: body, headers: headers)
108
+ end
109
+
110
+ it 'raise error' do
111
+ expect { subject }.to raise_error(Azure::Core::Http::HTTPError)
112
+ end
113
+ end
114
+ end
115
+
116
+ describe 'delete image' do
117
+ let(:model) { MockPaperclip.create(image: image) }
118
+
119
+ subject { model.image.destroy }
120
+
121
+ it 'success' do
122
+ expect { subject }.not_to raise_error
123
+ end
124
+ end
125
+
126
+ describe 'download image' do
127
+ let(:model) { MockPaperclip.create(image: image) }
128
+
129
+ subject { model.image.copy_to_local_file('original', "/tmp/#{SecureRandom.hex(4)}") }
130
+
131
+ it 'success' do
132
+ expect { subject }.not_to raise_error
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,12 @@
1
+ require './lib/paperclip/storage/azure_storage'
2
+ require 'rspec'
3
+ require 'paperclip'
4
+ require 'active_record'
5
+ require 'webmock/rspec'
6
+
7
+ ActiveRecord::Base.establish_connection(
8
+ adapter: 'sqlite3',
9
+ database: ':memory:'
10
+ )
11
+
12
+ Paperclip::DataUriAdapter.register
metadata ADDED
@@ -0,0 +1,156 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: paperclip-azure-storage
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.5
5
+ platform: ruby
6
+ authors:
7
+ - Irsyad Rizaldi
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-11-01 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: azure-storage-blob
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 1.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: 3.0.0
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 1.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 3.0.0
33
+ - !ruby/object:Gem::Dependency
34
+ name: paperclip
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 5.1.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: 7.0.0
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 5.1.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: 7.0.0
53
+ - !ruby/object:Gem::Dependency
54
+ name: activerecord
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '6.1'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '6.1'
67
+ - !ruby/object:Gem::Dependency
68
+ name: rspec
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '3.10'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '3.10'
81
+ - !ruby/object:Gem::Dependency
82
+ name: sqlite3
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '1.4'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '1.4'
95
+ - !ruby/object:Gem::Dependency
96
+ name: webmock
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '3.14'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '3.14'
109
+ description: paperclip-azure-storage is a paperclip adapter for azure storage that
110
+ use service principal authentication
111
+ email: irsyad.rizaldi97@gmail.com
112
+ executables: []
113
+ extensions: []
114
+ extra_rdoc_files: []
115
+ files:
116
+ - ".github/workflows/publish.yml"
117
+ - ".github/workflows/review.yml"
118
+ - ".gitignore"
119
+ - ".ruby-gemset"
120
+ - ".ruby-version"
121
+ - Gemfile
122
+ - Gemfile.lock
123
+ - LICENSE.md
124
+ - README.md
125
+ - lib/paperclip-azure-storage.rb
126
+ - lib/paperclip/storage/azure_storage.rb
127
+ - paperclip-azure-storage.gemspec
128
+ - spec/fixtures/list_blobs.xml
129
+ - spec/lib/paperclip/storage/azure_storage_spec.rb
130
+ - spec/spec_helper.rb
131
+ homepage: https://github.com/dadangeuy/paperclip-azure-storage
132
+ licenses:
133
+ - MIT
134
+ metadata:
135
+ source_code_uri: https://github.com/dadangeuy/paperclip-azure-storage
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ requirements:
142
+ - - ">="
143
+ - !ruby/object:Gem::Version
144
+ version: 2.5.0
145
+ required_rubygems_version: !ruby/object:Gem::Requirement
146
+ requirements:
147
+ - - ">="
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ requirements: []
151
+ rubyforge_project:
152
+ rubygems_version: 2.7.6.3
153
+ signing_key:
154
+ specification_version: 4
155
+ summary: Paperclip Adapter for Azure Storage
156
+ test_files: []