refcode 0.0.1 → 0.1.0

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: e758644ad3263ebb08c54c505b606c310ba5a88a
4
- data.tar.gz: 5eef6a2ba89fa9dc55922ee1ea6fe54488155c72
3
+ metadata.gz: 420403fbddbdbbfe612045ab19119651a54f8740
4
+ data.tar.gz: 41307cc055dfbea7997fc7e66f20dffbcf94ff9a
5
5
  SHA512:
6
- metadata.gz: aa418e724d2bc68c26e7fb06ce6758d8ab2aa04d96aa5b3aaadaf5981750ab8e428706016d15d0c543ddd0f88b38807f8f91ab2fcd209839ee60263c853b36c5
7
- data.tar.gz: d098a3bd746a7f4afe3fb4db4240c7ec645b795f8e99e7296d91bd8677bd013203536cb79437a35e6a843947882727caa35c4be16f8b44a469e7c49197915d00
6
+ metadata.gz: b3fd63ca01f994071ac81ab8545f1880433a661806d73aa81797aeb83fa4763ea7f636777926f823b2df1115df90a3ab463c0c6a74424cceef958274d2095284
7
+ data.tar.gz: 172f2f19bc9a3d6f02c75adc665bda99f4a12f5c6edbf825e4c4845cfd42de3fc88e9da06f215fbcfa862b54daa58a640bddf6eb4d50b291988e4a11dc2c270f
data/README.md CHANGED
@@ -5,7 +5,9 @@ URL-safe strings. The strings can be simply decrypted later to be used by your
5
5
  application.
6
6
 
7
7
  Refcode was conceived as a way to attach referral data to tracking links. Encryption
8
- makes it unlikely that the links can be tampered with.
8
+ makes it unlikely that the links will be tampered with. Still, it is not recommended
9
+ for critically sensitive applications! It was designed to power a simple referral
10
+ link tracking system.
9
11
 
10
12
  ## Implementation
11
13
 
@@ -31,6 +33,8 @@ Or install it yourself as:
31
33
 
32
34
  ## Usage
33
35
 
36
+ Refcode can be used in two ways. Most simply, you can use the `Refcode::Encoder` class directly.
37
+
34
38
  encoder = Refcode::Encoder.new do |e|
35
39
  e.secret = "a long crunchy secret"
36
40
  e.salt = "some salt"
@@ -39,11 +43,32 @@ Or install it yourself as:
39
43
  something = OpenStruct.new(channel: 'facebook', action: 'message', user_id: 43765)
40
44
  encoded_param = encoder.encode something
41
45
 
42
- # in some future request...
46
+ # in some future request:
43
47
 
44
48
  something = encoder.decode params[:encoded_param]
45
49
  puts something.channel # 'facebook'
46
50
 
51
+ For added convenience when using Refcode with an ORM such as ActiveRecord, a module called `Refcode::Encodable` is also provided.
52
+
53
+ class Job < ActiveRecord::Base
54
+ include Refcode::Encodable
55
+ has_refcode secret: 'a long crunchy secret', salt: :id
56
+ end
57
+
58
+ # the salt option of the has_refcode method can accept a proc/lambda, string
59
+ # or a symbol representing an existing method on the class (id in this case)
60
+
61
+ # in some controller code:
62
+
63
+ @job = Job.find params[:id]
64
+ referral_code = @job.generate_refcode channel: 'facebook', action: 'message', user_id: 43765
65
+
66
+ # and in another action:
67
+
68
+ @job = Job.find params[:id]
69
+ referral_data = @job.parse_refcode params[:encoded_param]
70
+
71
+
47
72
  ## Contributing
48
73
 
49
74
  1. Fork it
data/lib/refcode.rb CHANGED
@@ -3,39 +3,5 @@ require 'yaml'
3
3
  require 'base64url'
4
4
  require 'encryptor'
5
5
  require 'refcode/version'
