Project

General

Profile

Feature #1237 » 0002-Adds-a-setting-to-disable-enable-require-2fa-auth-12.patch

Go MAEDA, 2020-08-26 18:22

View differences:

app/controllers/application_controller.rb
56 56
    end
57 57
  end
58 58

  
59
  before_action :session_expiration, :user_setup, :check_if_login_required, :set_localization, :check_password_change
59
  before_action :session_expiration, :user_setup, :check_if_login_required, :set_localization, :check_password_change, :check_twofa_activation
60 60
  after_action :record_project_usage
61 61

  
62 62
  rescue_from ::Unauthorized, :with => :deny_access
......
89 89
    if user.must_change_password?
90 90
      session[:pwd] = '1'
91 91
    end
92
    if user.must_activate_twofa?
93
      session[:must_activate_twofa] = '1'
94
    end
92 95
  end
93 96

  
94 97
  def user_setup
......
205 208
    end
206 209
  end
207 210

  
211
  def init_twofa_pairing_and_send_code_for(twofa)
212
    twofa.init_pairing!
213
    if twofa.send_code(controller: 'twofa', action: 'activate')
214
      flash[:notice] = l('twofa_code_sent')
215
    end
216
    redirect_to controller: 'twofa', action: 'activate_confirm', scheme: twofa.scheme_name
217
  end
218

  
219
  def check_twofa_activation
220
    if session[:must_activate_twofa]
221
      if User.current.must_activate_twofa?
222
        flash[:warning] = l('twofa_warning_require')
223
        if Redmine::Twofa.available_schemes.length == 1
224
          twofa_scheme = Redmine::Twofa.for_twofa_scheme(Redmine::Twofa.available_schemes.first)
225
          twofa = twofa_scheme.new(User.current)
226
          init_twofa_pairing_and_send_code_for(twofa)
227
        else
228
          redirect_to controller: 'twofa', action: 'select_scheme'
229
        end
230
      else
231
        session.delete(:must_activate_twofa)
232
      end
233
    end
234
  end
235

  
208 236
  def set_localization(user=User.current)
209 237
    lang = nil
210 238
    if user && user.logged?
app/controllers/twofa_controller.rb
23 23
  before_action :require_login
24 24
  before_action :require_admin, only: :admin_deactivate
25 25

  
26
  before_action :require_active_twofa
27

  
26 28
  require_sudo_mode :activate_init, :deactivate_init
27 29

  
30
  skip_before_action :check_twofa_activation, only: [:select_scheme, :activate_init, :activate_confirm, :activate]
31

  
32
  def select_scheme
33
    @user = User.current
34
  end
35

  
28 36
  before_action :activate_setup, only: [:activate_init, :activate_confirm, :activate]
29 37

  
30 38
  def activate_init
31
    @twofa.init_pairing!
32
    if @twofa.send_code(controller: 'twofa', action: 'activate')
33
      flash[:notice] = l('twofa_code_sent')
34
    end
35
    redirect_to action: :activate_confirm, scheme: @twofa.scheme_name
39
    init_twofa_pairing_and_send_code_for(@twofa)
36 40
  end
37 41

  
38 42
  def activate_confirm
......
103 107
      redirect_to my_account_path
104 108
    end
105 109
  end
110

  
111
  def require_active_twofa
112
    Setting.twofa? ? true : deny_access
113
  end
106 114
end
app/models/setting.rb
223 223
    s
224 224
  end
225 225

  
226
  def self.twofa_from_params(params)
227
    # unpair all current 2FA pairings when switching off 2FA
228
    Redmine::Twofa.unpair_all! if params == '0' && self.twofa?
229
    params
230
  end
231

  
226 232
  # Helper that returns an array based on per_page_options setting
227 233
  def self.per_page_options_array
228 234
    per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
app/models/user.rb
396 396
    twofa_scheme.present?
397 397
  end
398 398

  
399
  def must_activate_twofa?
400
    Setting.twofa == '2' && !twofa_active?
401
  end
402

  
399 403
  def pref
400 404
    self.preference ||= UserPreference.new(:user => self)
401 405
  end
app/views/my/account.html.erb
28 28
  <% if Setting.openid? %>
29 29
  <p><%= f.text_field :identity_url  %></p>
30 30
  <% end %>
