refcode 0.1.1 → 0.1.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: b45526e91ab90f8b69e43976b600a8bbfa1dbdc0
4
- data.tar.gz: f580b982c0f61c0021f77b53f0f607047569ebdb
3
+ metadata.gz: 9a685e0c98a5089405fa727a02f854ffc2f27a05
4
+ data.tar.gz: e44c013ab75a304dabcd4c3c41693dd71eda05f0
5
5
  SHA512:
6
- metadata.gz: 21d4ebf71a2fb58ebf43068289ae42b80646b78f8bb8fdbdd05be8ac0e0778f044d21bf466b04f0cd640cef75ae14cff2828dacfecbea19eec5d67180ab8e0fe
7
- data.tar.gz: 25d0b08552e8e4f4c84080f084bd78d3ae89914aa380c9b81434b6993ee653f264b77961394d586615e213f6bbd262dab56f718cdf5f7d621020b8a5db527760
6
+ metadata.gz: 6cf38bfc747e4fa7a387f7f4e72f5b9d3aa5b788de1944becbb9aa01366f27669efecf66307c42165ea5b2b949114351595210ec8c3145795a4211c899b1ad79
7
+ data.tar.gz: cebc83c94a985bc14a89ac551d9f38d93f0484086500ffcd83b8f0f4f901aa46093d600b768d7eae3bfb39831687a49acb3c00ff8a22f4adc7005eac89cb12f0
data/README.md CHANGED
@@ -1,12 +1,14 @@
1
- # Refcode
1
+ # RefCode
2
2
 
3
- A ruby gem for converting arbitrary Ruby objects into encrypted,
4
- URL-safe strings. The strings can be easily decrypted later for use in your
5
- application.
3
+ A ruby gem for converting arbitrary Ruby objects into encrypted, URL-safe strings. The strings can be easily decrypted later for use in your application.
6
4
 
7
- RefCode was conceived as a way to attach referral data to tracking links. Encryption
8
- makes it unlikely that the links will be tampered with. Still, it is not recommended
9
- for critically sensitive data!
5
+ RefCode was conceived as a way to attach referral data to tracking links. Encryption makes it unlikely that the links will be tampered with. Still, it is not recommended for sensitive data!
6
+
7
+ ## Why would you want this?
8
+
9
+ Lets say your app needs to track activity around certain pages that are shared among your users. Using RefCode, you can generate URLs pointing to these pages that are meant to be shared across various channels (email, facebook, etc). These links can carry a small amount of encoded data as part of the URL that will guarantee that any events you track due to visits to these links can make use of this extra encoded data. The data might include, for example, which user originally shared the link and on which channel she did so.
10
+
11
+ A secondary feature offered by the `Refcode::Encodable` mixin is the ability to guarantee that a given code works only for one (or more) specific page. For example, by using a unique value for the `salt` option that is tied to a single record, the generated code cannot be used with any other record. See the usage example below for a demonstration of this.
10
12
 
11
13
  ## Implementation
12
14
 
@@ -31,15 +31,8 @@ module Refcode
31
31
  def encoder
32
32
  Refcode::Encoder.new do |r|
33
33
  check_refcode_options!
34
- r.secret = self.class.refcode_options[:secret]
35
- salt_option = self.class.refcode_options[:salt]
36
- if salt_option.respond_to? :call
37
- r.salt = salt_option.call self
38
- elsif salt_option.is_a? Symbol
39
- r.salt = self.send salt_option
40
- else
41
- r.salt = salt_option
42
- end
34
+ r.secret = get_option_value(self.class.refcode_options[:secret])
35
+ r.salt = get_option_value(self.class.refcode_options[:salt])
43
36
  raise "Value for salt is nil (#{salt_option} given)" if r.salt.nil?
44
37
  end
45
38
  end
@@ -48,6 +41,16 @@ module Refcode
48
41
  raise RefcodeInitException.new('You must call the has_refcode method in your class definition') unless self.class.refcode_options
49
42
  end
50
43
 
44
+ def get_option_value option
45
+ if option.respond_to? :call
46
+ option.call self
47
+ elsif option.is_a? Symbol
48
+ self.send option
49
+ else
50
+ option
51
+ end
52
+ end
53
+
51
54
  end
52
55
 
53
56
  end
@@ -13,6 +13,10 @@ module Refcode
13
13
  def decode val
14
14
  YAML.load(decrypt(Base64URL.decode(val)))
15
15
  end
16
+ def secret= secret
17
+ secret = secret * 2 until secret.size >= 32
18
+ @secret = secret
19
+ end
16
20
 
17
21
  private
18
22
 
@@ -1,3 +1,3 @@
1
1
  module Refcode
2
- VERSION = "0.1.1"
2
+ VERSION = "0.1.2"
3
3
  end
@@ -5,23 +5,34 @@ require File.join(File.dirname(__FILE__),"..","lib","refcode.rb")
5
5
  class RefcodeEncodableTest < Test::Unit::TestCase
6
6
 
7
7
  SECRET = "a short tidy secret, but not too short!"
8
+ CODE_CONTENT = {:channel => 'email', :action => 'forward', :user_id => 14325, :unique_hash => 'f'}
8
9
 
