Project

General

Profile

Patch #43640 » 0003-Implement-explicit-confirmation-when-removing-user-s.patch

Marius BĂLTEANU, 2026-05-12 22:45

View differences:

app/controllers/groups_controller.rb
130 130
  end
131 131

  
132 132
  def remove_users
133
    @users = User.where(:id => (params[:user_id] || params[:user_ids])).to_a
134
    @group.users.delete(@users) if request.delete?
135
    respond_to do |format|
136
      format.html {redirect_back_or_default edit_group_path(@group, :tab => 'users')}
137
      format.js
138
      format.api {render_api_ok}
133
    @users = @group.users.where(:id => (params[:user_id] || params[:user_ids])).to_a
134

  
135
    if @users.empty?
136
      render_404
137
      return
138
    end
139

  
140
    if request.delete? && (api_request? || params[:confirm] == I18n.t(:general_text_Yes))
141
      @group.users.delete(@users)
142
      respond_to do |format|
143
        format.html do
144
          flash[:notice] = l(:notice_successful_delete)
145
          redirect_back_or_default edit_group_path(@group, :tab => 'users')
146
        end
147
        format.api {render_api_ok}
148
      end
139 149
    end
140 150
  end
141 151

  
app/views/groups/_users.html.erb
11 11
      <tr id="user-<%= user.id %>">
12 12
        <td class="name"><%= link_to_user user %></td>
13 13
        <td class="buttons">
14
          <%= remove_link group_users_path(@group, :user_id => user), :remote => true %>
14
          <%= link_to sprite_icon('link-break', l(:button_remove)), group_users_path(@group, :user_id => user), :method => :delete, :class => 'icon icon-link-break' %>
15 15
        </td>
16 16
      </tr>
17 17
    <% end %>
app/views/groups/remove_users.erb
1
<%= title l(:label_confirmation) %>
2

  
3
<%= form_tag(group_users_path(@group, :user_ids => @users.map(&:id)), method: :delete) do %>
4
  <div class="warning">
5
    <p><%= simple_format l :text_users_remove_from_group_confirmation, group: "<strong>#{@group.name}</strong>".html_safe %></p>
6

  
7
    <% @users.each do |user| %>
8
      <p><strong><%= user.name %></strong> (<%= user.login %>)</p>
9
    <% end %>
10

  
11
    <p><%= l :text_users_bulk_destroy_confirm, yes: l(:general_text_Yes) %></p>
12
    <p><%= text_field_tag 'confirm' %></p>
13

  
14
  </div>
15

  
16
  <p>
17
    <%= submit_tag l(:button_delete) %>
18
    <%= link_to l(:button_cancel), @back_url || users_path %>
19
  </p>
20
<% end %>
app/views/groups/remove_users.js.erb
1
$('#tab-content-users').html('<%= escape_javascript(render :partial => 'groups/users') %>');
config/locales/en.yml
1478 1478
  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."
1479 1479
  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."
1480 1480
  text_user_destroy_confirmation: "Are you sure you want to delete this user and remove all references to them? This cannot be undone. Often, locking a user instead of deleting them is the better solution. To confirm, please enter their login (%{login}) below."
1481
  text_users_remove_from_group_confirmation: "You are about to remove the following user(s) from group %{group}."
1481 1482
  text_project_destroy_enter_identifier: "To confirm, please enter the project's identifier (%{identifier}) below."
1482 1483
  field_name_or_email_or_login: Name, email or login
1483 1484
  setting_wiki_tablesort_enabled: JavaScript based table sorting in wiki content
test/functional/groups_controller_test.rb
255 255
        :remove_users,
256 256
        :params => {
257 257
          :id => 10,
258
          :user_id => '8'
258
          :user_id => '8',
259
          :confirm => I18n.t(:general_text_Yes)
259 260
        }
260 261
      )
261 262
    end
262 263
  end
263 264

  
264
  def test_remove_users_plural
265
    group = Group.find(10)
266
    group.users << User.find(2)
267
    assert_difference 'group.users.count', -2 do
265
  def test_remove_users_without_confirmation
266
    assert_no_difference 'Group.find(10).users.count' do
268 267
      delete(
269 268
        :remove_users,
270 269
        :params => {
271 270
          :id => 10,
272
          :user_ids => ['2', '8']
271
          :user_id => '8'
273 272
        }
274 273
      )
275 274
    end
275
    assert_response :success
276
    assert_select 'input[name=confirm]'
276 277
  end
277 278

  
278
  def test_xhr_remove_users
279
    assert_difference 'Group.find(10).users.count', -1 do
279
  def test_remove_users_plural
280
    group = Group.find(10)
281
    group.users << User.find(2)
282
    assert_difference 'group.users.count', -2 do
280 283
      delete(
281 284
        :remove_users,
282 285
        :params => {
283 286
          :id => 10,
284
          :user_id => '8'
285
        },
286
        :xhr => true
287
          :user_ids => ['2', '8'],
288
          :confirm => I18n.t(:general_text_Yes)
289
        }
287 290
      )
288
      assert_response :success
289
      assert_equal 'text/javascript', response.media_type
290 291
    end
291 292
  end
292 293

  
294
  def test_remove_users_should_only_include_group_members
295
    assert !Group.find(10).users.include?(User.find(3))
296

  
297
    get(
298
      :remove_users,
299
      :params => {
300
        :id => 10,
301
        :user_ids => ['3', '8']
302
      }
303
    )
304
    assert_response :success
305
    assert_select 'input[name=confirm]'
306
    # Should show user 8 but not user 3
307
    assert_select 'p strong', :text => 'User Misc'
308
    assert_select 'p strong', :text => 'Dave Lopper', :count => 0
309
  end
310

  
293 311
  def test_remove_user_should_be_deprecated
294 312
    Rails.application.deprecators[:redmine].expects(:warn).with(regexp_matches(/GroupsController#remove_user is deprecated/))
295 313
    delete(
(14-14/16)