Feature #1237 » 0002-Adds-a-setting-to-disable-enable-require-2fa-auth-12.patch
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 + " »".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 |