did_will_sign 0.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.
- data/README +55 -0
- data/lib/will_sign.rb +42 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/will_sign_spec.rb +62 -0
- metadata +73 -0
data/README
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
will_sign
|
2
|
+
=========
|
3
|
+
|
4
|
+
Create time-based HMAC hashes from URLs.
|
5
|
+
|
6
|
+
USAGE
|
7
|
+
=====
|
8
|
+
|
9
|
+
# not really Rails-specific, works with POROs
|
10
|
+
class FooController < ApplicationController
|
11
|
+
include WillSign
|
12
|
+
|
13
|
+
protected
|
14
|
+
def sign_secret
|
15
|
+
:monkey # this should be something unique and special.
|
16
|
+
end
|
17
|
+
|
18
|
+
public
|
19
|
+
def index
|
20
|
+
url = "/foo/bar"
|
21
|
+
hash = sign_url(url)
|
22
|
+
redirect_to "#{url}?token=#{hash}"
|
23
|
+
end
|
24
|
+
|
25
|
+
def show
|
26
|
+
url = request.request_uri.split("?").first # "/foo/bar"
|
27
|
+
hash = params[:token]
|
28
|
+
if signed_url?(url, hash)
|
29
|
+
...
|
30
|
+
else
|
31
|
+
raise "Token expired"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
The default expiry for urls is 300 seconds (5 minutes). You can set a custom
|
37
|
+
expiry like this:
|
38
|
+
|
39
|
+
sign_url("foo/bar", 120) # 2 minutes
|
40
|
+
|
41
|
+
Or...
|
42
|
+
|
43
|
+
WillSign.default_expiry = 180
|
44
|
+
sign_url("foo/bar") # 3 minutes
|
45
|
+
|
46
|
+
CREDITS
|
47
|
+
=======
|
48
|
+
|
49
|
+
Thanks to Digisynd for funding this plugin, and TV for insight in how to properly
|
50
|
+
hash URLs.
|
51
|
+
|
52
|
+
TODO
|
53
|
+
====
|
54
|
+
|
55
|
+
gem spec...
|
data/lib/will_sign.rb
ADDED
@@ -0,0 +1,42 @@
|
|
1
|
+
require 'hmac-sha1'
|
2
|
+
|
3
|
+
module WillSign
|
4
|
+
# maximum allowed expiry
|
5
|
+
def self.default_expiry
|
6
|
+
@default_expiry ||= 300
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.default_expiry=(value)
|
10
|
+
@default_expiry = value.to_i
|
11
|
+
end
|
12
|
+
|
13
|
+
# relies on #sign_secret reader
|
14
|
+
|
15
|
+
# creates a header value like TIME:HASH
|
16
|
+
def sign_url(url, expiry = WillSign.default_expiry)
|
17
|
+
expiry = (Time.now.utc + expiry).to_i.to_s
|
18
|
+
pieces = split_url url
|
19
|
+
create_hash_from_url_and_expiry pieces, expiry
|
20
|
+
end
|
21
|
+
|
22
|
+
def signed_url?(url, given)
|
23
|
+
return false if url.nil? || given.nil? || given.size.zero?
|
24
|
+
expiry, hash = given.split(":")
|
25
|
+
expiry = expiry.to_i
|
26
|
+
now = Time.now.utc.to_i
|
27
|
+
return false if expiry < now
|
28
|
+
pieces = split_url url
|
29
|
+
result = create_hash_from_url_and_expiry pieces, expiry
|
30
|
+
result == given
|
31
|
+
end
|
32
|
+
|
33
|
+
protected
|
34
|
+
def split_url(url)
|
35
|
+
url.split("/"). \
|
36
|
+
delete_if { |piece| piece.nil? || piece.size.zero? }
|
37
|
+
end
|
38
|
+
|
39
|
+
def create_hash_from_url_and_expiry(pieces, expiry)
|
40
|
+
"#{expiry}:#{HMAC::SHA1.hexdigest(sign_secret.to_s, (pieces << expiry).join("/"))}"
|
41
|
+
end
|
42
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
begin
|
3
|
+
gem 'rspec'
|
4
|
+
rescue Gem::LoadError
|
5
|
+
end
|
6
|
+
|
7
|
+
$:.unshift File.dirname(__FILE__) + '/../../rspec/lib/'
|
8
|
+
$:.unshift File.dirname(__FILE__) + '/../lib'
|
9
|
+
|
10
|
+
require 'ruby-debug'
|
11
|
+
require 'spec'
|
12
|
+
require 'will_sign'
|
13
|
+
|
14
|
+
Debugger.start
|
@@ -0,0 +1,62 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
2
|
+
|
3
|
+
describe "WillSign" do
|
4
|
+
include WillSign
|
5
|
+
before do
|
6
|
+
@now = Time.utc(2007, 12, 31, 23, 58)
|
7
|
+
Time.stub!(:now).and_return(@now)
|
8
|
+
@hash = "1199145780:828170e4e98edc8b9d3f097695d2b0004234cb8e"
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "#sign_url" do
|
12
|
+
it "signs url with default expiry" do
|
13
|
+
sign_url("foo/bar").should == @hash
|
14
|
+
end
|
15
|
+
|
16
|
+
it "ignores beginning slash" do
|
17
|
+
sign_url("/foo/bar").should == @hash
|
18
|
+
end
|
19
|
+
|
20
|
+
it "ignores trailing slash" do
|
21
|
+
sign_url("foo/bar/").should == @hash
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe "#signed_url?" do
|
26
|
+
it "recognizes url with hash" do
|
27
|
+
signed_url?('foo/bar', @hash).should be_true
|
28
|
+
end
|
29
|
+
|
30
|
+
it "recognizes url with beginning slash and hash" do
|
31
|
+
signed_url?('/foo/bar', @hash).should be_true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "recognizes url with trailing slash and hash" do
|
35
|
+
signed_url?('foo/bar/', @hash).should be_true
|
36
|
+
end
|
37
|
+
|
38
|
+
it "recognizes nearly expired hash" do
|
39
|
+
Time.stub!(:now).and_return(@now + WillSign.default_expiry)
|
40
|
+
signed_url?('foo/bar', @hash).should be_true
|
41
|
+
end
|
42
|
+
|
43
|
+
it "doesn't recognize expired hash" do
|
44
|
+
Time.stub!(:now).and_return(@now + WillSign.default_expiry + 1)
|
45
|
+
signed_url?('foo/bar', @hash).should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "doesn't recognize nil url" do
|
49
|
+
signed_url?(nil, @hash).should be_false
|
50
|
+
end
|
51
|
+
|
52
|
+
it "doesn't recognize nil hash" do
|
53
|
+
signed_url?('foo/bar', nil).should be_false
|
54
|
+
end
|
55
|
+
|
56
|
+
it "doesn't recognize blank hash" do
|
57
|
+
signed_url?('foo/bar', '').should be_false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def sign_secret() :monkey end
|
62
|
+
end
|
metadata
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: did_will_sign
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
hash: 29
|
5
|
+
prerelease:
|
6
|
+
segments:
|
7
|
+
- 0
|
8
|
+
- 0
|
9
|
+
- 1
|
10
|
+
version: 0.0.1
|
11
|
+
platform: ruby
|
12
|
+
authors:
|
13
|
+
- technoweenie
|
14
|
+
autorequire:
|
15
|
+
bindir: bin
|
16
|
+
cert_chain: []
|
17
|
+
|
18
|
+
date: 2011-02-14 00:00:00 +01:00
|
19
|
+
default_executable:
|
20
|
+
dependencies: []
|
21
|
+
|
22
|
+
description: Small module for creating time-based hashes based on URLs
|
23
|
+
email:
|
24
|
+
- technoweenie@gmail.com
|
25
|
+
- didier@nocoffee.fr
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- README
|
32
|
+
files:
|
33
|
+
- lib/will_sign.rb
|
34
|
+
- README
|
35
|
+
- spec/spec_helper.rb
|
36
|
+
- spec/will_sign_spec.rb
|
37
|
+
has_rdoc: true
|
38
|
+
homepage: https://github.com/technoweenie/will_sign
|
39
|
+
licenses: []
|
40
|
+
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- --charset=UTF-8
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
none: false
|
48
|
+
requirements:
|
49
|
+
- - ">="
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
hash: 3
|
52
|
+
segments:
|
53
|
+
- 0
|
54
|
+
version: "0"
|
55
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
hash: 3
|
61
|
+
segments:
|
62
|
+
- 0
|
63
|
+
version: "0"
|
64
|
+
requirements: []
|
65
|
+
|
66
|
+
rubyforge_project:
|
67
|
+
rubygems_version: 1.4.2
|
68
|
+
signing_key:
|
69
|
+
specification_version: 3
|
70
|
+
summary: Small module for creating time-based hashes based on URLs
|
71
|
+
test_files:
|
72
|
+
- spec/spec_helper.rb
|
73
|
+
- spec/will_sign_spec.rb
|