##// END OF EJS Templates
Require password re-entry for sensitive actions (#19851)....
Jean-Philippe Lang -
r13951:d6f389658b9e
parent child
Show More
@@ -0,0 +1,10
1 <h2><%= l :label_api_access_key %></h2>
2
3 <div class="box">
4 <pre><%= @user.api_key %></pre>
5 </div>
6
7 <p><%= link_to l(:button_back), action: 'account' %></p>
8
9
10
@@ -0,0 +1,1
1 $('#api-access-key').html('<%= escape_javascript @user.api_key %>').toggle();
@@ -0,0 +1,19
1 <h3 class="title"><%= l(:label_password_required) %></h3>
2 <%= form_tag({}, remote: true) do %>
3
4 <%= hidden_field_tag '_method', request.request_method %>
5 <%= hash_to_hidden_fields @sudo_form.original_fields %>
6 <%= render_flash_messages %>
7 <div class="box tabular">
8 <p>
9 <label for="sudo_password"><%= l :field_password %><span class="required">*</span></label>
10 <%= password_field_tag :sudo_password, nil, size: 25 %>
11 </p>
12 </div>
13
14 <p class="buttons">
15 <%= submit_tag l(:button_confirm_password), onclick: "hideModal(this);" %>
16 <%= submit_tag l(:button_cancel), name: nil, onclick: "hideModal(this);", type: 'button' %>
17 </p>
18 <% end %>
19
@@ -0,0 +1,17
1 <h2><%= l :label_password_required %></h2>
2 <%= form_tag({}, class: 'tabular') do %>
3
4 <%= hidden_field_tag '_method', request.request_method %>
5 <%= hash_to_hidden_fields @sudo_form.original_fields %>
6
7 <div class="box">
8 <p>
9 <label for="sudo_password"><%= l :field_password %><span class="required">*</span></label>
10 <%= password_field_tag :sudo_password, nil, size: 25 %>
11 </p>
12 </div>
13 <%= submit_tag l(:button_confirm_password) %>
14 <% end %>
15 <%= javascript_tag "$('#sudo_password').focus();" %>
16
17
@@ -0,0 +1,4
1 $('#ajax-modal').html('<%= escape_javascript render partial: 'sudo_mode/new_modal' %>');
2 showModal('ajax-modal', '400px');
3 $('#sudo_password').focus();
4
@@ -0,0 +1,224
1 require 'active_support/core_ext/object/to_query'
2 require 'rack/utils'
3
4 module Redmine
5 module SudoMode
6
7 # timespan after which sudo mode expires when unused.
8 MAX_INACTIVITY = 15.minutes
9
10
11 class SudoRequired < StandardError
12 end
13
14
15 class Form
16 include ActiveModel::Validations
17
18 attr_accessor :password, :original_fields
19 validate :check_password
20
21 def initialize(password = nil)
22 self.password = password
23 end
24
25 def check_password
26 unless password.present? && User.current.check_password?(password)
27 errors[:password] << :invalid
28 end
29 end
30 end
31
32
33 module Helper
34 # Represents params data from hash as hidden fields
35 #
36 # taken from https://github.com/brianhempel/hash_to_hidden_fields
37 def hash_to_hidden_fields(hash)
38 cleaned_hash = hash.reject { |k, v| v.nil? }
39 pairs = cleaned_hash.to_query.split(Rack::Utils::DEFAULT_SEP)
40 tags = pairs.map do |pair|
41 key, value = pair.split('=', 2).map { |str| Rack::Utils.unescape(str) }
42 hidden_field_tag(key, value)
43 end
44 tags.join("\n").html_safe
45 end
46 end
47
48
49 module Controller
50 extend ActiveSupport::Concern
51
52 included do
53 around_filter :sudo_mode
54 end
55
56 # Sudo mode Around Filter
57 #
58 # Checks the 'last used' timestamp from session and sets the
59 # SudoMode::active? flag accordingly.
60 #
61 # After the request refreshes the timestamp if sudo mode was used during
62 # this request.
63 def sudo_mode
64 if api_request?
65 SudoMode.disable!
66 elsif sudo_timestamp_valid?
67 SudoMode.active!
68 end
69 yield
70 update_sudo_timestamp! if SudoMode.was_used?
71 end
72
73 # This renders the sudo mode form / handles sudo form submission.
74 #
75 # Call this method in controller actions if sudo permissions are required
76 # for processing this request. This approach is good in cases where the
77 # action needs to be protected in any case or where the check is simple.
78 #
79 # In cases where this decision depends on complex conditions in the model,
80 # consider the declarative approach using the require_sudo_mode class
81 # method and a corresponding declaration in the model that causes it to throw
82 # a SudoRequired Error when necessary.
83 #
84 # All parameter names given are included as hidden fields to be resubmitted
85 # along with the password.
86 #
87 # Returns true when processing the action should continue, false otherwise.
88 # If false is returned, render has already been called for display of the
89 # password form.
90 #
91 # if @user.mail_changed?
92 # require_sudo_mode :user or return
93 # end
94 #
95 def require_sudo_mode(*param_names)
96 return true if SudoMode.active?
97
98 if param_names.blank?
99 param_names = params.keys - %w(id action controller sudo_password)
100 end
101
102 process_sudo_form
103
104 if SudoMode.active?
105 true
106 else
107 render_sudo_form param_names
108 false
109 end
110 end
111
112 # display the sudo password form
113 def render_sudo_form(param_names)
114 @sudo_form ||= SudoMode::Form.new
115 @sudo_form.original_fields = params.slice( *param_names )
116 # a simple 'render "sudo_mode/new"' works when used directly inside an
117 # action, but not when called from a before_filter:
118 respond_to do |format|
119 format.html { render 'sudo_mode/new' }
120 format.js { render 'sudo_mode/new' }
121 end
122 end
123
124 # handle sudo password form submit
125 def process_sudo_form
126 if params[:sudo_password]
127 @sudo_form = SudoMode::Form.new(params[:sudo_password])
128 if @sudo_form.valid?
129 SudoMode.active!
130 else
131 flash.now[:error] = l(:notice_account_wrong_password)
132 end
133 end
134 end
135
136 def sudo_timestamp_valid?
137 session[:sudo_timestamp].to_i > MAX_INACTIVITY.ago.to_i
138 end
139
140 def update_sudo_timestamp!(new_value = Time.now.to_i)
141 session[:sudo_timestamp] = new_value
142 end
143
144 # Before Filter which is used by the require_sudo_mode class method.
145 class SudoRequestFilter < Struct.new(:parameters, :request_methods)
146 def before(controller)
147 method_matches = request_methods.blank? || request_methods.include?(controller.request.method_symbol)
148 if SudoMode.possible? && method_matches
149 controller.require_sudo_mode( *parameters )
150 else
151 true
152 end
153 end
154 end
155
156 module ClassMethods
157
158 # Handles sudo requirements for the given actions, preserving the named
159 # parameters, or any parameters if you omit the :parameters option.
160 #
161 # Sudo enforcement by default is active for all requests to an action
162 # but may be limited to a certain subset of request methods via the
163 # :only option.
164 #
165 # Examples:
166 #
167 # require_sudo_mode :account, only: :post
168 # require_sudo_mode :update, :create, parameters: %w(role)
169 # require_sudo_mode :destroy
170 #
171 def require_sudo_mode(*args)
172 actions = args.dup
173 options = actions.extract_options!
174 filter = SudoRequestFilter.new Array(options[:parameters]), Array(options[:only])
175 before_filter filter, only: actions
176 end
177 end
178 end
179
180
181 # true if the sudo mode state was queried during this request
182 def self.was_used?
183 !!RequestStore.store[:sudo_mode_was_used]
184 end
185
186 # true if sudo mode is currently active.
187 #
188 # Calling this method also turns was_used? to true, therefore
189 # it is important to only call this when sudo is actually needed, as the last
190 # condition to determine wether a change can be done or not.
191 #
192 # If you do it wrong, timeout of the sudo mode will happen too late or not at
193 # all.
194 def self.active?
195 if !!RequestStore.store[:sudo_mode]
196 RequestStore.store[:sudo_mode_was_used] = true
197 end
198 end
199
200 def self.active!
201 RequestStore.store[:sudo_mode] = true
202 end
203
204 def self.possible?
205 !disabled? && User.current.logged?
206 end
207
208 # Turn off sudo mode (never require password entry).
209 def self.disable!
210 RequestStore.store[:sudo_mode_disabled] = true
211 end
212
213 # Turn sudo mode back on
214 def self.enable!
215 RequestStore.store[:sudo_mode_disabled] = nil
216 end
217
218 def self.disabled?
219 !!RequestStore.store[:sudo_mode_disabled]
220 end
221
222 end
223 end
224
@@ -0,0 +1,126
1 require File.expand_path('../../test_helper', __FILE__)
2
3 class SudoTest < Redmine::IntegrationTest
4 fixtures :projects, :members, :member_roles, :roles, :users
5
6 def setup
7 Redmine::SudoMode.enable!
8 end
9
10 def teardown
11 Redmine::SudoMode.disable!
12 end
13
14 def test_create_member_xhr
15 log_user 'admin', 'admin'
16 get '/projects/ecookbook/settings/members'
17 assert_response :success
18
19 assert_no_difference 'Member.count' do
20 xhr :post, '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}
21 end
22
23 assert_no_difference 'Member.count' do
24 xhr :post, '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: ''
25 end
26
27 assert_no_difference 'Member.count' do
28 xhr :post, '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: 'wrong'
29 end
30
31 assert_difference 'Member.count' do
32 xhr :post, '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: 'admin'
33 end
34 assert User.find(7).member_of?(Project.find(1))
35 end
36
37 def test_create_member
38 log_user 'admin', 'admin'
39 get '/projects/ecookbook/settings/members'
40 assert_response :success
41
42 assert_no_difference 'Member.count' do
43 post '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}
44 end
45
46 assert_no_difference 'Member.count' do
47 post '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: ''
48 end
49
50 assert_no_difference 'Member.count' do
51 post '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: 'wrong'
52 end
53
54 assert_difference 'Member.count' do
55 post '/projects/ecookbook/memberships', membership: {role_ids: [1], user_id: 7}, sudo_password: 'admin'
56 end
57
58 assert_redirected_to '/projects/ecookbook/settings/members'
59 assert User.find(7).member_of?(Project.find(1))
60 end
61
62 def test_create_role
63 log_user 'admin', 'admin'
64 get '/roles'
65 assert_response :success
66
67 get '/roles/new'
68 assert_response :success
69
70 post '/roles', role: { }
71 assert_response :success
72 assert_select 'h2', 'Confirm your password to continue'
73 assert_select 'form[action="/roles"]'
74 assert assigns(:sudo_form).errors.blank?
75
76 post '/roles', role: { name: 'new role', issues_visibility: 'all' }
77 assert_response :success
78 assert_select 'h2', 'Confirm your password to continue'
79 assert_select 'form[action="/roles"]'
80 assert_match /"new role"/, response.body
81 assert assigns(:sudo_form).errors.blank?
82
83 post '/roles', role: { name: 'new role', issues_visibility: 'all' }, sudo_password: 'wrong'
84 assert_response :success
85 assert_select 'h2', 'Confirm your password to continue'
86 assert_select 'form[action="/roles"]'
87 assert_match /"new role"/, response.body
88 assert assigns(:sudo_form).errors[:password].present?
89
90 assert_difference 'Role.count' do
91 post '/roles', role: { name: 'new role', issues_visibility: 'all', assignable: '1', permissions: %w(view_calendar) }, sudo_password: 'admin'
92 end
93 assert_redirected_to '/roles'
94 end
95
96 def test_update_email_address
97 log_user 'jsmith', 'jsmith'
98 get '/my/account'
99 assert_response :success
100 post '/my/account', user: { mail: 'newmail@test.com' }
101 assert_response :success
102 assert_select 'h2', 'Confirm your password to continue'
103 assert_select 'form[action="/my/account"]'
104 assert_match /"newmail@test\.com"/, response.body
105 assert assigns(:sudo_form).errors.blank?
106
107 # wrong password
108 post '/my/account', user: { mail: 'newmail@test.com' }, sudo_password: 'wrong'
109 assert_response :success
110 assert_select 'h2', 'Confirm your password to continue'
111 assert_select 'form[action="/my/account"]'
112 assert_match /"newmail@test\.com"/, response.body
113 assert assigns(:sudo_form).errors[:password].present?
114
115 # correct password
116 post '/my/account', user: { mail: 'newmail@test.com' }, sudo_password: 'jsmith'
117 assert_redirected_to '/my/account'
118 assert_equal 'newmail@test.com', User.find_by_login('jsmith').mail
119
120 # sudo mode should now be active and not require password again
121 post '/my/account', user: { mail: 'even.newer.mail@test.com' }
122 assert_redirected_to '/my/account'
123 assert_equal 'even.newer.mail@test.com', User.find_by_login('jsmith').mail
124 end
125
126 end
@@ -59,6 +59,8 class ApplicationController < ActionController::Base
59 include Redmine::MenuManager::MenuController
59 include Redmine::MenuManager::MenuController
60 helper Redmine::MenuManager::MenuHelper
60 helper Redmine::MenuManager::MenuHelper
61
61
62 include Redmine::SudoMode::Controller
63
62 def session_expiration
64 def session_expiration
63 if session[:user_id]
65 if session[:user_id]
64 if session_expired? && !try_to_autologin
66 if session_expired? && !try_to_autologin
@@ -21,6 +21,7 class AuthSourcesController < ApplicationController
21
21
22 before_filter :require_admin
22 before_filter :require_admin
23 before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
23 before_filter :find_auth_source, :only => [:edit, :update, :test_connection, :destroy]
24 require_sudo_mode :update, :destroy
24
25
25 def index
26 def index
26 @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
27 @auth_source_pages, @auth_sources = paginate AuthSource, :per_page => 25
@@ -18,6 +18,7
18 class EmailAddressesController < ApplicationController
18 class EmailAddressesController < ApplicationController
19 before_filter :find_user, :require_admin_or_current_user
19 before_filter :find_user, :require_admin_or_current_user
20 before_filter :find_email_address, :only => [:update, :destroy]
20 before_filter :find_email_address, :only => [:update, :destroy]
21 require_sudo_mode :create, :update, :destroy
21
22
22 def index
23 def index
23 @addresses = @user.email_addresses.order(:id).where(:is_default => false).to_a
24 @addresses = @user.email_addresses.order(:id).where(:is_default => false).to_a
@@ -22,6 +22,8 class GroupsController < ApplicationController
22 before_filter :find_group, :except => [:index, :new, :create]
22 before_filter :find_group, :except => [:index, :new, :create]
23 accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
23 accept_api_auth :index, :show, :create, :update, :destroy, :add_users, :remove_user
24
24
25 require_sudo_mode :add_users, :remove_user, :create, :update, :destroy, :edit_membership, :destroy_membership
26
25 helper :custom_fields
27 helper :custom_fields
26 helper :principal_memberships
28 helper :principal_memberships
27
29
@@ -23,6 +23,8 class MembersController < ApplicationController
23 before_filter :authorize
23 before_filter :authorize
24 accept_api_auth :index, :show, :create, :update, :destroy
24 accept_api_auth :index, :show, :create, :update, :destroy
25
25
26 require_sudo_mode :create, :update, :destroy
27
26 def index
28 def index
27 scope = @project.memberships.active
29 scope = @project.memberships.active
28 @offset, @limit = api_offset_and_limit
30 @offset, @limit = api_offset_and_limit
@@ -20,6 +20,9 class MyController < ApplicationController
20 # let user change user's password when user has to
20 # let user change user's password when user has to
21 skip_before_filter :check_password_change, :only => :password
21 skip_before_filter :check_password_change, :only => :password
22
22
23 require_sudo_mode :account, only: :post
24 require_sudo_mode :reset_rss_key, :reset_api_key, :show_api_key, :destroy
25
23 helper :issues
26 helper :issues
24 helper :users
27 helper :users
25 helper :custom_fields
28 helper :custom_fields
@@ -123,6 +126,10 class MyController < ApplicationController
123 redirect_to my_account_path
126 redirect_to my_account_path
124 end
127 end
125
128
129 def show_api_key
130 @user = User.current
131 end
132
126 # Create a new API key
133 # Create a new API key
127 def reset_api_key
134 def reset_api_key
128 if request.post?
135 if request.post?
@@ -25,6 +25,7 class ProjectsController < ApplicationController
25 before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
25 before_filter :require_admin, :only => [ :copy, :archive, :unarchive, :destroy ]
26 accept_rss_auth :index
26 accept_rss_auth :index
27 accept_api_auth :index, :show, :create, :update, :destroy
27 accept_api_auth :index, :show, :create, :update, :destroy
28 require_sudo_mode :destroy
28
29
29 after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
30 after_filter :only => [:create, :edit, :update, :archive, :unarchive, :destroy] do |controller|
30 if controller.request.post?
31 if controller.request.post?
@@ -23,6 +23,8 class RolesController < ApplicationController
23 before_filter :find_role, :only => [:show, :edit, :update, :destroy]
23 before_filter :find_role, :only => [:show, :edit, :update, :destroy]
24 accept_api_auth :index, :show
24 accept_api_auth :index, :show
25
25
26 require_sudo_mode :create, :update, :destroy
27
26 def index
28 def index
27 respond_to do |format|
29 respond_to do |format|
28 format.html {
30 format.html {
@@ -23,6 +23,8 class SettingsController < ApplicationController
23
23
24 before_filter :require_admin
24 before_filter :require_admin
25
25
26 require_sudo_mode :index, :edit, :plugin
27
26 def index
28 def index
27 edit
29 edit
28 render :action => 'edit'
30 render :action => 'edit'
@@ -28,6 +28,8 class UsersController < ApplicationController
28 include CustomFieldsHelper
28 include CustomFieldsHelper
29 helper :principal_memberships
29 helper :principal_memberships
30
30
31 require_sudo_mode :create, :update, :destroy
32
31 def index
33 def index
32 sort_init 'login', 'asc'
34 sort_init 'login', 'asc'
33 sort_update %w(login firstname lastname admin created_on last_login_on)
35 sort_update %w(login firstname lastname admin created_on last_login_on)
@@ -25,6 +25,7 module ApplicationHelper
25 include Redmine::I18n
25 include Redmine::I18n
26 include GravatarHelper::PublicMethods
26 include GravatarHelper::PublicMethods
27 include Redmine::Pagination::Helper
27 include Redmine::Pagination::Helper
28 include Redmine::SudoMode::Helper
28
29
29 extend Forwardable
30 extend Forwardable
30 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
31 def_delegators :wiki_helper, :wikitoolbar_for, :heads_for_wiki_formatter
@@ -21,8 +21,8
21 <% if Setting.rest_api_enabled? %>
21 <% if Setting.rest_api_enabled? %>
22 <h4><%= l(:label_api_access_key) %></h4>
22 <h4><%= l(:label_api_access_key) %></h4>
23 <div>
23 <div>
24 <%= link_to_function(l(:button_show), "$('#api-access-key').toggle();")%>
24 <%= link_to l(:button_show), {:action => 'show_api_key'}, :remote => true %>
25 <pre id='api-access-key' class='autoscroll'><%= @user.api_key %></pre>
25 <pre id='api-access-key' class='autoscroll'></pre>
26 </div>
26 </div>
27 <%= javascript_tag("$('#api-access-key').hide();") %>
27 <%= javascript_tag("$('#api-access-key').hide();") %>
28 <p>
28 <p>
@@ -163,6 +163,7 de:
163 button_close: Schließen
163 button_close: Schließen
164 button_collapse_all: Alle einklappen
164 button_collapse_all: Alle einklappen
165 button_configure: Konfigurieren
165 button_configure: Konfigurieren
166 button_confirm_password: Kennwort bestätigen
166 button_copy: Kopieren
167 button_copy: Kopieren
167 button_copy_and_follow: Kopieren und Ticket anzeigen
168 button_copy_and_follow: Kopieren und Ticket anzeigen
168 button_create: Anlegen
169 button_create: Anlegen
@@ -670,6 +671,7 de:
670 label_overview: Übersicht
671 label_overview: Übersicht
671 label_parent_revision: Vorgänger
672 label_parent_revision: Vorgänger
672 label_password_lost: Kennwort vergessen
673 label_password_lost: Kennwort vergessen
674 label_password_required: Bitte geben Sie Ihr Kennwort ein
673 label_permissions: Berechtigungen
675 label_permissions: Berechtigungen
674 label_permissions_report: Berechtigungsübersicht
676 label_permissions_report: Berechtigungsübersicht
675 label_personalize_page: Diese Seite anpassen
677 label_personalize_page: Diese Seite anpassen
@@ -554,6 +554,7 en:
554 label_register: Register
554 label_register: Register
555 label_login_with_open_id_option: or login with OpenID
555 label_login_with_open_id_option: or login with OpenID
556 label_password_lost: Lost password
556 label_password_lost: Lost password
557 label_password_required: Confirm your password to continue
557 label_home: Home
558 label_home: Home
558 label_my_page: My page
559 label_my_page: My page
559 label_my_account: My account
560 label_my_account: My account
@@ -989,6 +990,7 en:
989 button_reset: Reset
990 button_reset: Reset
990 button_rename: Rename
991 button_rename: Rename
991 button_change_password: Change password
992 button_change_password: Change password
993 button_confirm_password: Confirm password
992 button_copy: Copy
994 button_copy: Copy
993 button_copy_and_follow: Copy and follow
995 button_copy_and_follow: Copy and follow
994 button_annotate: Annotate
996 button_annotate: Annotate
@@ -67,6 +67,7 Rails.application.routes.draw do
67 match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
67 match 'my', :controller => 'my', :action => 'index', :via => :get # Redirects to my/page
68 match 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key', :via => :post
68 match 'my/reset_rss_key', :controller => 'my', :action => 'reset_rss_key', :via => :post
69 match 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key', :via => :post
69 match 'my/reset_api_key', :controller => 'my', :action => 'reset_api_key', :via => :post
70 match 'my/show_api_key', :controller => 'my', :action => 'show_api_key', :via => :get
70 match 'my/password', :controller => 'my', :action => 'password', :via => [:get, :post]
71 match 'my/password', :controller => 'my', :action => 'password', :via => [:get, :post]
71 match 'my/page_layout', :controller => 'my', :action => 'page_layout', :via => :get
72 match 'my/page_layout', :controller => 'my', :action => 'page_layout', :via => :get
72 match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
73 match 'my/add_block', :controller => 'my', :action => 'add_block', :via => :post
@@ -22,6 +22,7 class AuthSourcesControllerTest < ActionController::TestCase
22
22
23 def setup
23 def setup
24 @request.session[:user_id] = 1
24 @request.session[:user_id] = 1
25 Redmine::SudoMode.disable!
25 end
26 end
26
27
27 def test_index
28 def test_index
@@ -22,6 +22,7 class EmailAddressesControllerTest < ActionController::TestCase
22
22
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 Redmine::SudoMode.disable!
25 end
26 end
26
27
27 def test_index_with_no_additional_emails
28 def test_index_with_no_additional_emails
@@ -22,6 +22,7 class GroupsControllerTest < ActionController::TestCase
22
22
23 def setup
23 def setup
24 @request.session[:user_id] = 1
24 @request.session[:user_id] = 1
25 Redmine::SudoMode.disable!
25 end
26 end
26
27
27 def test_index
28 def test_index
@@ -23,6 +23,7 class MembersControllerTest < ActionController::TestCase
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 @request.session[:user_id] = 2
25 @request.session[:user_id] = 2
26 Redmine::SudoMode.disable!
26 end
27 end
27
28
28 def test_new
29 def test_new
@@ -23,6 +23,7 class MyControllerTest < ActionController::TestCase
23
23
24 def setup
24 def setup
25 @request.session[:user_id] = 2
25 @request.session[:user_id] = 2
26 Redmine::SudoMode.disable!
26 end
27 end
27
28
28 def test_index
29 def test_index
@@ -253,6 +254,12 class MyControllerTest < ActionController::TestCase
253 assert_redirected_to '/my/account'
254 assert_redirected_to '/my/account'
254 end
255 end
255
256
257 def test_show_api_key
258 get :show_api_key
259 assert_response :success
260 assert_select 'pre', User.find(2).api_key
261 end
262
256 def test_reset_api_key_with_existing_key
263 def test_reset_api_key_with_existing_key
257 @previous_token_value = User.find(2).api_key # Will generate one if it's missing
264 @previous_token_value = User.find(2).api_key # Will generate one if it's missing
258 post :reset_api_key
265 post :reset_api_key
@@ -28,6 +28,7 class ProjectsControllerTest < ActionController::TestCase
28 def setup
28 def setup
29 @request.session[:user_id] = nil
29 @request.session[:user_id] = nil
30 Setting.default_language = 'en'
30 Setting.default_language = 'en'
31 Redmine::SudoMode.disable!
31 end
32 end
32
33
33 def test_index_by_anonymous_should_not_show_private_projects
34 def test_index_by_anonymous_should_not_show_private_projects
@@ -23,6 +23,7 class RolesControllerTest < ActionController::TestCase
23 def setup
23 def setup
24 User.current = nil
24 User.current = nil
25 @request.session[:user_id] = 1 # admin
25 @request.session[:user_id] = 1 # admin
26 Redmine::SudoMode.disable!
26 end
27 end
27
28
28 def test_index
29 def test_index
@@ -24,6 +24,7 class SettingsControllerTest < ActionController::TestCase
24 def setup
24 def setup
25 User.current = nil
25 User.current = nil
26 @request.session[:user_id] = 1 # admin
26 @request.session[:user_id] = 1 # admin
27 Redmine::SudoMode.disable!
27 end
28 end
28
29
29 def test_index
30 def test_index
@@ -30,6 +30,7 class UsersControllerTest < ActionController::TestCase
30 def setup
30 def setup
31 User.current = nil
31 User.current = nil
32 @request.session[:user_id] = 1 # admin
32 @request.session[:user_id] = 1 # admin
33 Redmine::SudoMode.disable!
33 end
34 end
34
35
35 def test_index
36 def test_index
@@ -26,6 +26,14 class AdminTest < Redmine::IntegrationTest
26 :members,
26 :members,
27 :enabled_modules
27 :enabled_modules
28
28
29 def setup
30 Redmine::SudoMode.enable!
31 end
32
33 def teardown
34 Redmine::SudoMode.disable!
35 end
36
29 def test_add_user
37 def test_add_user
30 log_user("admin", "admin")
38 log_user("admin", "admin")
31 get "/users/new"
39 get "/users/new"
@@ -36,6 +44,15 class AdminTest < Redmine::IntegrationTest
36 :lastname => "Smith", :mail => "psmith@somenet.foo",
44 :lastname => "Smith", :mail => "psmith@somenet.foo",
37 :language => "en", :password => "psmith09",
45 :language => "en", :password => "psmith09",
38 :password_confirmation => "psmith09" }
46 :password_confirmation => "psmith09" }
47 assert_response :success
48 assert_nil User.find_by_login("psmith")
49
50 post "/users",
51 :user => { :login => "psmith", :firstname => "Paul",
52 :lastname => "Smith", :mail => "psmith@somenet.foo",
53 :language => "en", :password => "psmith09",
54 :password_confirmation => "psmith09" },
55 :sudo_password => 'admin'
39
56
40 user = User.find_by_login("psmith")
57 user = User.find_by_login("psmith")
41 assert_kind_of User, user
58 assert_kind_of User, user
General Comments 0
You need to be logged in to leave comments. Login now