mirror of
https://github.com/discourse/discourse.git
synced 2025-05-22 21:52:43 +08:00
FIX: Reviewables should not be created for users until they are active
Conversely, if a user is deactivated the reviewable should automatically be rejected. Before this fix, if a user was not active they'd still show in the review queue but without an "Approve" button which was confusing.
This commit is contained in:
@ -310,7 +310,7 @@ class Admin::UsersController < Admin::AdminController
|
|||||||
|
|
||||||
def deactivate
|
def deactivate
|
||||||
guardian.ensure_can_deactivate!(@user)
|
guardian.ensure_can_deactivate!(@user)
|
||||||
@user.deactivate
|
@user.deactivate(current_user)
|
||||||
StaffActionLogger.new(current_user).log_user_deactivate(@user, I18n.t('user.deactivated_by_staff'), params.slice(:context))
|
StaffActionLogger.new(current_user).log_user_deactivate(@user, I18n.t('user.deactivated_by_staff'), params.slice(:context))
|
||||||
refresh_browser @user
|
refresh_browser @user
|
||||||
render body: nil
|
render body: nil
|
||||||
|
17
app/jobs/regular/create_user_reviewable.rb
Normal file
17
app/jobs/regular/create_user_reviewable.rb
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
class Jobs::CreateUserReviewable < Jobs::Base
|
||||||
|
def execute(args)
|
||||||
|
raise Discourse::InvalidParameters unless args[:user_id].present?
|
||||||
|
|
||||||
|
if user = User.find_by(id: args[:user_id])
|
||||||
|
return if user.approved?
|
||||||
|
|
||||||
|
reviewable = ReviewableUser.needs_review!(target: user, created_by: Discourse.system_user, reviewable_by_moderator: true)
|
||||||
|
reviewable.add_score(
|
||||||
|
Discourse.system_user,
|
||||||
|
ReviewableScore.types[:needs_approval],
|
||||||
|
force_review: true
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
@ -13,7 +13,7 @@ module Jobs
|
|||||||
.each do |user|
|
.each do |user|
|
||||||
|
|
||||||
User.transaction do
|
User.transaction do
|
||||||
user.deactivate
|
user.deactivate(Discourse.system_user)
|
||||||
user.email_tokens.update_all(confirmed: false, expired: true)
|
user.email_tokens.update_all(confirmed: false, expired: true)
|
||||||
|
|
||||||
Discourse.authenticators.each do |authenticator|
|
Discourse.authenticators.each do |authenticator|
|
||||||
|
@ -64,9 +64,9 @@ class EmailToken < ActiveRecord::Base
|
|||||||
if result[:success]
|
if result[:success]
|
||||||
# If we are activating the user, send the welcome message
|
# If we are activating the user, send the welcome message
|
||||||
user.send_welcome_message = !user.active?
|
user.send_welcome_message = !user.active?
|
||||||
user.active = true
|
|
||||||
user.email = result[:email_token].email
|
user.email = result[:email_token].email
|
||||||
user.save!
|
user.save!
|
||||||
|
user.activate
|
||||||
user.set_automatic_groups
|
user.set_automatic_groups
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -116,7 +116,6 @@ class User < ActiveRecord::Base
|
|||||||
after_create :set_random_avatar
|
after_create :set_random_avatar
|
||||||
after_create :ensure_in_trust_level_group
|
after_create :ensure_in_trust_level_group
|
||||||
after_create :set_default_categories_preferences
|
after_create :set_default_categories_preferences
|
||||||
after_create :create_reviewable
|
|
||||||
|
|
||||||
before_save :update_username_lower
|
before_save :update_username_lower
|
||||||
before_save :ensure_password_is_hashed
|
before_save :ensure_password_is_hashed
|
||||||
@ -898,10 +897,15 @@ class User < ActiveRecord::Base
|
|||||||
else
|
else
|
||||||
self.update!(active: true)
|
self.update!(active: true)
|
||||||
end
|
end
|
||||||
|
create_reviewable
|
||||||
end
|
end
|
||||||
|
|
||||||
def deactivate
|
def deactivate(performed_by)
|
||||||
self.update!(active: false)
|
self.update!(active: false)
|
||||||
|
|
||||||
|
if reviewable = ReviewableUser.pending.find_by(target: self)
|
||||||
|
reviewable.perform(performed_by, :reject)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def change_trust_level!(level, opts = nil)
|
def change_trust_level!(level, opts = nil)
|
||||||
@ -1242,14 +1246,7 @@ class User < ActiveRecord::Base
|
|||||||
return unless SiteSetting.must_approve_users? || SiteSetting.invite_only?
|
return unless SiteSetting.must_approve_users? || SiteSetting.invite_only?
|
||||||
return if approved?
|
return if approved?
|
||||||
|
|
||||||
reviewable = ReviewableUser.needs_review!(target: self, created_by: Discourse.system_user, reviewable_by_moderator: true)
|
Jobs.enqueue(:create_user_reviewable, user_id: self.id)
|
||||||
reviewable.add_score(
|
|
||||||
Discourse.system_user,
|
|
||||||
ReviewableScore.types[:needs_approval],
|
|
||||||
force_review: true
|
|
||||||
)
|
|
||||||
|
|
||||||
reviewable
|
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_user_stat
|
def create_user_stat
|
||||||
|
@ -22,7 +22,7 @@ class CreateReviewableUsers < ActiveRecord::Migration[5.2]
|
|||||||
created_at,
|
created_at,
|
||||||
created_at
|
created_at
|
||||||
FROM users
|
FROM users
|
||||||
WHERE approved = false
|
WHERE active AND approved = false
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -8,6 +8,7 @@ describe 'invite only' do
|
|||||||
it 'can create user via API' do
|
it 'can create user via API' do
|
||||||
|
|
||||||
SiteSetting.invite_only = true
|
SiteSetting.invite_only = true
|
||||||
|
Jobs.run_immediately!
|
||||||
|
|
||||||
admin = Fabricate(:admin)
|
admin = Fabricate(:admin)
|
||||||
api_key = Fabricate(:api_key, user: admin)
|
api_key = Fabricate(:api_key, user: admin)
|
||||||
|
@ -117,6 +117,7 @@ describe EmailToken do
|
|||||||
context 'confirms the token and redeems invite' do
|
context 'confirms the token and redeems invite' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.must_approve_users = true
|
SiteSetting.must_approve_users = true
|
||||||
|
Jobs.run_immediately!
|
||||||
end
|
end
|
||||||
|
|
||||||
let(:invite) { Fabricate(:invite, email: 'test@example.com', user_id: nil) }
|
let(:invite) { Fabricate(:invite, email: 'test@example.com', user_id: nil) }
|
||||||
|
@ -3,7 +3,11 @@ require 'rails_helper'
|
|||||||
RSpec.describe ReviewableUser, type: :model do
|
RSpec.describe ReviewableUser, type: :model do
|
||||||
|
|
||||||
let(:moderator) { Fabricate(:moderator) }
|
let(:moderator) { Fabricate(:moderator) }
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) do
|
||||||
|
user = Fabricate(:user)
|
||||||
|
user.activate
|
||||||
|
user
|
||||||
|
end
|
||||||
let(:admin) { Fabricate(:admin) }
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
|
||||||
context "actions_for" do
|
context "actions_for" do
|
||||||
@ -78,6 +82,7 @@ RSpec.describe ReviewableUser, type: :model do
|
|||||||
describe 'when must_approve_users is true' do
|
describe 'when must_approve_users is true' do
|
||||||
before do
|
before do
|
||||||
SiteSetting.must_approve_users = true
|
SiteSetting.must_approve_users = true
|
||||||
|
Jobs.run_immediately!
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates the ReviewableUser for a user, with moderator access" do
|
it "creates the ReviewableUser for a user, with moderator access" do
|
||||||
|
@ -125,23 +125,58 @@ describe User do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe 'reviewable' do
|
describe 'reviewable' do
|
||||||
let(:user) { Fabricate(:user) }
|
let(:user) { Fabricate(:user, active: false) }
|
||||||
let(:admin) { Fabricate(:admin) }
|
let(:admin) { Fabricate(:admin) }
|
||||||
|
|
||||||
it "creates a reviewable for the user if must_approve_users is true" do
|
before do
|
||||||
|
Jobs.run_immediately!
|
||||||
|
end
|
||||||
|
|
||||||
|
it "creates a reviewable for the user if must_approve_users is true and activate is called" do
|
||||||
SiteSetting.must_approve_users = true
|
SiteSetting.must_approve_users = true
|
||||||
user
|
user
|
||||||
|
|
||||||
|
# Inactive users don't have reviewables
|
||||||
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
|
expect(reviewable).to be_blank
|
||||||
|
|
||||||
|
user.activate
|
||||||
reviewable = ReviewableUser.find_by(target: user)
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
expect(reviewable).to be_present
|
expect(reviewable).to be_present
|
||||||
expect(reviewable.score > 0).to eq(true)
|
expect(reviewable.score > 0).to eq(true)
|
||||||
expect(reviewable.reviewable_scores).to be_present
|
expect(reviewable.reviewable_scores).to be_present
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "creates a reviewable for the user if must_approve_users is true and their token is confirmed" do
|
||||||
|
SiteSetting.must_approve_users = true
|
||||||
|
user
|
||||||
|
|
||||||
|
# Inactive users don't have reviewables
|
||||||
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
|
expect(reviewable).to be_blank
|
||||||
|
|
||||||
|
EmailToken.confirm(user.email_tokens.first.token)
|
||||||
|
expect(user.reload.active).to eq(true)
|
||||||
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
|
expect(reviewable).to be_present
|
||||||
|
end
|
||||||
|
|
||||||
it "doesn't create a reviewable if must_approve_users is false" do
|
it "doesn't create a reviewable if must_approve_users is false" do
|
||||||
user
|
user
|
||||||
expect(ReviewableUser.find_by(target: user)).to be_blank
|
expect(ReviewableUser.find_by(target: user)).to be_blank
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "will reject a reviewable if the user is deactivated" do
|
||||||
|
SiteSetting.must_approve_users = true
|
||||||
|
user
|
||||||
|
|
||||||
|
user.activate
|
||||||
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
|
expect(reviewable.pending?).to eq(true)
|
||||||
|
|
||||||
|
user.deactivate(admin)
|
||||||
|
expect(reviewable.reload.rejected?).to eq(true)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe 'bookmark' do
|
describe 'bookmark' do
|
||||||
|
@ -290,6 +290,9 @@ describe WebHook do
|
|||||||
Fabricate(:user_web_hook, active: true)
|
Fabricate(:user_web_hook, active: true)
|
||||||
|
|
||||||
user
|
user
|
||||||
|
user.activate
|
||||||
|
Jobs::CreateUserReviewable.new.execute(user_id: user.id)
|
||||||
|
|
||||||
job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first
|
job_args = Jobs::EmitWebHookEvent.jobs.last["args"].first
|
||||||
|
|
||||||
expect(job_args["event_name"]).to eq("user_created")
|
expect(job_args["event_name"]).to eq("user_created")
|
||||||
|
@ -71,6 +71,8 @@ RSpec.describe Admin::UsersController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it 'calls approve' do
|
it 'calls approve' do
|
||||||
|
Jobs.run_immediately!
|
||||||
|
evil_trout.activate
|
||||||
put "/admin/users/#{evil_trout.id}/approve.json"
|
put "/admin/users/#{evil_trout.id}/approve.json"
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
evil_trout.reload
|
evil_trout.reload
|
||||||
@ -102,6 +104,8 @@ RSpec.describe Admin::UsersController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "approves the user when permitted" do
|
it "approves the user when permitted" do
|
||||||
|
Jobs.run_immediately!
|
||||||
|
evil_trout.activate
|
||||||
put "/admin/users/approve-bulk.json", params: { users: [evil_trout.id] }
|
put "/admin/users/approve-bulk.json", params: { users: [evil_trout.id] }
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
evil_trout.reload
|
evil_trout.reload
|
||||||
|
@ -144,8 +144,10 @@ describe ReviewablesController do
|
|||||||
end
|
end
|
||||||
|
|
||||||
it "will use the ReviewableUser serializer for its fields" do
|
it "will use the ReviewableUser serializer for its fields" do
|
||||||
|
Jobs.run_immediately!
|
||||||
SiteSetting.must_approve_users = true
|
SiteSetting.must_approve_users = true
|
||||||
user = Fabricate(:user)
|
user = Fabricate(:user)
|
||||||
|
user.activate
|
||||||
reviewable = ReviewableUser.find_by(target: user)
|
reviewable = ReviewableUser.find_by(target: user)
|
||||||
|
|
||||||
get "/review.json"
|
get "/review.json"
|
||||||
|
Reference in New Issue
Block a user