ar-tokens 0.0.4
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/.gitignore +4 -0
- data/Gemfile +6 -0
- data/README.markdown +39 -0
- data/Rakefile +2 -0
- data/ar-tokens.gemspec +23 -0
- data/lib/active_record/mixin/token_generator.rb +84 -0
- data/lib/ar-tokens.rb +5 -0
- data/lib/no_free_token.rb +5 -0
- data/lib/object.rb +22 -0
- data/lib/tokens/version.rb +3 -0
- data/spec/active_record_spec.rb +58 -0
- data/spec/object_spec.rb +21 -0
- data/spec/spec_helper.rb +14 -0
- data/spec/support/active_record.rb +13 -0
- metadata +81 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/README.markdown
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
For generating a token on an active record column you can use `generate_token`
|
2
|
+
|
3
|
+
Parameters
|
4
|
+
----------
|
5
|
+
|
6
|
+
* column: the column of the active record
|
7
|
+
* options: some options for generating the token
|
8
|
+
* :length: the token length (default: 8)
|
9
|
+
* :uniq: whether the token must be uniq or not (default: true)
|
10
|
+
* :scope: the column for the scope to check the uniqueness (default: nil)
|
11
|
+
|
12
|
+
Example
|
13
|
+
-------
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class User < ActiveRecord::Base
|
17
|
+
tokenize :email_confirmation_token, length: 16
|
18
|
+
end
|
19
|
+
```
|
20
|
+
|
21
|
+
this is equal to
|
22
|
+
|
23
|
+
```ruby
|
24
|
+
class User < ActiveRecord::Base
|
25
|
+
before_validation on: :create do |obj|
|
26
|
+
obj.generate_token :email_confirmation_token, length: 16
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
Installation
|
32
|
+
------------
|
33
|
+
|
34
|
+
Currently the gem is not available on rubyforge, so you have to install it with git:
|
35
|
+
|
36
|
+
```
|
37
|
+
gem 'ar-tokens'
|
38
|
+
```
|
39
|
+
|
data/Rakefile
ADDED
data/ar-tokens.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
$:.push File.expand_path("../lib", __FILE__)
|
3
|
+
require "tokens/version"
|
4
|
+
|
5
|
+
Gem::Specification.new do |s|
|
6
|
+
s.name = "ar-tokens"
|
7
|
+
s.version = Tokens::VERSION
|
8
|
+
s.platform = Gem::Platform::RUBY
|
9
|
+
s.authors = ["Paul Spieker"]
|
10
|
+
s.email = ["p.spieker@duenos.de"]
|
11
|
+
s.homepage = "https://github.com/spieker/tokens"
|
12
|
+
s.summary = %q{Generating tokens on ruby objects and active record columns}
|
13
|
+
s.description = %q{This gem lets you easily generate tokens on ruby objects and provides additional methods on ActiveRecord::Base to generate tokens on records}
|
14
|
+
|
15
|
+
s.rubyforge_project = "tokens"
|
16
|
+
|
17
|
+
s.files = `git ls-files`.split("\n")
|
18
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
19
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
20
|
+
s.require_paths = ["lib"]
|
21
|
+
|
22
|
+
s.add_dependency 'activerecord'
|
23
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# This mixin provides methods on ActiveRecord::Base to generate a token for
|
2
|
+
# a given column. The token for the column can have a specific length, can
|
3
|
+
# be uniq and the uniqueness can be scoped on a given column.
|
4
|
+
#
|
5
|
+
module ActiveRecord
|
6
|
+
module Mixin
|
7
|
+
module TokenGenerator
|
8
|
+
module InstanceMethods
|
9
|
+
# Generates a token for the given active record column
|
10
|
+
#
|
11
|
+
# == Parameters
|
12
|
+
# * columns: the column of the active record as symbol or an array of columns
|
13
|
+
# * options: some options for generating the token
|
14
|
+
# ** :length: the token length (default: 8)
|
15
|
+
# ** :uniq: whether the token must be uniq or not (default: true)
|
16
|
+
# ** :scope: the column for the scope to check the uniqueness (default: nil)
|
17
|
+
# ** :same_token: if an array of columns is given and this option is true, all columns will get the same token (default: false)
|
18
|
+
#
|
19
|
+
# == Example
|
20
|
+
# class User < ActiveRecord::Base
|
21
|
+
# before_validation do |obj|
|
22
|
+
# obj.generate_token :email_confirmation_token, :length => 16
|
23
|
+
# end
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
def generate_token(columns, *args)
|
27
|
+
options = {
|
28
|
+
:length => 8,
|
29
|
+
:uniq => true,
|
30
|
+
:scope => nil,
|
31
|
+
:same_token => false,
|
32
|
+
:max_try => 8
|
33
|
+
}.merge(args.extract_options!)
|
34
|
+
|
35
|
+
columns = [columns] unless columns.is_a?(Array)
|
36
|
+
|
37
|
+
result = {}
|
38
|
+
token = nil
|
39
|
+
columns.each do |column|
|
40
|
+
counter = 0
|
41
|
+
begin
|
42
|
+
raise NoFreeToken.new(column) if counter >= options[:max_try]
|
43
|
+
counter += 1
|
44
|
+
|
45
|
+
token = new_token(options[:length]) if(token.blank? or not options[:same_token])
|
46
|
+
self.send("#{column}=".to_sym, token)
|
47
|
+
result[column.to_sym] = token
|
48
|
+
condition = { column => token }
|
49
|
+
condition[options[:scope]] = self[options[:scope]] if options[:scope].is_a?(Symbol) or options[:scope].is_a?(String)
|
50
|
+
end while options[:uniq] and self.class.exists?(condition)
|
51
|
+
end
|
52
|
+
result
|
53
|
+
end
|
54
|
+
|
55
|
+
end
|
56
|
+
|
57
|
+
module ClassMethods
|
58
|
+
# this method generates a token for the given columns before there get validated. Beside the
|
59
|
+
# options described at the +generate_token+ method, you can use the following options.
|
60
|
+
#
|
61
|
+
# :on: (default: :create)
|
62
|
+
#
|
63
|
+
def tokenize(column, *args)
|
64
|
+
options = {
|
65
|
+
:on => :create
|
66
|
+
}.merge(args.extract_options!)
|
67
|
+
before_validation_options = options.reject { |k,v| [:length, :uniq, :scope, :same_token].include?(k) }
|
68
|
+
options.select! { |k,v| [:length, :uniq, :scope, :same_token].include?(k) }
|
69
|
+
|
70
|
+
before_validation before_validation_options do |obj|
|
71
|
+
obj.generate_token column, options
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.included(receiver)
|
77
|
+
receiver.send :include, InstanceMethods
|
78
|
+
receiver.extend ClassMethods
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
ActiveRecord::Base.send :include, ActiveRecord::Mixin::TokenGenerator
|
data/lib/ar-tokens.rb
ADDED
data/lib/object.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
# This provides a method for generating a random token of the given length.
|
2
|
+
# The generated token is base58 encoded, so the token just contains numbers,
|
3
|
+
# up- and down case characters.
|
4
|
+
#
|
5
|
+
# Example:
|
6
|
+
# Object.new_token(10) # => "S2Mq4mJBv6" (i.e.)
|
7
|
+
# or
|
8
|
+
# Object.new.new_token(10) # => "S2Mq4mJBv6" (i.e.)
|
9
|
+
#
|
10
|
+
class Object
|
11
|
+
def self.new_token(length=8, characters = ('a'..'z').to_a+('A'..'Z').to_a+(0..9).to_a)
|
12
|
+
result = ''
|
13
|
+
length.times do
|
14
|
+
result += characters[SecureRandom.random_number(characters.length)].to_s
|
15
|
+
end
|
16
|
+
result
|
17
|
+
end
|
18
|
+
|
19
|
+
def new_token(length=8, characters = ('a'..'z').to_a+('A'..'Z').to_a+(0..9).to_a)
|
20
|
+
self.class.new_token(length, characters)
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ActiveRecord::Mixin::TokenGenerator do
|
4
|
+
before :each do
|
5
|
+
@klass = TokenTest.dup
|
6
|
+
end
|
7
|
+
|
8
|
+
it "geneates a token" do
|
9
|
+
SecureRandom.stub(:random_number).and_return(0)
|
10
|
+
@klass.tokenize :token
|
11
|
+
@klass.create.token.should == 'aaaaaaaa'
|
12
|
+
end
|
13
|
+
|
14
|
+
it "raises an exception if no free token is available" do
|
15
|
+
SecureRandom.stub(:random_number).and_return(0)
|
16
|
+
@klass.tokenize :token
|
17
|
+
@klass.create.token.should == 'aaaaaaaa'
|
18
|
+
expect {
|
19
|
+
@klass.create
|
20
|
+
}.to raise_error(NoFreeToken)
|
21
|
+
end
|
22
|
+
|
23
|
+
it "generates duplicate tokens if allowed" do
|
24
|
+
SecureRandom.stub(:random_number).and_return(0)
|
25
|
+
@klass.tokenize :token, :uniq => false
|
26
|
+
@klass.create.token.should == 'aaaaaaaa'
|
27
|
+
@klass.create.token.should == 'aaaaaaaa'
|
28
|
+
end
|
29
|
+
|
30
|
+
it "generates duplicate tokens in different scopes if allowed" do
|
31
|
+
SecureRandom.stub(:random_number).and_return(0)
|
32
|
+
@klass.tokenize :token, :scope => 'scope'
|
33
|
+
@klass.create(:scope => 'a').token.should == 'aaaaaaaa'
|
34
|
+
@klass.create(:scope => 'b').token.should == 'aaaaaaaa'
|
35
|
+
end
|
36
|
+
|
37
|
+
it "generates tokens with the specified length" do
|
38
|
+
(6..32).each do |i|
|
39
|
+
@klass = TokenTest.dup
|
40
|
+
@klass.tokenize :token, :length => i
|
41
|
+
10.times do
|
42
|
+
@klass.create.token.length.should == i
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
it "generates different tokens for different columns" do
|
48
|
+
@klass.tokenize [:token, :token_two]
|
49
|
+
r = @klass.create!
|
50
|
+
r.token.should_not == r.token_two
|
51
|
+
end
|
52
|
+
|
53
|
+
it "generates the same token for two columns if specified" do
|
54
|
+
@klass.tokenize [:token, :token_two], :same_token => true
|
55
|
+
r = @klass.create!
|
56
|
+
r.token.should == r.token_two
|
57
|
+
end
|
58
|
+
end
|
data/spec/object_spec.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Object do
|
4
|
+
it "returns 8 a's if only a is given as character list" do
|
5
|
+
new_token(8, ['a']).should == 'aaaaaaaa'
|
6
|
+
end
|
7
|
+
|
8
|
+
it "returns 'bbbbbbbb' if random_number retruns 1" do
|
9
|
+
SecureRandom.stub(:random_number).and_return(1)
|
10
|
+
new_token.should == 'bbbbbbbb'
|
11
|
+
end
|
12
|
+
|
13
|
+
it "returns a random string with the given length" do
|
14
|
+
32.times do |i|
|
15
|
+
100.times do
|
16
|
+
new_token(i).length.should == i
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'bundler/setup'
|
3
|
+
|
4
|
+
require 'ar-tokens'
|
5
|
+
require 'support/active_record'
|
6
|
+
|
7
|
+
RSpec.configure do |config|
|
8
|
+
config.around do |example|
|
9
|
+
ActiveRecord::Base.transaction do
|
10
|
+
example.run
|
11
|
+
raise ActiveRecord::Rollback
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'active_record'
|
2
|
+
ActiveRecord::Base.establish_connection adapter: "sqlite3", database: ":memory:"
|
3
|
+
|
4
|
+
ActiveRecord::Migration.create_table :token_tests do |t|
|
5
|
+
t.string :scope
|
6
|
+
t.string :token
|
7
|
+
t.string :token_two
|
8
|
+
t.timestamps
|
9
|
+
end
|
10
|
+
|
11
|
+
class TokenTest < ActiveRecord::Base
|
12
|
+
set_table_name 'token_tests'
|
13
|
+
end
|
metadata
ADDED
@@ -0,0 +1,81 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: ar-tokens
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.4
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Paul Spieker
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-12-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: activerecord
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: This gem lets you easily generate tokens on ruby objects and provides
|
31
|
+
additional methods on ActiveRecord::Base to generate tokens on records
|
32
|
+
email:
|
33
|
+
- p.spieker@duenos.de
|
34
|
+
executables: []
|
35
|
+
extensions: []
|
36
|
+
extra_rdoc_files: []
|
37
|
+
files:
|
38
|
+
- .gitignore
|
39
|
+
- Gemfile
|
40
|
+
- README.markdown
|
41
|
+
- Rakefile
|
42
|
+
- ar-tokens.gemspec
|
43
|
+
- lib/active_record/mixin/token_generator.rb
|
44
|
+
- lib/ar-tokens.rb
|
45
|
+
- lib/no_free_token.rb
|
46
|
+
- lib/object.rb
|
47
|
+
- lib/tokens/version.rb
|
48
|
+
- spec/active_record_spec.rb
|
49
|
+
- spec/object_spec.rb
|
50
|
+
- spec/spec_helper.rb
|
51
|
+
- spec/support/active_record.rb
|
52
|
+
homepage: https://github.com/spieker/tokens
|
53
|
+
licenses: []
|
54
|
+
post_install_message:
|
55
|
+
rdoc_options: []
|
56
|
+
require_paths:
|
57
|
+
- lib
|
58
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
none: false
|
60
|
+
requirements:
|
61
|
+
- - ! '>='
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '0'
|
64
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
requirements: []
|
71
|
+
rubyforge_project: tokens
|
72
|
+
rubygems_version: 1.8.24
|
73
|
+
signing_key:
|
74
|
+
specification_version: 3
|
75
|
+
summary: Generating tokens on ruby objects and active record columns
|
76
|
+
test_files:
|
77
|
+
- spec/active_record_spec.rb
|
78
|
+
- spec/object_spec.rb
|
79
|
+
- spec/spec_helper.rb
|
80
|
+
- spec/support/active_record.rb
|
81
|
+
has_rdoc:
|