mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -05:00
FEATURE: Log username changes by staff
Also fix the tests for changing username
This commit is contained in:
parent
18215f90d0
commit
1ab0d6bd82
6 changed files with 59 additions and 10 deletions
|
@ -88,7 +88,8 @@ class UsersController < ApplicationController
|
||||||
user = fetch_user_from_params
|
user = fetch_user_from_params
|
||||||
guardian.ensure_can_edit_username!(user)
|
guardian.ensure_can_edit_username!(user)
|
||||||
|
|
||||||
result = user.change_username(params[:new_username])
|
# TODO proper error surfacing (result is a Model#save call)
|
||||||
|
result = user.change_username(params[:new_username], current_user)
|
||||||
raise Discourse::InvalidParameters.new(:new_username) unless result
|
raise Discourse::InvalidParameters.new(:new_username) unless result
|
||||||
|
|
||||||
render json: {
|
render json: {
|
||||||
|
|
|
@ -185,7 +185,11 @@ class User < ActiveRecord::Base
|
||||||
Jobs.enqueue(:send_system_message, user_id: id, message_type: message_type)
|
Jobs.enqueue(:send_system_message, user_id: id, message_type: message_type)
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_username(new_username)
|
def change_username(new_username, actor=nil)
|
||||||
|
if actor && actor != self
|
||||||
|
StaffActionLogger.new(actor).log_username_change(self, self.username, new_username)
|
||||||
|
end
|
||||||
|
|
||||||
self.username = new_username
|
self.username = new_username
|
||||||
save
|
save
|
||||||
end
|
end
|
||||||
|
|
|
@ -34,7 +34,8 @@ class UserHistory < ActiveRecord::Base
|
||||||
:delete_post,
|
:delete_post,
|
||||||
:delete_topic,
|
:delete_topic,
|
||||||
:impersonate,
|
:impersonate,
|
||||||
:roll_up)
|
:roll_up,
|
||||||
|
:change_username)
|
||||||
end
|
end
|
||||||
|
|
||||||
# Staff actions is a subset of all actions, used to audit actions taken by staff users.
|
# Staff actions is a subset of all actions, used to audit actions taken by staff users.
|
||||||
|
@ -52,7 +53,8 @@ class UserHistory < ActiveRecord::Base
|
||||||
:delete_post,
|
:delete_post,
|
||||||
:delete_topic,
|
:delete_topic,
|
||||||
:impersonate,
|
:impersonate,
|
||||||
:roll_up]
|
:roll_up,
|
||||||
|
:change_username]
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.staff_action_ids
|
def self.staff_action_ids
|
||||||
|
|
|
@ -100,6 +100,16 @@ class StaffActionLogger
|
||||||
}))
|
}))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def log_username_change(user, old_username, new_username, opts={})
|
||||||
|
raise Discourse::InvalidParameters.new('user is nil') unless user
|
||||||
|
UserHistory.create( params(opts).merge({
|
||||||
|
action: UserHistory.actions[:change_username],
|
||||||
|
target_user_id: user.id,
|
||||||
|
previous_value: old_username,
|
||||||
|
new_value: new_username
|
||||||
|
}))
|
||||||
|
end
|
||||||
|
|
||||||
def log_user_suspend(user, reason, opts={})
|
def log_user_suspend(user, reason, opts={})
|
||||||
raise Discourse::InvalidParameters.new('user is nil') unless user
|
raise Discourse::InvalidParameters.new('user is nil') unless user
|
||||||
UserHistory.create( params(opts).merge({
|
UserHistory.create( params(opts).merge({
|
||||||
|
|
|
@ -1863,6 +1863,7 @@ en:
|
||||||
actions:
|
actions:
|
||||||
delete_user: "delete user"
|
delete_user: "delete user"
|
||||||
change_trust_level: "change trust level"
|
change_trust_level: "change trust level"
|
||||||
|
change_username: "change username"
|
||||||
change_site_setting: "change site setting"
|
change_site_setting: "change site setting"
|
||||||
change_site_customization: "change site customization"
|
change_site_customization: "change site customization"
|
||||||
delete_site_customization: "delete site customization"
|
delete_site_customization: "delete site customization"
|
||||||
|
|
|
@ -612,28 +612,59 @@ describe UsersController do
|
||||||
end
|
end
|
||||||
|
|
||||||
context 'while logged in' do
|
context 'while logged in' do
|
||||||
let!(:user) { log_in }
|
let(:old_username) { "OrigUsrname" }
|
||||||
let(:new_username) { "#{user.username}1234" }
|
let(:new_username) { "#{old_username}1234" }
|
||||||
|
let(:user) { Fabricate(:user, username: old_username) }
|
||||||
|
|
||||||
|
before do
|
||||||
|
user.username = old_username
|
||||||
|
log_in_user(user)
|
||||||
|
end
|
||||||
|
|
||||||
it 'raises an error without a new_username param' do
|
it 'raises an error without a new_username param' do
|
||||||
expect { xhr :put, :username, username: user.username }.to raise_error(ActionController::ParameterMissing)
|
expect { xhr :put, :username, username: user.username }.to raise_error(ActionController::ParameterMissing)
|
||||||
|
user.reload.username.should == old_username
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an error when you don\'t have permission to change the username' do
|
it 'raises an error when you don\'t have permission to change the username' do
|
||||||
Guardian.any_instance.expects(:can_edit_username?).with(user).returns(false)
|
Guardian.any_instance.expects(:can_edit_username?).with(user).returns(false)
|
||||||
xhr :put, :username, username: user.username, new_username: new_username
|
xhr :put, :username, username: user.username, new_username: new_username
|
||||||
expect(response).to be_forbidden
|
expect(response).to be_forbidden
|
||||||
|
user.reload.username.should == old_username
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Bad behavior, this should give a real JSON error, not an InvalidParameters
|
||||||
it 'raises an error when change_username fails' do
|
it 'raises an error when change_username fails' do
|
||||||
User.any_instance.expects(:change_username).with(new_username).returns(false)
|
User.any_instance.expects(:save).returns(false)
|
||||||
expect { xhr :put, :username, username: user.username, new_username: new_username }.to raise_error(Discourse::InvalidParameters)
|
expect { xhr :put, :username, username: user.username, new_username: new_username }.to raise_error(Discourse::InvalidParameters)
|
||||||
|
user.reload.username.should == old_username
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should succeed when the change_username returns true' do
|
it 'should succeed in normal circumstances' do
|
||||||
User.any_instance.expects(:change_username).with(new_username).returns(true)
|
|
||||||
xhr :put, :username, username: user.username, new_username: new_username
|
xhr :put, :username, username: user.username, new_username: new_username
|
||||||
expect(response).to be_success
|
response.should be_success
|
||||||
|
user.reload.username.should == new_username
|
||||||
|
end
|
||||||
|
|
||||||
|
pending 'should fail if the user is old', 'ensure_can_edit_username! is not throwing' do
|
||||||
|
# Older than the change period and >1 post
|
||||||
|
user.created_at = Time.now - (SiteSetting.username_change_period + 1).days
|
||||||
|
user.stubs(:post_count).returns(200)
|
||||||
|
Guardian.new(user).can_edit_username?(user).should == false
|
||||||
|
|
||||||
|
xhr :put, :username, username: user.username, new_username: new_username
|
||||||
|
|
||||||
|
response.should be_forbidden
|
||||||
|
user.reload.username.should == old_username
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should create a staff action log when a staff member changes the username' do
|
||||||
|
acting_user = Fabricate(:admin)
|
||||||
|
log_in_user(acting_user)
|
||||||
|
xhr :put, :username, username: user.username, new_username: new_username
|
||||||
|
response.should be_success
|
||||||
|
UserHistory.where(action: UserHistory.actions[:change_username], target_user_id: user.id, acting_user_id: acting_user.id).should be_present
|
||||||
|
user.reload.username.should == new_username
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should return a JSON response with the updated username' do
|
it 'should return a JSON response with the updated username' do
|
||||||
|
|
Loading…
Reference in a new issue