tokens 0.1.0 → 0.2.0.beta.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.rdoc CHANGED
@@ -78,7 +78,7 @@ Run migrations with <tt>rake db:migrate</tt>. Add the method call
78
78
  User.find_by_token(:activate, "ea2f14aeac40")
79
79
 
80
80
  # remove all expired tokens except those with NULL values
81
- Token.delete_expired
81
+ Token.clean
82
82
 
83
83
  # generate a token as string, without saving it
84
84
  User.generate_token
data/Rakefile CHANGED
@@ -8,7 +8,7 @@ begin
8
8
  gem.email = "fnando.vieira@gmail.com"
9
9
  gem.homepage = "http://github.com/fnando/has_tokens"
10
10
  gem.authors = ["Nando Vieira"]
11
- gem.version = SimplesIdeias::Tokens::Version::STRING
11
+ gem.version = SimplesIdeias::Tokens::Version::STRING + ".beta.1"
12
12
  gem.summary = "Generate named tokens on your ActiveRecord models."
13
13
  gem.files = FileList["README.rdoc", "init.rb", "{lib,spec,source}/**/*", "Rakefile"]
14
14
  end
data/lib/tokens/token.rb CHANGED
@@ -1,19 +1,19 @@
1
1
  class Token < ActiveRecord::Base
2
2
  belongs_to :tokenizable, :polymorphic => true
3
-
3
+
4
4
  def hash
5
5
  token
6
6
  end
7
-
7
+
8
8
  def to_s
9
9
  hash
10
10
  end
11
-
11
+
12
12
  def expired?
13
13
  expires_at && expires_at < Time.now
14
14
  end
15
-
16
- def self.delete_expired
17
- delete_all ["expires_at < ? AND expires_at IS NOT NULL", Time.now]
15
+
16
+ def self.clean
17
+ delete_all ["expires_at < ? AND expires_at IS NOT NULL", Time.now]
18
18
  end
19
- end
19
+ end
@@ -2,7 +2,7 @@ module SimplesIdeias
2
2
  module Tokens
3
3
  module Version
4
4
  MAJOR = 0
5
- MINOR = 1
5
+ MINOR = 2
6
6
  PATCH = 0
7
7
  STRING = "#{MAJOR}.#{MINOR}.#{PATCH}"
8
8
  end
data/lib/tokens.rb CHANGED
@@ -1,115 +1,131 @@
1
- require "active_record"
2
- require "digest/sha1"
3
- require "tokens/string_ext"
4
- require "tokens/token"
5
-
6
- module SimplesIdeias
7
- module Tokens #:nodoc:
8
- def self.included(base)
9
- base.extend ClassMethods
10
- end
11
-
12
- module ClassMethods
13
- def has_tokens
14
- write_inheritable_attribute(:has_tokens_options, {
15
- :token_type => ActiveRecord::Base.send(:class_name_of_active_record_descendant, self).to_s
16
- })
1
+ module Tokens
2
+ require "tokens/token"
3
+ require "tokens/version"
17
4
 
18
- class_inheritable_reader :has_tokens_options
19
-
20
- has_many :tokens, :as => :tokenizable, :dependent => :destroy
21
- include SimplesIdeias::Tokens::InstanceMethods
22
- end
23
-
24
- def generate_token(seed, size)
25
- validity = Proc.new { |token| Token.find(:first, :conditions => {:token => token}).nil? }
26
-
27
- begin
28
- seed = Digest::SHA1.hexdigest(seed)
29
- token = Digest::SHA1.hexdigest(seed)[0, size]
30
- end while !validity.call(token)
5
+ def self.included(base)
6
+ base.class_eval { extend ClassMethods }
7
+ end
31
8
 
32
- token
33
- end
9
+ module ClassMethods
10
+ # Set up model for using tokens.
11
+ #
12
+ # class User < ActiveRecord::Base
13
+ # has_tokens
14
+ # end
15
+ #
16
+ def has_tokens
17
+ has_many :tokens, :as => :tokenizable, :dependent => :destroy
18
+ include InstanceMethods
19
+ end
34
20
 
