url_store 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
data/README.markdown CHANGED
@@ -1,15 +1,23 @@
1
1
  Data securely stored in urls.
2
2
 
3
+ - url-save output
4
+ - short codes through GZip
5
+ - serializing through __:marshal__ :yaml
6
+ - hashing through DSS DSS1 MD2 MD4 MD5 MDC2 RIPEMD160 SHA __SHA1__ SHA224 SHA256 SHA384 SHA512
7
+
8
+
3
9
  Install
4
10
  =======
5
11
  - As gem: ` sudo gem install url_store `
6
12
  - As Rails plugin: ` script/plugin install git://github.com/grosser/url_store.git `
7
13
 
8
-
9
14
  Usage
10
15
  =====
16
+ # config (e.g environment.rb)
17
+ UrlStore.secret = 'adadasd2adsdasd4ads4eas4dea4dsea4sd'
18
+
11
19
  # View:
12
- <%= link_to 'paid', :controller=>:payments, :action=>:paid, :data=>UrlStore.encode(:id=>1, :status=>'paid')%>
20
+ <%= link_to 'paid', :controller=>:payments, :action=>:paid, :data=>UrlStore.encode(:id=>1, :status=>'paid') %>
13
21
 
14
22
  # Controller:
15
23
  if data = UrlStore.decode(params[:data])
@@ -18,6 +26,11 @@ Usage
18
26
  raise 'FRAUD!'
19
27
  end
20
28
 
29
+ ### Options
30
+ UrlStore.secret = 'something random'
31
+ UrlStore.hasher = 'MD5' # default: 'SHA1'
32
+ UrlStore.serializer = :yaml # default: :marshal
33
+
21
34
  Author
22
35
  =======
