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 +4 -4
- data/lib/condo.rb +8 -0
- data/lib/condo/strata/google_cloud_storage.rb +1 -2
- data/lib/condo/strata/microsoft_azure.rb +188 -0
- data/lib/condo/strata/open_stack_swift.rb +1 -2
- data/lib/condo/version.rb +1 -1
- metadata +21 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f1827a85ce98d40fd5de3f69857aeaa3944f29d3
|
4
|
+
data.tar.gz: f55839e3df14e84e133d949c101598283341ab0b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 56bdd19a5ccc8c1873038c60d37d373a62a6ec19d5617bae731fa9f2e5b24a0319fc1e902742dbc5db35b756eae9571e892f3d8c6842bea2d6cd2cc72ed30e9b
|
7
|
+
data.tar.gz: 6ecd0f2805ef502c2114c2049b271aded858eb811fb19968d8f9a2a0bdbffe393b4d99fe7caecd7d8c103adefb7aac96f84ef650ac9f9d0a6fd3371a6031d8e2
|
data/lib/condo.rb
CHANGED
@@ -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'
|
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
|
+
|
data/lib/condo/version.rb
CHANGED
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.
|
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-
|
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: '
|
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: '
|
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
|