35
- # Find a token
36
- # User.find_token(:activation, 'abcdefg')
37
- # User.find_token(:name => activation, :token => 'abcdefg')
38
- # User.find_token(:name => activation, :token => 'abcdefg', :tokenizable_id => 1)
39
- def find_token(*args)
40
- unless (options = args.first).is_a?(Hash)
41
- options = {:name => args.first, :token => args.last.to_s}
42
- end
43
-
44
- options[:name] = options[:name].to_s
45
- options.merge!({:tokenizable_type => has_tokens_options[:token_type]})
46
- Token.find(:first, :conditions => options)
47
- end
21
+ # Generate token using seed and size.
22
+ #
23
+ # User.generate_token("abc", 10)
24
+ #
25
+ def generate_token(seed, size)
26
+ validity = Proc.new {|token| Token.where(:token => token).first.nil?}
48
27
 
49
- # Find object by token
50
- # User.find_by_token(:activation, 'abcdefg')
51
- def find_by_token(name, token)
52
- t = find_token(:name => name.to_s, :token => token)
53
- return nil unless t
54
- t.tokenizable
55
- end
28
+ begin
29
+ seed = Digest::SHA1.hexdigest(seed)
30
+ token = Digest::SHA1.hexdigest(seed)[0, size]
31
+ end while validity[token] == false
56
32
 
57
- # Find object by valid token (same name, same hash, not expired)
58
- # User.find_by_valid_token(:activation, 'abcdefg')
59
- def find_by_valid_token(name, token)
60
- t = find_token(:name => name.to_s, :token => token)
61
- return nil unless t && !t.expired? && t.hash == token
62
- t.tokenizable
63
- end
33
+ token
64
34
  end
65
35
 
66
- module InstanceMethods
67
- # Object has a valid token (same name, same hash, not expired)
68
- # @user.valid_token?(:activation, 'abcdefg')
69
- def valid_token?(name, token)
70
- t = find_token_by_name(name)
71
- !!(t && !t.expired? && t.hash == token)
36
+ # Find a token
37
+ #
38
+ # User.find_token(:activation, 'abcdefg')
39
+ # User.find_token(:name => activation, :token => 'abcdefg')
40
+ # User.find_token(:name => activation, :token => 'abcdefg', :tokenizable_id => 1)
41
+ #
42
+ def find_token(*args)
43
+ if args.first.kind_of?(Hash)
44
+ args.first
45
+ else
46
+ options = {
47
+ :name => args.first,
48
+ :token => args.last
49
+ }
72
50
  end
73
51
 
74
- def remove_token(name)
75
- Token.delete_all([
76
- "tokenizable_id = ? AND tokenizable_type = ? AND name = ?",
77
- self.id,
78
- self.class.has_tokens_options[:token_type],
79
- name.to_s
80
- ])
81
- end
52
+ options.merge!(:name => options[:name].to_s, :tokenizable_type => self.name)
53
+ Token.where(options).include(:tokenizable).first
54
+ end
82
55
 
83
- def add_token(name, options={})
84
- options = {
85
- :expires_at => 2.days.from_now,
86
- :size => 12,
87
- :data => nil
88
- }.merge(options)
56
+ # Find object by token.
57
+ #
58
+ # User.find_by_token(:activation, 'abcdefg')
59
+ #
60
+ def find_by_token(name, hash)
61
+ token = find_token(:name => name.to_s, :token => hash)
62
+ return nil unless token
63
+ token.tokenizable
64
+ end
89
65
 
90
- remove_token(name)
66
+ # Find object by valid token (same name, same hash, not expired).
67
+ #
68
+ # User.find_by_valid_token(:activation, 'abcdefg')
69
+ #
70
+ def find_by_valid_token(name, hash)
71
+ token = find_token(:name => name.to_s, :token => hash)
72
+ return nil if !token || t.expired?
73
+ t.tokenizable
74
+ end
75
+ end
91
76
 
92
- seed = "--#{self.id}--#{self.object_id}--#{Time.now}--"
77
+ module InstanceMethods
78
+ # Find a token.
79
+ #
80
+ # @user.find_token(:activation, 'abcdefg')
81
+ #
82
+ def find_token(name, token)
83
+ self.class.find_token(
84
+ :tokenizable_id => self.id,
85
+ :name => name.to_s, :token => token
86
+ )
87
+ end
93
88
 
