diff options
| author | erdgeist <erdgeist@erdgeist.org> | 2026-07-24 13:53:13 +0200 |
|---|---|---|
| committer | erdgeist <erdgeist@erdgeist.org> | 2026-07-24 13:53:13 +0200 |
| commit | dcb576618b868b888a5b1b31e35491f300ce4050 (patch) | |
| tree | 3a970eae416fba2939cd366b1ba2b5d294154f2c /test/controllers/otp_challenges_controller_test.rb | |
| parent | fefec929c59c72dc93e4be30e8f23cd8c5258b0a (diff) | |
Complete the login only after the second factor
Enrolled users get a pending marker instead of a session after the
password step; a valid code through the challenge writes the real
session via reset_session. otp_required without enrollment funnels
into setup everywhere except the enrollment, user, and login
machinery.
Diffstat (limited to 'test/controllers/otp_challenges_controller_test.rb')
| -rw-r--r-- | test/controllers/otp_challenges_controller_test.rb | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/test/controllers/otp_challenges_controller_test.rb b/test/controllers/otp_challenges_controller_test.rb new file mode 100644 index 00000000..470e84a2 --- /dev/null +++ b/test/controllers/otp_challenges_controller_test.rb | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | require "test_helper" | ||
| 2 | |||
| 3 | class OtpChallengesControllerTest < ActionController::TestCase | ||
| 4 | fixtures :users | ||
| 5 | |||
| 6 | def setup | ||
| 7 | @user = users(:quentin) | ||
| 8 | @user.update!(:otp_secret => ROTP::Base32.random) | ||
| 9 | @request.session[:pending_otp_user_id] = @user.id | ||
| 10 | @request.session[:otp_deadline] = 2.minutes.from_now.to_i | ||
| 11 | @request.session[:otp_attempts] = 0 | ||
| 12 | end | ||
| 13 | |||
| 14 | test "a valid code completes the login" do | ||
| 15 | post :create, params: { :code => ROTP::TOTP.new(@user.otp_secret).now } | ||
| 16 | assert_equal @user.id, session[:user_id] | ||
| 17 | assert_nil session[:pending_otp_user_id] | ||
| 18 | end | ||
| 19 | |||
| 20 | test "a wrong code does not log in" do | ||
| 21 | post :create, params: { :code => "000000" } | ||
| 22 | assert_nil session[:user_id] | ||
| 23 | assert_response :success | ||
| 24 | end | ||
| 25 | |||
| 26 | test "the pending window expires" do | ||
| 27 | @request.session[:otp_deadline] = 1.minute.ago.to_i | ||
| 28 | post :create, params: { :code => ROTP::TOTP.new(@user.otp_secret).now } | ||
| 29 | assert_nil session[:user_id] | ||
| 30 | assert_redirected_to login_path | ||
| 31 | end | ||
| 32 | |||
| 33 | test "attempts are limited" do | ||
| 34 | 5.times { post :create, params: { :code => "000000" } } | ||
| 35 | post :create, params: { :code => ROTP::TOTP.new(@user.otp_secret).now } | ||
| 36 | assert_nil session[:user_id] | ||
| 37 | assert_redirected_to login_path | ||
| 38 | end | ||
| 39 | end | ||
