Project

General

Profile

Feature #1237 » 0004-adds-integration-test-for-totp-two-factor-auth.patch

Jens Krämer, 2019-08-17 16:05

View differences:

test/integration/twofa_test.rb
1
require File.expand_path('../../test_helper', __FILE__)
2

  
3
class TwofaTest < Redmine::IntegrationTest
4
  fixtures :projects, :users, :email_addresses
5

  
6
  test "should require twofa setup when configured" do
7
    with_settings twofa: "2" do
8
      log_user('jsmith', 'jsmith')
9
      follow_redirect!
10
      assert_redirected_to "/my/twofa/totp/activate/confirm"
11
    end
12
  end
13

  
14
  test "should generate and accept backup codes" do
15
    log_user('jsmith', 'jsmith')
16
    get "/my/account"
17
    assert_response :success
18
    post "/my/twofa/totp/activate/init"
19
    assert_redirected_to "/my/twofa/totp/activate/confirm"
20
    follow_redirect!
21
    assert_response :success
22

  
23
    totp = ROTP::TOTP.new User.find_by_login('jsmith').twofa_totp_key
24
    post "/my/twofa/totp/activate", params: { twofa_code: totp.now }
25
    assert_redirected_to "/my/account"
26
    follow_redirect!
27
    assert_response :success
28
    assert_select '.flash', /Two-factor authentication successfully enabled/i
29

  
30
    post "/my/twofa/backup_codes/init"
31
    assert_redirected_to "/my/twofa/backup_codes/confirm"
32
    follow_redirect!
33
    assert_response :success
34
    assert_select 'form', /Please enter your two-factor authentication code/i
35

  
36
    post "/my/twofa/backup_codes/create", params: { twofa_code: "wrong" }
37
    assert_redirected_to "/my/twofa/backup_codes/confirm"
38
    follow_redirect!
39
    assert_response :success
40
    assert_select 'form', /Please enter your two-factor authentication code/i
41

  
42
    # prevent replay attack prevention from kicking in
43
    User.find_by_login('jsmith').update_column :twofa_totp_last_used_at, 2.minutes.ago.to_i
44

  
45
    post "/my/twofa/backup_codes/create", params: { twofa_code: totp.now }
46
    assert_redirected_to "/my/twofa/backup_codes"
47
    follow_redirect!
48
    assert_response :success
49
    assert_select ".flash", /your backup codes have been generated/i
50

  
51
    assert code = response.body.scan(/<code>([a-z0-9]{4} [a-z0-9]{4} [a-z0-9]{4})<\/code>/).flatten.first
52

  
53
    post "/logout"
54
    follow_redirect!
55
    # prevent replay attack prevention from kicking in
56
    User.find_by_login('jsmith').update_column :twofa_totp_last_used_at, 2.minutes.ago.to_i
57

  
58
    # sign in with backup code
59
    get "/login"
60
    assert_nil session[:user_id]
61
    assert_response :success
62
    post "/login", params: {
63
      username: 'jsmith',
64
      password: 'jsmith'
65
    }
66
    assert_redirected_to "/account/twofa/confirm"
67
    follow_redirect!
68

  
69
    assert_select "#login-form h3", /two-factor authentication/i
70
    post "/account/twofa", params: { twofa_code: code }
71
    assert_redirected_to "/my/page"
72
    follow_redirect!
73
    assert_response :success
74
  end
75

  
76
  test "should configure totp and require code on login" do
77
    with_settings twofa: "2" do
78
      log_user('jsmith', 'jsmith')
79
      follow_redirect!
80
      assert_redirected_to "/my/twofa/totp/activate/confirm"
81
      follow_redirect!
82

  
83
      assert key = User.find_by_login('jsmith').twofa_totp_key
84
      assert key.present?
85
      totp = ROTP::TOTP.new key
86

  
87
      post "/my/twofa/totp/activate", params: { twofa_code: '123456789' }
88
      assert_redirected_to "/my/twofa/totp/activate/confirm"
89
      follow_redirect!
90

  
91
      post "/my/twofa/totp/activate", params: { twofa_code: totp.now }
92
      assert_redirected_to "/my/account"
93

  
94
      post "/logout"
95
      follow_redirect!
96

  
97
      # prevent replay attack prevention from kicking in
98
      User.find_by_login('jsmith').update_column :twofa_totp_last_used_at, 2.minutes.ago.to_i
99

  
100
      # sign in with totp
101
      get "/login"
102
      assert_nil session[:user_id]
103
      assert_response :success
104
      post "/login", params: {
105
        username: 'jsmith',
106
        password: 'jsmith'
107
      }
108

  
109
      assert_redirected_to "/account/twofa/confirm"
110
      follow_redirect!
111

  
112
      assert_select "#login-form h3", /two-factor authentication/i
113
      post "/account/twofa", params: { twofa_code: 'wrong code' }
114
      assert_redirected_to "/account/twofa/confirm"
115
      follow_redirect!
116
      assert_select "#login-form h3", /two-factor authentication/i
117
      assert_select ".flash", /code is invalid/i
118

  
119
      post "/account/twofa", params: { twofa_code: totp.now }
120
      assert_redirected_to "/my/page"
121
      follow_redirect!
122
      assert_response :success
123
    end
124

  
125
  end
126
end
(16-16/22)