23
36
  [Michael Grosser](http://pragmatig.wordpress.com)
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
@@ -0,0 +1,62 @@
1
+ require 'base64'
2
+ require 'zlib'
3
+
4
+ class UrlStore
5
+ class CompactEncoder
6
+ def initialize(secret, options={})
7
+ @secret = secret
8
+ @hasher = options[:hasher] || 'SHA1'
9
+ @serializer = options[:serializer] || :marshal
10
+ end
11
+
12
+ def encode(data)
13
+ data = compress(serialize(data))
14
+ data+digest(data)
15
+ end
16
+
17
+ def decode(data)
18
+ hash = data[-hash_length..-1]
19
+ data = data[0...-hash_length]
20
+
21
+ if digest(data) == hash
22
+ deserialize extract(data)
23
+ else
24
+ nil
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def serialize(data)
31
+ case @serializer.to_sym
32
+ when :yaml then data.to_yaml
33
+ when :marshal then Marshal.dump(data)
34
+ end
35
+ end
36
+
37
+ def deserialize(data)
38
+ case @serializer.to_sym
39
+ when :yaml then YAML.load(data)
40
+ when :marshal then Marshal.load(data)
41
+ end
42
+ end
43
+
44
+ def compress(data)
45
+ Base64.encode64( Zlib::Deflate.deflate(data)).gsub("\n",'')
46
+ end
47
+
48
+ def extract(data)
49
+ Zlib::Inflate.inflate Base64.decode64(data)
50
+ end
51
+
52
+ def hash_length
53
+ digest('x').size
54
+ end
55
+
56
+ # stolen from ActiveSupport
57
+ def digest(data)
58
+ require 'openssl' unless defined?(OpenSSL)
59
+ OpenSSL::HMAC.hexdigest(OpenSSL::Digest::Digest.new(@hasher.to_s), @secret, data)
60
+ end
61
+ end
62
+ end
data/lib/url_store.rb CHANGED
@@ -1,37 +1,44 @@
1
- require 'active_support'
1
+ require 'url_store/compact_encoder'
2
2
 
3
3
  class UrlStore
4
4
  VERSION = File.read( File.join(File.dirname(__FILE__),'..','VERSION') ).strip
5
5
  SECRET = 'asdkasjlwqjdqaccxnjkasdfh2313'
6
- METHOD = 'SHA1'
6
+ HASHER = 'SHA1'
7
+ SERIALIZER = :marshal
7
8
 
8
9
  # (convert to base64url <-> RFC4648) and '|'
9
10
  # which is not url-safe if you ask ERB/CGI, but browsers accept it
10
11
  IN = '+/='
11
12
  OUT = '-_|'
12
13
 
13
- cattr_accessor :secret
14
- self.secret = SECRET
14
+ @@secret = SECRET
15
+ def self.secret=(x); @@secret=x; end
16
+ def self.secret; @@secret; end
17
+
18
+ @@hasher = HASHER
19
+ def self.hasher=(x); @@hasher=x; end
20
+ def self.hasher; @@hasher; end
21
+
22
+ @@serializer = SERIALIZER
23
+ def self.serializer=(x); @@serializer=x; end
24
+ def self.serializer; @@serializer; end
15
25
 
16
26
  def self.encode(data)
17
- string = encoder.generate(data)
18
- string = string.sub('--', ';') # seperator of verifier
27
+ string = encoder.encode(data)
19
28
  string.to_s.tr(IN,OUT)
20
29
  end
21
30
 
22
31
  def self.decode(string)
23
32
  string = string.to_s.tr(OUT,IN) # convert to base64url <-> RFC4648
24
- string = string.sub(';','--') # seperator of verifier
25
- begin
26
- encoder.verify(string)
27
- rescue ActiveSupport::MessageVerifier::InvalidSignature
28
- nil
29
- end
33
+ encoder.decode(string)
30
34
  end
31
35
 
32
36
  private
33
37
 
34
38
  def self.encoder
35
- ActiveSupport::MessageVerifier.new(secret, METHOD)
39
+ if secret == SECRET
40
+ warn "WARNING: you should not use the default secret! use UrlStore.secret='something'"
41
+ end
42
+ UrlStore::CompactEncoder.new(secret, :hasher => hasher, :serializer => serializer)
36
43
  end
37
44
  end
@@ -0,0 +1,31 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe UrlStore::CompactEncoder do
4
+ before do
5
+ @encoder = UrlStore::CompactEncoder.new('asdasdsa')
6
+ @data = {:x => 1, 'asdadadadas' => 'asdasdadawvxcxcxcvjs', 'dasdasdadsadad' => 'asdasdwxczvvcjjkdfjkdf'}
7
+ end
8
+
9
+ it "generates same code for same data" do
10
+ @encoder.encode(@data).should == @encoder.encode(@data)
11
+ end
12
+
13
+ it "can decode / encode" do
14
+ @encoder.decode(@encoder.encode(@data)).should == @data
15
+ end
16
+
17
+ it "generates shorter codes than pure base64" do
18
+ hash_length = 40
19
+ @encoder.encode(@data).size.should < (Base64.encode64(Marshal.dump(@data)).size + hash_length)
20
+ end
21
+
22
+ it "can encode/decode with yaml" do
23
+ @encoder = UrlStore::CompactEncoder.new('asdasdsa', :serializer => :yaml)
24
+ @encoder.decode(@encoder.encode(@data)).should == @data
25
+ end
26
+
27
+ it "can hash with other hasher" do
28
+ @encoder = UrlStore::CompactEncoder.new('asdasdsa', :hasher => 'MD5')
29
+ @encoder.decode(@encoder.encode(@data)).should == @data
30
+ end
31
+ end
@@ -3,6 +3,7 @@ require 'cgi'
3
3
 
4
4
  describe UrlStore do
5
5
  before do
6
+ UrlStore.secret = 'not the standart sssecrettt1231231áßðáïíœï©óáßïáöððííïö'
6
7
  @data = {:x => 11212, :y => 'asdasda sdasdasdASDJKSAJDLSKDLKDS', 'asdasd' => 12312312, 12.12 => 123123212312123, :asdasdasd => '2134 adasdasóáößðóöáåöäóðᜩöóöfóöåäfóöéåfó'}
7
8
  end
8
9
 
@@ -20,7 +21,7 @@ describe UrlStore do
20
21
  end
21
22
 
22
23
  it "uses a lot of different chars" do
23
- UrlStore.encode(@data).split('').uniq.size.should >= 63
24
+ UrlStore.encode(@data).split('').uniq.size.should >= 62
24
25
  end
25
26
 
26
27
  it "uses url-save characters" do
@@ -34,6 +35,29 @@ describe UrlStore do
34
35
  UrlStore.decode(encoded).should == nil
35
36
  end
36
37
 
38
+ it "warns when default secret is used" do
39
+ UrlStore.secret = UrlStore::SECRET
40
+ UrlStore.should_receive(:warn)
41
+ UrlStore.encode(1)
42
+ end
43
+
44
+ it "can compress" do
45
+ x = 'a'*100
46
+ UrlStore.encode(x).size.should <= x.size
47
+ end
48
+
49
+ it "can serialize using a different method" do
50
+ old = UrlStore.encode(@data)
51
+ UrlStore.serializer = :yaml
52
+ UrlStore.encode(@data).size.should_not == old.size
53
+ end
54
+
55
+ it "can serialize using different hasher" do
56
+ old = UrlStore.encode(@data)
57
+ UrlStore.hasher = 'MD5'
58
+ UrlStore.encode(@data).size.should_not == old.size
59
+ end
60
+
37
61
  it "has a VERSION" do
38
62
  UrlStore::VERSION.should =~ /^\d+\.\d+\.\d+$/
39
63
  end
data/url_store.gemspec CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{url_store}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Michael Grosser"]
@@ -20,7 +20,9 @@ Gem::Specification.new do |s|
20
20
  "Rakefile",
21
21
  "VERSION",
22
22
  "lib/url_store.rb",
23
+ "lib/url_store/compact_encoder.rb",
23
24
  "spec/spec_helper.rb",
25
+ "spec/url_store/compact_encoder_spec.rb",
24
26
  "spec/url_store_spec.rb",
25
27
  "url_store.gemspec"
26
28
  ]
@@ -31,7 +33,8 @@ Gem::Specification.new do |s|
31
33
  s.summary = %q{Data securely stored in urls.}
32
34
  s.test_files = [
33
35
  "spec/spec_helper.rb",
34
- "spec/url_store_spec.rb"
36
+ "spec/url_store_spec.rb",
37
+ "spec/url_store/compact_encoder_spec.rb"
35
38
  ]
36
39
 
37
40
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: url_store
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Grosser
@@ -26,7 +26,9 @@ files:
26
26
  - Rakefile
27
27
  - VERSION
28
28
  - lib/url_store.rb
29
+ - lib/url_store/compact_encoder.rb
29
30
  - spec/spec_helper.rb
31
+ - spec/url_store/compact_encoder_spec.rb
30
32
  - spec/url_store_spec.rb
31
33
  - url_store.gemspec
32
34
  has_rdoc: true
@@ -60,3 +62,4 @@ summary: Data securely stored in urls.
60
62
  test_files:
61
63
  - spec/spec_helper.rb
62
64
  - spec/url_store_spec.rb
65
+ - spec/url_store/compact_encoder_spec.rb