From 16cd3e2a53f0ba1f5d2a1d6bcbb87c1cb22187d1 Mon Sep 17 00:00:00 2001
From: Neil Lalonde <neillalonde@gmail.com>
Date: Tue, 30 Jul 2013 14:13:56 -0400
Subject: [PATCH] Fix to allow admins to change the case of a someone's
 username

---
 .../controllers/preferences_username_controller.js       | 2 +-
 app/assets/javascripts/discourse/models/user.js          | 4 ++--
 app/controllers/users_controller.rb                      | 8 +++++---
 spec/controllers/users_controller_spec.rb                | 9 +++++++++
 4 files changed, 17 insertions(+), 6 deletions(-)

diff --git a/app/assets/javascripts/discourse/controllers/preferences_username_controller.js b/app/assets/javascripts/discourse/controllers/preferences_username_controller.js
index e011feeb0..7fc6cebca 100644
--- a/app/assets/javascripts/discourse/controllers/preferences_username_controller.js
+++ b/app/assets/javascripts/discourse/controllers/preferences_username_controller.js
@@ -26,7 +26,7 @@ Discourse.PreferencesUsernameController = Discourse.ObjectController.extend({
       this.set('errorMessage', null);
       if (this.blank('newUsername')) return;
       if (this.get('unchanged')) return;
-      Discourse.User.checkUsername(this.get('newUsername')).then(function(result) {
+      Discourse.User.checkUsername(this.get('newUsername'), undefined, this.get('content.id')).then(function(result) {
         if (result.errors) {
           preferencesUsernameController.set('errorMessage', result.errors.join(' '));
         } else if (result.available === false) {
diff --git a/app/assets/javascripts/discourse/models/user.js b/app/assets/javascripts/discourse/models/user.js
index 65570c0f5..646403805 100644
--- a/app/assets/javascripts/discourse/models/user.js
+++ b/app/assets/javascripts/discourse/models/user.js
@@ -331,9 +331,9 @@ Discourse.User.reopenClass({
     @param {String} username A username to check
     @param {String} email An email address to check
   **/
-  checkUsername: function(username, email) {
+  checkUsername: function(username, email, forUserId) {
     return Discourse.ajax('/users/check_username', {
-      data: { username: username, email: email }
+      data: { username: username, email: email, for_user_id: forUserId }
     });
   },
 
diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb
index 168ab564b..54d091a6c 100644
--- a/app/controllers/users_controller.rb
+++ b/app/controllers/users_controller.rb
@@ -102,8 +102,10 @@ class UsersController < ApplicationController
   def check_username
     params.require(:username)
 
+    target_user = params[:for_user_id] ? User.find(params[:for_user_id]) : current_user
+
     # The special case where someone is changing the case of their own username
-    return render(json: {available: true}) if current_user and params[:username].downcase == current_user.username.downcase
+    return render(json: {available: true}) if target_user and params[:username].downcase == target_user.username.downcase
 
     validator = UsernameValidator.new(params[:username])
     if !validator.valid_format?
@@ -117,12 +119,12 @@ class UsersController < ApplicationController
     else
 
       # Contact the Discourse Hub server
-      email_given = (params[:email].present? || current_user.present?)
+      email_given = (params[:email].present? || target_user.present?)
       available_locally = User.username_available?(params[:username])
       global_match = false
       available_globally, suggestion_from_discourse_hub = begin
         if email_given
-          global_match, available, suggestion = DiscourseHub.nickname_match?( params[:username], params[:email] || current_user.email )
+          global_match, available, suggestion = DiscourseHub.nickname_match?( params[:username], params[:email] || target_user.email )
           [available || global_match, suggestion]
         else
           DiscourseHub.nickname_available?(params[:username])
diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb
index 463885bed..7255e6211 100644
--- a/spec/controllers/users_controller_spec.rb
+++ b/spec/controllers/users_controller_spec.rb
@@ -802,6 +802,15 @@ describe UsersController do
         end
         include_examples 'when username is unavailable locally'
       end
+
+      context "an admin changing it for someone else" do
+        let!(:user) { Fabricate(:user, username: 'hansolo') }
+        before do
+          log_in_user(Fabricate(:admin))
+          xhr :get, :check_username, username: 'HanSolo', for_user_id: user.id
+        end
+        include_examples 'when username is available everywhere'
+      end
     end
   end