carrierwave_direct 2.0.0 → 2.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.travis.yml +2 -2
- data/Changelog.md +12 -1
- data/README.md +1 -1
- data/carrierwave_direct.gemspec +1 -1
- data/gemfiles/5.2.gemfile +13 -0
- data/lib/carrierwave_direct/form_builder.rb +30 -14
- data/lib/carrierwave_direct/mount.rb +1 -11
- data/lib/carrierwave_direct/policies/aws4_hmac_sha256.rb +93 -0
- data/lib/carrierwave_direct/policies/aws_base64_sha1.rb +57 -0
- data/lib/carrierwave_direct/policies/base.rb +21 -0
- data/lib/carrierwave_direct/uploader.rb +41 -76
- data/lib/carrierwave_direct/version.rb +1 -1
- data/spec/form_builder_spec.rb +11 -8
- data/spec/mount_spec.rb +2 -2
- data/spec/policies/aws4_hmac_sha256_spec.rb +243 -0
- data/spec/policies/aws_base64_sha1_spec.rb +229 -0
- data/spec/spec_helper.rb +5 -1
- data/spec/uploader_spec.rb +13 -31
- metadata +15 -10
- data/lib/carrierwave_direct/uploader/direct_url.rb +0 -16
- data/spec/uploader/direct_url_spec.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: fc82b1086314ce00c9bda47de03a897ecd59f1e3dca2f0b7617de586c572e129
|
4
|
+
data.tar.gz: dea3d79dfd532cf823f49eb22790c39aeffa5d273b3010763345f0ccb00fb201
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f489411ef1403569962e800e548e0511a258d1861b577c13d822d26a3d662e216694c213f43ba07898feabc47d2f5b9e6b3ac2b4df27a11a2826e97b07ea685f
|
7
|
+
data.tar.gz: b604ac58fe82f7d10077855f562665f93f7edf54261bc2f3556b9ed6fd7f378c5626dc9f7a0fad9218b8fa05802b4cc8d2a29023c20f6f18b760b4b8b66a816d
|
data/.travis.yml
CHANGED
@@ -5,10 +5,10 @@ rvm:
|
|
5
5
|
|
6
6
|
script: 'bundle exec rspec spec'
|
7
7
|
gemfile:
|
8
|
-
- Gemfile
|
9
8
|
- gemfiles/4.2.gemfile
|
10
9
|
- gemfiles/5.1.gemfile
|
11
|
-
|
10
|
+
- gemfiles/5.2.gemfile
|
11
|
+
|
12
12
|
# Move to containerized travis, see http://docs.travis-ci.com/user/migrating-from-legacy
|
13
13
|
sudo: false
|
14
14
|
cache: bundler
|
data/Changelog.md
CHANGED
@@ -1,3 +1,14 @@
|
|
1
|
+
### 2.1.0
|
2
|
+
|
3
|
+
Features:
|
4
|
+
* Refactor policies to seperate classes and add back the old policy for
|
5
|
+
backwards compatibility.
|
6
|
+
* Added `direct_fog_hash` method that can be used for returning json
|
7
|
+
|
8
|
+
Misc:
|
9
|
+
* Removed deprecated `key` methods.
|
10
|
+
* Removed deprecated `:with_path` option for `direct_fog_url`
|
11
|
+
|
1
12
|
### 2.0.0
|
2
13
|
|
3
14
|
Features:
|
@@ -10,7 +21,7 @@ Misc:
|
|
10
21
|
### 1.1.0
|
11
22
|
|
12
23
|
Deprecations:
|
13
|
-
* Calling `
|
24
|
+
* Calling `direct_fog_url` with `:with_path` is deprecated, please use `url` instead.
|
14
25
|
|
15
26
|
### 1.0.0
|
16
27
|
|
data/README.md
CHANGED
@@ -363,7 +363,7 @@ Your users may find it convenient to upload a file from a location on the Intern
|
|
363
363
|
class User < ActiveRecord::Base
|
364
364
|
def save_and_process_avatar(options = {})
|
365
365
|
if options[:now]
|
366
|
-
self.remote_avatar_url = has_remote_avatar_net_url? ? remote_avatar_net_url : avatar.
|
366
|
+
self.remote_avatar_url = has_remote_avatar_net_url? ? remote_avatar_net_url : avatar.url
|
367
367
|
save
|
368
368
|
else
|
369
369
|
Resque.enqueue(AvatarProcessor, attributes)
|
data/carrierwave_direct.gemspec
CHANGED
@@ -17,7 +17,7 @@ Gem::Specification.new do |s|
|
|
17
17
|
s.add_dependency "carrierwave", '>= 1.0.0'
|
18
18
|
s.add_dependency "fog-aws"
|
19
19
|
|
20
|
-
s.add_development_dependency "rspec"
|
20
|
+
s.add_development_dependency "rspec", '~> 3.0'
|
21
21
|
s.add_development_dependency "timecop"
|
22
22
|
s.add_development_dependency "rails", ">= 3.2.12"
|
23
23
|
s.add_development_dependency "sqlite3"
|
@@ -0,0 +1,13 @@
|
|
1
|
+
source "https://rubygems.org"
|
2
|
+
|
3
|
+
gem "carrierwave"
|
4
|
+
gem "fog-aws"
|
5
|
+
|
6
|
+
group :test do
|
7
|
+
gem "rspec", '~> 3.0'
|
8
|
+
gem "timecop"
|
9
|
+
gem "rails", "~>5.2.0"
|
10
|
+
gem "sqlite3", :platform => [:ruby, :mswin, :mingw]
|
11
|
+
gem "capybara"
|
12
|
+
# gem "activerecord-jdbcsqlite3-adapter", :platform => :jruby
|
13
|
+
end
|
@@ -5,19 +5,21 @@ module CarrierWaveDirect
|
|
5
5
|
def file_field(method, options = {})
|
6
6
|
@object.policy(enforce_utf8: true)
|
7
7
|
|
8
|
-
|
9
|
-
|
10
|
-
fields = required_base_fields
|
11
|
-
|
12
|
-
fields << content_type_field(options)
|
13
|
-
|
14
|
-
fields << success_action_field(options)
|
8
|
+
fields = hidden_fields(options)
|
15
9
|
|
16
10
|
# The file field must be the last element in the form.
|
17
11
|
# Any element after this will be ignored by Amazon.
|
12
|
+
options.merge!(:name => "file")
|
13
|
+
|
18
14
|
fields << super
|
19
15
|
end
|
20
16
|
|
17
|
+
def fields_except_file_field(options = {})
|
18
|
+
@object.policy(enforce_utf8: true)
|
19
|
+
|
20
|
+
hidden_fields(options)
|
21
|
+
end
|
22
|
+
|
21
23
|
def content_type_label(content=nil)
|
22
24
|
content ||= 'Content Type'
|
23
25
|
@template.label_tag('Content-Type', content)
|
@@ -29,14 +31,28 @@ module CarrierWaveDirect
|
|
29
31
|
|
30
32
|
private
|
31
33
|
|
34
|
+
def hidden_fields(options)
|
35
|
+
fields = required_base_fields
|
36
|
+
fields << content_type_field(options)
|
37
|
+
fields << success_action_field(options)
|
38
|
+
fields
|
39
|
+
end
|
40
|
+
|
32
41
|
def required_base_fields
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
42
|
+
fields = ''.html_safe
|
43
|
+
@object.direct_fog_hash(enforce_utf8: true).each do |key, value|
|
44
|
+
normalized_keys = {
|
45
|
+
'X-Amz-Signature': 'signature',
|
46
|
+
'X-Amz-Credential': 'credential',
|
47
|
+
'X-Amz-Algorithm': 'algorithm',
|
48
|
+
'X-Amz-Date': 'date'
|
49
|
+
}
|
50
|
+
id = "#{@template.dom_class(@object)}_#{normalized_keys[key] || key}"
|
51
|
+
if key != :uri
|
52
|
+
fields << @template.hidden_field_tag(key, value, id: id, required: false)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
fields
|
40
56
|
end
|
41
57
|
|
42
58
|
def content_type_field(options)
|
@@ -14,7 +14,7 @@ module CarrierWaveDirect
|
|
14
14
|
def #{column}; self; end
|
15
15
|
RUBY
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
self.instance_eval <<-RUBY, __FILE__, __LINE__+1
|
19
19
|
attr_accessor :remote_#{column}_net_url
|
20
20
|
RUBY
|
@@ -23,16 +23,6 @@ module CarrierWaveDirect
|
|
23
23
|
include mod
|
24
24
|
mod.class_eval <<-RUBY, __FILE__, __LINE__+1
|
25
25
|
|
26
|
-
def key
|
27
|
-
warn "key method is deprecated, please use column_key method instead."
|
28
|
-
send(:#{column}).key
|
29
|
-
end
|
30
|
-
|
31
|
-
def key=(k)
|
32
|
-
warn "key= method is deprecated, please use column_key= method instead."
|
33
|
-
send(:#{column}).key = k
|
34
|
-
end
|
35
|
-
|
36
26
|
def #{column}_key
|
37
27
|
send(:#{column}).key
|
38
28
|
end
|
@@ -0,0 +1,93 @@
|
|
1
|
+
require "carrierwave_direct/policies/base"
|
2
|
+
|
3
|
+
module CarrierWaveDirect
|
4
|
+
module Policies
|
5
|
+
class Aws4HmacSha256 < Base
|
6
|
+
|
7
|
+
def direct_fog_hash(policy_options = {})
|
8
|
+
{
|
9
|
+
key: uploader.key,
|
10
|
+
acl: uploader.acl,
|
11
|
+
policy: policy(policy_options),
|
12
|
+
'X-Amz-Signature': signature,
|
13
|
+
'X-Amz-Credential': credential,
|
14
|
+
'X-Amz-Algorithm': algorithm,
|
15
|
+
'X-Amz-Date': date,
|
16
|
+
uri: uploader.direct_fog_url,
|
17
|
+
}
|
18
|
+
end
|
19
|
+
|
20
|
+
def date
|
21
|
+
timestamp.strftime("%Y%m%dT%H%M%SZ")
|
22
|
+
end
|
23
|
+
|
24
|
+
def generate(options, &block)
|
25
|
+
|
26
|
+
return @policy if @policy.present?
|
27
|
+
conditions = []
|
28
|
+
|
29
|
+
conditions << ["starts-with", "$utf8", ""] if options[:enforce_utf8]
|
30
|
+
conditions << ["starts-with", "$key", uploader.key.sub(/#{Regexp.escape(CarrierWaveDirect::Uploader::FILENAME_WILDCARD)}\z/, "")]
|
31
|
+
conditions << {'X-Amz-Algorithm' => algorithm}
|
32
|
+
conditions << {'X-Amz-Credential' => credential}
|
33
|
+
conditions << {'X-Amz-Date' => date }
|
34
|
+
conditions << ["starts-with", "$Content-Type", ""] if uploader.will_include_content_type
|
35
|
+
conditions << {"bucket" => uploader.fog_directory}
|
36
|
+
conditions << {"acl" => uploader.acl}
|
37
|
+
|
38
|
+
if uploader.use_action_status
|
39
|
+
conditions << {"success_action_status" => uploader.success_action_status}
|
40
|
+
else
|
41
|
+
conditions << {"success_action_redirect" => uploader.success_action_redirect}
|
42
|
+
end
|
43
|
+
|
44
|
+
conditions << ["content-length-range", options[:min_file_size], options[:max_file_size]]
|
45
|
+
|
46
|
+
yield conditions if block_given?
|
47
|
+
|
48
|
+
@policy = Base64.encode64(
|
49
|
+
{
|
50
|
+
'expiration' => (Time.now + options[:expiration]).utc.iso8601,
|
51
|
+
'conditions' => conditions
|
52
|
+
}.to_json
|
53
|
+
).gsub("\n","")
|
54
|
+
end
|
55
|
+
|
56
|
+
def credential
|
57
|
+
"#{uploader.aws_access_key_id}/#{timestamp.strftime("%Y%m%d")}/#{uploader.region}/s3/aws4_request"
|
58
|
+
end
|
59
|
+
|
60
|
+
def algorithm
|
61
|
+
'AWS4-HMAC-SHA256'
|
62
|
+
end
|
63
|
+
|
64
|
+
def clear!
|
65
|
+
super
|
66
|
+
@timestamp = nil
|
67
|
+
end
|
68
|
+
|
69
|
+
def signature
|
70
|
+
OpenSSL::HMAC.hexdigest(
|
71
|
+
'sha256',
|
72
|
+
signing_key,
|
73
|
+
policy
|
74
|
+
)
|
75
|
+
end
|
76
|
+
|
77
|
+
def signing_key(options = {})
|
78
|
+
#AWS Signature Version 4
|
79
|
+
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + uploader.aws_secret_access_key, timestamp.strftime("%Y%m%d"))
|
80
|
+
kRegion = OpenSSL::HMAC.digest('sha256', kDate, uploader.region)
|
81
|
+
kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
|
82
|
+
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
|
83
|
+
|
84
|
+
kSigning
|
85
|
+
end
|
86
|
+
|
87
|
+
def timestamp
|
88
|
+
@timestamp ||= Time.now.utc
|
89
|
+
end
|
90
|
+
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require "carrierwave_direct/policies/base"
|
2
|
+
|
3
|
+
module CarrierWaveDirect
|
4
|
+
module Policies
|
5
|
+
class AwsBase64Sha1 < Base
|
6
|
+
def signature
|
7
|
+
Base64.encode64(
|
8
|
+
OpenSSL::HMAC.digest(
|
9
|
+
OpenSSL::Digest.new('sha1'),
|
10
|
+
uploader.aws_secret_access_key, policy
|
11
|
+
)
|
12
|
+
).gsub("\n", "")
|
13
|
+
end
|
14
|
+
|
15
|
+
def direct_fog_hash(policy_options = {})
|
16
|
+
{
|
17
|
+
key: uploader.key,
|
18
|
+
AWSAccessKeyId: uploader.aws_access_key_id,
|
19
|
+
acl: uploader.acl,
|
20
|
+
policy: policy(policy_options),
|
21
|
+
signature: signature,
|
22
|
+
uri: uploader.direct_fog_url
|
23
|
+
}
|
24
|
+
end
|
25
|
+
|
26
|
+
def generate(options, &block)
|
27
|
+
|
28
|
+
return @policy if @policy.present?
|
29
|
+
conditions = []
|
30
|
+
|
31
|
+
conditions << ["starts-with", "$utf8", ""] if options[:enforce_utf8]
|
32
|
+
conditions << ["starts-with", "$key", uploader.key.sub(/#{Regexp.escape(CarrierWaveDirect::Uploader::FILENAME_WILDCARD)}\z/, "")]
|
33
|
+
conditions << ["starts-with", "$Content-Type", ""] if uploader.will_include_content_type
|
34
|
+
conditions << {"bucket" => uploader.fog_directory}
|
35
|
+
conditions << {"acl" => uploader.acl}
|
36
|
+
|
37
|
+
if uploader.use_action_status
|
38
|
+
conditions << {"success_action_status" => uploader.success_action_status}
|
39
|
+
else
|
40
|
+
conditions << {"success_action_redirect" => uploader.success_action_redirect}
|
41
|
+
end
|
42
|
+
|
43
|
+
conditions << ["content-length-range", options[:min_file_size], options[:max_file_size]]
|
44
|
+
|
45
|
+
yield conditions if block_given?
|
46
|
+
|
47
|
+
@policy = Base64.encode64(
|
48
|
+
{
|
49
|
+
'expiration' => (Time.now + options[:expiration]).utc.iso8601,
|
50
|
+
'conditions' => conditions
|
51
|
+
}.to_json
|
52
|
+
).gsub("\n","")
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module CarrierWaveDirect
|
2
|
+
module Policies
|
3
|
+
class Base
|
4
|
+
attr_reader :uploader
|
5
|
+
def initialize(uploader)
|
6
|
+
@uploader = uploader
|
7
|
+
end
|
8
|
+
|
9
|
+
def policy(options = {}, &block)
|
10
|
+
options[:expiration] ||= uploader.upload_expiration
|
11
|
+
options[:min_file_size] ||= uploader.min_file_size
|
12
|
+
options[:max_file_size] ||= uploader.max_file_size
|
13
|
+
@policy ||= generate(options, &block)
|
14
|
+
end
|
15
|
+
|
16
|
+
def clear!
|
17
|
+
@policy = nil
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -2,7 +2,8 @@
|
|
2
2
|
|
3
3
|
require "securerandom"
|
4
4
|
require "carrierwave_direct/uploader/content_type"
|
5
|
-
require "carrierwave_direct/
|
5
|
+
require "carrierwave_direct/policies/aws_base64_sha1"
|
6
|
+
require "carrierwave_direct/policies/aws4_hmac_sha256"
|
6
7
|
|
7
8
|
module CarrierWaveDirect
|
8
9
|
module Uploader
|
@@ -24,7 +25,6 @@ module CarrierWaveDirect
|
|
24
25
|
end
|
25
26
|
|
26
27
|
include CarrierWaveDirect::Uploader::ContentType
|
27
|
-
include CarrierWaveDirect::Uploader::DirectUrl
|
28
28
|
|
29
29
|
#ensure that region returns something. Since sig v4 it is required in the signing key & credentials
|
30
30
|
def region
|
@@ -36,40 +36,27 @@ module CarrierWaveDirect
|
|
36
36
|
end
|
37
37
|
|
38
38
|
def policy(options = {}, &block)
|
39
|
-
options
|
40
|
-
options[:min_file_size] ||= min_file_size
|
41
|
-
options[:max_file_size] ||= max_file_size
|
42
|
-
|
43
|
-
@date ||= Time.now.utc.strftime("%Y%m%d")
|
44
|
-
@timestamp ||= Time.now.utc.strftime("%Y%m%dT%H%M%SZ")
|
45
|
-
@policy ||= generate_policy(options, &block)
|
39
|
+
signing_policy.policy(options, &block)
|
46
40
|
end
|
47
41
|
|
48
42
|
def date
|
49
|
-
|
43
|
+
signing_policy.date
|
50
44
|
end
|
51
45
|
|
52
46
|
def algorithm
|
53
|
-
|
47
|
+
signing_policy.algorithm
|
54
48
|
end
|
55
49
|
|
56
50
|
def credential
|
57
|
-
|
58
|
-
"#{aws_access_key_id}/#{@date}/#{region}/s3/aws4_request"
|
51
|
+
signing_policy.credential
|
59
52
|
end
|
60
53
|
|
61
54
|
def clear_policy!
|
62
|
-
|
63
|
-
@date = nil
|
64
|
-
@timestamp = nil
|
55
|
+
signing_policy.clear!
|
65
56
|
end
|
66
57
|
|
67
58
|
def signature
|
68
|
-
|
69
|
-
'sha256',
|
70
|
-
signing_key,
|
71
|
-
policy
|
72
|
-
)
|
59
|
+
signing_policy.signature
|
73
60
|
end
|
74
61
|
|
75
62
|
def url_scheme_white_list
|
@@ -80,13 +67,22 @@ module CarrierWaveDirect
|
|
80
67
|
false
|
81
68
|
end
|
82
69
|
|
70
|
+
def signing_policy_class
|
71
|
+
@signing_policy_class ||= Policies::Aws4HmacSha256
|
72
|
+
end
|
73
|
+
|
74
|
+
def signing_policy_class=(signing_policy_class)
|
75
|
+
@signing_policy_class = signing_policy_class
|
76
|
+
end
|
77
|
+
|
83
78
|
def key
|
84
79
|
return @key if @key.present?
|
85
80
|
if present?
|
86
81
|
identifier = model.send("#{mounted_as}_identifier")
|
87
|
-
self.key =
|
82
|
+
self.key = [store_dir, identifier].join("/")
|
88
83
|
else
|
89
|
-
|
84
|
+
guid = SecureRandom.uuid
|
85
|
+
@key = [store_dir, guid, FILENAME_WILDCARD].join("/")
|
90
86
|
end
|
91
87
|
@key
|
92
88
|
end
|
@@ -96,10 +92,6 @@ module CarrierWaveDirect
|
|
96
92
|
update_version_keys(:with => @key)
|
97
93
|
end
|
98
94
|
|
99
|
-
def guid
|
100
|
-
SecureRandom.uuid
|
101
|
-
end
|
102
|
-
|
103
95
|
def has_key?
|
104
96
|
key !~ /#{Regexp.escape(FILENAME_WILDCARD)}\z/
|
105
97
|
end
|
@@ -117,27 +109,37 @@ module CarrierWaveDirect
|
|
117
109
|
unless has_key?
|
118
110
|
# Use the attached models remote url to generate a new key otherwise return nil
|
119
111
|
remote_url = model.send("remote_#{mounted_as}_url")
|
120
|
-
|
112
|
+
if remote_url
|
113
|
+
key_from_file(CarrierWave::SanitizedFile.new(remote_url).filename)
|
114
|
+
else
|
115
|
+
return
|
116
|
+
end
|
121
117
|
end
|
122
118
|
|
123
|
-
|
119
|
+
key_parts = key.split("/")
|
120
|
+
filename = key_parts.pop
|
121
|
+
guid = key_parts.pop
|
122
|
+
|
124
123
|
filename_parts = []
|
125
|
-
filename_parts
|
126
|
-
|
127
|
-
filename_parts.unshift(unique_key) if unique_key
|
124
|
+
filename_parts << guid if guid
|
125
|
+
filename_parts << filename
|
128
126
|
filename_parts.join("/")
|
129
127
|
end
|
130
128
|
|
131
|
-
|
129
|
+
def direct_fog_url
|
130
|
+
CarrierWave::Storage::Fog::File.new(self, CarrierWave::Storage::Fog.new(self), nil).public_url
|
131
|
+
end
|
132
132
|
|
133
|
-
def
|
134
|
-
|
133
|
+
def direct_fog_hash(policy_options = {})
|
134
|
+
signing_policy.direct_fog_hash(policy_options)
|
135
135
|
end
|
136
136
|
|
137
|
-
|
137
|
+
private
|
138
|
+
|
139
|
+
def key_from_file(filename)
|
138
140
|
new_key_parts = key.split("/")
|
139
141
|
new_key_parts.pop
|
140
|
-
new_key_parts <<
|
142
|
+
new_key_parts << filename
|
141
143
|
self.key = new_key_parts.join("/")
|
142
144
|
end
|
143
145
|
|
@@ -155,45 +157,8 @@ module CarrierWaveDirect
|
|
155
157
|
[for_file.chomp(extname), version_name].compact.join('_') << extname
|
156
158
|
end
|
157
159
|
|
158
|
-
def
|
159
|
-
|
160
|
-
|
161
|
-
conditions << ["starts-with", "$utf8", ""] if options[:enforce_utf8]
|
162
|
-
conditions << ["starts-with", "$key", key.sub(/#{Regexp.escape(FILENAME_WILDCARD)}\z/, "")]
|
163
|
-
conditions << {'X-Amz-Algorithm' => algorithm}
|
164
|
-
conditions << {'X-Amz-Credential' => credential}
|
165
|
-
conditions << {'X-Amz-Date' => date}
|
166
|
-
conditions << ["starts-with", "$Content-Type", ""] if will_include_content_type
|
167
|
-
conditions << {"bucket" => fog_directory}
|
168
|
-
conditions << {"acl" => acl}
|
169
|
-
|
170
|
-
if use_action_status
|
171
|
-
conditions << {"success_action_status" => success_action_status}
|
172
|
-
else
|
173
|
-
conditions << {"success_action_redirect" => success_action_redirect}
|
174
|
-
end
|
175
|
-
|
176
|
-
conditions << ["content-length-range", options[:min_file_size], options[:max_file_size]]
|
177
|
-
|
178
|
-
yield conditions if block_given?
|
179
|
-
|
180
|
-
Base64.encode64(
|
181
|
-
{
|
182
|
-
'expiration' => (Time.now + options[:expiration]).utc.iso8601,
|
183
|
-
'conditions' => conditions
|
184
|
-
}.to_json
|
185
|
-
).gsub("\n","")
|
186
|
-
end
|
187
|
-
|
188
|
-
def signing_key(options = {})
|
189
|
-
@date ||= Time.now.utc.strftime("%Y%m%d")
|
190
|
-
#AWS Signature Version 4
|
191
|
-
kDate = OpenSSL::HMAC.digest('sha256', "AWS4" + aws_secret_access_key, @date)
|
192
|
-
kRegion = OpenSSL::HMAC.digest('sha256', kDate, region)
|
193
|
-
kService = OpenSSL::HMAC.digest('sha256', kRegion, 's3')
|
194
|
-
kSigning = OpenSSL::HMAC.digest('sha256', kService, "aws4_request")
|
195
|
-
|
196
|
-
kSigning
|
160
|
+
def signing_policy
|
161
|
+
@signing_policy ||= signing_policy_class.new(self)
|
197
162
|
end
|
198
163
|
end
|
199
164
|
end
|