condo 2.0.0 → 2.0.1

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: 92cc7003ecce7499b7c92bc3aed7facde40cf79d
4
- data.tar.gz: a4b4e8d9a93bace70e3c236d13d23d97116dd44e
3
+ metadata.gz: f1827a85ce98d40fd5de3f69857aeaa3944f29d3
4
+ data.tar.gz: f55839e3df14e84e133d949c101598283341ab0b
5
5
  SHA512:
6
- metadata.gz: c45dcf3f6aed9abe71705db52d83ffd3731c105259d10d43672f2deff33d2e19bcb6e3d7e77a7b47e373ef882ddf3ffc9949661363460a103f25356787e402cc
7
- data.tar.gz: bbd682e45ad4a9f651d77abd5cae57e14b163ca476d38cc89c78ff8b3678c35ab37a9c6df36a601e2f28339a605ff67958a2bef7faf82d59f661aad6a6ba3ebd
6
+ metadata.gz: 56bdd19a5ccc8c1873038c60d37d373a62a6ec19d5617bae731fa9f2e5b24a0319fc1e902742dbc5db35b756eae9571e892f3d8c6842bea2d6cd2cc72ed30e9b
7
+ data.tar.gz: 6ecd0f2805ef502c2114c2049b271aded858eb811fb19968d8f9a2a0bdbffe393b4d99fe7caecd7d8c103adefb7aac96f84ef650ac9f9d0a6fd3371a6031d8e2
@@ -7,6 +7,14 @@ require 'condo/configuration'
7
7
 
8
8
 
9
9
  module Condo
10
+ module Condo::Strata
11
+ autoload :AmazonS3, File.expand_path('../condo/strata/amazon_s3', __FILE__)
12
+ autoload :GoogleCloudStorage, File.expand_path('../condo/strata/google_cloud_storage', __FILE__)
13
+ autoload :MicrosoftAzure, File.expand_path('../condo/strata/microsoft_azure', __FILE__)
14
+ autoload :OpenStackSwift, File.expand_path('../condo/strata/open_stack_swift', __FILE__)
15
+ end
16
+
17
+
10
18
  def self.included(base)
11
19
  base.class_eval do
12
20
 
@@ -75,7 +75,7 @@ DATA
75
75
  :headers => {},
76
76
  :host => "#{bucket}.storage.googleapis.com",
77
77
  :idempotent => true,
78
- :path => '?cors' # There is an issue with Fog where this isn't included as a canonical_resource
78
+ :path => '?cors'
79
79
  )
80
80
  end
81
81
 
@@ -191,7 +191,6 @@ DATA
191
191
  def set_part(options)
192
192
  resp = get_parts(options, true)
193
193
  resp[:type] = :resume_upload
194
- resp[:type] = :resume_upload
195
194
  return resp
196
195
  end
197
196
 
