qoobaa-d2s3 0.1.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.5
1
+ 0.2.0
data/d2s3.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{d2s3}
5
- s.version = "0.1.5"
5
+ s.version = "0.2.0"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["Matthew Williams", "Jakub Kuźma"]
@@ -20,13 +20,11 @@ Gem::Specification.new do |s|
20
20
  "Rakefile",
21
21
  "VERSION",
22
22
  "d2s3.gemspec",
23
- "generators/d2s3/d2s3.rb",
23
+ "generators/d2s3/d2s3_generator.rb",
24
24
  "generators/d2s3/templates/initializers/d2s3.rb",
25
25
  "lib/d2s3.rb",
26
26
  "lib/d2s3/configuration.rb",
27
- "lib/d2s3/signature.rb",
28
27
  "lib/d2s3/view_helpers.rb",
29
- "test/signature_test.rb",
30
28
  "test/test_helper.rb"
31
29
  ]
32
30
  s.homepage = %q{http://github.com/qoobaa/d2s3}
@@ -35,8 +33,7 @@ Gem::Specification.new do |s|
35
33
  s.rubygems_version = %q{1.3.4}
36
34
  s.summary = %q{direct to s3}
37
35
  s.test_files = [
38
- "test/signature_test.rb",
39
- "test/test_helper.rb"
36
+ "test/test_helper.rb"
40
37
  ]
41
38
 
42
39
  if s.respond_to? :specification_version then
@@ -1,6 +1,6 @@
1
1
  require 'rbconfig'
2
2
 
3
- class D2S3Generator < Rails::Generator::Base
3
+ class D2s3Generator < Rails::Generator::Base
4
4
  def manifest
5
5
  record do |m|
6
6
  m.directory "config"
@@ -1,5 +1,5 @@
1
- D2S3.configuration do |config|
1
+ D2s3.configuration do |config|
2
2
  config.access_key_id = "your_access_key_id"
3
3
  config.secret_access_key = "your_secret_access_key"
4
- config.bucket = "your_application_name"
4
+ config.bucket = "your_bucket_name"
5
5
  end
data/lib/d2s3.rb CHANGED
@@ -1,3 +1,8 @@
1
- require 'd2s3/signature'
1
+ require 'base64'
2
+ require 'openssl'
3
+ require 'digest/sha1'
4
+
2
5
  require 'd2s3/configuration'
3
6
  require 'd2s3/view_helpers'
7
+
8
+ ActionView::Base.send(:include, D2s3::ViewHelpers) if defined?(ActionView::Base)
@@ -1,6 +1,6 @@
1
1
  require "singleton"
2
2
 
3
- module D2S3
3
+ module D2s3
4
4
  class Configuration
5
5
  include Singleton
6
6
 
@@ -1,50 +1,52 @@
1
- require 'base64'
2
-
3
- module D2S3
1
+ module D2s3
4
2
  module ViewHelpers
5
- include D2S3::Signature
6
-
7
3
  def s3_upload_form_tag(options = {})
8
- bucket = D2S3.configuration.bucket
9
- access_key_id = D2S3.configuration.access_key_id
10
- protocol = options[:protocol] || "http"
11
- key = options[:key] || ''
12
- redirect = options[:redirect] || '/'
13
- acl = options[:acl] || 'public-read'
14
- expiration_date = (options[:expiration_date] || 10.hours).from_now.strftime('%Y-%m-%dT%H:%M:%S.000Z')
15
- max_filesize = options[:max_filesize] || 1.megabyte
16
- submit_button = options[:submit_button] || %(<input type="submit" value="#{I18n.t("button.upload", :default => "Upload")}">)
4
+ bucket = D2s3.configuration.bucket
5
+ access_key_id = D2s3.configuration.access_key_id
6
+ secret_access_key = D2s3.configuration.secret_access_key
7
+
8
+ raise "Please configure D2s3 before use" unless bucket and access_key_id and secret_access_key
17
9
 
18
- options[:form] ||= {}
19
- options[:form][:id] ||= 'upload-form'
20
- options[:form][:class] ||= 'upload-form'
10
+ protocol = options.delete(:protocol) || "http"
11
+ key = options.delete(:key) || ""
12
+ redirect = options.delete(:redirect) || "/"
13
+ acl = options.delete(:acl) || "public-read"
14
+ expiration_date = (options.delete(:expiration_date) || 10.hours).from_now.strftime("%Y-%m-%dT%H:%M:%S.000Z")
15
+ max_filesize = options.delete(:max_filesize) || 1.megabyte
16
+ submit = options.delete(:submit_button) || submit_tag(I18n.t("button.upload", :default => "Upload"))
21
17
 
22
- policy = Base64.encode64(
23
- %({"expiration": "#{expiration_date}",
24
- "conditions": [
25
- {"bucket": "#{bucket}"},
26
- ["starts-with", "$key", "#{key}"],
27
- {"acl": "#{acl}"},
28
- {"success_action_redirect": "#{redirect}"},
29
- ["content-length-range", 0, #{max_filesize}]
30
- ]
31
- })).gsub(/\n|\r/, '')
18
+ policy_document = <<-eos
19
+ {
20
+ "expiration": "#{expiration_date}",
21
+ "conditions":
22
+ [
23
+ {"bucket": "#{bucket}"},
24
+ ["starts-with", "$key", "#{key}"],
25
+ {"acl": "#{acl}"},
26
+ {"success_action_redirect": "#{redirect}"},
27
+ ["content-length-range", 0, #{max_filesize}]
28
+ ]
29
+ }
30
+ eos
32
31
 
33
- signature = b64_hmac_sha1(D2S3.configuration.secret_access_key, policy)
34
- out = ""
35
- out << %(
36
- <form action="#{protocol}://#{bucket}.s3.amazonaws.com/" method="post" enctype="multipart/form-data" id="#{options[:form][:id]}" class="#{options[:form][:class]}" style="#{options[:form][:style]}">
37
- <input type="hidden" name="key" value="#{key}/${filename}">
38
- <input type="hidden" name="AWSAccessKeyId" value="#{access_key_id}">
39
- <input type="hidden" name="acl" value="#{acl}">
40
- <input type="hidden" name="success_action_redirect" value="#{redirect}">
41
- <input type="hidden" name="policy" value="#{policy}">
42
- <input type="hidden" name="signature" value="#{signature}">
43
- <input name="file" type="file">#{submit_button}
44
- </form>
45
- )
32
+ policy = Base64.encode64(policy_document).gsub("\n","")
33
+ signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new("sha1"), secret_access_key, policy)).gsub("\n","")
34
+
35
+ options[:action] ||= "#{protocol}://#{bucket}.s3.amazonaws.com/"
36
+ options[:method] ||= "post"
37
+ options[:enctype] ||= "multipart/form-data"
38
+
39
+ content_tag :form, options do
40
+ content = ""
41
+ content << hidden_field_tag("key", "#{key}/${filename}")
42
+ content << hidden_field_tag("AWSAccessKeyId", access_key_id)
43
+ content << hidden_field_tag("acl", acl)
44
+ content << hidden_field_tag("success_action_redirect", redirect)
45
+ content << hidden_field_tag("policy", policy)
46
+ content << hidden_field_tag("signature", signature)
47
+ content << file_field_tag("file")
48
+ content << submit
49
+ end
46
50
  end
47
51
  end
48
52
  end
49
-
50
- ActionView::Base.send(:include, D2S3::ViewHelpers) if defined?(ActionView::Base)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: qoobaa-d2s3
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.5
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matthew Williams
@@ -31,13 +31,11 @@ files:
31
31
  - Rakefile
32
32
  - VERSION
33
33
  - d2s3.gemspec
34
- - generators/d2s3/d2s3.rb
34
+ - generators/d2s3/d2s3_generator.rb
35
35
  - generators/d2s3/templates/initializers/d2s3.rb
36
36
  - lib/d2s3.rb
37
37
  - lib/d2s3/configuration.rb
38
- - lib/d2s3/signature.rb
39
38
  - lib/d2s3/view_helpers.rb
40
- - test/signature_test.rb
41
39
  - test/test_helper.rb
42
40
  has_rdoc: false
43
41
  homepage: http://github.com/qoobaa/d2s3
@@ -66,5 +64,4 @@ signing_key:
66
64
  specification_version: 3
67
65
  summary: direct to s3
68
66
  test_files:
69
- - test/signature_test.rb
70
67
  - test/test_helper.rb
@@ -1,194 +0,0 @@
1
- module D2S3
2
- module Signature
3
- HEXCASE = false # hex output format. false - lowercase; true - uppercase
4
- B64PAD = "=" # base-64 pad character. "=" for strict RFC compliance
5
- CHRSH = 8 # bits per input character. 8 - ASCII; 16 - Unicode
6
-
7
- def hex_sha1(s)
8
- return binb2hex(core_sha1(str2binb(s), s.length * CHRSH))
9
- end
10
-
11
- def b64_hmac_sha1(key, data)
12
- return binb2b64(core_hmac_sha1(key, data))
13
- end
14
-
15
- # 32-bit left shift
16
- def js_shl(num, count)
17
- v = (num << count) & 0xffffffff
18
- v > 2**31 ? v - 2**32 : v
19
- end
20
-
21
- # 32-bit zero-fill right shift (>>>)
22
- def js_shr_zf(num, count)
23
- num >> count & (2**(32-count)-1)
24
- end
25
-
26
- # Calculate the SHA-1 of an array of big-endian words, and a bit length
27
- def core_sha1(x, len)
28
- # append padding
29
- x[len >> 5] ||= 0
30
- x[len >> 5] |= 0x80 << (24 - len % 32)
31
- x[((len + 64 >> 9) << 4) + 15] = len
32
-
33
- w = Array.new(80, 0)
34
- a = 1732584193
35
- b = -271733879
36
- c = -1732584194
37
- d = 271733878
38
- e = -1009589776
39
-
40
- #for(var i = 0; i < x.length; i += 16)
41
- i = 0
42
- while(i < x.length)
43
- olda = a
44
- oldb = b
45
- oldc = c
46
- oldd = d
47
- olde = e
48
-
49
- #for(var j = 0; j < 80; j++)
50
- j = 0
51
- while(j < 80)
52
- if(j < 16)
53
- w[j] = x[i + j] || 0
54
- else
55
- w[j] = rol(w[j-3] ^ w[j-8] ^ w[j-14] ^ w[j-16], 1)
56
- end
57
-
58
- t = safe_add(safe_add(rol(a, 5), sha1_ft(j, b, c, d)),
59
- safe_add(safe_add(e, w[j]), sha1_kt(j)))
60
- e = d
61
- d = c
62
- c = rol(b, 30)
63
- b = a
64
- a = t
65
- j += 1
66
- end
67
-
68
- a = safe_add(a, olda)
69
- b = safe_add(b, oldb)
70
- c = safe_add(c, oldc)
71
- d = safe_add(d, oldd)
72
- e = safe_add(e, olde)
73
- i += 16
74
- end
75
- return [a, b, c, d, e]
76
- end
77
-
78
- # Perform the appropriate triplet combination function for the current
79
- # iteration
80
- def sha1_ft(t, b, c, d)
81
- return (b & c) | ((~b) & d) if(t < 20)
82
- return b ^ c ^ d if(t < 40)
83
- return (b & c) | (b & d) | (c & d) if(t < 60)
84
- return b ^ c ^ d;
85
- end
86
-
87
- # Determine the appropriate additive constant for the current iteration
88
- def sha1_kt(t)
89
- return (t < 20) ? 1518500249 : (t < 40) ? 1859775393 :
90
- (t < 60) ? -1894007588 : -899497514
91
- end
92
-
93
- # Calculate the HMAC-SHA1 of a key and some data
94
- def core_hmac_sha1(key, data)
95
- bkey = str2binb(key)
96
- if(bkey.length > 16)
97
- bkey = core_sha1(bkey, key.length * CHRSH)
98
- end
99
-
100
- ipad = Array.new(16, 0)
101
- opad = Array.new(16, 0)
102
- #for(var i = 0; i < 16; i++)
103
- i = 0
104
- while(i < 16)
105
- ipad[i] = (bkey[i] || 0) ^ 0x36363636
106
- opad[i] = (bkey[i] || 0) ^ 0x5C5C5C5C
107
- i += 1
108
- end
109
-
110
- hash = core_sha1((ipad + str2binb(data)), 512 + data.length * CHRSH)
111
- return core_sha1((opad + hash), 512 + 160)
112
- end
113
-
114
- # Add integers, wrapping at 2^32. This uses 16-bit operations internally
115
- # to work around bugs in some JS interpreters.
116
- def safe_add(x, y)
117
- v = (x+y) % (2**32)
118
- return v > 2**31 ? v- 2**32 : v
119
- end
120
-
121
- # Bitwise rotate a 32-bit number to the left.
122
- def rol(num, cnt)
123
- #return (num << cnt) | (num >>> (32 - cnt))
124
- return (js_shl(num, cnt)) | (js_shr_zf(num, 32 - cnt))
125
- end
126
-
127
- # Convert an 8-bit or 16-bit string to an array of big-endian words
128
- # In 8-bit function, characters >255 have their hi-byte silently ignored.
129
- def str2binb(str)
130
- bin = []
131
- mask = (1 << CHRSH) - 1
132
- #for(var i = 0; i < str.length * CHRSH; i += CHRSH)
133
- i = 0
134
- while(i < str.length * CHRSH)
135
- bin[i>>5] ||= 0
136
- byte = str.respond_to?(:getbyte) ? str.getbyte(i / CHRSH) : str[i / CHRSH]
137
- bin[i>>5] |= (byte & mask) << (32 - CHRSH - i%32)
138
- i += CHRSH
139
- end
140
- return bin
141
- end
142
-
143
- # Convert an array of big-endian words to a string
144
- # function binb2str(bin)
145
- # {
146
- # var str = "";
147
- # var mask = (1 << CHRSH) - 1;
148
- # for(var i = 0; i < bin.length * 32; i += CHRSH)
149
- # str += String.fromCharCode((bin[i>>5] >>> (32 - CHRSH - i%32)) & mask);
150
- # return str;
151
- # }
152
- #
153
-
154
- # Convert an array of big-endian words to a hex string.
155
- def binb2hex(binarray)
156
- hex_tab = HEXCASE ? "0123456789ABCDEF" : "0123456789abcdef"
157
- str = ""
158
- #for(var i = 0; i < binarray.length * 4; i++)
159
- i = 0
160
- while(i < binarray.length * 4)
161
- str += hex_tab[(binarray[i>>2] >> ((3 - i%4)*8+4)) & 0xF].chr +
162
- hex_tab[(binarray[i>>2] >> ((3 - i%4)*8 )) & 0xF].chr
163
- i += 1
164
- end
165
- return str;
166
- end
167
-
168
- # Convert an array of big-endian words to a base-64 string
169
- def binb2b64(binarray)
170
- tab = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"
171
- str = ""
172
-
173
- #for(var i = 0; i < binarray.length * 4; i += 3)
174
- i = 0
175
- while(i < binarray.length * 4)
176
- triplet = (((binarray[i >> 2].to_i >> 8 * (3 - i %4)) & 0xFF) << 16) |
177
- (((binarray[i+1 >> 2].to_i >> 8 * (3 - (i+1)%4)) & 0xFF) << 8 ) |
178
- ((binarray[i+2 >> 2].to_i >> 8 * (3 - (i+2)%4)) & 0xFF)
179
- #for(var j = 0; j < 4; j++)
180
- j = 0
181
- while(j < 4)
182
- if(i * 8 + j * 6 > binarray.length * 32)
183
- str += B64PAD
184
- else
185
- str += tab[(triplet >> 6*(3-j)) & 0x3F].chr
186
- end
187
- j += 1
188
- end
189
- i += 3
190
- end
191
- return str
192
- end
193
- end
194
- end
@@ -1,57 +0,0 @@
1
- require 'test_helper'
2
-
3
- include D2S3::Signature
4
-
5
- class SignatureTest < Test::Unit::TestCase
6
- should "return correct core_sha1 values" do
7
- str = "abc"
8
- assert [-519653305, -1566383753, -2070791546, -753729183, -204968198], core_sha1(str2binb(str), str.length)
9
- end
10
-
11
- should "return correct str2binb values" do
12
- assert [1718578976, 1650553376, 1751480608, 1952998770, 1694498816], str2binb('foo bar hey there')
13
- end
14
-
15
- should "return correct hex_sha1 value" do
16
- assert "a9993e364706816aba3e25717850c26c9cd0d89d", hex_sha1("abc")
17
- end
18
-
19
- should "return correct b64_hmac_sha1 value" do
20
- assert "frFXMR9cNoJdsSPnjebZpBhUKzI=", b64_hmac_sha1("foo", "abc")
21
- end
22
-
23
- context "with num=1732584193 and cnt=5" do
24
- setup do
25
- @num = 1732584193
26
- @cnt = 5
27
- end
28
-
29
- should "return correct roll value" do
30
- assert -391880660, rol(@num, @cnt)
31
- end
32
-
33
- should "return correct safe_add value" do
34
- assert -519653305, safe_add(2042729798, @num)
35
- end
36
-
37
- should "return correct js_shl value" do
38
- assert -391880672, js_shl(@num, @cnt)
39
- end
40
-
41
- should "return correct js_shr_zf value" do
42
- assert 12, js_shr_zf(@num, 32 - @cnt)
43
- end
44
-
45
- should "return correct sha1_ft value" do
46
- assert -1732584194, sha1_ft(0, -271733879, -1732584194, 271733878)
47
- end
48
-
49
- should "return correct sha1_kt value" do
50
- assert 1518500249, sha1_kt(0)
51
- end
52
-
53
- should "return correct safe_add value" do
54
- assert 286718899, safe_add(safe_add(rol(@num, @cnt), sha1_ft(0, -271733879, -1732584194, 271733878)), safe_add(safe_add(-1009589776, 1902273280), sha1_kt(0)))
55
- end
56
- end
57
- end