diff options
Diffstat (limited to 'app/controllers/otp_enrollments_controller.rb')
| -rw-r--r-- | app/controllers/otp_enrollments_controller.rb | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/app/controllers/otp_enrollments_controller.rb b/app/controllers/otp_enrollments_controller.rb new file mode 100644 index 00000000..7a31d1e1 --- /dev/null +++ b/app/controllers/otp_enrollments_controller.rb | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | # Self-service TOTP enrollment, deliberately scoped to current_user only: | ||
| 2 | # an administrator must never hold another account's secret -- admins get | ||
| 3 | # the witnessed reset on the user page instead. | ||
| 4 | class OtpEnrollmentsController < ApplicationController | ||
| 5 | before_action :login_required | ||
| 6 | |||
| 7 | layout 'admin' | ||
| 8 | |||
| 9 | # QR plus confirmation form; only meaningful while a pending secret exists. | ||
| 10 | def show | ||
| 11 | redirect_to edit_user_path(current_user) if current_user.otp_pending_secret.blank? | ||
| 12 | end | ||
| 13 | |||
| 14 | # Begins (or restarts) enrollment. Requires the current password so an | ||
| 15 | # unattended logged-in session cannot be enrolled onto a stranger's phone. | ||
| 16 | def create | ||
| 17 | unless User.authenticate(current_user.login, params[:current_password].to_s) | ||
| 18 | flash[:error] = "Wrong password." | ||
| 19 | return redirect_to edit_user_path(current_user) | ||
| 20 | end | ||
| 21 | current_user.begin_otp_enrollment! | ||
| 22 | redirect_to otp_enrollment_path | ||
| 23 | end | ||
| 24 | |||
| 25 | # Confirms with the first generated code. | ||
| 26 | def update | ||
| 27 | if current_user.confirm_otp_enrollment!(params[:code]) | ||
| 28 | flash[:notice] = "Second factor enabled. The code you just entered is " \ | ||
| 29 | "spent -- wait for the next one before logging in with it." | ||
| 30 | redirect_to edit_user_path(current_user) | ||
| 31 | else | ||
| 32 | flash.now[:error] = "That code did not match. Rescan or wait for the next code." | ||
| 33 | render :show | ||
| 34 | end | ||
| 35 | end | ||
| 36 | |||
| 37 | # Self-service disable: password AND a current code. | ||
| 38 | def destroy | ||
| 39 | unless User.authenticate(current_user.login, params[:current_password].to_s) && | ||
| 40 | current_user.verify_otp!(params[:code]) | ||
| 41 | flash[:error] = "Password or code wrong -- second factor unchanged." | ||
| 42 | return redirect_to edit_user_path(current_user) | ||
| 43 | end | ||
| 44 | current_user.disable_otp!(:actor => current_user) | ||
| 45 | flash[:notice] = "Second factor disabled." | ||
| 46 | redirect_to edit_user_path(current_user) | ||
| 47 | end | ||
| 48 | end | ||
