diff --git a/app/models/user.rb b/app/models/user.rb index a70b21973..1e87cadaf 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -73,7 +73,7 @@ class User < ActiveRecord::Base validates_presence_of :username validate :username_validator, if: :username_changed? validates :email, presence: true, uniqueness: true - validates :email, email: true, if: Proc.new { |u| !u.staged && u.email_changed? } + validates :email, email: true, if: :should_validate_email? validate :password_validator validates :name, user_full_name: true, if: :name_changed? validates :ip_address, allowed_ip_address: {on: :create, message: :signup_not_allowed} @@ -102,6 +102,9 @@ class User < ActiveRecord::Base TopicViewItem.delete_all(user_id: self.id) end + # Skip validating email, for example from a particular auth provider plugin + attr_accessor :skip_email_validation + # Whether we need to be sending a system message after creation attr_accessor :send_welcome_message @@ -247,6 +250,10 @@ class User < ActiveRecord::Base used_invite.try(:invited_by) end + def should_validate_email? + return !skip_email_validation && !staged? && email_changed? + end + # Approve this user def approve(approved_by, send_mail=true) self.approved = true diff --git a/app/services/user_authenticator.rb b/app/services/user_authenticator.rb index dd27dbcd1..4019fefea 100644 --- a/app/services/user_authenticator.rb +++ b/app/services/user_authenticator.rb @@ -12,6 +12,8 @@ class UserAuthenticator else @user.password_required! end + + @user.skip_email_validation = true if @session && @session[:skip_email_validation].present? end def has_authenticator? diff --git a/lib/auth/result.rb b/lib/auth/result.rb index 3c78b2cf5..eabc69999 100644 --- a/lib/auth/result.rb +++ b/lib/auth/result.rb @@ -3,7 +3,8 @@ class Auth::Result :email_valid, :extra_data, :awaiting_activation, :awaiting_approval, :authenticated, :authenticator_name, :requires_invite, :not_allowed_from_ip_address, - :admin_not_allowed_from_ip_address, :omit_username + :admin_not_allowed_from_ip_address, :omit_username, + :skip_email_validation attr_accessor :failed, :failed_reason @@ -23,7 +24,8 @@ class Auth::Result omit_username: omit_username, name: name, authenticator_name: authenticator_name, - extra_data: extra_data } + extra_data: extra_data, + skip_email_validation: !!skip_email_validation } end def to_client_hash diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 419f77113..2eae85e49 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -477,6 +477,13 @@ describe User do expect(Fabricate.build(:user, email: 'notgood@sub.domain.com')).not_to be_valid end + it 'skips the blacklist if skip_email_validation is set' do + SiteSetting.email_domains_blacklist = 'domain.com' + user = Fabricate.build(:user, email: 'notgood@sub.domain.com') + user.skip_email_validation = true + expect(user).to be_valid + end + it 'blacklist should not reject developer emails' do Rails.configuration.stubs(:developer_emails).returns('developer@discourse.org') SiteSetting.email_domains_blacklist = 'discourse.org'