diff --git a/app/controllers/users_controller.rb b/app/controllers/users_controller.rb index a0dcfd5aee4..1e111af4783 100644 --- a/app/controllers/users_controller.rb +++ b/app/controllers/users_controller.rb @@ -312,8 +312,6 @@ class UsersController < ApplicationController params[:for_user_id] ? User.find(params[:for_user_id]) : current_user end - FROM_STAGED = "from_staged".freeze - def create params.require(:email) params.permit(:user_fields) @@ -334,14 +332,9 @@ class UsersController < ApplicationController return fail_with("login.reserved_username") end - if user = User.where(staged: true).with_email(params[:email].strip.downcase).first - user_params.each { |k, v| user.send("#{k}=", v) } - user.staged = false - user.active = false - user.custom_fields[FROM_STAGED] = true - else - user = User.new(user_params) - end + new_user_params = user_params + user = User.unstage(new_user_params) + user = User.new(new_user_params) if user.nil? # Handle API approval if user.approved @@ -602,7 +595,7 @@ class UsersController < ApplicationController if user = User.where(id: session_user_id.to_i).first @account_created[:username] = user.username @account_created[:email] = user.email - @account_created[:show_controls] = !user.custom_fields[FROM_STAGED] + @account_created[:show_controls] = !user.from_staged? end end @@ -656,11 +649,7 @@ class UsersController < ApplicationController @user = User.where(id: user_key.to_i).first end - if @user.blank? || @user.active? || current_user.present? - raise Discourse::InvalidAccess.new - end - - if @user.custom_fields[FROM_STAGED] + if @user.blank? || @user.active? || current_user.present? || @user.from_staged? raise Discourse::InvalidAccess.new end diff --git a/app/models/invite.rb b/app/models/invite.rb index b9fcb44e247..5a57084a076 100644 --- a/app/models/invite.rb +++ b/app/models/invite.rb @@ -32,7 +32,7 @@ class Invite < ActiveRecord::Base def user_doesnt_already_exist @email_already_exists = false return if email.blank? - user = User.find_by_email(email) + user = Invite.find_user_by_email(email) if user && user.id != self.user_id @email_already_exists = true @@ -102,7 +102,7 @@ class Invite < ActiveRecord::Base custom_message = opts[:custom_message] lower_email = Email.downcase(email) - if user = User.find_by_email(lower_email) + if user = find_user_by_email(lower_email) extend_permissions(topic, user, invited_by) if topic raise UserExists.new I18n.t("invite.user_exists", email: lower_email, username: user.username) end @@ -150,6 +150,10 @@ class Invite < ActiveRecord::Base invite end + def self.find_user_by_email(email) + User.with_email(email).where(staged: false).first + end + def self.get_group_ids(group_names) group_ids = [] if group_names diff --git a/app/models/invite_redeemer.rb b/app/models/invite_redeemer.rb index 37a37a978c4..157e28b5ad1 100644 --- a/app/models/invite_redeemer.rb +++ b/app/models/invite_redeemer.rb @@ -26,7 +26,16 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password, :user_custom_f end available_name = name || available_username - user = User.new(email: invite.email, username: available_username, name: available_name, active: true, trust_level: SiteSetting.default_invitee_trust_level) + user_params = { + email: invite.email, + username: available_username, + name: available_name, + active: true, + trust_level: SiteSetting.default_invitee_trust_level + } + + user = User.unstage(user_params) + user = User.new(user_params) if user.nil? if !SiteSetting.must_approve_users? || (SiteSetting.must_approve_users? && invite.invited_by.staff?) user.approved = true @@ -91,7 +100,7 @@ InviteRedeemer = Struct.new(:invite, :username, :name, :password, :user_custom_f end def get_existing_user - User.where(admin: false).find_by_email(invite.email) + User.where(admin: false, staged: false).find_by_email(invite.email) end def add_to_private_topics_if_invited diff --git a/app/models/user.rb b/app/models/user.rb index 28dc1e85522..39344eb28f9 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -218,6 +218,7 @@ class User < ActiveRecord::Base end EMAIL = %r{([^@]+)@([^\.]+)} + FROM_STAGED = "from_staged".freeze def self.new_from_params(params) user = User.new @@ -228,6 +229,16 @@ class User < ActiveRecord::Base user end + def self.unstage(params) + if user = User.where(staged: true).with_email(params[:email].strip.downcase).first + params.each { |k, v| user.send("#{k}=", v) } + user.staged = false + user.active = false + user.custom_fields[FROM_STAGED] = true + end + user + end + def self.suggest_name(email) return "" if email.blank? email[/\A[^@]+/].tr(".", " ").titleize @@ -987,6 +998,10 @@ class User < ActiveRecord::Base self.user_stat&.time_read end + def from_staged? + custom_fields[User::FROM_STAGED] + end + protected def badge_grant diff --git a/spec/models/invite_redeemer_spec.rb b/spec/models/invite_redeemer_spec.rb index 49b800daa22..f71f9de29b7 100644 --- a/spec/models/invite_redeemer_spec.rb +++ b/spec/models/invite_redeemer_spec.rb @@ -30,6 +30,18 @@ describe InviteRedeemer do expect(error).to be_present expect(error.record.errors[:password]).to be_present end + + it "should unstage user" do + staged_user = Fabricate(:staged, email: 'staged@account.com', active: true, username: 'staged1', name: 'Stage Name') + user = InviteRedeemer.create_user_from_invite(Fabricate(:invite, email: 'staged@account.com'), 'walter', 'Walter White') + + expect(user.id).to eq(staged_user.id) + expect(user.username).to eq('walter') + expect(user.name).to eq('Walter White') + expect(user.active).to eq(false) + expect(user.email).to eq('staged@account.com') + expect(user.approved).to eq(true) + end end describe "#redeem" do diff --git a/spec/models/invite_spec.rb b/spec/models/invite_spec.rb index 552a953194f..c72ef714ed2 100644 --- a/spec/models/invite_spec.rb +++ b/spec/models/invite_spec.rb @@ -178,6 +178,16 @@ describe Invite do end + context 'a staged user' do + it 'creates an invite for a staged user' do + Fabricate(:staged, email: 'staged@account.com') + invite = Invite.invite_by_email('staged@account.com', Fabricate(:coding_horror)) + + expect(invite).to be_valid + expect(invite.email).to eq('staged@account.com') + end + end + context '.redeem' do let(:invite) { Fabricate(:invite) } diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 621dd964249..a0bcda79d8f 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1580,4 +1580,24 @@ describe User do end end + describe "#unstage" do + it "correctyl unstages a user" do + staged_user = Fabricate(:staged, email: 'staged@account.com', active: true, username: 'staged1', name: 'Stage Name') + params = { email: 'staged@account.com', active: true, username: 'unstaged1', name: 'Foo Bar' } + user = User.unstage(params) + + expect(user.id).to eq(staged_user.id) + expect(user.username).to eq('unstaged1') + expect(user.name).to eq('Foo Bar') + expect(user.active).to eq(false) + expect(user.email).to eq('staged@account.com') + end + + it "returns nil when the user cannot be unstaged" do + Fabricate(:coding_horror) + expect(User.unstage(email: 'jeff@somewhere.com')).to be_nil + expect(User.unstage(email: 'no@account.com')).to be_nil + end + end + end