cloudfront-signer 2.1.0 → 2.1.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 +7 -0
- data/ChangeLog.markdown +4 -0
- data/README.markdown +18 -7
- data/lib/cloudfront-signer.rb +36 -24
- data/lib/cloudfront-signer/version.rb +1 -1
- data/lib/generators/cloudfront/install/templates/cloudfront-signer.rb +1 -0
- data/spec/signer_spec.rb +82 -52
- metadata +10 -14
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d37c96b16a6cb79d5ac0d02e63832c5a7e0f025b
|
4
|
+
data.tar.gz: 18a4dec2b55f184a73101d7cc5c7215442fd83ec
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: c85cc296da175cc226fb149a84bb45d0c8cef0dca4fa738ebc79ebeae2e9e64d0556a7ddc69ceb9fa50ae18986b109d6bef914b5a3385260ff9f29a2cd2f428b
|
7
|
+
data.tar.gz: 3dc4a69e1e0aa92dbefa2621bc88d267a212edf9168b70b47f47c4817600f57e538f97b7c8cc2b48296a681c036463e36af4fab5f520c58893272d7c939ce445
|
data/ChangeLog.markdown
ADDED
data/README.markdown
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
# cloudfront-signer
|
2
2
|
|
3
|
-
|
3
|
+
See the [ChangeLog](https://github.com/58bits/cloudfront-signer/blob/master/ChangeLog.markdown) for details of this release.
|
4
|
+
|
5
|
+
A fork and re-write of Dylan Vaughn's [signing gem](https://github.com/stlondemand/aws_cf_signer).
|
4
6
|
|
5
7
|
See Amazon docs for [Using a Signed URL to Serve Private Content](http://docs.amazonwebservices.com/AmazonCloudFront/latest/DeveloperGuide/index.html?PrivateContent.html)
|
6
8
|
|
@@ -12,11 +14,11 @@ Seperate helper methods exist for safe signing of urls and stream paths, each of
|
|
12
14
|
|
13
15
|
The original gem was published as `aws_cf_signer`. Use `gem install aws_cf_signer` to install that version.
|
14
16
|
|
15
|
-
This gem has been publised as `cloudfront-signer`. Use `gem install cloudfront-signer` to install this gem.
|
17
|
+
This gem has been publised as `cloudfront-signer`. Use `gem install cloudfront-signer` to install this gem.
|
16
18
|
|
17
19
|
Alternatively, place a copy of cloudfront-signer.rb (and the cloundfront-signer sub directory) in your lib directory.
|
18
20
|
|
19
|
-
In either case the signing class must be configured - supplying the path to a signing key
|
21
|
+
In either case the signing class must be configured - supplying the path to a signing key, or supplying the signing key directly as a string along with the `key_pair_id`. Create the initializer by running:
|
20
22
|
|
21
23
|
```
|
22
24
|
bundle exec rails g cloudfront:install
|
@@ -24,13 +26,22 @@ bundle exec rails g cloudfront:install
|
|
24
26
|
|
25
27
|
and customizing the resulting `config/initializers/cloudfront-signer.rb` file.
|
26
28
|
|
29
|
+
### Generated `cloudfront-signer.rb`
|
30
|
+
|
31
|
+
AWS::CF::Signer.configure do |config|
|
32
|
+
config.key_path = '/path/to/keyfile.pem'
|
33
|
+
# config.key = ENV.fetch('PRIVATE_KEY') # key_path not required if key supplied directly
|
34
|
+
config.key_pair_id = "XXYYZZ"
|
35
|
+
config.default_expires = 3600
|
36
|
+
end
|
37
|
+
|
27
38
|
## Usage
|
28
39
|
|
29
40
|
Call the class `sign_url` or `sign_path` method with optional policy settings.
|
30
41
|
|
31
42
|
AWS::CF::Signer.sign_url 'http://mydomain/path/to/my/content'
|
32
43
|
|
33
|
-
or
|
44
|
+
or
|
34
45
|
|
35
46
|
AWS::CF::Signer.sign_url 'http://mydomain/path/to/my/content', :expires => Time.now + 600
|
36
47
|
|
@@ -38,7 +49,7 @@ Streaming paths can be signed with the `sign_path` method.
|
|
38
49
|
|
39
50
|
AWS::CF::Signer.sign_path 'path/to/my/content'
|
40
51
|
|
41
|
-
or
|
52
|
+
or
|
42
53
|
|
43
54
|
AWS::CF::Signer.sign_path 'path/to/my/content', :expires => Time.now + 600
|
44
55
|
|
@@ -70,11 +81,11 @@ You can also pass in a path to a policy file. This will supersede any other poli
|
|
70
81
|
url = AWS::CF::Signer.sign_url('http://d84l721fxaaqy9.cloudfront.net/downloads/pictures.tgz', :policy_file => '/path/to/policy/file.txt')
|
71
82
|
|
72
83
|
|
73
|
-
## Patches/Pull Requests
|
84
|
+
## Patches/Pull Requests
|
74
85
|
|
75
86
|
* Fork the project.
|
76
87
|
* Make your feature addition or bug fix.
|
77
|
-
* Add tests for it.
|
88
|
+
* Add tests for it.
|
78
89
|
* Commit
|
79
90
|
* Send me a pull request. Bonus points for topic branches.
|
80
91
|
|
data/lib/cloudfront-signer.rb
CHANGED
@@ -10,8 +10,8 @@ module AWS
|
|
10
10
|
class Signer
|
11
11
|
# Public non-inheritable class accessors
|
12
12
|
class << self
|
13
|
-
|
14
|
-
# Public: Provides a configuration option to set the key_pair_id if it has not
|
13
|
+
|
14
|
+
# Public: Provides a configuration option to set the key_pair_id if it has not
|
15
15
|
# been inferred from the key_path
|
16
16
|
#
|
17
17
|
# Examples
|
@@ -23,7 +23,7 @@ module AWS
|
|
23
23
|
# Returns a String value indicating the current setting
|
24
24
|
attr_accessor :key_pair_id
|
25
25
|
|
26
|
-
# Public: Provides a configuration option that sets the key_path
|
26
|
+
# Public: Provides a configuration option that sets the key_path
|
27
27
|
#
|
28
28
|
# Examples
|
29
29
|
#
|
@@ -35,10 +35,22 @@ module AWS
|
|
35
35
|
def key_path=(path)
|
36
36
|
raise ArgumentError.new("The signing key could not be found at #{path}") unless File.exists?(path)
|
37
37
|
@key_path = path
|
38
|
-
|
38
|
+
self.key=(File.readlines(path).join(""))
|
39
39
|
end
|
40
40
|
|
41
|
-
# Public: Provides
|
41
|
+
# Public: Provides a configuration option to set the key directly as a string e.g. as an ENV var
|
42
|
+
#
|
43
|
+
# Examples
|
44
|
+
#
|
45
|
+
# AWS::CF::Signer.configure do |config|
|
46
|
+
# config.key = ENV.fetch('KEY')
|
47
|
+
# end
|
48
|
+
# Returns nothing.
|
49
|
+
def key=(key)
|
50
|
+
@key = OpenSSL::PKey::RSA.new(key)
|
51
|
+
end
|
52
|
+
|
53
|
+
# Public: Provides an accessor to the key_path
|
42
54
|
#
|
43
55
|
# Returns a String value indicating the current setting
|
44
56
|
def key_path
|
@@ -59,7 +71,7 @@ module AWS
|
|
59
71
|
@default_expires = value
|
60
72
|
end
|
61
73
|
|
62
|
-
# Public: Provides an accessor to the default_expires value
|
74
|
+
# Public: Provides an accessor to the default_expires value
|
63
75
|
#
|
64
76
|
# Returns an Integer value indicating the current setting
|
65
77
|
def default_expires
|
@@ -69,7 +81,7 @@ module AWS
|
|
69
81
|
|
70
82
|
private
|
71
83
|
|
72
|
-
# Private: Provides an accessor to the RSA key value
|
84
|
+
# Private: Provides an accessor to the RSA key value
|
73
85
|
#
|
74
86
|
# Returns an RSA key pair.
|
75
87
|
def private_key
|
@@ -94,30 +106,30 @@ module AWS
|
|
94
106
|
|
95
107
|
yield self if block_given?
|
96
108
|
|
97
|
-
raise ArgumentError.new("You must supply the path to a PEM format RSA key pair.") unless self.key_path
|
109
|
+
raise ArgumentError.new("You must supply the path to a PEM format RSA key pair.") unless self.key_path || private_key
|
98
110
|
|
99
111
|
unless @key_pair_id
|
100
112
|
@key_pair_id = extract_key_pair_id(self.key_path)
|
101
|
-
raise ArgumentError.new("The Cloudfront signing key id could not be inferred from #{self.key_path}. Please supply the key pair id as a configuration argument.") unless @key_pair_id
|
113
|
+
raise ArgumentError.new("The Cloudfront signing key id could not be inferred from #{self.key_path}. Please supply the key pair id as a configuration argument.") unless @key_pair_id
|
102
114
|
end
|
103
115
|
|
104
116
|
end
|
105
117
|
|
106
|
-
# Public: Provides a configuration check method which tests to see
|
118
|
+
# Public: Provides a configuration check method which tests to see
|
107
119
|
# that the key_path, key_pair_id and private key values have all been set.
|
108
120
|
#
|
109
121
|
# Returns a Boolean value indicating that settings are present.
|
110
122
|
def self.is_configured?
|
111
|
-
(self.
|
123
|
+
(self.key_pair_id.nil? || private_key.nil?) ? false : true
|
112
124
|
end
|
113
125
|
|
114
|
-
# Public: Sign a url - encoding any spaces in the url before signing. CloudFront
|
126
|
+
# Public: Sign a url - encoding any spaces in the url before signing. CloudFront
|
115
127
|
# stipulates that signed URLs must not contain spaces (as opposed to stream
|
116
|
-
# paths/filenames which CAN contain spaces).
|
128
|
+
# paths/filenames which CAN contain spaces).
|
117
129
|
#
|
118
|
-
# Returns a String
|
119
|
-
def self.sign_url(subject, policy_options = {})
|
120
|
-
self.sign(subject, {:remove_spaces => true}, policy_options)
|
130
|
+
# Returns a String
|
131
|
+
def self.sign_url(subject, policy_options = {})
|
132
|
+
self.sign(subject, {:remove_spaces => true}, policy_options)
|
121
133
|
end
|
122
134
|
|
123
135
|
|
@@ -125,27 +137,27 @@ module AWS
|
|
125
137
|
# Public: Sign a url (as above) and HTML encode the result.
|
126
138
|
#
|
127
139
|
# Returns a String
|
128
|
-
def self.sign_url_safe(subject, policy_options = {})
|
129
|
-
self.sign(subject, {:remove_spaces => true, :html_escape => true}, policy_options)
|
140
|
+
def self.sign_url_safe(subject, policy_options = {})
|
141
|
+
self.sign(subject, {:remove_spaces => true, :html_escape => true}, policy_options)
|
130
142
|
end
|
131
143
|
|
132
|
-
# Public: Sign a stream path part or filename (spaces are allowed in stream paths
|
144
|
+
# Public: Sign a stream path part or filename (spaces are allowed in stream paths
|
133
145
|
# and so are not removed).
|
134
|
-
#
|
146
|
+
#
|
135
147
|
# Returns a String
|
136
148
|
def self.sign_path(subject, policy_options ={})
|
137
|
-
self.sign(subject, {:remove_spaces => false}, policy_options)
|
149
|
+
self.sign(subject, {:remove_spaces => false}, policy_options)
|
138
150
|
end
|
139
151
|
|
140
152
|
# Public: Sign a stream path or filename and HTML encode the result.
|
141
153
|
#
|
142
154
|
# Returns a String
|
143
155
|
def self.sign_path_safe(subject, policy_options ={})
|
144
|
-
self.sign(subject, {:remove_spaces => false, :html_escape => true}, policy_options)
|
156
|
+
self.sign(subject, {:remove_spaces => false, :html_escape => true}, policy_options)
|
145
157
|
end
|
146
158
|
|
147
159
|
|
148
|
-
# Public: Sign a subject url or stream resource name with optional configuration and
|
160
|
+
# Public: Sign a subject url or stream resource name with optional configuration and
|
149
161
|
# policy options
|
150
162
|
#
|
151
163
|
# Returns a String
|
@@ -178,7 +190,7 @@ module AWS
|
|
178
190
|
end
|
179
191
|
|
180
192
|
if configuration_options[:html_escape]
|
181
|
-
return html_encode(result)
|
193
|
+
return html_encode(result)
|
182
194
|
else
|
183
195
|
return result
|
184
196
|
end
|
data/spec/signer_spec.rb
CHANGED
@@ -1,80 +1,110 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe AWS::CF::Signer do
|
4
|
-
|
5
|
-
let(:key_path) { File.expand_path(File.dirname(__FILE__) +
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
4
|
+
let(:key_pair_id) { 'APKAIKUROOUNR2BAFUUU' }
|
5
|
+
let(:key_path) { File.expand_path(File.dirname(__FILE__) + "/keys/pk-#{key_pair_id}.pem") }
|
6
|
+
let(:key) { File.readlines(key_path).join("") }
|
7
|
+
|
8
|
+
context "configured with key and key_pair_id" do
|
9
|
+
before do
|
10
|
+
AWS::CF::Signer.configure do |config|
|
11
|
+
config.key_pair_id = key_pair_id
|
12
|
+
config.key = key
|
13
|
+
end
|
12
14
|
end
|
13
|
-
end
|
14
|
-
|
15
|
-
describe "before default use" do
|
16
15
|
|
17
16
|
it "should be configured" do
|
18
17
|
AWS::CF::Signer.is_configured?.should eql(true)
|
19
18
|
end
|
20
19
|
|
21
|
-
it "
|
22
|
-
AWS::CF::Signer.
|
20
|
+
it "sets the private_key" do
|
21
|
+
AWS::CF::Signer.send(:private_key).should be_instance_of OpenSSL::PKey::RSA
|
23
22
|
end
|
24
23
|
|
25
|
-
it "should
|
26
|
-
|
27
|
-
AWS::CF::Signer.
|
28
|
-
|
24
|
+
it "should expire in one hour by default" do
|
25
|
+
url = "http://somedomain.com/sign me"
|
26
|
+
result = AWS::CF::Signer.sign_url(url)
|
27
|
+
get_query_value(result, 'Expires').to_i.should eql((Time.now + 3600).to_i)
|
29
28
|
end
|
30
29
|
end
|
31
30
|
|
32
|
-
|
31
|
+
context "configured with key_path" do
|
33
32
|
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
33
|
+
before(:each) do
|
34
|
+
AWS::CF::Signer.configure do |config|
|
35
|
+
config.key_path = key_path
|
36
|
+
#config.key_pair_id = "XXYYZZ"
|
37
|
+
#config.default_expires = 3600
|
38
|
+
end
|
38
39
|
end
|
39
40
|
|
40
|
-
|
41
|
-
url = "http://somedomain.com/someresource?opt1=one&opt2=two"
|
42
|
-
result = AWS::CF::Signer.sign_url(url)
|
43
|
-
(result =~ /\?/).should_not be_nil
|
44
|
-
(result =~ /=/).should_not be_nil
|
45
|
-
(result =~ /&/).should_not be_nil
|
46
|
-
end
|
41
|
+
describe "before default use" do
|
47
42
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
(result =~ /\?/).should be_nil
|
52
|
-
(result =~ /=/).should be_nil
|
53
|
-
(result =~ /&/).should be_nil
|
54
|
-
end
|
43
|
+
it "should be configured" do
|
44
|
+
AWS::CF::Signer.is_configured?.should eql(true)
|
45
|
+
end
|
55
46
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
get_query_value(result, 'Expires').to_i.should eql((Time.now + 3600).to_i)
|
60
|
-
end
|
47
|
+
it "sets the private_key" do
|
48
|
+
AWS::CF::Signer.send(:private_key).should be_instance_of OpenSSL::PKey::RSA
|
49
|
+
end
|
61
50
|
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
51
|
+
it "should expire urls and paths in one hour by default" do
|
52
|
+
AWS::CF::Signer.default_expires.should eql(3600)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "should optionally be configured to expire urls and paths in ten minutes" do
|
56
|
+
AWS::CF::Signer.default_expires = 600
|
57
|
+
AWS::CF::Signer.default_expires.should eql(600)
|
58
|
+
AWS::CF::Signer.default_expires = nil
|
59
|
+
end
|
66
60
|
end
|
67
61
|
|
68
|
-
|
62
|
+
describe "when signing a url" do
|
63
|
+
|
64
|
+
it "should remove spaces from the url" do
|
65
|
+
url = "http://somedomain.com/sign me"
|
66
|
+
result = AWS::CF::Signer.sign_url(url)
|
67
|
+
(result =~ /\s/).should be_nil
|
68
|
+
end
|
69
|
+
|
70
|
+
it "should not html encode the signed url by default" do
|
71
|
+
url = "http://somedomain.com/someresource?opt1=one&opt2=two"
|
72
|
+
result = AWS::CF::Signer.sign_url(url)
|
73
|
+
(result =~ /\?/).should_not be_nil
|
74
|
+
(result =~ /=/).should_not be_nil
|
75
|
+
(result =~ /&/).should_not be_nil
|
76
|
+
end
|
77
|
+
|
78
|
+
it "should optionally html encode the signed url" do
|
79
|
+
url = "http://somedomain.com/someresource?opt1=one&opt2=two"
|
80
|
+
result = AWS::CF::Signer.sign_url_safe(url)
|
81
|
+
(result =~ /\?/).should be_nil
|
82
|
+
(result =~ /=/).should be_nil
|
83
|
+
(result =~ /&/).should be_nil
|
84
|
+
end
|
85
|
+
|
86
|
+
it "should expire in one hour by default" do
|
87
|
+
url = "http://somedomain.com/sign me"
|
88
|
+
result = AWS::CF::Signer.sign_url(url)
|
89
|
+
get_query_value(result, 'Expires').to_i.should eql((Time.now + 3600).to_i)
|
90
|
+
end
|
91
|
+
|
92
|
+
it "should optionally expire in ten minutes" do
|
93
|
+
url = "http://somedomain.com/sign me"
|
94
|
+
result = AWS::CF::Signer.sign_url(url, :expires => Time.now + 600)
|
95
|
+
get_query_value(result, 'Expires').to_i.should eql((Time.now + 600 ).to_i)
|
96
|
+
end
|
69
97
|
|
98
|
+
end
|
70
99
|
|
71
|
-
|
100
|
+
describe "when signing a path" do
|
72
101
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
102
|
+
it "should not remove spaces from the path" do
|
103
|
+
path = "/someprefix/sign me"
|
104
|
+
result = AWS::CF::Signer.sign_path(path)
|
105
|
+
(result =~ /\s/).should_not be_nil
|
106
|
+
end
|
78
107
|
|
108
|
+
end
|
79
109
|
end
|
80
110
|
end
|
metadata
CHANGED
@@ -1,30 +1,27 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cloudfront-signer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.1.
|
5
|
-
prerelease:
|
4
|
+
version: 2.1.1
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Anthony Bouch
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2013-10-30 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rspec
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - '>='
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - '>='
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
description: A gem to sign url and stream paths for Amazon CloudFront private content.
|
@@ -38,6 +35,7 @@ extra_rdoc_files: []
|
|
38
35
|
files:
|
39
36
|
- .gitignore
|
40
37
|
- .rspec
|
38
|
+
- ChangeLog.markdown
|
41
39
|
- Gemfile
|
42
40
|
- LICENSE
|
43
41
|
- README.markdown
|
@@ -53,31 +51,29 @@ files:
|
|
53
51
|
- spec/spec_helper.rb
|
54
52
|
homepage: http://github.com/58bits/cloudfront-signer
|
55
53
|
licenses: []
|
54
|
+
metadata: {}
|
56
55
|
post_install_message:
|
57
56
|
rdoc_options: []
|
58
57
|
require_paths:
|
59
58
|
- lib
|
60
59
|
required_ruby_version: !ruby/object:Gem::Requirement
|
61
|
-
none: false
|
62
60
|
requirements:
|
63
|
-
- -
|
61
|
+
- - '>='
|
64
62
|
- !ruby/object:Gem::Version
|
65
63
|
version: '0'
|
66
64
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
67
|
-
none: false
|
68
65
|
requirements:
|
69
|
-
- -
|
66
|
+
- - '>='
|
70
67
|
- !ruby/object:Gem::Version
|
71
68
|
version: '0'
|
72
69
|
requirements: []
|
73
70
|
rubyforge_project: cloudfront-signer
|
74
|
-
rubygems_version:
|
71
|
+
rubygems_version: 2.0.3
|
75
72
|
signing_key:
|
76
|
-
specification_version:
|
73
|
+
specification_version: 4
|
77
74
|
summary: A gem to sign url and stream paths for Amazon CloudFront private content.
|
78
75
|
test_files:
|
79
76
|
- spec/keys/pk-APKAIKUROOUNR2BAFUUU.pem
|
80
77
|
- spec/keys/rsa-APKAIKUROOUNR2BAFUUU.pem
|
81
78
|
- spec/signer_spec.rb
|
82
79
|
- spec/spec_helper.rb
|
83
|
-
has_rdoc:
|