31
  <% if Setting.twofa? -%>
31 32
  <p>
32 33
    <label><%=l :setting_twofa -%></label>
33 34
    <% if @user.twofa_active? %>
......
39 40
      <% end %>
40 41
    <% end %>
41 42
  </p>
43
  <% end -%>
42 44

  
43 45
  <% @user.custom_field_values.select(&:editable?).each do |value| %>
44 46
    <p><%= custom_field_tag_with_label :user, value %></p>
app/views/settings/_authentication.html.erb
28 28

  
29 29
<p><%= setting_check_box :lost_password %></p>
30 30

  
31
<p>
32
  <%= setting_select :twofa, [[l(:label_disabled), "0"],
33
                              [l(:label_optional), "1"],
34
                              [l(:label_required_lower), "2"]] -%>
35
  <em class="info">
36
    <%= t 'twofa_hint_disabled_html', label: t(:label_disabled) -%><br/>
37
    <%= t 'twofa_hint_required_html', label: t(:label_required_lower) -%>
38
  </em>
39
</p>
40

  
41

  
31 42
<p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p>
32 43
</div>
33 44

  
app/views/twofa/activate_confirm.html.erb
22 22
  <% end %>
23 23
</div>
24 24

  
25
<% unless @user.must_activate_twofa? %>
25 26
<% content_for :sidebar do %>
26 27
<%= render :partial => 'my/sidebar' %>
27 28
<% end %>
29
<% end %>
app/views/twofa/select_scheme.html.erb
1
<%= title l('twofa_label_setup') %>
2

  
3
<%= form_tag({ controller: 'twofa', action: 'activate_init' }, method: :post) do %>
4
  <div class="box">
5
  <p><%=l 'twofa_notice_select' -%></p>
6
  <p>
7
  <% Redmine::Twofa.available_schemes.each_with_index do |s, idx| %>
8
    <label style="display:block;"><%= radio_button_tag 'scheme', s, idx == 0 -%> <%=l "twofa__#{s}__name" -%></label>
9
  <% end %>
10
  </p>
11
  </div>
12
  <p><%= submit_tag l(:label_next).html_safe + " &#187;".html_safe -%></p>
13
<% end %>
14

  
15
<% unless @user.must_activate_twofa? %>
16
<% content_for :sidebar do %>
17
<%= render partial: 'my/sidebar' %>
18
<% end %>
19
<% end %>
app/views/users/_form.html.erb
42 42
  <p><%= f.check_box :generate_password %></p>
43 43
  <p><%= f.check_box :must_change_passwd %></p>
44 44
  </div>
45
  <% if Setting.twofa? -%>
45 46
  <p>
46 47
    <label><%=l :setting_twofa -%></label>
47 48
    <% if @user.twofa_active? %>
......
55 56
      <%=l 'twofa_not_active' %>
56 57
    <% end %>
57 58
  </p>
59
  <% end -%>
58 60
</fieldset>
59 61
</div>
60 62

  
config/locales/de.yml
719 719
  label_repository_new: Neues Repository
720 720
  label_repository_plural: Repositories
721 721
  label_required: Erforderlich
722
  label_required_lower: erforderlich
722 723
  label_result_plural: Resultate
723 724
  label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge
724 725
  label_revision: Revision
......
1330 1331
  twofa_currently_active: "Aktiv: %{twofa_scheme_name}"
1331 1332
  twofa_not_active: "Nicht aktiv"
1332 1333
  twofa_label_code: Code
1334
  twofa_hint_disabled_html: Die Einstellung <strong>%{label}</strong> deaktiviert Zwei-Faktor-Authentifizierung für alle Nutzer und löscht verbundene Apps.
1335
  twofa_hint_required_html: Die Einstellung <strong>%{label}</strong> fordert alle Nutzer bei ihrem nächsten Login dazu auf Zwei-Faktor-Authentifizierung einzurichten.
1333 1336
  twofa_label_setup: Zwei-Faktor-Authentifizierung einrichten
1334 1337
  twofa_label_deactivation_confirmation: Zwei-Faktor-Authentifizierung abschalten
1338
  twofa_notice_select: "Bitte wählen Sie Ihr gewünschtes Schema für die Zwei-Faktor-Authentifizierung:"
