Feature #1237 » 0002-adds-a-setting-to-disable-enable-require-2fa-auth.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 |
| ... | ... | |
| 200 | 203 |
end |
| 201 | 204 |
end |
| 202 | 205 | |
| 206 |
def init_twofa_pairing_and_send_code_for(twofa) |
|
| 207 |
twofa.init_pairing! |
|
| 208 |
if twofa.send_code(controller: 'twofa', action: 'activate') |
|
| 209 |
flash[:notice] = l('twofa_code_sent')
|
|
| 210 |
end |
|
| 211 |
redirect_to controller: 'twofa', action: 'activate_confirm', scheme: twofa.scheme_name |
|
| 212 |
end |
|
| 213 | ||
| 214 |
def check_twofa_activation |
|
| 215 |
if session[:must_activate_twofa] |
|
| 216 |
if User.current.must_activate_twofa? |
|
| 217 |
flash[:warning] = l('twofa_warning_require')
|
|
| 218 |
if Redmine::Twofa.available_schemes.length == 1 |
|
| 219 |
twofa_scheme = Redmine::Twofa.for_twofa_scheme(Redmine::Twofa.available_schemes.first) |
|
| 220 |
twofa = twofa_scheme.new(User.current) |
|
| 221 |
init_twofa_pairing_and_send_code_for(twofa) |
|
| 222 |
else |
|
| 223 |
redirect_to controller: 'twofa', action: 'select_scheme' |
|
| 224 |
end |
|
| 225 |
else |
|
| 226 |
session.delete(:must_activate_twofa) |
|
| 227 |
end |
|
| 228 |
end |
|
| 229 |
end |
|
| 230 | ||
| 203 | 231 |
def set_localization(user=User.current) |
| 204 | 232 |
lang = nil |
| 205 | 233 |
if user && user.logged? |
| app/controllers/twofa_controller.rb | ||
|---|---|---|
| 4 | 4 |
before_action :require_login |
| 5 | 5 |
before_action :require_admin, only: :admin_deactivate |
| 6 | 6 | |
| 7 |
before_action :require_active_twofa |
|
| 8 | ||
| 7 | 9 |
require_sudo_mode :activate_init, :deactivate_init |
| 8 | 10 | |
| 11 |
skip_before_action :check_twofa_activation, only: [:select_scheme, :activate_init, :activate_confirm, :activate] |
|
| 12 | ||
| 13 |
def select_scheme |
|
| 14 |
@user = User.current |
|
| 15 |
end |
|
| 16 | ||
| 9 | 17 |
before_action :activate_setup, only: [:activate_init, :activate_confirm, :activate] |
| 10 | 18 | |
| 11 | 19 |
def activate_init |
| 12 |
@twofa.init_pairing! |
|
| 13 |
if @twofa.send_code(controller: 'twofa', action: 'activate') |
|
| 14 |
flash[:notice] = l('twofa_code_sent')
|
|
| 15 |
end |
|
| 16 |
redirect_to action: :activate_confirm, scheme: @twofa.scheme_name |
|
| 20 |
init_twofa_pairing_and_send_code_for(@twofa) |
|
| 17 | 21 |
end |
| 18 | 22 | |
| 19 | 23 |
def activate_confirm |
| ... | ... | |
| 84 | 88 |
redirect_to my_account_path |
| 85 | 89 |
end |
| 86 | 90 |
end |
| 91 | ||
| 92 |
def require_active_twofa |
|
| 93 |
Setting.twofa? ? true : deny_access |
|
| 94 |
end |
|
| 87 | 95 |
end |
| app/models/setting.rb | ||
|---|---|---|
| 205 | 205 |
s |
| 206 | 206 |
end |
| 207 | 207 | |
| 208 |
def self.twofa_from_params(params) |
|
| 209 |
# unpair all current 2FA pairings when switching off 2FA |
|
| 210 |
Redmine::Twofa.unpair_all! if params == '0' && self.twofa? |
|
| 211 |
params |
|
| 212 |
end |
|
| 213 | ||
| 208 | 214 |
# Helper that returns an array based on per_page_options setting |
| 209 | 215 |
def self.per_page_options_array |
| 210 | 216 |
per_page_options.split(%r{[\s,]}).collect(&:to_i).select {|n| n > 0}.sort
|
| app/models/user.rb | ||
|---|---|---|
| 381 | 381 |
twofa_scheme.present? |
| 382 | 382 |
end |
| 383 | 383 | |
| 384 |
def must_activate_twofa? |
|
| 385 |
Setting.twofa == '2' && !twofa_active? |
|
| 386 |
end |
|
| 387 | ||
| 384 | 388 |
def pref |
| 385 | 389 |
self.preference ||= UserPreference.new(:user => self) |
| 386 | 390 |
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 | ||
|---|---|---|
| 26 | 26 | |
| 27 | 27 |
<p><%= setting_check_box :lost_password %></p> |
| 28 | 28 | |
| 29 |
<p> |
|
| 30 |
<%= setting_select :twofa, [[l(:label_disabled), "0"], |
|
| 31 |
[l(:label_optional), "1"], |
|
| 32 |
[l(:label_required_lower), "2"]] -%> |
|
| 33 |
<em class="info"> |
|
| 34 |
<%= t 'twofa_hint_disabled_html', label: t(:label_disabled) -%><br/> |
|
| 35 |
<%= t 'twofa_hint_required_html', label: t(:label_required_lower) -%> |
|
| 36 |
</em> |
|
| 37 |
</p> |
|
| 38 | ||
| 39 | ||
| 29 | 40 |
<p><%= setting_check_box :openid, :disabled => !Object.const_defined?(:OpenID) %></p> |
| 30 | 41 |
</div> |
| 31 | 42 | |
| 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 | ||
|---|---|---|
| 37 | 37 |
<p><%= f.check_box :generate_password %></p> |
| 38 | 38 |
<p><%= f.check_box :must_change_passwd %></p> |
| 39 | 39 |
</div> |
| 40 |
<% if Setting.twofa? -%> |
|
| 40 | 41 |
<p> |
| 41 | 42 |
<label><%=l :setting_twofa -%></label> |
| 42 | 43 |
<% if @user.twofa_active? %> |
| ... | ... | |
| 50 | 51 |
<%=l 'twofa_not_active' %> |
| 51 | 52 |
<% end %> |
| 52 | 53 |
</p> |
| 54 |
<% end -%> |
|
| 53 | 55 |
</fieldset> |
| 54 | 56 |
</div> |
| 55 | 57 | |
| config/locales/de.yml | ||
|---|---|---|
| 718 | 718 |
label_repository_new: Neues Repository |
| 719 | 719 |
label_repository_plural: Repositories |
| 720 | 720 |
label_required: Erforderlich |
| 721 |
label_required_lower: erforderlich |
|
| 721 | 722 |
label_result_plural: Resultate |
| 722 | 723 |
label_reverse_chronological_order: in umgekehrter zeitlicher Reihenfolge |
| 723 | 724 |
label_revision: Revision |
| ... | ... | |
| 1297 | 1298 |
twofa_currently_active: "Aktiv: %{twofa_scheme_name}"
|
| 1298 | 1299 |
twofa_not_active: "Nicht aktiv" |
| 1299 | 1300 |
twofa_label_code: Code |
| 1301 |
twofa_hint_disabled_html: Die Einstellung <strong>%{label}</strong> deaktiviert Zwei-Faktor-Authentifizierung für alle Nutzer und löscht verbundene Apps.
|
|
| 1302 |
twofa_hint_required_html: Die Einstellung <strong>%{label}</strong> fordert alle Nutzer bei ihrem nächsten Login dazu auf Zwei-Faktor-Authentifizierung einzurichten.
|
|
| 1300 | 1303 |
twofa_label_setup: Zwei-Faktor-Authentifizierung einrichten |
| 1301 | 1304 |
twofa_label_deactivation_confirmation: Zwei-Faktor-Authentifizierung abschalten |
| 1305 |
twofa_notice_select: "Bitte wählen Sie Ihr gewünschtes Schema für die Zwei-Faktor-Authentifizierung:" |
|
| 1306 |
twofa_warning_require: Der Administrator fordert Sie dazu auf Zwei-Faktor-Authentifizierung einzurichten. |
|
| 1302 | 1307 |
twofa_activated: Zwei-Faktor-Authentifizierung erfolgreich eingerichtet. |
| 1303 | 1308 |
twofa_deactivated: Zwei-Faktor-Authentifizierung abgeschaltet. |
| 1304 | 1309 |
twofa_mail_body_security_notification_paired: "Zwei-Faktor-Authentifizierung per %{field} eingerichtet."
|
| config/locales/en.yml | ||
|---|---|---|
| 853 | 853 |
label_copied_from: Copied from |
| 854 | 854 |
label_stay_logged_in: Stay logged in |
| 855 | 855 |
label_disabled: disabled |
| 856 |
label_optional: optional |
|
| 856 | 857 |
label_show_completed_versions: Show completed versions |
| 857 | 858 |
label_me: me |
| 858 | 859 |
label_board: Forum |
| ... | ... | |
| 975 | 976 |
label_fields_permissions: Fields permissions |
| 976 | 977 |
label_readonly: Read-only |
| 977 | 978 |
label_required: Required |
| 979 |
label_required_lower: required |
|
| 978 | 980 |
label_hidden: Hidden |
| 979 | 981 |
label_attribute_of_project: "Project's %{name}"
|
| 980 | 982 |
label_attribute_of_issue: "Issue's %{name}"
|
| ... | ... | |
| 1276 | 1278 |
twofa_currently_active: "Currently active: %{twofa_scheme_name}"
|
| 1277 | 1279 |
twofa_not_active: "Not activated" |
| 1278 | 1280 |
twofa_label_code: Code |
| 1281 |
twofa_hint_disabled_html: Setting <strong>%{label}</strong> will deactivate and unpair two-factor authentication devices for all users.
|
|
| 1282 |
twofa_hint_required_html: Setting <strong>%{label}</strong> will require all users to set up two-factor authentication at their next login.
|
|
| 1279 | 1283 |
twofa_label_setup: Enable two-factor authentication |
| 1280 | 1284 |
twofa_label_deactivation_confirmation: Disable two-factor authentication |
| 1285 |
twofa_notice_select: "Please select the two-factor scheme you would like to use:" |
|
| 1286 |
twofa_warning_require: The administrator requires you to enable two-factor authentication. |
|
| 1281 | 1287 |
twofa_activated: Two-factor authentication successfully enabled. |
| 1282 | 1288 |
twofa_deactivated: Two-factor authentication disabled. |
| 1283 | 1289 |
twofa_mail_body_security_notification_paired: "Two-factor authentication successfully enabled using %{field}."
|
| config/routes.rb | ||
|---|---|---|
| 87 | 87 |
match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post |
| 88 | 88 |
match 'my/remove_block', :controller => 'my', :action => 'remove_block', :via => :post |
| 89 | 89 |
match 'my/order_blocks', :controller => 'my', :action => 'order_blocks', :via => :post |
| 90 |
match 'my/twofa/activate/init', :controller => 'twofa', :action => 'activate_init', :via => :post |
|
| 90 | 91 |
match 'my/twofa/:scheme/activate/init', :controller => 'twofa', :action => 'activate_init', :via => :post |
| 91 | 92 |
match 'my/twofa/:scheme/activate/confirm', :controller => 'twofa', :action => 'activate_confirm', :via => :get |
| 92 | 93 |
match 'my/twofa/:scheme/activate', :controller => 'twofa', :action => 'activate', :via => [:get, :post] |
| 93 | 94 |
match 'my/twofa/:scheme/deactivate/init', :controller => 'twofa', :action => 'deactivate_init', :via => :post |
| 94 | 95 |
match 'my/twofa/:scheme/deactivate/confirm', :controller => 'twofa', :action => 'deactivate_confirm', :via => :get |
| 95 | 96 |
match 'my/twofa/:scheme/deactivate', :controller => 'twofa', :action => 'deactivate', :via => [:get, :post] |
| 97 |
match 'my/twofa/select_scheme', :controller => 'twofa', :action => 'select_scheme', :via => :get |
|
| 96 | 98 |
match 'users/:user_id/twofa/deactivate', :controller => 'twofa', :action => 'admin_deactivate', :via => :post |
| 97 | 99 | |
| 98 | 100 |
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_min_length: |
| lib/redmine/twofa.rb | ||
|---|---|---|
| 17 | 17 |
for_twofa_scheme(user.twofa_scheme).try(:new, user) |
| 18 | 18 |
end |
| 19 | 19 | |
| 20 |
def self.unpair_all! |
|
| 21 |
users = User.where.not(twofa_scheme: nil) |
|
| 22 |
users.each { |u| self.for_user(u).destroy_pairing_without_verify! }
|
|
| 23 |
end |
|
| 24 | ||
| 20 | 25 |
private |
| 21 | 26 | |
| 22 | 27 |
def self.schemes |