DEV: Make user field validation more specific (#16746)
- Only validate if custom_fields are loaded, so that we don't trigger a db query
- Only validate public user fields, not all custom_fields
This commit also reverts the unrelated spec changes in ba148e08
, which were required to work around these issues
This commit is contained in:
parent
b65ecf6987
commit
38216f6f0b
|
@ -114,7 +114,7 @@ class User < ActiveRecord::Base
|
||||||
validates :name, user_full_name: true, if: :will_save_change_to_name?, length: { maximum: 255 }
|
validates :name, user_full_name: true, if: :will_save_change_to_name?, length: { maximum: 255 }
|
||||||
validates :ip_address, allowed_ip_address: { on: :create, message: :signup_not_allowed }
|
validates :ip_address, allowed_ip_address: { on: :create, message: :signup_not_allowed }
|
||||||
validates :primary_email, presence: true
|
validates :primary_email, presence: true
|
||||||
validates :custom_fields_values, watched_words: true
|
validates :public_user_field_values, watched_words: true, unless: :custom_fields_clean?
|
||||||
validates_associated :primary_email, message: -> (_, user_email) { user_email[:value]&.errors[:email]&.first }
|
validates_associated :primary_email, message: -> (_, user_email) { user_email[:value]&.errors[:email]&.first }
|
||||||
|
|
||||||
after_initialize :add_trust_level
|
after_initialize :add_trust_level
|
||||||
|
@ -1245,6 +1245,11 @@ class User < ActiveRecord::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def public_user_field_values
|
||||||
|
@public_user_field_ids ||= UserField.public_fields.pluck(:id)
|
||||||
|
user_fields(@public_user_field_ids).values.join(" ")
|
||||||
|
end
|
||||||
|
|
||||||
def set_user_field(field_id, value)
|
def set_user_field(field_id, value)
|
||||||
custom_fields["#{USER_FIELD_PREFIX}#{field_id}"] = value
|
custom_fields["#{USER_FIELD_PREFIX}#{field_id}"] = value
|
||||||
end
|
end
|
||||||
|
@ -1792,10 +1797,6 @@ class User < ActiveRecord::Base
|
||||||
)
|
)
|
||||||
SQL
|
SQL
|
||||||
end
|
end
|
||||||
|
|
||||||
def custom_fields_values
|
|
||||||
custom_fields.values.join(" ")
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# == Schema Information
|
# == Schema Information
|
||||||
|
|
|
@ -14,6 +14,8 @@ class UserField < ActiveRecord::Base
|
||||||
before_save :sanitize_description
|
before_save :sanitize_description
|
||||||
after_save :queue_index_search
|
after_save :queue_index_search
|
||||||
|
|
||||||
|
scope :public_fields, -> { where(show_on_profile: true).or(where(show_on_user_card: true)) }
|
||||||
|
|
||||||
def self.max_length
|
def self.max_length
|
||||||
2048
|
2048
|
||||||
end
|
end
|
||||||
|
|
|
@ -12,9 +12,12 @@ describe Jobs::ActivationReminderEmails do
|
||||||
expect { described_class.new.execute({}) }
|
expect { described_class.new.execute({}) }
|
||||||
.to change { ActionMailer::Base.deliveries.size }.by(1)
|
.to change { ActionMailer::Base.deliveries.size }.by(1)
|
||||||
.and change { user.email_tokens.count }.by(1)
|
.and change { user.email_tokens.count }.by(1)
|
||||||
.and change { user.reload.custom_fields[:activation_reminder] }.to "t"
|
|
||||||
|
expect(user.custom_fields['activation_reminder']).to eq("t")
|
||||||
expect { described_class.new.execute({}) }.to change { ActionMailer::Base.deliveries.size }.by(0)
|
expect { described_class.new.execute({}) }.to change { ActionMailer::Base.deliveries.size }.by(0)
|
||||||
expect { user.activate }.to change { user.reload.custom_fields[:activation_reminder] }.to nil
|
|
||||||
|
user.activate
|
||||||
|
expect(user.reload.custom_fields['activation_reminder']).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'should not email active users' do
|
it 'should not email active users' do
|
||||||
|
|
|
@ -100,7 +100,7 @@ describe Jobs::BulkInvite do
|
||||||
expect(User.where(staged: true).find_by_email('test@discourse.org')).to eq(nil)
|
expect(User.where(staged: true).find_by_email('test@discourse.org')).to eq(nil)
|
||||||
expect(user.user_fields[user_field.id.to_s]).to eq('value 1')
|
expect(user.user_fields[user_field.id.to_s]).to eq('value 1')
|
||||||
expect(user.user_fields[user_field_color.id.to_s]).to eq('Blue')
|
expect(user.user_fields[user_field_color.id.to_s]).to eq('Blue')
|
||||||
expect(staged_user.reload.user_fields[user_field.id.to_s]).to eq('value 2')
|
expect(staged_user.user_fields[user_field.id.to_s]).to eq('value 2')
|
||||||
expect(staged_user.user_fields[user_field_color.id.to_s]).to eq(nil)
|
expect(staged_user.user_fields[user_field_color.id.to_s]).to eq(nil)
|
||||||
new_staged_user = User.where(staged: true).find_by_email('test2@discourse.org')
|
new_staged_user = User.where(staged: true).find_by_email('test2@discourse.org')
|
||||||
expect(new_staged_user.user_fields[user_field.id.to_s]).to eq('value 3')
|
expect(new_staged_user.user_fields[user_field.id.to_s]).to eq('value 3')
|
||||||
|
|
|
@ -138,7 +138,7 @@ RSpec.describe User do
|
||||||
end
|
end
|
||||||
|
|
||||||
describe "#user_fields" do
|
describe "#user_fields" do
|
||||||
fab!(:user_field) { Fabricate(:user_field) }
|
fab!(:user_field) { Fabricate(:user_field, show_on_profile: true) }
|
||||||
fab!(:watched_word) { Fabricate(:watched_word, word: "bad") }
|
fab!(:watched_word) { Fabricate(:watched_word, word: "bad") }
|
||||||
|
|
||||||
before { user.set_user_field(user_field.id, value) }
|
before { user.set_user_field(user_field.id, value) }
|
||||||
|
@ -146,10 +146,18 @@ RSpec.describe User do
|
||||||
context "when user fields contain watched words" do
|
context "when user fields contain watched words" do
|
||||||
let(:value) { "bad user field value" }
|
let(:value) { "bad user field value" }
|
||||||
|
|
||||||
it "is not valid" do
|
context "when user field is public" do
|
||||||
user.valid?
|
it "is not valid" do
|
||||||
expect(user.errors[:base].size).to eq(1)
|
user.valid?
|
||||||
expect(user.errors.messages[:base]).to include(/you can't post the word/)
|
expect(user.errors[:base].size).to eq(1)
|
||||||
|
expect(user.errors.messages[:base]).to include(/you can't post the word/)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "when user field is private" do
|
||||||
|
before { user_field.update(show_on_profile: false) }
|
||||||
|
|
||||||
|
it { is_expected.to be_valid }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -289,9 +289,9 @@ describe UserAnonymizer do
|
||||||
"user_field_#{field2.id}": "bar",
|
"user_field_#{field2.id}": "bar",
|
||||||
"another_field": "456"
|
"another_field": "456"
|
||||||
}
|
}
|
||||||
user.save
|
|
||||||
|
|
||||||
expect { make_anonymous }.to change { user.reload.custom_fields }.to "some_field" => "123", "another_field" => "456"
|
expect { make_anonymous }.to change { user.custom_fields }
|
||||||
|
expect(user.reload.custom_fields).to eq("some_field" => "123", "another_field" => "456")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue