Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Lots of changes, this is working nicely now. Working on generators

  • Loading branch information...
commit fcdc5e9ffbb862d4831c5d8b823a65a4f532dee4 1 parent 91434d4
Christian Frichot authored
View
100 Gemfile.lock
@@ -1,38 +1,39 @@
GEM
remote: http://rubygems.org/
specs:
- actionmailer (3.1.1)
- actionpack (= 3.1.1)
+ actionmailer (3.1.3)
+ actionpack (= 3.1.3)
mail (~> 2.3.0)
- actionpack (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
+ actionpack (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
builder (~> 3.0.0)
erubis (~> 2.7.0)
i18n (~> 0.6)
- rack (~> 1.3.2)
+ rack (~> 1.3.5)
rack-cache (~> 1.1)
rack-mount (~> 0.8.2)
rack-test (~> 0.6.1)
- sprockets (~> 2.0.2)
- activemodel (3.1.1)
- activesupport (= 3.1.1)
+ sprockets (~> 2.0.3)
+ activemodel (3.1.3)
+ activesupport (= 3.1.3)
builder (~> 3.0.0)
i18n (~> 0.6)
- activerecord (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
+ activerecord (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
arel (~> 2.2.1)
tzinfo (~> 0.3.29)
- activeresource (3.1.1)
- activemodel (= 3.1.1)
- activesupport (= 3.1.1)
- activesupport (3.1.1)
+ activeresource (3.1.3)
+ activemodel (= 3.1.3)
+ activesupport (= 3.1.3)
+ activesupport (3.1.3)
multi_json (~> 1.0)
arel (2.2.1)
bcrypt-ruby (3.0.1)
- bson (1.4.0)
- bson_ext (1.3.1)
+ bson (1.5.2)
+ bson_ext (1.5.2)
+ bson (= 1.5.2)
builder (3.0.0)
capybara (0.4.1.2)
celerity (>= 0.7.9)
@@ -43,20 +44,20 @@ GEM
rack-test (>= 0.5.4)
selenium-webdriver (>= 0.0.27)
xpath (~> 0.1.3)
- celerity (0.9.1)
- childprocess (0.2.2)
+ celerity (0.9.2)
+ childprocess (0.3.0)
ffi (~> 1.0.6)
culerity (0.2.15)
- devise (1.4.9)
+ devise (1.5.3)
bcrypt-ruby (~> 3.0)
orm_adapter (~> 0.0.3)
- warden (~> 1.0.3)
+ warden (~> 1.1)
diff-lcs (1.1.3)
erubis (2.7.0)
- factory_girl (2.3.0)
+ factory_girl (2.4.0)
activesupport
- factory_girl_rails (1.4.0)
- factory_girl (~> 2.3.0)
+ factory_girl_rails (1.5.0)
+ factory_girl (~> 2.4.0)
railties (>= 3.0.0)
ffi (1.0.11)
git (1.2.5)
@@ -66,25 +67,24 @@ GEM
bundler (~> 1.0)
git (>= 1.2.5)
rake
- json (1.6.1)
- json_pure (1.6.1)
+ json (1.6.4)
mail (2.3.0)
i18n (>= 0.4.0)
mime-types (~> 1.16)
treetop (~> 1.4.8)
mime-types (1.17.2)
mocha (0.9.12)
- mongo (1.3.1)
- bson (>= 1.3.1)
- mongoid (2.3.3)
+ mongo (1.5.2)
+ bson (= 1.5.2)
+ mongoid (2.4.0)
activemodel (~> 3.1)
mongo (~> 1.3)
tzinfo (~> 0.3.22)
- multi_json (1.0.3)
+ multi_json (1.0.4)
nokogiri (1.5.0)
- orm_adapter (0.0.5)
+ orm_adapter (0.0.6)
polyglot (0.3.3)
- rack (1.3.5)
+ rack (1.3.6)
rack-cache (1.1)
rack (>= 0.4)
rack-mount (0.8.3)
@@ -93,24 +93,24 @@ GEM
rack
rack-test (0.6.1)
rack (>= 1.0)
- rails (3.1.1)
- actionmailer (= 3.1.1)
- actionpack (= 3.1.1)
- activerecord (= 3.1.1)
- activeresource (= 3.1.1)
- activesupport (= 3.1.1)
+ rails (3.1.3)
+ actionmailer (= 3.1.3)
+ actionpack (= 3.1.3)
+ activerecord (= 3.1.3)
+ activeresource (= 3.1.3)
+ activesupport (= 3.1.3)
bundler (~> 1.0)
- railties (= 3.1.1)
- railties (3.1.1)
- actionpack (= 3.1.1)
- activesupport (= 3.1.1)
+ railties (= 3.1.3)
+ railties (3.1.3)
+ actionpack (= 3.1.3)
+ activesupport (= 3.1.3)
rack-ssl (~> 1.3.2)
rake (>= 0.8.7)
rdoc (~> 3.4)
thor (~> 0.14.6)
rake (0.9.2.2)
rcov (0.9.11)
- rdoc (3.11)
+ rdoc (3.12)
json (~> 1.4)
rotp (1.3.2)
rspec (2.5.0)
@@ -126,25 +126,25 @@ GEM
activesupport (~> 3.0)
railties (~> 3.0)
rspec (~> 2.5.0)
- rubyzip (0.9.4)
- selenium-webdriver (2.13.0)
- childprocess (>= 0.2.1)
+ rubyzip (0.9.5)
+ selenium-webdriver (2.16.0)
+ childprocess (>= 0.2.5)
ffi (~> 1.0.9)
- json_pure
+ multi_json (~> 1.0.4)
rubyzip
shoulda (2.11.3)
sprockets (2.0.3)
hike (~> 1.2)
rack (~> 1.0)
tilt (~> 1.1, != 1.3.0)
- sqlite3 (1.3.4)
+ sqlite3 (1.3.5)
thor (0.14.6)
tilt (1.3.3)
treetop (1.4.10)
polyglot
polyglot (>= 0.3.1)
tzinfo (0.3.31)
- warden (1.0.6)
+ warden (1.1.0)
rack (>= 1.0)
xpath (0.1.4)
nokogiri (~> 1.3)
View
36 app/controllers/devise/checkga_controller.rb
@@ -3,11 +3,41 @@ class Devise::CheckgaController < Devise::SessionsController
include Devise::Controllers::InternalHelpers
def show
- render_with_scope :show
+ @tmpid = params[:id]
+ if @tmpid.nil?
+ redirect_to :root
+ else
+ render_with_scope :show
+ end
end
def update
- sign_in(resource_name, resource)
- respond_with resource, :location => redirect_location(resource_name, resource)
+ resource = resource_class.find_by_gauth_tmp(params[resource_name]['tmpid'])
+
+ if not resource.nil?
+
+ if resource.gauth_tmp_datetime < 10.minutes.ago
+ puts "Too slow"
+ redirect_to :root
+ else
+
+ valid_vals = []
+ valid_vals << ROTP::TOTP.new(resource.get_qr).at(Time.now)
+ (1..3).each do |cc|
+ valid_vals << ROTP::TOTP.new(resource.get_qr).at(Time.now.ago(30*cc))
+ valid_vals << ROTP::TOTP.new(resource.get_qr).at(Time.now.in(30*cc))
+ end
+
+ if valid_vals.include?(params[resource_name]['token'].to_i)
+ set_flash_message(:notice, :signed_in) if is_navigational_format?
+ sign_in(resource_name,resource)
+ respond_with resource, :location => redirect_location(resource_name, resource)
+ else
+ redirect_to :root
+ end
+ end
+ else
+ redirect_to :root
+ end
end
end
View
7 app/views/devise/checkga/show.html.erb
@@ -1,6 +1,7 @@
-<h2>Submit QR Code</h2>
+<h2><%= :submit_token_title %></h2>
<%= form_for(resource, :as => resource_name, :url => [resource_name, :checkga], :html => { :method => :put }) do |f| %>
-
- <p><%= f.submit "Continue.." %></p>
+ <%= f.hidden_field :tmpid, {:value => @tmpid} %>
+ <%= f.text_field :token, :autocomplete => :off%>
+ <p><%= f.submit :submit_token %></p>
<% end %>
View
4 config/locales/en.yml
@@ -0,0 +1,4 @@
+en:
+ devise:
+ submit_token: "Check Token"
+ submit_token_title: "Please enter your Google Authenticator token:"
View
9 lib/devise_google_authenticatable/models/google_authenticatable.rb
@@ -28,6 +28,11 @@ def login_phase_one
return "yep"
end
+ def assign_tmp
+ self.update_attributes(:gauth_tmp => ROTP::Base32.random_base32, :gauth_tmp_datetime => DateTime.now)
+ self.gauth_tmp
+ end
+
private
def assign_auth_secret
@@ -37,7 +42,9 @@ def assign_auth_secret
end
module ClassMethods # :nodoc:
- #Something here?
+ def find_by_gauth_tmp(gauth_tmp)
+ find(:first, :conditions => {:gauth_tmp => gauth_tmp})
+ end
end
end
end
View
81 lib/devise_google_authenticatable/patches/check_ga.rb
@@ -6,85 +6,26 @@ module CheckGA
# here the patch
alias_method :create_original, :create
-
- #Below is trial 1 .. over-writing most of the create method
- #Whilst this works, I wish it was about a gazillion times cleaner
-
+
define_method :create do
- #Okay, firstly we grab the resource, if the user stuffs up anything, this dies immediately.
- #This actually authenticates their password
+
resource = warden.authenticate!(:scope => resource_name, :recall => "#{controller_path}#new")
- #Okay, check that the resource model includes the get_qr method
- if resource.respond_to?(:get_qr) #Therefore we can quiz for a QR
+ if resource.respond_to?(:get_qr) and resource.gauth_enabled.to_i != 0 #Therefore we can quiz for a QR
+ tmpid = resource.assign_tmp #assign a temporary key and fetch it
+ warden.logout #log the user out
- # Okay, we have the method to get the qr secret, lets check if the user has gauth enabled
- if resource.gauth_enabled.to_i != 0 #gauth_enabled is not set to zero, therefore it's ON!
-
- # Orite, At this point the user model includes the extension stuff
- # PLUS, gauth_enabled is ON, so lets try and authenticate .. but first
-
- # Lets check if the "POST" includes the gauth_submit parameter
- if params.fetch(resource_name).include?("gauth_submit") #Yep, the browser submitted the gauth_submit - OTP
-
- #Okay, lets get what they submitted in the form, crunch it into an int
- submitted_value = params.fetch(resource_name).fetch("gauth_submit").to_i
-
- #By default, gauth is not successful
- gauth_successful = false
-
- if submitted_value == 0 #We have a field, but they've left it blank..
- #Nothing, they left the field blank, and therefore will not sign in, gauth_successfull remains false
- else
- #Okay, they submitted something into the OTP field
-
- #Lets account for the fact the timing may not always be accurate, so go backwards, current and forwards
- #If the submitted OTP matches, then gauth_successful is true - YAY for you! .. Yay for you indeed.
-
- #CF TODO: Do some checking here, how late can these codes be??
- if submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now.ago(30))
- gauth_successful = true
- elsif submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now)
- gauth_successful = true
- elsif submitted_value == ROTP::TOTP.new(resource.get_qr).at(Time.now.in(30))
- gauth_successful = true
- end
- end
-
- if gauth_successful == true #That means the OTP actually worked, lets log 'em in
- set_flash_message(:notice, :signed_in) if is_navigational_format?
- sign_in(resource_name, resource)
- respond_with resource, :location => redirect_location(resource_name, resource)
- else #That means that, the OTP did NOT line up properly, lets kick 'em back to the start
- signed_in = signed_in?(resource_name)
- Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
- resource = build_resource
- clean_up_passwords(resource)
- respond_with resource, :location => {:controller => 'sessions', :action => 'new'}
- end
-
- else #Okay, this is odd, the user is all set to go, but the browser did NOT include the OTP, tampering occurred
- # OR - the developer did NOT modify the "sessions" view to include
- # TODO: What should they put in the view again?
-
- #At this point, we're going to log them back out and send them back to the start
- signed_in = signed_in?(resource_name)
- Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
- resource = build_resource
- clean_up_passwords(resource)
- respond_with resource, :location => {:controller => 'sessions', :action => 'new'}
- end
- else #gauth_enabled must have been set to zero, therefore it's off .. lets just continue with the original sign in process
- set_flash_message(:notice, :signed_in) if is_navigational_format?
- sign_in(resource_name, resource)
- respond_with resource, :location => redirect_location(resource_name, resource)
- end
- else #It looks like the model did NOT include the get_qr method .. lets just continue with the original sign in process
+ #we head back into the checkga controller with the temporary id
+ respond_with resource, :location => { :controller => 'checkga', :action => 'show', :id => tmpid}
+
+ else #It's not using, or not enabled for Google 2FA - carry on, nothing to see here.
set_flash_message(:notice, :signed_in) if is_navigational_format?
sign_in(resource_name, resource)
respond_with resource, :location => redirect_location(resource_name, resource)
end
+
end
+
end
end
end
View
8 lib/devise_google_authenticatable/schema.rb
@@ -26,5 +26,13 @@ def gauth_enabled
apply_devise_schema :gauth_enabled, Integer, {:default => 0}
end
+ def gauth_tmp
+ apply_devise_schema :gauth_tmp, String
+ end
+
+ def gauth_tmp_datetime
+ apply_devise_schema :gauth_tmp_datetime, Datetime
+ end
+
end
end
View
14 lib/generators/devise_google_authenticator/install_generator.rb
@@ -0,0 +1,14 @@
+module DeviseGoogleAuthenticator
+ module Generators # :nodoc:
+ # Install Generator
+ class InstallGenerator < Rails::Generators::Base
+ source_root File.expand_path("../../templates", __FILE__)
+
+ desc "Install the devise google authenticator extension"
+
+ def copy_locale
+ copy_file "../../../config/locales/en.yml", "config/locales/devise.google_authenticator.en.yml"
+ end
+ end
+ end
+end
Please sign in to comment.
Something went wrong with that request. Please try again.