relishable 0.19 → 0.20
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.
- data/lib/relish.rb +1 -0
- data/lib/relish/cloudfront_helper.rb +65 -0
- metadata +2 -1
data/lib/relish.rb
CHANGED
@@ -0,0 +1,65 @@
|
|
1
|
+
# Adapted from https://github.com/stlondemand/aws_cf_signer
|
2
|
+
# Modified to support in-memory instead of on-disk signing keys
|
3
|
+
require 'openssl'
|
4
|
+
require 'time'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
class Relish
|
8
|
+
class CloudFrontHelper
|
9
|
+
|
10
|
+
attr_reader :key_pair_id
|
11
|
+
|
12
|
+
def initialize(pem, key_pair_id)
|
13
|
+
@key = OpenSSL::PKey::RSA.new(pem)
|
14
|
+
@key_pair_id = key_pair_id
|
15
|
+
end
|
16
|
+
|
17
|
+
def sign(url_to_sign, policy_options = {})
|
18
|
+
separator = url_to_sign =~ /\?/ ? '&' : '?'
|
19
|
+
if policy_options[:policy_file]
|
20
|
+
policy = IO.read(policy_options[:policy_file])
|
21
|
+
"#{url_to_sign}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
|
22
|
+
else
|
23
|
+
raise ArgumentError.new("'ending' argument is required") if policy_options[:ending].nil?
|
24
|
+
if policy_options.keys.size == 1
|
25
|
+
# Canned Policy - shorter URL
|
26
|
+
expires_at = epoch_time(policy_options[:ending])
|
27
|
+
policy = %({"Statement":[{"Resource":"#{url_to_sign}","Condition":{"DateLessThan":{"AWS:EpochTime":#{expires_at}}}}]})
|
28
|
+
"#{url_to_sign}#{separator}Expires=#{expires_at}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
|
29
|
+
else
|
30
|
+
# Custom Policy
|
31
|
+
resource = policy_options[:resource] || url_to_sign
|
32
|
+
policy = generate_custom_policy(resource, policy_options)
|
33
|
+
"#{url_to_sign}#{separator}Policy=#{encode_policy(policy)}&Signature=#{create_signature(policy)}&Key-Pair-Id=#{@key_pair_id}"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def generate_custom_policy(resource, options)
|
39
|
+
conditions = ["\"DateLessThan\":{\"AWS:EpochTime\":#{epoch_time(options[:ending])}}"]
|
40
|
+
conditions << "\"DateGreaterThan\":{\"AWS:EpochTime\":#{epoch_time(options[:starting])}}" if options[:starting]
|
41
|
+
conditions << "\"IpAddress\":{\"AWS:SourceIp\":\"#{options[:ip_range]}\"" if options[:ip_range]
|
42
|
+
%({"Statement":[{"Resource":"#{resource}","Condition":{#{conditions.join(',')}}}}]})
|
43
|
+
end
|
44
|
+
|
45
|
+
def epoch_time(timelike)
|
46
|
+
case timelike
|
47
|
+
when String then Time.parse(timelike).to_i
|
48
|
+
when Time then timelike.to_i
|
49
|
+
else raise ArgumentError.new("Invalid argument - String or Time required - #{timelike.class} passed.")
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def encode_policy(policy)
|
54
|
+
url_safe(Base64.encode64(policy))
|
55
|
+
end
|
56
|
+
|
57
|
+
def create_signature(policy)
|
58
|
+
url_safe(Base64.encode64(@key.sign(OpenSSL::Digest::SHA1.new, (policy))))
|
59
|
+
end
|
60
|
+
|
61
|
+
def url_safe(s)
|
62
|
+
s.gsub('+','-').gsub('=','_').gsub('/','~').gsub(/\n/,'').gsub(' ','')
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: relishable
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0.
|
4
|
+
version: '0.20'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -50,6 +50,7 @@ executables: []
|
|
50
50
|
extensions: []
|
51
51
|
extra_rdoc_files: []
|
52
52
|
files:
|
53
|
+
- lib/relish/cloudfront_helper.rb
|
53
54
|
- lib/relish/dynamo_helper.rb
|
54
55
|
- lib/relish/encryption_helper.rb
|
55
56
|
- lib/relish/release.rb
|