google-authenticator-rails 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ .rvmrc
7
+ .rspec
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in google-authenticator.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Jared McFarland
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,102 @@
1
+ # Google::Authenticator
2
+
3
+ Rails (ActiveRecord) integration with the Google Authenticator apps for Android and the iPhone.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'google-authenticator-rails'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install google-authenticator-rails
18
+
19
+ ## Usage
20
+
21
+ Example:
22
+
23
+ ```ruby
24
+ class User
25
+ acts_as_google_authenticated
26
+ end
27
+
28
+ @user = User.new
29
+ @user.set_google_secret! # => true
30
+ @user.google_qr_uri # => http://path.to.google/qr?with=params
31
+ @user.google_authenticate(123456) # => true
32
+ ```
33
+
34
+ Google Labels
35
+ When setting up an account with the GoogleAuthenticator you need to provide
36
+ a label for that account (to distinguish it from other accounts).
37
+
38
+ GoogleAuthenticatorRails allows you to customize how the record will create
39
+ that label. There are three options:
40
+ - The default just uses the column "email" on the model
41
+ - You can specify a custom column with the :column_name option
42
+ - You can specify a custom method via a symbol or a proc
43
+
44
+ Examples:
45
+
46
+ ```ruby
47
+ class User
48
+ acts_as_google_authenticated :column => :user_name
49
+ end
50
+
51
+ @user = User.new(:user_name => "ted")
52
+ @user.google_label # => "ted"
53
+
54
+ class User
55
+ acts_as_google_authenticated :method => :user_name_with_label
56
+
57
+ def user_name_with_label
58
+ "#{user_name}@mysweetservice.com"
59
+ end
60
+ end
61
+
62
+ @user = User.new(:user_name => "ted")
63
+ @user.google_label # => "ted@mysweetservice.com"
64
+
65
+ class User
66
+ acts_as_google_authenticated :method => Proc.new { |user| user.user_name_with_label.upcase }
67
+
68
+ def user_name_with_label
69
+ "#{user_name}@mysweetservice.com"
70
+ end
71
+ end
72
+
73
+ @user = User.new(:user_name => "ted")
74
+ @user.google_label # => "TED@MYSWEETSERVICE.COM"
75
+ ```
76
+
77
+ You can also sepcify a column for storing the google secret. The default is `google_secret`.
78
+
79
+ Example
80
+
81
+ ```ruby
82
+ class User
83
+ acts_as_google_authenticated :google_secret_column => :mfa_secret
84
+ end
85
+
86
+ @user = User.new
87
+ @user.set_google_secret!
88
+ @user.mfa_secret # => "56ahi483"
89
+ ```
90
+
91
+
92
+ ## Contributing
93
+
94
+ 1. Fork it
95
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
96
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
97
+ 4. Push to the branch (`git push origin my-new-feature`)
98
+ 5. Create new Pull Request
99
+
100
+ ## License
101
+
102
+ MIT.
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env rake
2
+ require "bundler/gem_tasks"
@@ -0,0 +1,25 @@
1
+ # -*- encoding: utf-8 -*-
2
+ require File.expand_path('../lib/google-authenticator-rails/version', __FILE__)
3
+
4
+ Gem::Specification.new do |gem|
5
+ gem.authors = ["Jared McFarland"]
6
+ gem.email = ["jared.online@gmail.com"]
7
+ gem.description = %q{Add the ability to use the Google Authenticator with ActiveRecord.}
8
+ gem.summary = %q{Add the ability to use the Google Authenticator with ActiveRecord.}
9
+ gem.homepage = "http://github.com/jaredonline/google-authenticator-rails"
10
+
11
+ gem.files = `git ls-files`.split($\)
12
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14
+ gem.name = "google-authenticator-rails"
15
+ gem.require_paths = ["lib"]
16
+ gem.version = Google::Authenticator::Rails::VERSION
17
+
18
+ gem.add_dependency "activesupport", "~> 3.2.0"
19
+ gem.add_dependency "rotp"
20
+ gem.add_dependency "activerecord", "~> 3.2.0"
21
+ gem.add_dependency "google-qr"
22
+
23
+ gem.add_development_dependency "rspec", "~> 2.8.0"
24
+ gem.add_development_dependency "sqlite3"
25
+ end
@@ -0,0 +1,13 @@
1
+ # Stuff the gem requireds
2
+ #
3
+ require 'active_support'
4
+ require 'active_record'
5
+ require 'openssl'
6
+ require 'rotp'
7
+ require 'google-qr'
8
+
9
+ # Stuff the gem is
10
+ #
11
+ require "google-authenticator-rails/version"
12
+ require 'google-authenticator-rails/google'
13
+ require 'google-authenticator-rails/active_record'
@@ -0,0 +1,66 @@
1
+ require 'google-authenticator-rails/active_record/google_authentication'
2
+ require 'google-authenticator-rails/active_record/acts_as_google_authenticated'
3
+
4
+ class ActiveRecord::Base # :nodoc:
5
+
6
+ # This is the single integration point. Monkey patch ActiveRecord::Base
7
+ # to include the ActsAsGoogleAuthenticated module, which allows a user
8
+ # to call User.acts_as_google_authenticated.
9
+ #
10
+ # The model being used must have a string column named "google_secret", or an explicitly
11
+ # named column.
12
+ #
13
+ # Example:
14
+ #
15
+ # class User
16
+ # acts_as_google_authenticated
17
+ # end
18
+ #
19
+ # @user = user.new
20
+ # @user.set_google_secret! # => true
21
+ # @user.google_qr_uri # => http://path.to.google/qr?with=params
22
+ # @user.google_authenticate(123456) # => true
23
+ #
24
+ # Google Labels
25
+ # When setting up an account with the GoogleAuthenticator you need to provide
26
+ # a label for that account (to distinguish it from other accounts).
27
+ #
28
+ # GoogleAuthenticatorRails allows you to customize how the record will create
29
+ # that label. There are three options:
30
+ # - The default just uses the column "email" on the model
31
+ # - You can specify a custom column with the :column_name option
32
+ # - You can specify a custom method via a symbol or a proc
33
+ #
34
+ # Examples:
35
+ #
36
+ # class User
37
+ # acts_as_google_authenticated :column => :user_name
38
+ # end
39
+ #
40
+ # @user = User.new(:user_name => "ted")
41
+ # @user.google_label # => "ted"
42
+ #
43
+ # class User
44
+ # acts_as_google_authenticated :method => :user_name_with_label
45
+ #
46
+ # def user_name_with_label
47
+ # "#{user_name}@mysweetservice.com"
48
+ # end
49
+ # end
50
+ #
51
+ # @user = User.new(:user_name => "ted")
52
+ # @user.google_label # => "ted@mysweetservice.com"
53
+ #
54
+ # class User
55
+ # acts_as_google_authenticated :method => Proc.new { |user| user.user_name_with_label.upcase }
56
+ #
57
+ # def user_name_with_label
58
+ # "#{user_name}@mysweetservice.com"
59
+ # end
60
+ # end
61
+ #
62
+ # @user = User.new(:user_name => "ted")
63
+ # @user.google_label # => "TED@MYSWEETSERVICE.COM"
64
+ #
65
+ include ActiveRecord::ActsAsGoogleAuthenticated
66
+ end
@@ -0,0 +1,35 @@
1
+ module ActiveRecord # :nodoc:
2
+ module ActsAsGoogleAuthenticated # :nodoc:
3
+ def self.included(base)
4
+ base.extend ClassMethods
5
+ end
6
+
7
+ module ClassMethods # :nodoc
8
+
9
+ # Initializes the class attributes with the specified options and includes the
10
+ # GoogleAuthentication module
11
+ #
12
+ # Options:
13
+ # [:column_name] the name of the column used to create the google_label
14
+ # [:method] name of the method to call to created the google_label
15
+ # it supercedes :column_name
16
+ # [:google_secret_column] the column the secret will be stored in, defaults
17
+ # to "google_secret"
18
+ def acts_as_google_authenticated(options = {})
19
+ @google_label_column = options[:column_name] || :email
20
+ @google_label_method = options[:method] || :default_google_label_method
21
+ @google_secret_column = options[:google_secret_column] || :google_secret
22
+
23
+ attr_accessible @google_secret_column
24
+
25
+ [:google_label_column, :google_label_method, :google_secret_column].each do |cattr|
26
+ self.class.__send__(:define_method, cattr) do
27
+ instance_variable_get("@#{cattr}")
28
+ end
29
+ end
30
+
31
+ include ActiveRecord::GoogleAuthentication
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,34 @@
1
+ module ActiveRecord # :nodoc:
2
+ module GoogleAuthentication # :nodoc:
3
+ def set_google_secret!
4
+ update_attributes("#{self.class.google_secret_column}" => Google::Authenticator::Rails::generate_secret)
5
+ end
6
+
7
+ def google_authenticate(code)
8
+ Google::Authenticator::Rails.valid?(code, google_secret_value)
9
+ end
10
+
11
+ def google_qr_uri
12
+ GoogleQR.new(data: ROTP::TOTP.new(google_secret_value).provisioning_uri(google_label), size: "200x200").to_s
13
+ end
14
+
15
+ def google_label
16
+ method = self.class.google_label_method
17
+ case method
18
+ when Proc
19
+ method.call(self)
20
+ when Symbol, String
21
+ self.__send__(method)
22
+ end
23
+ end
24
+
25
+ private
26
+ def default_google_label_method
27
+ self.__send__(self.class.google_label_column)
28
+ end
29
+
30
+ def google_secret_value
31
+ self.__send__(self.class.google_secret_column)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1 @@
1
+ require 'google-authenticator-rails/google/rails'
@@ -0,0 +1 @@
1
+ require 'google-authenticator-rails/google/rails/rotp_integration'
@@ -0,0 +1,26 @@
1
+ # Sets up some basic accessors for use with the ROTP module
2
+ #
3
+ module Google
4
+ module Authenticator # :nodoc:
5
+ module Rails # :nodoc:
6
+ # Drift is set to 6 because ROTP drift is not inclusive. This allows a drift of 5 seconds.
7
+ DRIFT = 6
8
+
9
+ def self.generate_password(secret, iteration)
10
+ ROTP::HOTP.new(secret).at(iteration)
11
+ end
12
+
13
+ def self.time_based_password(secret)
14
+ ROTP::TOTP.new(secret).now
15
+ end
16
+
17
+ def self.valid?(code, secret)
18
+ ROTP::TOTP.new(secret).verify_with_drift(code, DRIFT)
19
+ end
20
+
21
+ def self.generate_secret
22
+ ROTP::Base32.random_base32
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,7 @@
1
+ module Google
2
+ module Authenticator
3
+ module Rails
4
+ VERSION = "0.0.1"
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,122 @@
1
+ require 'spec_helper'
2
+
3
+ class User < ActiveRecord::Base
4
+ attr_accessible :email, :user_name
5
+
6
+ acts_as_google_authenticated
7
+ end
8
+
9
+ class CustomUser < ActiveRecord::Base
10
+ attr_accessible :email, :user_name
11
+
12
+ acts_as_google_authenticated :google_secret_column => :mfa_secret
13
+ end
14
+
15
+ describe Google::Authenticator::Rails do
16
+ before do
17
+ ROTP::Base32.stub!(:random_base32).and_return("5qlcip7azyjuwm36")
18
+ end
19
+
20
+ it 'implements counter based passwords' do
21
+ Google::Authenticator::Rails::generate_password("test", 1).should == 812658
22
+ Google::Authenticator::Rails::generate_password("test", 2).should == 73348
23
+ end
24
+
25
+ it 'implements time based password' do
26
+ time = Time.parse("2012-08-07 11:11:11 AM +0700")
27
+ Time.stub!(:now).and_return(time)
28
+ Google::Authenticator::Rails::time_based_password("test").should == 472374
29
+ end
30
+
31
+ it 'can validate a code' do
32
+ time = Time.parse("2012-08-07 11:11:11 AM +0700")
33
+ Time.stub!(:now).and_return(time)
34
+ Google::Authenticator::Rails::valid?(472374, "test").should be_true
35
+ end
36
+
37
+ it 'can create a secret' do
38
+ Google::Authenticator::Rails::generate_secret.should == "5qlcip7azyjuwm36"
39
+ end
40
+
41
+ context 'integration with ActiveRecord' do
42
+
43
+ before do
44
+ time = Time.parse("2012-08-07 11:11:00 AM +0700")
45
+ Time.stub!(:now).and_return(time)
46
+ @user = User.create(email: "test@test.com", user_name: "test_user")
47
+ @user.google_secret = "test"
48
+ end
49
+
50
+ it 'validates codes' do
51
+ @user.google_authenticate(472374).should be_true
52
+ end
53
+
54
+ it 'validates with 5 seconds of drift' do
55
+ time = Time.parse("2012-08-07 11:11:34 AM +0700")
56
+ Time.stub!(:now).and_return(time)
57
+ @user.google_authenticate(472374).should be_true
58
+ end
59
+
60
+ it 'does not validate with 6 seconds of drift' do
61
+ time = Time.parse("2012-08-07 11:11:36 AM +0700")
62
+ Time.stub!(:now).and_return(time)
63
+ @user.google_authenticate(472374).should be_false
64
+ end
65
+
66
+ it 'creates a secret' do
67
+ @user.set_google_secret!
68
+ @user.google_secret.should == "5qlcip7azyjuwm36"
69
+ end
70
+
71
+ context 'secret column' do
72
+ before do
73
+ Google::Authenticator::Rails.stub!(:generate_secret).and_return("test")
74
+ @user = CustomUser.create(email: "test@test.com", user_name: "test_user")
75
+ @user.set_google_secret!
76
+ end
77
+
78
+ it 'validates code' do
79
+ @user.google_authenticate(472374).should be_true
80
+ end
81
+
82
+ it 'generates a url for a qr code' do
83
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40test.com%3Fsecret%3Dtest&chs=200x200"
84
+ end
85
+ end
86
+
87
+ context 'qr codes' do
88
+
89
+ it 'generates a url for a qr code' do
90
+ @user.set_google_secret!
91
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40test.com%3Fsecret%3D5qlcip7azyjuwm36&chs=200x200"
92
+ end
93
+
94
+ it 'can generate off any column' do
95
+ @user.class.acts_as_google_authenticated :column_name => :user_name
96
+ @user.set_google_secret!
97
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest_user%3Fsecret%3D5qlcip7azyjuwm36&chs=200x200"
98
+ end
99
+
100
+ it 'can generate with a custom proc' do
101
+ @user.class.acts_as_google_authenticated :method => Proc.new { |user| "#{user.user_name}@futureadvisor-admin" }
102
+ @user.set_google_secret!
103
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest_user%40futureadvisor-admin%3Fsecret%3D5qlcip7azyjuwm36&chs=200x200"
104
+ end
105
+
106
+ it 'can generate with a method symbol' do
107
+ @user.class.acts_as_google_authenticated :method => :email
108
+ @user.set_google_secret!
109
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40test.com%3Fsecret%3D5qlcip7azyjuwm36&chs=200x200"
110
+ end
111
+
112
+ it 'can generate with a method string' do
113
+ @user.class.acts_as_google_authenticated :method => "email"
114
+ @user.set_google_secret!
115
+ @user.google_qr_uri.should == "https://chart.googleapis.com/chart?cht=qr&chl=otpauth%3A%2F%2Ftotp%2Ftest%40test.com%3Fsecret%3D5qlcip7azyjuwm36&chs=200x200"
116
+ end
117
+
118
+ end
119
+
120
+ end
121
+
122
+ end
@@ -0,0 +1,27 @@
1
+ require 'google-authenticator-rails'
2
+ require 'time'
3
+ require 'active_record'
4
+ require 'rotp'
5
+
6
+ ActiveRecord::Base.establish_connection(
7
+ :adapter => 'sqlite3',
8
+ :database => ':memory:'
9
+ )
10
+
11
+ ActiveRecord::Schema.define do
12
+ self.verbose = false
13
+
14
+ create_table :users, :force => true do |t|
15
+ t.string :google_secret
16
+ t.string :email
17
+ t.string :user_name
18
+ t.timestamps
19
+ end
20
+
21
+ create_table :custom_users, :force => true do |t|
22
+ t.string :mfa_secret
23
+ t.string :email
24
+ t.string :user_name
25
+ t.timestamps
26
+ end
27
+ end
metadata ADDED
@@ -0,0 +1,160 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: google-authenticator-rails
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Jared McFarland
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-08-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 3.2.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: 3.2.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: rotp
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: activerecord
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 3.2.0
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 3.2.0
62
+ - !ruby/object:Gem::Dependency
63
+ name: google-qr
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: rspec
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 2.8.0
86
+ type: :development
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 2.8.0
94
+ - !ruby/object:Gem::Dependency
95
+ name: sqlite3
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ description: Add the ability to use the Google Authenticator with ActiveRecord.
111
+ email:
112
+ - jared.online@gmail.com
113
+ executables: []
114
+ extensions: []
115
+ extra_rdoc_files: []
116
+ files:
117
+ - .gitignore
118
+ - .rspec
119
+ - Gemfile
120
+ - LICENSE
121
+ - README.md
122
+ - Rakefile
123
+ - google-authenticator.gemspec
124
+ - lib/google-authenticator-rails.rb
125
+ - lib/google-authenticator-rails/active_record.rb
126
+ - lib/google-authenticator-rails/active_record/acts_as_google_authenticated.rb
127
+ - lib/google-authenticator-rails/active_record/google_authentication.rb
128
+ - lib/google-authenticator-rails/google.rb
129
+ - lib/google-authenticator-rails/google/rails.rb
130
+ - lib/google-authenticator-rails/google/rails/rotp_integration.rb
131
+ - lib/google-authenticator-rails/version.rb
132
+ - spec/google_authenticator_spec.rb
133
+ - spec/spec_helper.rb
134
+ homepage: http://github.com/jaredonline/google-authenticator-rails
135
+ licenses: []
136
+ post_install_message:
137
+ rdoc_options: []
138
+ require_paths:
139
+ - lib
140
+ required_ruby_version: !ruby/object:Gem::Requirement
141
+ none: false
142
+ requirements:
143
+ - - ! '>='
144
+ - !ruby/object:Gem::Version
145
+ version: '0'
146
+ required_rubygems_version: !ruby/object:Gem::Requirement
147
+ none: false
148
+ requirements:
149
+ - - ! '>='
150
+ - !ruby/object:Gem::Version
151
+ version: '0'
152
+ requirements: []
153
+ rubyforge_project:
154
+ rubygems_version: 1.8.24
155
+ signing_key:
156
+ specification_version: 3
157
+ summary: Add the ability to use the Google Authenticator with ActiveRecord.
158
+ test_files:
159
+ - spec/google_authenticator_spec.rb
160
+ - spec/spec_helper.rb