New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fixes #36017 - Remove spacing from array type settings #9614
Conversation
Issues: #36017 |
Can one of the admins verify this patch? |
2 similar comments
Can one of the admins verify this patch? |
Can one of the admins verify this patch? |
ok to test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @girijaasoni !
the value which is stored in the DB still has spaces,
can we also trim the spaces from it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should consider trimming the values from the frontend, e.g:
Line 26 in 662c4a3
values: submitValues, |
Though to better protect the DB also from the API point, maybe we can use this library: https://github.com/holli/auto_strip_attributes
this can be a solution for more scenarios across Foreman and plugins...
interested in what @nofaralfasi and @theforeman/packaging have to say about it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@@ -1,5 +1,5 @@ | |||
class ArrayTypeValidator < ActiveModel::EachValidator | |||
def validate_each(record, attribute, value) | |||
record.errors.add attribute, _("must be comma separated") unless Array(value).map { |item| item.to_s.match /\A\S+\z/ }.all? | |||
record.errors.add attribute, _("must be comma separated") unless Array(value).map { |item| item.to_s.strip.match /\A\S+\z/ }.all? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unrelated to this PR, but I think .all?
accepts a block and this could be optimized:
record.errors.add attribute, _("must be comma separated") unless Array(value).map { |item| item.to_s.strip.match /\A\S+\z/ }.all? | |
record.errors.add attribute, _("must be comma separated") unless Array(value).all? { |item| item.to_s.strip.match?(/\A\S+\z/) } |
Note I didn't test this and it's probably better to do in a separate PR
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be explicit: the changes to the validators should be reverted. They should not accept any whitespace.
@ekohl Are you suggesting that we shall apply the change somewhere else or we can modify the Regex for the same validation?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd apply the change elsewhere. Normally the flow is:
- User input
- Apply normalization
- Apply validators
- Process data
Processing data can mean storing it in the DB, but you want it to be as clean as possible. The main reason is that if you can assume that data in the database doesn't have whitespace around the value, you can keep the code that uses data from the database simpler. Or put in another way: if you must remember to always call .strip
on a value, you can easily introduce bugs. That's more important than the potential performance difference, but that's another factor.
An example:
if model.value == 'value'
# Do X
else
# Do Y
end
This will work most of the time, but if the user (accidentally) has spaces in the value it can introduce a bug.
Looking back at the flow, this means we want to clean up the data before processing it. A validator is then only supposed to validate. It never changes data. This means normalization can happen in the UI, before it's submitted, or in the controller before it's passed to the validators. But the validator must remain strict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks a lot for the clarification Ewoud!!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be explicit: the changes to the validators should be reverted. They should not accept any whitespace.
@girijaasoni Some tests are failing. |
12c5d0e
to
f556ff3
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @girijaasoni, I tested and it works as expected now 👍🏼
@@ -44,13 +44,13 @@ def setup | |||
end | |||
|
|||
test 'if audience is not valid' do | |||
Setting['oidc_audience'] = "no-client" | |||
Setting['oidc_audience'] = ["no-client"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice catch, it was indeed moved to setting_type of array in
setting.settings_type = 'array' |
@ekohl , could you please review the updated changes? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Changes look good to me. It would be great to have a test, but I don't know where would be a great place.
test/models/setting_test.rb
Outdated
assert Setting.create(name: 'trusted_hosts', value: []) | ||
setting = Setting.find_by_name("trusted_hosts") | ||
setting.value = ["localhost ", " remotehost"] | ||
assert setting.save |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
setting = Setting.create(name: 'trusted_hosts', value: ["localhost ", " remotehost"])
assert_equal ["localhost", "remotehost"], setting.value
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you @stejskalleos
test/models/setting_test.rb
Outdated
@@ -174,6 +174,13 @@ def test_settings_should_save_strings | |||
assert_equal "must be comma separated", setting.errors[:value].first | |||
end | |||
|
|||
test "trusted_hosts should accept values with spaces" do |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
trusted_hosts should trim values with spaces
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://www.betterspecs.org/#should says you should make it:
test "trusted_hosts should accept values with spaces" do | |
test "trusted_hosts accepts values with spaces" do |
Granted, that's for RSpec, but I like the convention.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @ekohl , updated it
1955637
to
e1d7bcc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍏 LGTM
Failed tests are not related, but let's wait with the merge until they are fixed.
The tests pass now! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🍏 LGTM
Works as expected.
Thanks @girijaasoni!
…ts to make it into a valid format