9
10
  class BareEncodableObject < OpenStruct
10
11
  include Refcode::Encodable
11
12
  end
12
- class EncodableObjectSymbol < BareEncodableObject
13
- has_refcode :secret => SECRET, :salt => :record_id
13
+ class EncodableObjectSaltSymbol < BareEncodableObject
14
+ has_refcode :secret => SECRET, :salt => :user_id
14
15
  end
15
- class EncodableObjectString < BareEncodableObject
16
+ class EncodableObjectSaltString < BareEncodableObject
16
17
  has_refcode :secret => SECRET, :salt => "123 abc xyz"
17
18
  end
18
- class EncodableObjectSaltyLambda < BareEncodableObject
19
- has_refcode :secret => SECRET, :salt => lambda { |me| "#{me.record_id}-42" }
19
+ class EncodableObjectSaltLambda < BareEncodableObject
20
+ has_refcode :secret => SECRET, :salt => lambda { |me| "#{me.user_id}-42" }
21
+ end
22
+ class EncodableObjectSecretSymbol < BareEncodableObject
23
+ has_refcode :secret => :unique_hash, :salt => :user_id
24
+ end
25
+ class EncodableObjectSecretString < BareEncodableObject
26
+ has_refcode :secret => SECRET, :salt => "123 abc xyz"
27
+ end
28
+ class EncodableObjectSecretLambda < BareEncodableObject
29
+ has_refcode :secret => lambda { |me| me.channel*20 }, :salt => "aaa"
20
30
  end
21
31
 
22
32
  def test_should_raise_argument_error_if_generate_refcode_called_without_val
23
33
  assert_raise ArgumentError do
24
- encodable_object.generate_refcode
34
+ obj = EncodableObjectSaltString.new CODE_CONTENT
35
+ obj.generate_refcode
25
36
  end
26
37
  end
27
38
 
@@ -42,33 +53,51 @@ class RefcodeEncodableTest < Test::Unit::TestCase
42
53
  end
43
54
 
44
55
  def test_should_raise_an_error_if_salt_is_empty
45
- encodable_object.record_id = nil
56
+ obj = EncodableObjectSaltSymbol.new CODE_CONTENT
57
+ obj.user_id = nil
46
58
  assert_raise RuntimeError do
47
- referral_code_content = { :channel => 'email', :action => 'forward', :user_id => 14325 }
48
- code = encodable_object.generate_refcode referral_code_content
49
- assert_equal referral_code_content, encodable_object.parse_refcode(code)
59
+ code = obj.generate_refcode CODE_CONTENT
60
+ assert_equal CODE_CONTENT, obj.parse_refcode(code)
50
61
  end
51
62
  end
52
63
 
53
64
  def test_should_work_with_different_salt_options
54
- [EncodableObjectSaltyLambda, EncodableObjectString].each do |klass|
55
- referral_code_content = { :channel => 'email', :action => 'forward', :user_id => 14325 }
56
- obj = klass.new referral_code_content
57
- code = obj.generate_refcode referral_code_content
58
- assert_equal referral_code_content, obj.parse_refcode(code)
65
+ with_all_fixtures do |klass|
66
+ obj = klass.new CODE_CONTENT
67
+ code = obj.generate_refcode CODE_CONTENT
68
+ assert_equal CODE_CONTENT, obj.parse_refcode(code)
59
69
  end
60
70
  end
61
71
 
62
- def test_encodable_against_hash
63
- referral_code_content = { :channel => 'email', :action => 'forward', :user_id => 14325 }
64
- code = encodable_object.generate_refcode referral_code_content
65
- assert_equal referral_code_content, encodable_object.parse_refcode(code)
72
+ def test_should_work_with_different_secret_options
73
+ with_all_fixtures do |klass|
74
+ obj = klass.new CODE_CONTENT
75
+ code = obj.generate_refcode CODE_CONTENT
76
+ assert_equal CODE_CONTENT, obj.parse_refcode(code)
77
+ end
78
+ end
79
+
80
+ def test_should_adjust_key_length_to_satisfy_encryption_algorithm
81
+ content = CODE_CONTENT
82
+ content[:unique_hash] = "x"
83
+ obj = EncodableObjectSecretSymbol.new content
84
+ code = obj.generate_refcode content
85
+ assert_equal content, obj.parse_refcode(code)
66
86
  end
67
87
 
68
88
  private
69
89
 
70
- def encodable_object
71
- @encodable_object ||= EncodableObjectSymbol.new :name => 'Unimportant Value', :record_id => 381598
90
+ def with_all_fixtures
91
+ [
92
+ EncodableObjectSaltLambda,
93
+ EncodableObjectSaltString,
94
+ EncodableObjectSaltSymbol,
95
+ EncodableObjectSecretLambda,
96
+ EncodableObjectSecretString,
97
+ EncodableObjectSecretSymbol
98
+ ].each do |klass|
99
+ yield klass
100
+ end
72
101
  end
73
102
 
74
103
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refcode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.1
4
+ version: 0.1.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sitkin
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-10-01 00:00:00.000000000 Z
11
+ date: 2013-10-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: base64url