Project

General

Profile

Feature #31920 » 0005-per-group-2fa-requirement.patch

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

View differences:

app/models/group.rb
40 40
  scope :givable, lambda {where(:type => 'Group')}
41 41

  
42 42
  safe_attributes 'name',
43
    'twofa_required',
43 44
    'user_ids',
44 45
    'custom_field_values',
45 46
    'custom_fields',
app/models/setting.rb
211 211
    params
212 212
  end
213 213

  
214
  def self.twofa_required?
215
    twofa == '2'
216
  end
217

  
218
  def self.twofa_optional?
219
    twofa == '1'
220
  end
221

  
214 222
  # Helper that returns an array based on per_page_options setting
215 223
  def self.per_page_options_array
216 224
    per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
app/models/user.rb
382 382
  end
383 383

  
384 384
  def must_activate_twofa?
385
    Setting.twofa == '2' && !twofa_active?
385
    (
386
      Setting.twofa_required? ||
387
      (Setting.twofa_optional? && groups.any?(&:twofa_required?))
388
    ) && !twofa_active?
386 389
  end
387 390

  
388 391
  def pref
app/views/groups/_form.html.erb
3 3
<div class="box tabular">
4 4
  <p><%= f.text_field :name, :required => true, :size => 60,
5 5
           :disabled => !@group.safe_attribute?('name')  %></p>
6
  <p><%= f.check_box :twofa_required, disabled: !Setting.twofa_optional? %>
7
    <% if Setting.twofa_required? %>
8
      <em class="info"><%= l 'twofa_text_group_required' %></em>
9
    <% elsif !Setting.twofa_optional? %>
10
      <em class="info"><%= l 'twofa_text_group_disabled' %></em>
11
    <% end %>
12
  </p>
6 13

  
7 14
  <% @group.custom_field_values.each do |value| %>
8 15
    <p><%= custom_field_tag_with_label :group, value %></p>
app/views/settings/_authentication.html.erb
32 32
                              [l(:label_required_lower), "2"]] -%>
33 33
  <em class="info">
34 34
    <%= t 'twofa_hint_disabled_html', label: t(:label_disabled) -%><br/>
35
    <%= t 'twofa_hint_optional_html', label: t(:label_optional) -%><br/>
35 36
    <%= t 'twofa_hint_required_html', label: t(:label_required_lower) -%>
36 37
  </em>
37 38
</p>
config/locales/en.yml
1279 1279
  twofa_not_active: "Not activated"
1280 1280
  twofa_label_code: Code
1281 1281
  twofa_hint_disabled_html: Setting <strong>%{label}</strong> will deactivate and unpair two-factor authentication devices for all users.
1282
  twofa_hint_optional_html: Setting <strong>%{label}</strong> will let users set up two-factor authentication at will, unless it is required by one of their groups.
1282 1283
  twofa_hint_required_html: Setting <strong>%{label}</strong> will require all users to set up two-factor authentication at their next login.
1283 1284
  twofa_label_setup: Enable two-factor authentication
1284 1285
  twofa_label_deactivation_confirmation: Disable two-factor authentication
......
1303 1304
  twofa_text_backup_codes_hint: Use these codes instead of a one-time password should you not have access to your second factor. Each code can only be used once. It is recommended to print and store them in a safe place.
1304 1305
  twofa_text_backup_codes_created_at: Backup codes generated %{datetime}.
1305 1306
  twofa_backup_codes_already_shown: Backup codes cannot be shown again, please <a data-method="post" href="%{bc_path}">generate new backup codes</a> if required.
1307
  field_twofa_required: Require two factor authentication
1308
  twofa_text_group_required: "This setting is only effective when the global two factor authentication setting is set to 'optional'. Currently, two factor authentication is required for all users."
1309
  twofa_text_group_disabled: "This setting is only effective when the global two factor authentication setting is set to 'optional'. Currently, two factor authentication is disabled."
db/migrate/20190817093525_add_twofa_required_to_groups.rb
1
class AddTwofaRequiredToGroups < ActiveRecord::Migration[5.2]
2
  def change
3
    add_column :users, :twofa_required, :boolean, default: false
4
  end
5
end
test/integration/twofa_test.rb
3 3
class TwofaTest < Redmine::IntegrationTest
4 4
  fixtures :projects, :users, :email_addresses
5 5

  
6
  setup do
7
  end
8

  
6 9
  test "should require twofa setup when configured" do
7 10
    with_settings twofa: "2" do
11
      assert Setting.twofa_required?
12
      log_user('jsmith', 'jsmith')
13
      follow_redirect!
14
      assert_redirected_to "/my/twofa/totp/activate/confirm"
15
    end
16
  end
17

  
18
  test "should require twofa setup when required by group" do
19
    user = User.find_by_login 'jsmith'
20
    refute user.must_activate_twofa?
21

  
22
    group = Group.all.first
23
    group.update_column :twofa_required, true
24
    group.users << user
25
    user.reload
26

  
27
    with_settings twofa: "0" do
28
      refute Setting.twofa_optional?
29
      refute Setting.twofa_required?
30
      refute user.must_activate_twofa?
31
    end
32

  
33
    with_settings twofa: "1" do
34
      assert Setting.twofa_optional?
35
      refute Setting.twofa_required?
36
      assert user.must_activate_twofa?
8 37
      log_user('jsmith', 'jsmith')
9 38
      follow_redirect!
10 39
      assert_redirected_to "/my/twofa/totp/activate/confirm"
(1-1/2)