diff --git a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars index 0a614262a..f9bb83eae 100644 --- a/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/preferences.js.handlebars @@ -27,7 +27,9 @@
{{email}} - {{#linkTo "preferences.email" class="btn pad-left"}}{{/linkTo}} + {{#if can_edit_email}} + {{#linkTo "preferences.email" class="btn pad-left"}}{{/linkTo}} + {{/if}}
{{i18n user.email.instructions}} diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index 020232a7b..6b839dd4d 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -205,7 +205,7 @@ class UsersController < ApplicationController def change_email params.require(:email) user = fetch_user_from_params - guardian.ensure_can_edit!(user) + guardian.ensure_can_edit_email!(user) lower_email = Email.downcase(params[:email]).strip # Raise an error if the email is already in use diff --git a/app/models/site_setting.rb b/app/models/site_setting.rb index 19591ff06..9bf4e63d0 100644 --- a/app/models/site_setting.rb +++ b/app/models/site_setting.rb @@ -251,6 +251,7 @@ class SiteSetting < ActiveRecord::Base setting(:delete_all_posts_max, 10) setting(:username_change_period, 3) # days + setting(:email_editable, true) client_setting(:allow_uploaded_avatars, true) client_setting(:allow_animated_avatars, false) diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index f76744822..3f9f85182 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -10,6 +10,7 @@ class UserSerializer < BasicUserSerializer :website, :can_edit, :can_edit_username, + :can_edit_email, :stats, :can_send_private_message_to_user, :bio_excerpt, @@ -78,6 +79,10 @@ class UserSerializer < BasicUserSerializer scope.can_edit_username?(object) end + def can_edit_email + scope.can_edit_email?(object) + end + def stats UserAction.stats(object.id, scope) end diff --git a/config/locales/server.en.yml b/config/locales/server.en.yml index b05adac77..ff79017f8 100644 --- a/config/locales/server.en.yml +++ b/config/locales/server.en.yml @@ -684,7 +684,8 @@ en: relative_date_duration: "Number of days after posting where post dates will be shown as relative instead of absolute. Examples: relative date: 7d, absolute date: 20 Feb" delete_user_max_age: "The maximum age of a user, in days, which can be deleted by an admin." delete_all_posts_max: "The maximum number of posts that can be deleted at once with the Delete All Posts button. If a user has more than this many posts, the posts cannot all be deleted at once and the user can't be deleted." - username_change_period: "The number of days after registration that accounts can change their username." + username_change_period: "The number of days after registration that accounts can change their username (0 to disallow username change)." + email_editable: "Allow users to change their e-mail address after registration." allow_uploaded_avatars: "Allow users to upload their custom avatars" allow_animated_avatars: "Allow users to use animated gif for avatars. WARNING: it is highly recommended to run the avatars:regenerate rake task after changing that setting." diff --git a/lib/guardian.rb b/lib/guardian.rb index 11b4b5626..6cc15b1c7 100644 --- a/lib/guardian.rb +++ b/lib/guardian.rb @@ -285,7 +285,15 @@ class Guardian end def can_edit_username?(user) - is_staff? || (is_me?(user) && (user.post_count == 0 || user.created_at > SiteSetting.username_change_period.days.ago)) + return true if is_staff? + return false if SiteSetting.username_change_period <= 0 + is_me?(user) && (user.post_count == 0 || user.created_at > SiteSetting.username_change_period.days.ago) + end + + def can_edit_email?(user) + return true if is_staff? + return false unless SiteSetting.email_editable? + can_edit?(user) end # Deleting Methods diff --git a/spec/components/guardian_spec.rb b/spec/components/guardian_spec.rb index ad8d1d0ec..065035569 100644 --- a/spec/components/guardian_spec.rb +++ b/spec/components/guardian_spec.rb @@ -1195,6 +1195,72 @@ describe Guardian do end end end + + context 'when editing is disabled in preferences' do + before do + SiteSetting.stubs(:username_change_period).returns(0) + end + + include_examples "staff can always change usernames" + + it "is false for the user to change his own username" do + Guardian.new(user).can_edit_username?(user).should be_false + end + end + end + + describe "can_edit_email?" do + context 'when allowed in settings' do + before do + SiteSetting.stubs(:email_editable?).returns(true) + end + + it "is false when not logged in" do + Guardian.new(nil).can_edit_email?(build(:user, created_at: 1.minute.ago)).should be_false + end + + it "is false for regular users to edit another user's email" do + Guardian.new(build(:user)).can_edit_email?(build(:user, created_at: 1.minute.ago)).should be_false + end + + it "is true for a regular user to edit his own email" do + Guardian.new(user).can_edit_email?(user).should be_true + end + + it "is true for moderators" do + Guardian.new(moderator).can_edit_email?(user).should be_true + end + + it "is true for admins" do + Guardian.new(admin).can_edit_email?(user).should be_true + end + end + + context 'when not allowed in settings' do + before do + SiteSetting.stubs(:email_editable?).returns(false) + end + + it "is false when not logged in" do + Guardian.new(nil).can_edit_email?(build(:user, created_at: 1.minute.ago)).should be_false + end + + it "is false for regular users to edit another user's email" do + Guardian.new(build(:user)).can_edit_email?(build(:user, created_at: 1.minute.ago)).should be_false + end + + it "is false for a regular user to edit his own email" do + Guardian.new(user).can_edit_email?(user).should be_false + end + + it "is true for admins" do + Guardian.new(admin).can_edit_email?(user).should be_true + end + + it "is true for moderators" do + Guardian.new(moderator).can_edit_email?(user).should be_true + end + end end end diff --git a/spec/controllers/users_controller_spec.rb b/spec/controllers/users_controller_spec.rb index 5d1494dfc..e308c2bbd 100644 --- a/spec/controllers/users_controller_spec.rb +++ b/spec/controllers/users_controller_spec.rb @@ -181,8 +181,8 @@ describe UsersController do lambda { xhr :put, :change_email, username: user.username }.should raise_error(ActionController::ParameterMissing) end - it "raises an error if you can't edit the user" do - Guardian.any_instance.expects(:can_edit?).with(user).returns(false) + it "raises an error if you can't edit the user's email" do + Guardian.any_instance.expects(:can_edit_email?).with(user).returns(false) xhr :put, :change_email, username: user.username, email: new_email response.should be_forbidden end