diff options
Diffstat (limited to 'app/controllers/otp_challenges_controller.rb')
| -rw-r--r-- | app/controllers/otp_challenges_controller.rb | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/app/controllers/otp_challenges_controller.rb b/app/controllers/otp_challenges_controller.rb new file mode 100644 index 00000000..892503a8 --- /dev/null +++ b/app/controllers/otp_challenges_controller.rb | |||
| @@ -0,0 +1,54 @@ | |||
| 1 | # The second half of a two-step login. A pending marker (set by | ||
| 2 | # sessions#create after a correct password) plus deadline and attempt | ||
| 3 | # counter live in the session; the real user_id is only written after a | ||
| 4 | # valid code, through a fresh session. | ||
| 5 | class OtpChallengesController < ApplicationController | ||
| 6 | |||
| 7 | layout 'admin' | ||
| 8 | |||
| 9 | MAX_ATTEMPTS = 5 | ||
| 10 | |||
| 11 | def new | ||
| 12 | redirect_to login_path unless pending_user | ||
| 13 | end | ||
| 14 | |||
| 15 | def create | ||
| 16 | user = pending_user | ||
| 17 | return redirect_to login_path unless user | ||
| 18 | |||
| 19 | session[:otp_attempts] = session[:otp_attempts].to_i + 1 | ||
| 20 | if session[:otp_attempts] > MAX_ATTEMPTS | ||
| 21 | clear_pending | ||
| 22 | flash[:error] = "Too many attempts -- log in again." | ||
| 23 | return redirect_to login_path | ||
| 24 | end | ||
| 25 | |||
| 26 | if user.verify_otp!(params[:code]) | ||
| 27 | return_to = session[:return_to] | ||
| 28 | reset_session | ||
| 29 | self.current_user = user | ||
| 30 | flash[:notice] = "Logged in successfully" | ||
| 31 | redirect_to safe_return_to(return_to, :default => admin_path) | ||
| 32 | else | ||
| 33 | flash.now[:error] = "That code did not match." | ||
| 34 | render :new | ||
| 35 | end | ||
| 36 | end | ||
| 37 | |||
| 38 | private | ||
| 39 | |||
| 40 | def pending_user | ||
| 41 | return nil if session[:pending_otp_user_id].blank? | ||
| 42 | if session[:otp_deadline].to_i < Time.now.to_i | ||
| 43 | clear_pending | ||
| 44 | return nil | ||
| 45 | end | ||
| 46 | @pending_user ||= User.find_by(:id => session[:pending_otp_user_id]) | ||
| 47 | end | ||
| 48 | |||
| 49 | def clear_pending | ||
| 50 | session.delete(:pending_otp_user_id) | ||
| 51 | session.delete(:otp_deadline) | ||
| 52 | session.delete(:otp_attempts) | ||
| 53 | end | ||
| 54 | end | ||