94
- self.tokens.create(
95
- :name => name.to_s,
96
- :token => self.class.generate_token(seed, options[:size]),
97
- :expires_at => options[:expires_at],
98
- :data => options[:data]
99
- )
100
- end
89
+ # Find token by its name.
90
+ def find_token_by_name(name)
91
+ self.tokens.find_by_name(name.to_s)
92
+ end
101
93
 
102
- def find_token_by_name(name)
103
- self.tokens.find_by_name(name.to_s)
104
- end
94
+ # Remove token.
95
+ #
96
+ # @user.remove_token(:activate)
97
+ #
98
+ def remove_token(name)
99
+ return if new_record?
100
+ token = find_token_by_name(name)
101
+ token && token.destroy
102
+ end
105
103
 
106
- # Find a token
107
- # @user.find_token(:activation, 'abcdefg')
108
- def find_token(name, token)
109
- self.class.find_token(:tokenizable_id => self.id, :name => name.to_s, :token => token)
110
- end
104
+ # Add a new token.
105
+ #
106
+ # @user.add_token(:api_key, :expires_at => nil)
107
+ # @user.add_token(:api_key, :size => 20)
108
+ # @user.add_token(:api_key, :data => data.to_yaml)
109
+ #
110
+ def add_token(name, options={})
111
+ options.reverse_merge!({
112
+ :expires_at => 2.days.from_now,
113
+ :size => 12,
114
+ :data => nil
115
+ })
116
+
117
+ remove_token(name)
118
+
119
+ seed = "--#{rand}--#{self.object_id}--#{Time.now}--"
120
+
121
+ self.tokens.create(
122
+ :name => name.to_s,
123
+ :token => self.class.generate_token(seed, options[:size]),
124
+ :expires_at => options[:expires_at],
125
+ :data => options[:data]
126
+ )
111
127
  end
112
128
  end
113
129
  end
114
130
 
115
- ActiveRecord::Base.send(:include, SimplesIdeias::Tokens)
131
+ ActiveRecord::Base.send :include, Tokens
data/spec/schema.rb CHANGED
@@ -2,17 +2,19 @@ ActiveRecord::Schema.define(:version => 0) do
2
2
  create_table :users do |t|
3
3
  t.string :name
4
4
  end
5
-
5
+
6
6
  create_table :posts do |t|
7
7
  t.string :title
8
8
  end
9
-
9
+
10
10
  create_table :tokens do |t|
11
- t.integer :tokenizable_id, :null => false
12
- t.string :tokenizable_type, :name, :null => false
13
- t.string :token, :limit => 40, :null => false
14
- t.text :data, :null => true
15
- t.datetime :expires_at, :null => true
16
- t.datetime :created_at
11
+ t.integer :tokenizable_id, :null => false
12
+ t.string :tokenizable_type, :name, :null => false
13
+ t.string :token, :null => false, :limit => 40
14
+ t.text :data, :null => true
15
+ t.datetime :expires_at, :null => true
16
+ t.datetime :created_at
17
17
  end
18
- end
18
+
19
+ add_index :tokens, :token, :unique => true
20
+ end
data/spec/spec_helper.rb CHANGED
@@ -1,23 +1,9 @@
1
1
  $LOAD_PATH.unshift File.dirname(__FILE__) + "/../lib"
2
2
 
3
- require "spec"
4
- require "ruby-debug"
3
+ require "rspec"
5
4
  require "active_record"
6
5
  require "tokens"
7
6
 
8
- ActiveRecord::Base.establish_connection(:adapter => 'sqlite3', :database => ":memory:")
7
+ ActiveRecord::Base.establish_connection(:adapter => "sqlite3", :database => ":memory:")
9
8
 
