Skip to content

Commit b6285b8

Browse files
committed
Add reject option to pending users page
1 parent 30caa0d commit b6285b8

7 files changed

Lines changed: 104 additions & 0 deletions

File tree

app/assets/javascripts/admin/controllers/admin_users_list_controller.js

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,24 @@ Discourse.AdminUsersListController = Ember.ArrayController.extend(Discourse.Pres
119119
approveUsers: function() {
120120
Discourse.AdminUser.bulkApprove(this.get('content').filterProperty('selected'));
121121
this.refreshUsers();
122+
},
123+
124+
/**
125+
Reject all the currently selected users.
126+
127+
@method rejectUsers
128+
**/
129+
rejectUsers: function() {
130+
var controller = this;
131+
Discourse.AdminUser.bulkReject(this.get('content').filterProperty('selected')).then(function(result){
132+
var message = I18n.t("admin.users.reject_successful", {count: result.success});
133+
if (result.failed > 0) {
134+
message += ' ' + I18n.t("admin.users.reject_failures", {count: result.failed});
135+
message += ' ' + I18n.t("admin.user.delete_forbidden", {count: Discourse.SiteSettings.delete_user_max_age});
136+
}
137+
bootbox.alert(message);
138+
controller.refreshUsers();
139+
});
122140
}
123141

124142
});

app/assets/javascripts/admin/models/admin_user.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,21 @@ Discourse.AdminUser.reopenClass({
343343
});
344344
},
345345

346+
bulkReject: function(users) {
347+
_.each(users, function(user){
348+
user.set('can_approve', false);
349+
user.set('selected', false);
350+
});
351+
352+
return Discourse.ajax("/admin/users/reject-bulk", {
353+
type: 'DELETE',
354+
data: {
355+
users: users.map(function(u) { return u.id; }),
356+
context: window.location.pathname
357+
}
358+
});
359+
},
360+
346361
find: function(username) {
347362
return Discourse.ajax("/admin/users/" + username).then(function (result) {
348363
result.loadedDetails = true;

app/assets/javascripts/admin/templates/users_list.js.handlebars

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
{{#if hasSelection}}
2121
<div id='selected-controls'>
2222
<button {{action approveUsers}} class='btn'>{{countI18n admin.users.approved_selected countBinding="selectedCount"}}</button>
23+
<button {{action rejectUsers}} class='btn btn-danger'>{{countI18n admin.users.reject_selected countBinding="selectedCount"}}</button>
2324
</div>
2425
{{/if}}
2526

app/controllers/admin/users_controller.rb

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,15 @@ def unblock
114114
render nothing: true
115115
end
116116

117+
def reject_bulk
118+
d = UserDestroyer.new(current_user)
119+
success_count = 0
120+
User.where(id: params[:users]).each do |u|
121+
success_count += 1 if guardian.can_delete_user?(u) and d.destroy(u, params.slice(:context)) rescue UserDestroyer::PostsExistError
122+
end
123+
render json: {success: success_count, failed: (params[:users].try(:size) || 0) - success_count}
124+
end
125+
117126
def destroy
118127
user = User.where(id: params[:id]).first
119128
guardian.ensure_can_delete_user!(user)

config/locales/client.en.yml

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,6 +1233,9 @@ en:
12331233
approved_selected:
12341234
one: "approve user"
12351235
other: "approve users ({{count}})"
1236+
reject_selected:
1237+
one: "reject user"
1238+
other: "reject users ({{count}})"
12361239
titles:
12371240
active: 'Active Users'
12381241
new: 'New Users'
@@ -1246,6 +1249,12 @@ en:
12461249
moderators: 'Moderators'
12471250
blocked: 'Blocked Users'
12481251
banned: 'Banned Users'
1252+
reject_successful:
1253+
one: "Successfully rejected 1 user."
1254+
other: "Successfully rejected %{count} users."
1255+
reject_failures:
1256+
one: "Failed to reject 1 user."
1257+
other: "Failed to reject %{count} users."
12491258

12501259
user:
12511260
ban_failed: "Something went wrong banning this user {{error}}"

config/routes.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
collection do
3737
get 'list/:query' => 'users#index'
3838
put 'approve-bulk' => 'users#approve_bulk'
39+
delete 'reject-bulk' => 'users#reject_bulk'
3940
end
4041
put 'ban'
4142
put 'delete_all_posts'

spec/controllers/admin/users_controller_spec.rb

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,57 @@
196196
end
197197
end
198198

199+
context '.reject_bulk' do
200+
let(:reject_me) { Fabricate(:user) }
201+
let(:reject_me_too) { Fabricate(:user) }
202+
203+
it 'does nothing without users' do
204+
UserDestroyer.any_instance.expects(:destroy).never
205+
xhr :delete, :reject_bulk
206+
end
207+
208+
it "won't delete users if not allowed" do
209+
Guardian.any_instance.stubs(:can_delete_user?).returns(false)
210+
UserDestroyer.any_instance.expects(:destroy).never
211+
xhr :delete, :reject_bulk, users: [reject_me.id]
212+
end
213+
214+
it "reports successes" do
215+
Guardian.any_instance.stubs(:can_delete_user?).returns(true)
216+
UserDestroyer.any_instance.stubs(:destroy).returns(true)
217+
xhr :delete, :reject_bulk, users: [reject_me.id, reject_me_too.id]
218+
response.should be_success
219+
json = ::JSON.parse(response.body)
220+
json['success'].to_i.should == 2
221+
json['failed'].to_i.should == 0
222+
end
223+
224+
context 'failures' do
225+
before do
226+
Guardian.any_instance.stubs(:can_delete_user?).returns(true)
227+
end
228+
229+
it 'can handle some successes and some failures' do
230+
UserDestroyer.any_instance.stubs(:destroy).with(reject_me, anything).returns(false)
231+
UserDestroyer.any_instance.stubs(:destroy).with(reject_me_too, anything).returns(true)
232+
xhr :delete, :reject_bulk, users: [reject_me.id, reject_me_too.id]
233+
response.should be_success
234+
json = ::JSON.parse(response.body)
235+
json['success'].to_i.should == 1
236+
json['failed'].to_i.should == 1
237+
end
238+
239+
it 'reports failure due to a user still having posts' do
240+
UserDestroyer.any_instance.expects(:destroy).with(reject_me, anything).raises(UserDestroyer::PostsExistError)
241+
xhr :delete, :reject_bulk, users: [reject_me.id]
242+
response.should be_success
243+
json = ::JSON.parse(response.body)
244+
json['success'].to_i.should == 0
245+
json['failed'].to_i.should == 1
246+
end
247+
end
248+
end
249+
199250
context '.destroy' do
200251
before do
201252
@delete_me = Fabricate(:user)

0 commit comments

Comments
 (0)