devise_google_authenticator 0.2.0 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE.txt +1 -1
- data/README.rdoc +58 -7
- data/app/controllers/devise/checkga_controller.rb +21 -3
- data/app/views/devise/checkga/show.html.erb +4 -3
- data/app/views/devise/displayqr/show.html.erb +4 -4
- data/config/locales/en.yml +9 -0
- data/lib/devise_google_authenticatable/models/google_authenticatable.rb +30 -6
- data/lib/devise_google_authenticatable/patches/check_ga.rb +11 -70
- data/lib/devise_google_authenticatable/schema.rb +8 -0
- data/lib/devise_google_authenticator.rb +8 -4
- data/lib/generators/active_record/devise_google_authenticator_generator.rb +13 -0
- data/lib/generators/active_record/templates/migration.rb +17 -0
- data/lib/generators/devise_google_authenticator/devise_google_authenticator_generator.rb +19 -0
- data/lib/generators/devise_google_authenticator/install_generator.rb +23 -0
- data/lib/generators/devise_google_authenticator/views_generator.rb +19 -0
- metadata +39 -70
- data/.document +0 -5
- data/Gemfile +0 -16
- data/Gemfile.lock +0 -109
- data/Rakefile +0 -53
- data/VERSION +0 -1
- data/devise_google_authenticator.gemspec +0 -80
- data/lib/devise_google_authenticatable/hooks/google_authenticatable.rb +0 -9
data/LICENSE.txt
CHANGED
data/README.rdoc
CHANGED
@@ -4,14 +4,65 @@ This is a devise[https://github.com/plataformatec/devise] extension to allow you
|
|
4
4
|
|
5
5
|
== Changes
|
6
6
|
* Version 0.1 - initial release, just to push it up, is still very early and requires a bit work
|
7
|
+
* Version 0.2 - tidied up some of the code - changed the references to AsteriskLabs
|
8
|
+
* Version 0.3 - first working version! With working generators, tests, and doesnt require changes to Devise's Sign In view
|
9
|
+
|
10
|
+
== Installation
|
11
|
+
|
12
|
+
Add the gem to your Gemfile (don't forget devise too):
|
13
|
+
|
14
|
+
* gem 'devise', '~> 1.5.3'
|
15
|
+
* gem 'devise_google_authenticator', '0.3.0'
|
16
|
+
|
17
|
+
Don't forget to "bundle install"
|
18
|
+
|
19
|
+
=== Automatic Installation (Lets assume this is a bare bones app)
|
20
|
+
|
21
|
+
Run the following generator to add the necessary configuration options to Devise's config file:
|
22
|
+
|
23
|
+
* rails g devise_google_authenticator:install
|
24
|
+
|
25
|
+
After you've created your Devise user models (which is usually done with a "rails g devise MODEL"), set up your Google Authenticator additions:
|
26
|
+
|
27
|
+
* rails g devise_google_authenticator MODEL
|
28
|
+
|
29
|
+
Don't forget to migrate:
|
30
|
+
|
31
|
+
* rake db:migrate
|
32
|
+
|
33
|
+
== Configuration Options
|
34
|
+
|
35
|
+
The install generator adds some options to the end of your Devise config file (config/initializers/devise.rb)
|
36
|
+
|
37
|
+
* config.ga_timeout - how long should the user be able to authenticate with their Google Authenticator token
|
38
|
+
* config.ga_timedrift - a multiplier which provides for drift between a user's clock (and therefore their OTP) and the system clock. This should be fine at 3.
|
39
|
+
|
40
|
+
== Custom Views
|
41
|
+
|
42
|
+
If you want to customise your views (which you likely will want to, as they're pretty ugly right now), you can use the generator:
|
43
|
+
|
44
|
+
* rails g devise_google_authenticator:views
|
7
45
|
|
8
46
|
== Usage
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
*
|
13
|
-
*
|
14
|
-
*
|
47
|
+
|
48
|
+
With this extension enabled, the following is expected behaviour:
|
49
|
+
|
50
|
+
* When a user registers, they are forwarded onto the Display QR page. This allows them to add their new "token" to their mobile device, and enable, or disable, the functionality.
|
51
|
+
* If users can't self-register, they're still able to visit this page by visiting /MODEL/displayqr (eg: /users/displayqr).
|
52
|
+
* If the function is enabled (for that user), when they sign in, they'll be prompted for their password (as per normal), but then redirected into the Check QR page. They have to enter their token (from their device) to then successfully authenticate.
|
53
|
+
|
54
|
+
== I18n
|
55
|
+
|
56
|
+
The install generator also installs an english copy of a Devise Google Authenticator i18n file. This can be modified (or used to create other language versions) and is located at: config/locales/devise.google_authenticator.en.yml
|
57
|
+
|
58
|
+
== Thanks (and unknown contributors)
|
59
|
+
|
60
|
+
This extension would not exist without the following other projects and associated authors (Whom I have turned to for inspiration and definitely have helped contributing by providing awesome Devise extensions. A lot of this code has been refactored from various sources, in particular these - in particular Sergio and Devise_invitable for his excellent unit test code):
|
61
|
+
|
62
|
+
* Devise (José Valim, Carlos Antônio da Silva, Rodrigo Flores) https://github.com/plataformatec/devise
|
63
|
+
* Devise_invitable (Sergio Cambra) https://github.com/scambra/devise_invitable
|
64
|
+
* Devise_openid_authenticatable (Nat Budin) https://github.com/nbudin/devise_openid_authenticatable
|
65
|
+
* Devise_security_extension (Team Phatworx, Marco Scholl, Alexander Dreher) https://github.com/phatworx/devise_security_extension
|
15
66
|
|
16
67
|
|
17
68
|
== Contributing to devise_google_authenticator
|
@@ -26,6 +77,6 @@ This is a devise[https://github.com/plataformatec/devise] extension to allow you
|
|
26
77
|
|
27
78
|
== Copyright
|
28
79
|
|
29
|
-
Copyright (c)
|
80
|
+
Copyright (c) 2012 Christian Frichot. See LICENSE.txt for
|
30
81
|
further details.
|
31
82
|
|
@@ -3,11 +3,29 @@ class Devise::CheckgaController < Devise::SessionsController
|
|
3
3
|
include Devise::Controllers::InternalHelpers
|
4
4
|
|
5
5
|
def show
|
6
|
-
|
6
|
+
@tmpid = params[:id]
|
7
|
+
if @tmpid.nil?
|
8
|
+
redirect_to :root
|
9
|
+
else
|
10
|
+
render_with_scope :show
|
11
|
+
end
|
7
12
|
end
|
8
13
|
|
9
14
|
def update
|
10
|
-
|
11
|
-
|
15
|
+
resource = resource_class.find_by_gauth_tmp(params[resource_name]['tmpid'])
|
16
|
+
|
17
|
+
if not resource.nil?
|
18
|
+
|
19
|
+
if resource.validate_token(params[resource_name]['token'].to_i)
|
20
|
+
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
21
|
+
sign_in(resource_name,resource)
|
22
|
+
respond_with resource, :location => redirect_location(resource_name, resource)
|
23
|
+
else
|
24
|
+
redirect_to :root
|
25
|
+
end
|
26
|
+
|
27
|
+
else
|
28
|
+
redirect_to :root
|
29
|
+
end
|
12
30
|
end
|
13
31
|
end
|
@@ -1,6 +1,7 @@
|
|
1
|
-
<h2
|
1
|
+
<h2><%= I18n.t('submit_token_title', {:scope => 'devise'}) %></h2>
|
2
2
|
|
3
3
|
<%= form_for(resource, :as => resource_name, :url => [resource_name, :checkga], :html => { :method => :put }) do |f| %>
|
4
|
-
|
5
|
-
|
4
|
+
<%= f.hidden_field :tmpid, {:value => @tmpid} %>
|
5
|
+
<%= f.text_field :token, :autocomplete => :off%>
|
6
|
+
<p><%= f.submit I18n.t('submit_token', {:scope => 'devise'}) %></p>
|
6
7
|
<% end %>
|
@@ -1,12 +1,12 @@
|
|
1
|
-
<h2
|
1
|
+
<h2><%= I18n.t('title', {:scope => 'devise.registration'}) %></h2>
|
2
2
|
|
3
3
|
<%= google_authenticator_qrcode(resource) %>
|
4
4
|
|
5
5
|
<%= form_for(resource, :as => resource_name, :url => [resource_name, :displayqr], :html => { :method => :put }) do |f| %>
|
6
6
|
<%= devise_error_messages! %>
|
7
|
-
<h3
|
8
|
-
<p><%= f.label :gauth_enabled,
|
7
|
+
<h3><%= I18n.t('nice_request', {:scope => 'devise.registration'}) %></h3>
|
8
|
+
<p><%= f.label :gauth_enabled, I18n.t('qrstatus', {:scope => 'devise.registration'}) %><br />
|
9
9
|
<%= f.check_box :gauth_enabled %></p>
|
10
10
|
|
11
|
-
<p><%= f.submit
|
11
|
+
<p><%= f.submit I18n.t('submit', {:scope => 'devise.registration'}) %></p>
|
12
12
|
<% end %>
|
@@ -0,0 +1,9 @@
|
|
1
|
+
en:
|
2
|
+
devise:
|
3
|
+
submit_token: "Check Token"
|
4
|
+
submit_token_title: "Please enter your Google Authenticator token:"
|
5
|
+
registration:
|
6
|
+
title: "Your QR Code:"
|
7
|
+
nice_request: "Would you like to enable Google Authenticator?"
|
8
|
+
qrstatus: "Google Authenticator Status:"
|
9
|
+
submit: "Continue..."
|
@@ -1,5 +1,4 @@
|
|
1
1
|
require 'rotp'
|
2
|
-
#require 'devise_google_authenticatable/hooks/google_authenticatable'
|
3
2
|
|
4
3
|
module Devise # :nodoc:
|
5
4
|
module Models # :nodoc:
|
@@ -23,9 +22,31 @@ module Devise # :nodoc:
|
|
23
22
|
def set_gauth_enabled(param)
|
24
23
|
self.update_without_password(param)
|
25
24
|
end
|
26
|
-
|
27
|
-
def
|
28
|
-
|
25
|
+
|
26
|
+
def assign_tmp
|
27
|
+
self.update_attributes(:gauth_tmp => ROTP::Base32.random_base32, :gauth_tmp_datetime => DateTime.now)
|
28
|
+
self.gauth_tmp
|
29
|
+
end
|
30
|
+
|
31
|
+
def validate_token(token)
|
32
|
+
return false if self.gauth_tmp_datetime.nil?
|
33
|
+
if self.gauth_tmp_datetime < self.class.ga_timeout.ago
|
34
|
+
return false
|
35
|
+
else
|
36
|
+
|
37
|
+
valid_vals = []
|
38
|
+
valid_vals << ROTP::TOTP.new(self.get_qr).at(Time.now)
|
39
|
+
(1..self.class.ga_timedrift).each do |cc|
|
40
|
+
valid_vals << ROTP::TOTP.new(self.get_qr).at(Time.now.ago(30*cc))
|
41
|
+
valid_vals << ROTP::TOTP.new(self.get_qr).at(Time.now.in(30*cc))
|
42
|
+
end
|
43
|
+
|
44
|
+
if valid_vals.include?(token.to_i)
|
45
|
+
return true
|
46
|
+
else
|
47
|
+
return false
|
48
|
+
end
|
49
|
+
end
|
29
50
|
end
|
30
51
|
|
31
52
|
private
|
@@ -33,11 +54,14 @@ module Devise # :nodoc:
|
|
33
54
|
def assign_auth_secret
|
34
55
|
self.gauth_secret = ROTP::Base32.random_base32
|
35
56
|
end
|
36
|
-
|
57
|
+
|
37
58
|
end
|
38
59
|
|
39
60
|
module ClassMethods # :nodoc:
|
40
|
-
|
61
|
+
def find_by_gauth_tmp(gauth_tmp)
|
62
|
+
find(:first, :conditions => {:gauth_tmp => gauth_tmp})
|
63
|
+
end
|
64
|
+
::Devise::Models.config(self, :ga_timeout, :ga_timedrift)
|
41
65
|
end
|
42
66
|
end
|
43
67
|
end
|
@@ -6,85 +6,26 @@ module DeviseGoogleAuthenticator::Patches
|
|
6
6
|
# here the patch
|
7
7
|
|
8
8
|
alias_method :create_original, :create
|
9
|
-
|
10
|
-
#Below is trial 1 .. over-writing most of the create method
|
11
|
-
#Whilst this works, I wish it was about a gazillion times cleaner
|
12
|
-
|
9
|
+
|
13
10
|
define_method :create do
|
14
|
-
|
15
|
-
#This actually authenticates their password
|
11
|
+
|
16
12
|
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
|
17
13
|
|
18
|
-
|
19
|
-
|
14
|
+
if resource.respond_to?(:get_qr) and resource.gauth_enabled.to_i != 0 #Therefore we can quiz for a QR
|
15
|
+
tmpid = resource.assign_tmp #assign a temporary key and fetch it
|
16
|
+
warden.logout #log the user out
|
20
17
|
|
21
|
-
#
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
# PLUS, gauth_enabled is ON, so lets try and authenticate .. but first
|
26
|
-
|
27
|
-
# Lets check if the "POST" includes the gauth_submit parameter
|
28
|
-
if params.fetch(resource_name).include?("gauth_submit") #Yep, the browser submitted the gauth_submit - OTP
|
29
|
-
|
30
|
-
#Okay, lets get what they submitted in the form, crunch it into an int
|
31
|
-
submitted_value = params.fetch(resource_name).fetch("gauth_submit").to_i
|
32
|
-
|
33
|
-
#By default, gauth is not successful
|
34
|
-
gauth_successful = false
|
35
|
-
|
36
|
-
if submitted_value == 0 #We have a field, but they've left it blank..
|
37
|
-
#Nothing, they left the field blank, and therefore will not sign in, gauth_successfull remains false
|
38
|
-
else
|
39
|
-
#Okay, they submitted something into the OTP field
|
40
|
-
|
41
|
-
#Lets account for the fact the timing may not always be accurate, so go backwards, current and forwards
|
42
|
-
#If the submitted OTP matches, then gauth_successful is true - YAY for you! .. Yay for you indeed.
|
43
|
-
|
44
|
-
#CF TODO: Do some checking here, how late can these codes be??
|
45
|
-
if submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now.ago(30))
|
46
|
-
gauth_successful = true
|
47
|
-
elsif submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now)
|
48
|
-
gauth_successful = true
|
49
|
-
elsif submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now.in(30))
|
50
|
-
gauth_successful = true
|
51
|
-
end
|
52
|
-
end
|
53
|
-
|
54
|
-
if gauth_successful == true #That means the OTP actually worked, lets log 'em in
|
55
|
-
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
56
|
-
sign_in(resource_name, resource)
|
57
|
-
respond_with resource, :location => redirect_location(resource_name, resource)
|
58
|
-
else #That means that, the OTP did NOT line up properly, lets kick 'em back to the start
|
59
|
-
signed_in = signed_in?(resource_name)
|
60
|
-
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
61
|
-
resource = build_resource
|
62
|
-
clean_up_passwords(resource)
|
63
|
-
respond_with resource, :location => {:controller => 'sessions', :action => 'new'}
|
64
|
-
end
|
65
|
-
|
66
|
-
else #Okay, this is odd, the user is all set to go, but the browser did NOT include the OTP, tampering occurred
|
67
|
-
# OR - the developer did NOT modify the "sessions" view to include
|
68
|
-
# TODO: What should they put in the view again?
|
69
|
-
|
70
|
-
#At this point, we're going to log them back out and send them back to the start
|
71
|
-
signed_in = signed_in?(resource_name)
|
72
|
-
Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
|
73
|
-
resource = build_resource
|
74
|
-
clean_up_passwords(resource)
|
75
|
-
respond_with resource, :location => {:controller => 'sessions', :action => 'new'}
|
76
|
-
end
|
77
|
-
else #gauth_enabled must have been set to zero, therefore it's off .. lets just continue with the original sign in process
|
78
|
-
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
79
|
-
sign_in(resource_name, resource)
|
80
|
-
respond_with resource, :location => redirect_location(resource_name, resource)
|
81
|
-
end
|
82
|
-
else #It looks like the model did NOT include the get_qr method .. lets just continue with the original sign in process
|
18
|
+
#we head back into the checkga controller with the temporary id
|
19
|
+
respond_with resource, :location => { :controller => 'checkga', :action => 'show', :id => tmpid}
|
20
|
+
|
21
|
+
else #It's not using, or not enabled for Google 2FA - carry on, nothing to see here.
|
83
22
|
set_flash_message(:notice, :signed_in) if is_navigational_format?
|
84
23
|
sign_in(resource_name, resource)
|
85
24
|
respond_with resource, :location => redirect_location(resource_name, resource)
|
86
25
|
end
|
26
|
+
|
87
27
|
end
|
28
|
+
|
88
29
|
end
|
89
30
|
end
|
90
31
|
end
|
@@ -26,5 +26,13 @@ module DeviseGoogleAuthenticator
|
|
26
26
|
apply_devise_schema :gauth_enabled, Integer, {:default => 0}
|
27
27
|
end
|
28
28
|
|
29
|
+
def gauth_tmp
|
30
|
+
apply_devise_schema :gauth_tmp, String
|
31
|
+
end
|
32
|
+
|
33
|
+
def gauth_tmp_datetime
|
34
|
+
apply_devise_schema :gauth_tmp_datetime, Datetime
|
35
|
+
end
|
36
|
+
|
29
37
|
end
|
30
38
|
end
|
@@ -5,14 +5,18 @@ require 'active_support/ordered_hash'
|
|
5
5
|
require 'active_support/concern'
|
6
6
|
require 'devise'
|
7
7
|
|
8
|
+
module Devise # :nodoc:
|
9
|
+
mattr_accessor :ga_timeout
|
10
|
+
@@ga_timeout = 3.minutes
|
11
|
+
|
12
|
+
mattr_accessor :ga_timedrift
|
13
|
+
@@ga_timedrift = 3
|
14
|
+
end
|
15
|
+
|
8
16
|
# a security extension for devise
|
9
17
|
module DeviseGoogleAuthenticator
|
10
18
|
autoload :Schema, 'devise_google_authenticatable/schema'
|
11
19
|
autoload :Patches, 'devise_google_authenticatable/patches'
|
12
|
-
|
13
|
-
# module Controllers # :nodoc:
|
14
|
-
# autoload :Helpers, 'devise_google_authenticatable/controllers/helpers'
|
15
|
-
# end
|
16
20
|
end
|
17
21
|
|
18
22
|
|
@@ -0,0 +1,13 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module ActiveRecord
|
4
|
+
module Generators
|
5
|
+
class DeviseGoogleAuthenticatorGenerator < ActiveRecord::Generators::Base
|
6
|
+
source_root File.expand_path("../templates", __FILE__)
|
7
|
+
|
8
|
+
def copy_devise_migration
|
9
|
+
migration_template "migration.rb", "db/migrate/devise_google_authenticator_add_to_#{table_name}"
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
class DeviseGoogleAuthenticatorAddTo<%= table_name.camelize %> < ActiveRecord::Migration
|
2
|
+
def self.up
|
3
|
+
change_table :<%= table_name %> do |t|
|
4
|
+
t.string :gauth_secret
|
5
|
+
t.string :gauth_enabled, :default => "f"
|
6
|
+
t.string :gauth_tmp
|
7
|
+
t.datetime :gauth_tmp_datetime
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.down
|
13
|
+
change_table :<%= table_name %> do |t|
|
14
|
+
t.remove :gauth_secret, :gauth_enabled, :gauth_tmp, :gauth_tmp_datetime
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module DeviseGoogleAuthenticator
|
2
|
+
module Generators
|
3
|
+
class DeviseGoogleAuthenticatorGenerator < Rails::Generators::NamedBase
|
4
|
+
|
5
|
+
namespace "devise_google_authenticator"
|
6
|
+
|
7
|
+
desc "Add :google_authenticatable directive in the given model, plus accessors. Also generate migration for ActiveRecord"
|
8
|
+
|
9
|
+
def inject_devise_google_authenticator_content
|
10
|
+
path = File.join("app","models","#{file_path}.rb")
|
11
|
+
inject_into_file(path, "google_authenticatable, :", :after => "devise :") if File.exists?(path)
|
12
|
+
inject_into_file(path, "gauth_enabled, :gauth_tmp, :gauth_tmp_datetime, :", :after => "attr_accessible :") if File.exists?(path)
|
13
|
+
end
|
14
|
+
|
15
|
+
hook_for :orm
|
16
|
+
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module DeviseGoogleAuthenticator
|
2
|
+
module Generators # :nodoc:
|
3
|
+
# Install Generator
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
|
+
source_root File.expand_path("../../templates", __FILE__)
|
6
|
+
|
7
|
+
desc "Install the devise google authenticator extension"
|
8
|
+
|
9
|
+
def add_configs
|
10
|
+
inject_into_file "config/initializers/devise.rb", "\n # ==> Devise Google Authenticator Extension\n # Configure extension for devise\n\n" +
|
11
|
+
" # How long should the user have to enter their token. To change the default, uncomment and change the below:\n" +
|
12
|
+
" # config.ga_timeout = 3.minutes\n\n" +
|
13
|
+
" # Change time drift settings for valid token values. To change the default, uncomment and change the below:\n" +
|
14
|
+
" # config.ga_timedrift = 3\n\n" +
|
15
|
+
"\n", :before => /end[ |\n|]+\Z/
|
16
|
+
end
|
17
|
+
|
18
|
+
def copy_locale
|
19
|
+
copy_file "../../../config/locales/en.yml", "config/locales/devise.google_authenticator.en.yml"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require 'generators/devise/views_generator'
|
2
|
+
|
3
|
+
module DeviseGoogleAuthenticator
|
4
|
+
module Generators
|
5
|
+
class ViewsGenerator < Rails::Generators::Base
|
6
|
+
desc 'Copies all Devise Google Authenticator views to your application.'
|
7
|
+
|
8
|
+
argument :scope, :required => false, :default => nil,
|
9
|
+
:desc => "The scope to copy views to"
|
10
|
+
|
11
|
+
include ::Devise::Generators::ViewPathTemplates
|
12
|
+
source_root File.expand_path("../../../../app/views/devise", __FILE__)
|
13
|
+
def copy_views
|
14
|
+
view_directory :checkga
|
15
|
+
view_directory :displayqr
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: devise_google_authenticator
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,85 +9,58 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-01-29 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
|
-
name:
|
16
|
-
requirement: &
|
15
|
+
name: bundler
|
16
|
+
requirement: &70215350254940 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ~>
|
20
20
|
- !ruby/object:Gem::Version
|
21
|
-
version:
|
22
|
-
type: :
|
21
|
+
version: 1.0.7
|
22
|
+
type: :development
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70215350254940
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
name:
|
27
|
-
requirement: &
|
26
|
+
name: rails
|
27
|
+
requirement: &70215350251860 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
31
31
|
- !ruby/object:Gem::Version
|
32
|
-
version:
|
33
|
-
|
34
|
-
prerelease: false
|
35
|
-
version_requirements: *70110996096960
|
36
|
-
- !ruby/object:Gem::Dependency
|
37
|
-
name: rotp
|
38
|
-
requirement: &70110996095860 !ruby/object:Gem::Requirement
|
39
|
-
none: false
|
40
|
-
requirements:
|
41
|
-
- - ! '>='
|
32
|
+
version: 3.0.0
|
33
|
+
- - <
|
42
34
|
- !ruby/object:Gem::Version
|
43
|
-
version: '
|
35
|
+
version: '3.2'
|
44
36
|
type: :runtime
|
45
37
|
prerelease: false
|
46
|
-
version_requirements: *
|
47
|
-
- !ruby/object:Gem::Dependency
|
48
|
-
name: shoulda
|
49
|
-
requirement: &70110996094140 !ruby/object:Gem::Requirement
|
50
|
-
none: false
|
51
|
-
requirements:
|
52
|
-
- - ~>
|
53
|
-
- !ruby/object:Gem::Version
|
54
|
-
version: 2.11.3
|
55
|
-
type: :development
|
56
|
-
prerelease: false
|
57
|
-
version_requirements: *70110996094140
|
38
|
+
version_requirements: *70215350251860
|
58
39
|
- !ruby/object:Gem::Dependency
|
59
|
-
name:
|
60
|
-
requirement: &
|
40
|
+
name: devise
|
41
|
+
requirement: &70215350226540 !ruby/object:Gem::Requirement
|
61
42
|
none: false
|
62
43
|
requirements:
|
63
|
-
- -
|
44
|
+
- - ! '>='
|
64
45
|
- !ruby/object:Gem::Version
|
65
|
-
version: 1.
|
66
|
-
|
67
|
-
prerelease: false
|
68
|
-
version_requirements: *70110996093400
|
69
|
-
- !ruby/object:Gem::Dependency
|
70
|
-
name: jeweler
|
71
|
-
requirement: &70110996092680 !ruby/object:Gem::Requirement
|
72
|
-
none: false
|
73
|
-
requirements:
|
74
|
-
- - ~>
|
46
|
+
version: 1.4.6
|
47
|
+
- - <
|
75
48
|
- !ruby/object:Gem::Version
|
76
|
-
version: 1.6
|
77
|
-
type: :
|
49
|
+
version: '1.6'
|
50
|
+
type: :runtime
|
78
51
|
prerelease: false
|
79
|
-
version_requirements: *
|
52
|
+
version_requirements: *70215350226540
|
80
53
|
- !ruby/object:Gem::Dependency
|
81
|
-
name:
|
82
|
-
requirement: &
|
54
|
+
name: rotp
|
55
|
+
requirement: &70215350224940 !ruby/object:Gem::Requirement
|
83
56
|
none: false
|
84
57
|
requirements:
|
85
|
-
- -
|
58
|
+
- - <
|
86
59
|
- !ruby/object:Gem::Version
|
87
|
-
version:
|
88
|
-
type: :
|
60
|
+
version: 1.3.2
|
61
|
+
type: :runtime
|
89
62
|
prerelease: false
|
90
|
-
version_requirements: *
|
63
|
+
version_requirements: *70215350224940
|
91
64
|
description: Devise Google Authenticator Extension, for adding Google's OTP to your
|
92
65
|
Rails apps!
|
93
66
|
email: xntrik@gmail.com
|
@@ -97,29 +70,28 @@ extra_rdoc_files:
|
|
97
70
|
- LICENSE.txt
|
98
71
|
- README.rdoc
|
99
72
|
files:
|
100
|
-
- .document
|
101
|
-
- Gemfile
|
102
|
-
- Gemfile.lock
|
103
|
-
- LICENSE.txt
|
104
|
-
- README.rdoc
|
105
|
-
- Rakefile
|
106
|
-
- VERSION
|
107
73
|
- app/controllers/devise/checkga_controller.rb
|
108
74
|
- app/controllers/devise/displayqr_controller.rb
|
109
75
|
- app/views/devise/checkga/show.html.erb
|
110
76
|
- app/views/devise/displayqr/show.html.erb
|
111
|
-
-
|
77
|
+
- config/locales/en.yml
|
112
78
|
- lib/devise_google_authenticatable/controllers/helpers.rb
|
113
|
-
- lib/devise_google_authenticatable/hooks/google_authenticatable.rb
|
114
79
|
- lib/devise_google_authenticatable/models/google_authenticatable.rb
|
115
80
|
- lib/devise_google_authenticatable/orm/active_record.rb
|
116
|
-
- lib/devise_google_authenticatable/patches.rb
|
117
81
|
- lib/devise_google_authenticatable/patches/check_ga.rb
|
118
82
|
- lib/devise_google_authenticatable/patches/display_qr.rb
|
83
|
+
- lib/devise_google_authenticatable/patches.rb
|
119
84
|
- lib/devise_google_authenticatable/rails.rb
|
120
85
|
- lib/devise_google_authenticatable/routes.rb
|
121
86
|
- lib/devise_google_authenticatable/schema.rb
|
122
87
|
- lib/devise_google_authenticator.rb
|
88
|
+
- lib/generators/active_record/devise_google_authenticator_generator.rb
|
89
|
+
- lib/generators/active_record/templates/migration.rb
|
90
|
+
- lib/generators/devise_google_authenticator/devise_google_authenticator_generator.rb
|
91
|
+
- lib/generators/devise_google_authenticator/install_generator.rb
|
92
|
+
- lib/generators/devise_google_authenticator/views_generator.rb
|
93
|
+
- LICENSE.txt
|
94
|
+
- README.rdoc
|
123
95
|
homepage: http://github.com/AsteriskLabs/devise_google_authenticator
|
124
96
|
licenses:
|
125
97
|
- MIT
|
@@ -132,16 +104,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
132
104
|
requirements:
|
133
105
|
- - ! '>='
|
134
106
|
- !ruby/object:Gem::Version
|
135
|
-
version:
|
136
|
-
segments:
|
137
|
-
- 0
|
138
|
-
hash: 157752787018540220
|
107
|
+
version: 1.8.6
|
139
108
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
140
109
|
none: false
|
141
110
|
requirements:
|
142
111
|
- - ! '>='
|
143
112
|
- !ruby/object:Gem::Version
|
144
|
-
version:
|
113
|
+
version: 1.3.6
|
145
114
|
requirements: []
|
146
115
|
rubyforge_project:
|
147
116
|
rubygems_version: 1.8.10
|
data/.document
DELETED
data/Gemfile
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
source "http://rubygems.org"
|
2
|
-
# Add dependencies required to use your gem here.
|
3
|
-
# Example:
|
4
|
-
# gem "activesupport", ">= 2.3.5"
|
5
|
-
gem "rails"
|
6
|
-
gem "devise"
|
7
|
-
gem "rotp"
|
8
|
-
|
9
|
-
# Add dependencies to develop your gem here.
|
10
|
-
# Include everything needed to run rake, tests, features, etc.
|
11
|
-
group :development do
|
12
|
-
gem "shoulda", ">= 0"
|
13
|
-
gem "bundler", "~> 1.0.0"
|
14
|
-
gem "jeweler", "~> 1.6.4"
|
15
|
-
gem "rcov", ">= 0"
|
16
|
-
end
|
data/Gemfile.lock
DELETED
@@ -1,109 +0,0 @@
|
|
1
|
-
GEM
|
2
|
-
remote: http://rubygems.org/
|
3
|
-
specs:
|
4
|
-
actionmailer (3.1.1)
|
5
|
-
actionpack (= 3.1.1)
|
6
|
-
mail (~> 2.3.0)
|
7
|
-
actionpack (3.1.1)
|
8
|
-
activemodel (= 3.1.1)
|
9
|
-
activesupport (= 3.1.1)
|
10
|
-
builder (~> 3.0.0)
|
11
|
-
erubis (~> 2.7.0)
|
12
|
-
i18n (~> 0.6)
|
13
|
-
rack (~> 1.3.2)
|
14
|
-
rack-cache (~> 1.1)
|
15
|
-
rack-mount (~> 0.8.2)
|
16
|
-
rack-test (~> 0.6.1)
|
17
|
-
sprockets (~> 2.0.2)
|
18
|
-
activemodel (3.1.1)
|
19
|
-
activesupport (= 3.1.1)
|
20
|
-
builder (~> 3.0.0)
|
21
|
-
i18n (~> 0.6)
|
22
|
-
activerecord (3.1.1)
|
23
|
-
activemodel (= 3.1.1)
|
24
|
-
activesupport (= 3.1.1)
|
25
|
-
arel (~> 2.2.1)
|
26
|
-
tzinfo (~> 0.3.29)
|
27
|
-
activeresource (3.1.1)
|
28
|
-
activemodel (= 3.1.1)
|
29
|
-
activesupport (= 3.1.1)
|
30
|
-
activesupport (3.1.1)
|
31
|
-
multi_json (~> 1.0)
|
32
|
-
arel (2.2.1)
|
33
|
-
bcrypt-ruby (3.0.1)
|
34
|
-
builder (3.0.0)
|
35
|
-
devise (1.4.9)
|
36
|
-
bcrypt-ruby (~> 3.0)
|
37
|
-
orm_adapter (~> 0.0.3)
|
38
|
-
warden (~> 1.0.3)
|
39
|
-
erubis (2.7.0)
|
40
|
-
git (1.2.5)
|
41
|
-
hike (1.2.1)
|
42
|
-
i18n (0.6.0)
|
43
|
-
jeweler (1.6.4)
|
44
|
-
bundler (~> 1.0)
|
45
|
-
git (>= 1.2.5)
|
46
|
-
rake
|
47
|
-
json (1.6.1)
|
48
|
-
mail (2.3.0)
|
49
|
-
i18n (>= 0.4.0)
|
50
|
-
mime-types (~> 1.16)
|
51
|
-
treetop (~> 1.4.8)
|
52
|
-
mime-types (1.17.2)
|
53
|
-
multi_json (1.0.3)
|
54
|
-
orm_adapter (0.0.5)
|
55
|
-
polyglot (0.3.3)
|
56
|
-
rack (1.3.5)
|
57
|
-
rack-cache (1.1)
|
58
|
-
rack (>= 0.4)
|
59
|
-
rack-mount (0.8.3)
|
60
|
-
rack (>= 1.0.0)
|
61
|
-
rack-ssl (1.3.2)
|
62
|
-
rack
|
63
|
-
rack-test (0.6.1)
|
64
|
-
rack (>= 1.0)
|
65
|
-
rails (3.1.1)
|
66
|
-
actionmailer (= 3.1.1)
|
67
|
-
actionpack (= 3.1.1)
|
68
|
-
activerecord (= 3.1.1)
|
69
|
-
activeresource (= 3.1.1)
|
70
|
-
activesupport (= 3.1.1)
|
71
|
-
bundler (~> 1.0)
|
72
|
-
railties (= 3.1.1)
|
73
|
-
railties (3.1.1)
|
74
|
-
actionpack (= 3.1.1)
|
75
|
-
activesupport (= 3.1.1)
|
76
|
-
rack-ssl (~> 1.3.2)
|
77
|
-
rake (>= 0.8.7)
|
78
|
-
rdoc (~> 3.4)
|
79
|
-
thor (~> 0.14.6)
|
80
|
-
rake (0.9.2.2)
|
81
|
-
rcov (0.9.11)
|
82
|
-
rdoc (3.11)
|
83
|
-
json (~> 1.4)
|
84
|
-
rotp (1.3.2)
|
85
|
-
shoulda (2.11.3)
|
86
|
-
sprockets (2.0.3)
|
87
|
-
hike (~> 1.2)
|
88
|
-
rack (~> 1.0)
|
89
|
-
tilt (~> 1.1, != 1.3.0)
|
90
|
-
thor (0.14.6)
|
91
|
-
tilt (1.3.3)
|
92
|
-
treetop (1.4.10)
|
93
|
-
polyglot
|
94
|
-
polyglot (>= 0.3.1)
|
95
|
-
tzinfo (0.3.31)
|
96
|
-
warden (1.0.6)
|
97
|
-
rack (>= 1.0)
|
98
|
-
|
99
|
-
PLATFORMS
|
100
|
-
ruby
|
101
|
-
|
102
|
-
DEPENDENCIES
|
103
|
-
bundler (~> 1.0.0)
|
104
|
-
devise
|
105
|
-
jeweler (~> 1.6.4)
|
106
|
-
rails
|
107
|
-
rcov
|
108
|
-
rotp
|
109
|
-
shoulda
|
data/Rakefile
DELETED
@@ -1,53 +0,0 @@
|
|
1
|
-
# encoding: utf-8
|
2
|
-
|
3
|
-
require 'rubygems'
|
4
|
-
require 'bundler'
|
5
|
-
begin
|
6
|
-
Bundler.setup(:default, :development)
|
7
|
-
rescue Bundler::BundlerError => e
|
8
|
-
$stderr.puts e.message
|
9
|
-
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
-
exit e.status_code
|
11
|
-
end
|
12
|
-
require 'rake'
|
13
|
-
|
14
|
-
require 'jeweler'
|
15
|
-
Jeweler::Tasks.new do |gem|
|
16
|
-
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
-
gem.name = "devise_google_authenticator"
|
18
|
-
gem.homepage = "http://github.com/xntrik/devise_google_authenticator"
|
19
|
-
gem.license = "MIT"
|
20
|
-
gem.summary = %Q{Devise Google Authenticator Extension}
|
21
|
-
gem.description = %Q{Devise Google Authenticator Extension, for adding Google's OTP to your Rails apps!}
|
22
|
-
gem.email = "xntrik@gmail.com"
|
23
|
-
gem.authors = ["Christian Frichot"]
|
24
|
-
# dependencies defined in Gemfile
|
25
|
-
end
|
26
|
-
Jeweler::RubygemsDotOrgTasks.new
|
27
|
-
|
28
|
-
require 'rake/testtask'
|
29
|
-
Rake::TestTask.new(:test) do |test|
|
30
|
-
test.libs << 'lib' << 'test'
|
31
|
-
test.pattern = 'test/**/test_*.rb'
|
32
|
-
test.verbose = true
|
33
|
-
end
|
34
|
-
|
35
|
-
require 'rcov/rcovtask'
|
36
|
-
Rcov::RcovTask.new do |test|
|
37
|
-
test.libs << 'test'
|
38
|
-
test.pattern = 'test/**/test_*.rb'
|
39
|
-
test.verbose = true
|
40
|
-
test.rcov_opts << '--exclude "gems/*"'
|
41
|
-
end
|
42
|
-
|
43
|
-
task :default => :test
|
44
|
-
|
45
|
-
require 'rake/rdoctask'
|
46
|
-
Rake::RDocTask.new do |rdoc|
|
47
|
-
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
48
|
-
|
49
|
-
rdoc.rdoc_dir = 'rdoc'
|
50
|
-
rdoc.title = "devise_google_authenticator #{version}"
|
51
|
-
rdoc.rdoc_files.include('README*')
|
52
|
-
rdoc.rdoc_files.include('lib/**/*.rb')
|
53
|
-
end
|
data/VERSION
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
0.1.0
|
@@ -1,80 +0,0 @@
|
|
1
|
-
# Generated by jeweler
|
2
|
-
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
-
# -*- encoding: utf-8 -*-
|
5
|
-
|
6
|
-
Gem::Specification.new do |s|
|
7
|
-
s.name = "devise_google_authenticator"
|
8
|
-
s.version = "0.2.0"
|
9
|
-
|
10
|
-
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
-
s.authors = ["Christian Frichot"]
|
12
|
-
s.date = "2011-11-22"
|
13
|
-
s.description = "Devise Google Authenticator Extension, for adding Google's OTP to your Rails apps!"
|
14
|
-
s.email = "xntrik@gmail.com"
|
15
|
-
s.extra_rdoc_files = [
|
16
|
-
"LICENSE.txt",
|
17
|
-
"README.rdoc"
|
18
|
-
]
|
19
|
-
s.files = [
|
20
|
-
".document",
|
21
|
-
"Gemfile",
|
22
|
-
"Gemfile.lock",
|
23
|
-
"LICENSE.txt",
|
24
|
-
"README.rdoc",
|
25
|
-
"Rakefile",
|
26
|
-
"VERSION",
|
27
|
-
"app/controllers/devise/checkga_controller.rb",
|
28
|
-
"app/controllers/devise/displayqr_controller.rb",
|
29
|
-
"app/views/devise/checkga/show.html.erb",
|
30
|
-
"app/views/devise/displayqr/show.html.erb",
|
31
|
-
"devise_google_authenticator.gemspec",
|
32
|
-
"lib/devise_google_authenticatable/controllers/helpers.rb",
|
33
|
-
"lib/devise_google_authenticatable/hooks/google_authenticatable.rb",
|
34
|
-
"lib/devise_google_authenticatable/models/google_authenticatable.rb",
|
35
|
-
"lib/devise_google_authenticatable/orm/active_record.rb",
|
36
|
-
"lib/devise_google_authenticatable/patches.rb",
|
37
|
-
"lib/devise_google_authenticatable/patches/check_ga.rb",
|
38
|
-
"lib/devise_google_authenticatable/patches/display_qr.rb",
|
39
|
-
"lib/devise_google_authenticatable/rails.rb",
|
40
|
-
"lib/devise_google_authenticatable/routes.rb",
|
41
|
-
"lib/devise_google_authenticatable/schema.rb",
|
42
|
-
"lib/devise_google_authenticator.rb"
|
43
|
-
]
|
44
|
-
s.homepage = "http://github.com/AsteriskLabs/devise_google_authenticator"
|
45
|
-
s.licenses = ["MIT"]
|
46
|
-
s.require_paths = ["lib"]
|
47
|
-
s.rubygems_version = "1.8.10"
|
48
|
-
s.summary = "Devise Google Authenticator Extension"
|
49
|
-
|
50
|
-
if s.respond_to? :specification_version then
|
51
|
-
s.specification_version = 3
|
52
|
-
|
53
|
-
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
54
|
-
s.add_runtime_dependency(%q<rails>, [">= 0"])
|
55
|
-
s.add_runtime_dependency(%q<devise>, [">= 0"])
|
56
|
-
s.add_runtime_dependency(%q<rotp>, [">= 0"])
|
57
|
-
s.add_development_dependency(%q<shoulda>, ["~> 2.11.3"])
|
58
|
-
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
59
|
-
s.add_development_dependency(%q<jeweler>, ["~> 1.6.4"])
|
60
|
-
s.add_development_dependency(%q<rcov>, [">= 0"])
|
61
|
-
else
|
62
|
-
s.add_dependency(%q<rails>, [">= 0"])
|
63
|
-
s.add_dependency(%q<devise>, [">= 0"])
|
64
|
-
s.add_dependency(%q<rotp>, [">= 0"])
|
65
|
-
s.add_dependency(%q<shoulda>, ["~> 2.11.3"])
|
66
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
67
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
68
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
69
|
-
end
|
70
|
-
else
|
71
|
-
s.add_dependency(%q<rails>, [">= 0"])
|
72
|
-
s.add_dependency(%q<devise>, [">= 0"])
|
73
|
-
s.add_dependency(%q<rotp>, [">= 0"])
|
74
|
-
s.add_dependency(%q<shoulda>, ["~> 2.11.3"])
|
75
|
-
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
76
|
-
s.add_dependency(%q<jeweler>, ["~> 1.6.4"])
|
77
|
-
s.add_dependency(%q<rcov>, [">= 0"])
|
78
|
-
end
|
79
|
-
end
|
80
|
-
|
@@ -1,9 +0,0 @@
|
|
1
|
-
Warden::Manager.after_set_user do |record, warden, options|
|
2
|
-
if record.respond_to?(:login_phase_one)
|
3
|
-
if warden.session(options[:scope]).fetch(:gauth_phase_one,"nope") == "nope"
|
4
|
-
redirect_to :controller => 'checkga', :action => 'show'
|
5
|
-
end
|
6
|
-
#warden.session(options[:scope])[:gauth_phase_one]
|
7
|
-
#respond_with record, :location => {:controller => 'checkga', :action => 'show'}
|
8
|
-
end
|
9
|
-
end
|