1339
  twofa_warning_require: Der Administrator fordert Sie dazu auf Zwei-Faktor-Authentifizierung einzurichten.
1335 1340
  twofa_activated: Zwei-Faktor-Authentifizierung erfolgreich eingerichtet.
1336 1341
  twofa_deactivated: Zwei-Faktor-Authentifizierung abgeschaltet.
1337 1342
  twofa_mail_body_security_notification_paired: "Zwei-Faktor-Authentifizierung per %{field} eingerichtet."
config/locales/en.yml
870 870
  label_copied_from: Copied from
871 871
  label_stay_logged_in: Stay logged in
872 872
  label_disabled: disabled
873
  label_optional: optional
873 874
  label_show_completed_versions: Show completed versions
874 875
  label_me: me
875 876
  label_board: Forum
......
993 994
  label_fields_permissions: Fields permissions
994 995
  label_readonly: Read-only
995 996
  label_required: Required
997
  label_required_lower: required
996 998
  label_hidden: Hidden
997 999
  label_attribute_of_project: "Project's %{name}"
998 1000
  label_attribute_of_issue: "Issue's %{name}"
......
1307 1309
  twofa_currently_active: "Currently active: %{twofa_scheme_name}"
1308 1310
  twofa_not_active: "Not activated"
1309 1311
  twofa_label_code: Code
1312
  twofa_hint_disabled_html: Setting <strong>%{label}</strong> will deactivate and unpair two-factor authentication devices for all users.
1313
  twofa_hint_required_html: Setting <strong>%{label}</strong> will require all users to set up two-factor authentication at their next login.
1310 1314
  twofa_label_setup: Enable two-factor authentication
1311 1315
  twofa_label_deactivation_confirmation: Disable two-factor authentication
1316
  twofa_notice_select: "Please select the two-factor scheme you would like to use:"
1317
  twofa_warning_require: The administrator requires you to enable two-factor authentication.
1312 1318
  twofa_activated: Two-factor authentication successfully enabled.
1313 1319
  twofa_deactivated: Two-factor authentication disabled.
1314 1320
  twofa_mail_body_security_notification_paired: "Two-factor authentication successfully enabled using %{field}."
config/routes.rb
88 88
  match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
89 89
  match 'my/remove_block', :controller => 'my', :action => 'remove_block', :via => :post
90 90
  match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post
91
  match 'my/twofa/activate/init', :controller => 'twofa', :action => 'activate_init', :via => :post
91 92
  match 'my/twofa/:scheme/activate/init', :controller => 'twofa', :action => 'activate_init', :via => :post
92 93
  match 'my/twofa/:scheme/activate/confirm', :controller => 'twofa', :action => 'activate_confirm', :via => :get
93 94
  match 'my/twofa/:scheme/activate', :controller => 'twofa', :action => 'activate', :via => [:get, :post]
94 95
  match 'my/twofa/:scheme/deactivate/init', :controller => 'twofa', :action => 'deactivate_init', :via => :post
95 96
  match 'my/twofa/:scheme/deactivate/confirm', :controller => 'twofa', :action => 'deactivate_confirm', :via => :get
96 97
  match 'my/twofa/:scheme/deactivate', :controller => 'twofa', :action => 'deactivate', :via => [:get, :post]
98
  match 'my/twofa/select_scheme', :controller => 'twofa', :action => 'select_scheme', :via => :get
97 99
  match 'users/:user_id/twofa/deactivate', :controller => 'twofa', :action => 'admin_deactivate', :via => :post
98 100

  
99 101
  resources :users do
config/settings.yml
34 34
lost_password:
35 35
  default: 1
36 36
  security_notifications: 1
37
twofa:
38
  default: 1
39
  security_notifications: 1
37 40
unsubscribe:
38 41
  default: 1
39 42
password_required_char_classes:
lib/redmine/twofa.rb
36 36
      for_twofa_scheme(user.twofa_scheme).try(:new, user)
37 37
    end
38 38

  
39
    def self.unpair_all!
40
      users = User.where.not(twofa_scheme: nil)
41
      users.each { |u| self.for_user(u).destroy_pairing_without_verify! }
42
    end
43

  
39 44
    def self.schemes
40 45
      initialize_schemes
41 46
      @@schemes
(20-20/22)