tokens 0.1.0 → 0.2.0.beta.1

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