10
- load('schema.rb')
11
-
12
- class Object
13
- def self.unset_class(*args)
14
- class_eval do
15
- args.each do |klass|
16
- eval(klass) rescue nil
17
- remove_const(klass) if const_defined?(klass)
18
- end
19
- end
20
- end
21
- end
22
-
23
- alias :doing :lambda
9
+ load("schema.rb")
data/spec/tokens_spec.rb CHANGED
@@ -21,7 +21,7 @@ describe "has_tokens" do
21
21
 
22
22
  describe "- token" do
23
23
  it "should be created" do
24
- doing { @user.add_token(:uid) }.should change(Token, :count)
24
+ expect { @user.add_token(:uid) }.to change(Token, :count)
25
25
  end
26
26
 
27
27
  it "should be created for different users" do
@@ -101,23 +101,23 @@ describe "has_tokens" do
101
101
  end
102
102
 
103
103
  it "should have tokens association" do
104
- doing { @user.tokens }.should_not raise_error
104
+ expect { @user.tokens }.to_not raise_error
105
105
  end
106
106
 
107
107
  it "should remove all expired tokens" do
108
- doing {
108
+ expect {
109
109
  %w(uid activation_code reset_password_code).each do |name|
110
110
  @user.add_token(name, :expires_at => 3.days.ago)
111
111
  end
112
- }.should change(Token, :count).by(3)
112
+ }.to change(Token, :count).by(3)
113
113
 
114
114
  Token.delete_expired.should == 3
115
115
  end
116
116
 
117
117
  it "should generate token without saving it" do
118
- doing {
118
+ expect {
119
119
  User.generate_token(Time.now.to_s, 32)
120
- }.should_not change(Token, :count)
120
+ }.to_not change(Token, :count)
121
121
  end
122
122
 
123
123
  it "should generate token with custom size" do
metadata CHANGED
@@ -1,12 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: tokens
3
3
  version: !ruby/object:Gem::Version
4
- prerelease: false
4
+ hash: 62196353
5
+ prerelease: true
5
6
  segments:
6
7
  - 0
7
- - 1
8
+ - 2
8
9
  - 0
9
- version: 0.1.0
10
+ - beta
11
+ - 1
12
+ version: 0.2.0.beta.1
10
13
  platform: ruby
11
14
  authors:
12
15
  - Nando Vieira
@@ -14,7 +17,7 @@ autorequire:
14
17
  bindir: bin
15
18
  cert_chain: []
16
19
 
17
- date: 2010-07-09 00:00:00 -03:00
20
+ date: 2010-07-27 00:00:00 -03:00
18
21
  default_executable:
19
22
  dependencies: []
20
23
 
@@ -29,9 +32,7 @@ extra_rdoc_files:
29
32
  files:
30
33
  - README.rdoc
31
34
  - Rakefile
32
- - init.rb
33
35
  - lib/tokens.rb
34
- - lib/tokens/string_ext.rb
35
36
  - lib/tokens/token.rb
36
37
  - lib/tokens/version.rb
37
38
  - spec/schema.rb
@@ -47,23 +48,29 @@ rdoc_options:
47
48
  require_paths:
48
49
  - lib
49
50
  required_ruby_version: !ruby/object:Gem::Requirement
51
+ none: false
50
52
  requirements:
51
53
  - - ">="
52
54
  - !ruby/object:Gem::Version
55
+ hash: 3
53
56
  segments:
54
57
  - 0
55
58
  version: "0"
56
59
  required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
57
61
  requirements:
58
- - - ">="
62
+ - - ">"
59
63
  - !ruby/object:Gem::Version
64
+ hash: 25
60
65
  segments:
61
- - 0
62
- version: "0"
66
+ - 1
67
+ - 3
68
+ - 1
69
+ version: 1.3.1
63
70
  requirements: []
64
71
 
65
72
  rubyforge_project:
66
- rubygems_version: 1.3.6
73
+ rubygems_version: 1.3.7
67
74
  signing_key:
68
75
  specification_version: 3
69
76
  summary: Generate named tokens on your ActiveRecord models.
data/init.rb DELETED
@@ -1 +0,0 @@
1
- require 'tokens'
@@ -1,7 +0,0 @@
1
- require "digest/sha1"
2
-
3
- class String
4
- def to_sha1
5
- Digest::SHA1.hexdigest(self.dup)
6
- end
7
- end