Commit e55e0c5
Changed files (4)
app/controllers/mfas_controller.rb
@@ -1,4 +1,18 @@
class MfasController < ApplicationController
def new
end
+
+ def create
+ if current_user.tfa.authenticate(secure_params[:code])
+ redirect_to response_path
+ else
+ redirect_to mfa_path, error: "Invalid code"
+ end
+ end
+
+ private
+
+ def secure_params
+ params.require(:mfa).permit(:code)
+ end
end
app/models/tfa.rb
@@ -12,7 +12,6 @@ class Tfa
end
def provisioning_uri
- totp = ::ROTP::TOTP.new(secret, issuer: 'saml-kit')
totp.provisioning_uri(user.email)
end
@@ -29,6 +28,16 @@ class Tfa
end
def current_totp
- ROTP::TOTP.new(secret).now
+ totp.now
+ end
+
+ def authenticate(entered_code)
+ totp.verify(entered_code)
+ end
+
+ private
+
+ def totp
+ @totp ||= ::ROTP::TOTP.new(secret, issuer: 'saml-kit')
end
end
config/routes.rb
@@ -4,6 +4,7 @@ Rails.application.routes.draw do
post "/session/new" => "sessions#new"
resource :metadata, only: [:show]
resource :mfa, only: [:new, :create]
+ resource :response, only: [:show]
resource :session, only: [:new, :create, :destroy]
resources :registrations, only: [:new, :create]
spec/requests/mfas_spec.rb
@@ -11,6 +11,23 @@ RSpec.describe "/mfa" do
specify { expect(response).to have_http_status(:ok) }
end
+
+ describe "POST /mfa" do
+ context "when the code is correct" do
+ let(:correct_code) { current_user.tfa.current_totp }
+ before { post '/mfa', params: { mfa: { code: correct_code } } }
+
+ specify { expect(response).to redirect_to(response_path) }
+ end
+
+ context "when the code is incorrect" do
+ let(:incorrect_code) { rand(1_000) }
+ before { post '/mfa', params: { mfa: { code: incorrect_code } } }
+
+ specify { expect(response).to redirect_to(mfa_path) }
+ specify { expect(flash[:error]).to be_present }
+ end
+ end
end
context "when username/password entry has not been completed" do