did_will_sign 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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...
@@ -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
@@ -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