condo 2.0.0 → 2.0.1

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