@@ -0,0 +1,188 @@
1
+ # encoding: utf-8
2
+ # Good reference: http://gauravmantri.com/2013/02/16/uploading-large-files-in-windows-azure-blob-storage-using-shared-access-signature-html-and-javascript/
3
+
4
+ require 'azure' # Tested against 0.7.1
5
+ require 'azure/blob/auth/shared_access_signature'
6
+
7
+ require 'uri'
8
+
9
+
10
+ module Condo; end
11
+ module Condo::Strata; end
12
+
13
+
14
+ class Condo::Strata::MicrosoftAzure
15
+ def initialize(options)
16
+ @options = {
17
+ :name => :MicrosoftAzure
18
+ }.merge!(options)
19
+
20
+ raise ArgumentError, 'Azure Account Name missing' if @options[:account_name].nil?
21
+ raise ArgumentError, 'Azure Access Key missing' if @options[:access_key].nil?
22
+
23
+ @options[:blob_host] = "https://#{@options[:account_name]}.blob.core.windows.net" if @options[:blob_host].nil?
24
+
25
+ @options[:location] = @options[:blob_host].to_sym
26
+ end
27
+
28
+
29
+ def name
30
+ @options[:name]
31
+ end
32
+
33
+ def location
34
+ @options[:location]
35
+ end
36
+
37
+ def enable_cors(origin = 'http://localhost:9000')
38
+ origins = origin.class == Array ? origin : [origin]
39
+ blobs = azure_connection
40
+
41
+ p = blobs.get_service_properties
42
+ p.cors = Azure::Service::Cors.new do |cors|
43
+ cors.cors_rules = []
44
+ cors.cors_rules.push(Azure::Service::CorsRule.new { |cors_rule|
45
+ cors_rule.allowed_origins = origins
46
+ cors_rule.allowed_methods = ["GET", "HEAD", "PUT", "POST", "OPTIONS"]
47
+ cors_rule.max_age_in_seconds = 60
48
+ cors_rule.exposed_headers = ["x-ms-*", "etag", "content-type", "content-md5"]
49
+ cors_rule.allowed_headers = ["x-ms-blob-type", "x-ms-version", "content-md5", "content-type"]
50
+ })
51
+ end
52
+
53
+ blobs.set_service_properties(p)
54
+ end
55
+
56
+
57
+ # Create a signed URL for accessing a private file
58
+ def get_object(options)
59
+ options = {}.merge!(options) # Need to deep copy here
60
+ options[:object_options] = {
61
+ verb: :get,
62
+ headers: {},
63
+ permission: 'r',
64
+ expires: 5.minutes.from_now
65
+ }.merge!(options[:object_options] || {})
66
+ options.merge!(@options)
67
+
68
+ sign_request(options)[:url]
69
+ end
70
+
71
+
72
+ # Creates a new upload request (either single shot or multi-part)
73
+ # => Passed: bucket_name, object_key, object_options, file_size
74
+ def new_upload(options)
75
+ options = build_request(options)
76
+ options[:object_options][:headers]['x-ms-blob-type'] = 'BlockBlob'
77
+
78
+ # Decide what type of request is being sent
79
+ if options[:file_size] > 2.megabytes
80
+ return {
81
+ signature: sign_request(options),
82
+ type: :chunked_upload
83
+ }
84
+ else
85
+ return {
86
+ signature: sign_request(options),
87
+ type: :direct_upload
88
+ }
89
+ end
90
+ end
91
+
92
+
93
+ # No signing required for this request in Azure
94
+ def get_parts(options)
95
+ {
96
+ type: :parts,
97
+ current_part: options[:resumable_id]
98
+ }
99
+ end
100
+
101
+
102
+ # Returns the requests for uploading parts and completing a resumable upload
103
+ def set_part(options)
104
+ options = build_request(options)
105
+
106
+ if options[:part] == 'finish'
107
+ options[:object_options][:headers]['Content-Type'] = 'application/xml; charset=UTF-8'
108
+
109
+ return {
110
+ signature: sign_request(options),
111
+ type: :finish
112
+ }
113
+ else
114
+ options = build_request(options)
115
+ options[:object_options][:headers]['x-ms-blob-type'] = 'BlockBlob'
116
+ # MaxID for a part is 100_000, hence rjust 6
117
+ options[:partId] = Base64.encode64(options[:part].to_s.rjust(6, '0')).gsub("\n", '')
118
+
119
+ return {
120
+ signature: sign_request(options),
121
+ type: :part_upload
122
+ }
123
+ end
124
+ end
125
+
126
+
127
+ def azure_connection
128
+ options = {
129
+ storage_account_name: @options[:account_name],
130
+ storage_access_key: @options[:access_key]
131
+ }
132
+ options[:storage_blob_host] = @options[:location].to_s if @options[:location]
133
+
134
+ client = Azure.client(options)
135
+ client.blobs
136
+ end
137
+
138
+
139
+ def destroy(upload)
140
+ blobs = azure_connection
141
+ blobs.delete_blob(upload.bucket_name, upload.object_key)
142
+ end
143
+
144
+
145
+
146
+ protected
147
+
148
+
149
+
150
+ def build_request(options)
151
+ options = {}.merge!(options) # Need to deep copy here
152
+ options[:object_options] = {
153
+ verb: :put,
154
+ headers: {},
155
+ permission: 'w',
156
+ expires: 5.minutes.from_now
157
+ }.merge!(options[:object_options] || {})
158
+ options.merge!(@options)
159
+
160
+ options[:object_options][:headers]['Content-Md5'] = options[:file_id] if options[:file_id].present? && options[:object_options][:headers]['Content-Md5'].nil?
161
+ options
162
+ end
163
+
164
+ def sign_request(options)
165
+ signer = ::Azure::Blob::Auth::SharedAccessSignature.new(@options[:account_name], @options[:access_key])
166
+ url = URI "#{@options[:blob_host]}/#{options[:bucket_name]}/#{options[:object_key]}"
167
+ url = signer.signed_uri(url, {
168
+ permissions: options[:object_options][:permission],
169
+ expires: options[:object_options][:expires].utc.iso8601,
170
+ resource: 'b'
171
+ })
172
+
173
+ # Adjust the request for chunked uploads
174
+ if options[:partId]
175
+ url.query += "&comp=block&blockid=#{options[:partId]}"
176
+ elsif options[:part] == 'finish'
177
+ url.query += '&comp=blocklist'
178
+ end
179
+
180
+ # Finish building the request
181
+ return {
182
+ verb: options[:object_options][:verb].to_s.upcase,
183
+ url: url.to_s,
184
+ headers: options[:object_options][:headers]
185
+ }
186
+ end
187
+ end
188
+
@@ -8,8 +8,7 @@ module Condo::Strata; end
8
8
  #