6
-
7
- module Refcode
8
-
9
- class Encoder
10
-
11
- attr_accessor :secret, :salt
12
-
13
- def initialize
14
- yield self if block_given?
15
- end
16
-
17
- def encode val
18
- Base64URL.encode(encrypt(YAML.dump(val)))
19
- end
20
-
21
- def decode val
22
- YAML.load(decrypt(Base64URL.decode(val)))
23
- end
24
-
25
- def encrypt val
26
- Encryptor.encrypt(:value => val, :key => @secret, :salt => @salt, :iv => iv)
27
- end
28
-
29
- def decrypt val
30
- Encryptor.decrypt(:value => val, :key => @secret, :salt => @salt, :iv => iv)
31
- end
32
-
33
- private
34
-
35
- def iv
36
- [@secret, @salt].join
37
- end
38
-
39
- end
40
-
41
- end
6
+ require 'refcode/encoder'
7
+ require 'refcode/encodable'
@@ -0,0 +1,47 @@
1
+ module Refcode
2
+
3
+ module Encodable
4
+
5
+ def self.included base
6
+ base.extend ClassMethods
7
+ end
8
+
9
+ def generate_refcode val
10
+ raise 'You must call the has_refcode method in your class definition' unless self.class.refcode_options
11
+ encoder.encode val
12
+ end
13
+
14
+ def parse_refcode code
15
+ encoder.decode code
16
+ end
17
+
18
+ module ClassMethods
19
+ def has_refcode options
20
+ raise ArgumentError unless options[:secret] && options[:salt]
21
+ @refcode_options = options
22
+ end
23
+ def refcode_options
24
+ @refcode_options
25
+ end
26
+ end
27
+
28
+ private
29
+
30
+ def encoder
31
+ Refcode::Encoder.new do |r|
32
+ r.secret = self.class.refcode_options[:secret]
33
+ salt_option = self.class.refcode_options[:salt]
34
+ if salt_option.respond_to? :call
35
+ r.salt = salt_option.call
36
+ elsif salt_option.is_a? Symbol
37
+ r.salt = self.send salt_option
38
+ else
39
+ r.salt = salt_option
40
+ end
41
+ raise "Value for salt is nil (#{salt_option} given)" if r.salt.nil?
42
+ end
43
+ end
44
+
45
+ end
46
+
47
+ end
@@ -0,0 +1,31 @@
1
+ module Refcode
2
+
3
+ class Encoder
4
+
5
+ attr_accessor :secret, :salt
6
+
7
+ def initialize
8
+ yield self if block_given?
9
+ end
10
+ def encode val
11
+ Base64URL.encode(encrypt(YAML.dump(val)))
12
+ end
13
+ def decode val
14
+ YAML.load(decrypt(Base64URL.decode(val)))
15
+ end
16
+
17
+ private
18
+
19
+ def encrypt val
20
+ Encryptor.encrypt(:value => val, :key => @secret, :salt => @salt, :iv => iv)
21
+ end
22
+ def decrypt val
23
+ Encryptor.decrypt(:value => val, :key => @secret, :salt => @salt, :iv => iv)
24
+ end
25
+ def iv
26
+ [@secret, @salt].join
27
+ end
28
+
29
+ end
30
+
31
+ end
@@ -1,3 +1,3 @@
1
1
  module Refcode
2
- VERSION = "0.0.1"
2
+ VERSION = "0.1.0"
3
3
  end
data/test/refcode_test.rb CHANGED
@@ -7,6 +7,13 @@ class RefcodeTest < Test::Unit::TestCase
7
7
  SECRET = "686cb0461769ebed556f56bc88c956bfdf786646ab1920f58201723c557ccbaeb57112fd53302c06475e6e19a176ba617ee284b091d375858cb259e8578c620f"
8
8
  SALT = "dcc74de5efdab0d80b5d763f8a63bef3d37c7453ee45446fbbccd26648af8ca6a112576dafbf5475f3cd7b968703cc9e0682ee45b8b622045cec287908f536e8"
9
9
 
10
+ class BareEncodableObject < OpenStruct
11
+ include Refcode::Encodable
12
+ end
13
+ class EncodableObject < BareEncodableObject
14
+ has_refcode :secret => SECRET, :salt => :record_id
15
+ end
16
+
10
17
  def test_encoder_against_hash
11
18
  test_hash = { :channel => 'email', :record_id => 49203, :action => 'forward' }
12
19
  assert_equal test_hash, encode_and_decode(test_hash)
@@ -26,8 +33,40 @@ class RefcodeTest < Test::Unit::TestCase
26
33
  assert_equal test_struct, encode_and_decode(test_struct)
27
34
  end
28
35
 
36
+ def test_should_raise_argument_error_if_generate_refcode_called_without_val
37
+ assert_raise ArgumentError do
38
+ encodable_object.generate_refcode
39
+ end
40
+ end
41
+
42
+ def test_should_raise_error_if_generate_refcode_called_before_has_refcode
43
+ assert_raise ArgumentError do
44
+ obj = BareEncodableObject.new :some => 'value'
45
+ obj.generate_refcode
46
+ end
47
+ end
48
+
49
+ def test_should_raise_an_error_if_salt_is_empty
50
+ encodable_object.record_id = nil
51
+ assert_raise RuntimeError do
52
+ referral_code_content = { :channel => 'email', :action => 'forward', :user_id => 14325 }
53
+ code = encodable_object.generate_refcode referral_code_content
54
+ assert_equal referral_code_content, encodable_object.parse_refcode(code)
55
+ end
56
+ end
57
+
58
+ def test_encodable_against_hash
59
+ referral_code_content = { :channel => 'email', :action => 'forward', :user_id => 14325 }
60
+ code = encodable_object.generate_refcode referral_code_content
61
+ assert_equal referral_code_content, encodable_object.parse_refcode(code)
62
+ end
63
+
29
64
  private
30
65
 
66
+ def encodable_object
67
+ @encodable_object ||= EncodableObject.new :name => 'Unimportant Value', :record_id => 381598
68
+ end
69
+
31
70
  def encoder
32
71
  @encoder ||= Refcode::Encoder.new do |e|
33
72
  e.secret = SECRET
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: refcode
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jordan Sitkin
@@ -79,6 +79,8 @@ files:
79
79
  - README.md
80
80
  - Rakefile
81
81
  - lib/refcode.rb
82
+ - lib/refcode/encodable.rb
83
+ - lib/refcode/encoder.rb
82
84
  - lib/refcode/version.rb
83
85
  - refcode.gemspec
84
86
  - test/refcode_test.rb