9
9
 
10
10
  class Condo::Strata::OpenStackSwift
11
-
12
- MIN_CHUNK_SIZE = 2097152
11
+ MIN_CHUNK_SIZE = 2.megabytes
13
12
 
14
13
  def initialize(options)
15
14
  @options = {
@@ -1,3 +1,3 @@
1
1
  module Condo
2
- VERSION = "2.0.0"
2
+ VERSION = "2.0.1"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: condo
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 2.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Stephen von Takach
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-03-01 00:00:00.000000000 Z
11
+ date: 2016-03-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rails
@@ -38,20 +38,34 @@ dependencies:
38
38
  - - ">="
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: azure
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - '='
46
+ - !ruby/object:Gem::Version
47
+ version: 0.7.1
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - '='
53
+ - !ruby/object:Gem::Version
54
+ version: 0.7.1
41
55
  - !ruby/object:Gem::Dependency
42
56
  name: rspec
43
57
  requirement: !ruby/object:Gem::Requirement
44
58
  requirements:
45
- - - ">="
59
+ - - "~>"
46
60
  - !ruby/object:Gem::Version
47
- version: '2.14'
61
+ version: '3.4'
48
62
  type: :development
49
63
  prerelease: false
50
64
  version_requirements: !ruby/object:Gem::Requirement
51
65
  requirements:
52
- - - ">="
66
+ - - "~>"
53
67
  - !ruby/object:Gem::Version
54
- version: '2.14'
68
+ version: '3.4'
55
69
  description: Provides signed upload signatures to your users browsers so they can
56
70
  upload directly to cloud storage providers
57
71
  email:
@@ -69,6 +83,7 @@ files:
69
83
  - lib/condo/errors.rb
70
84
  - lib/condo/strata/amazon_s3.rb
71
85
  - lib/condo/strata/google_cloud_storage.rb
86
+ - lib/condo/strata/microsoft_azure.rb
72
87
  - lib/condo/strata/open_stack_swift.rb
73
88
  - lib/condo/version.rb
74
89
  - lib/tasks/condo_tasks.rake