Support Feature Flag userWithId Strategy on Backend
What does this MR do?
Add backend support for the userWithId
feature flag strategy.
Relevant Issue: https://gitlab.com/gitlab-org/gitlab-ee/issues/11459
Behavior of the Unleash server and ruby client in several edge cases.
1,2, 3
(with space)
The Unleash server lets you save a value like this.
It saves the value with the space in the database:
{"name":"userWithId","parameters":{"userIds":"1,2, 3"}
It also reports it with a space to clients:
{
"name": "userWithId",
"parameters": {
"userIds": "1,2, 3"
}
}
But then the ruby client matches on the trimmed value. I have to make the context's user_id
value 3
in order to match and have the feature enabled. 3
(with a leading space) does not match and the feature is disabled.
You can see that the ruby client trims the user id's: https://github.com/Unleash/unleash-client-ruby/blob/c88196a105d274344c26dc89bb265f98de18d71e/lib/unleash/strategy/user_with_id.rb#L16
1,2,ほげ
(with unicode)
This causes no problems. The Unleash server saves the value, reports it to clients, and the ruby client will match on it.
1,2," !"#$%&'()*+-./:;<=>?@[\]^_{}~"
(with special characters)
This seems to work. The Unleash server saves the value, escapes characters as necessary, returns the escaped string to clients, and the client can match on it.
{"name":"userWithId","parameters":{"userIds":"1,2,\" !\"#$%&'()*+-./:;<=>?@[\\]^_{}~\""}}
{
"name": "userWithId",
"parameters": {
"userIds": "1,2,\" !\"#$%&'()*+-./:;<=>?@[\\]^_{}~\""
}
}
1,2,,,,,,,
(no values defined)
The Unleash Server saves values like this. There is a discrepancy between the UI and the values saved in the database.
Saves values in the database like:
{"name":"userWithId","parameters":{"userIds":"1,2,,,,,,,"}}
And reports them as such to clients. But this doesn't seem to cause any problems for the ruby client.
Next time I save a value, the extra blank values are removed from the database:
{"name":"userWithId","parameters":{"userIds":"1,2,3"}}
1,2,2,2
(duplicated)
The Unleash server will let you save values like this. The values are displayed multiple times in the UI:
They are saved in the database multiple times:
{"name":"userWithId","parameters":{"userIds":"hi guy spaces, and me,tab\\tcharacter,hi,hi,hi,hi"}
They are given this way to clients:
{
"version": 1,
"features": [
{
"name": "fog",
"description": "Turn the fog on and off",
"enabled": true,
"strategies": [
{
"name": "gradualRolloutUserId",
"parameters": {
"groupId": "mygroup",
"percentage": "5"
}
},
{
"name": "userWithId",
"parameters": {
"userIds": "hi guy spaces, and me,tab\\tcharacter,hi,hi,hi,hi"
}
}
],
"variants": null,
"createdAt": "2019-06-07T18:35:23.224Z"
}
]
}
The ruby client handles this situation without any issues. I can toggle the feature on locally by changing the unleash client context's user_id
parameter to hi
or off by setting it to something else.
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa...
(Super long text)
I tried a string of 183 random characters. It works with Unleash. The server accepts it, saves it in the database, and returns it to clients. The client matches properly on the string. I can toggle a feature on and off for myself by setting the unleash context's user_id
parameter to the long string.
You can see that it causes some trouble in the Unleash server's UI:
I cannot delete the long ID, because the string is too long and pushes the X
beyond the clickable area.
Does this MR meet the acceptance criteria?
Conformity
-
Changelog entry -
Documentation created/updated or follow-up review issue created -
Code review guidelines -
Merge request performance guidelines -
Style guides -
Database guides -
Separation of EE specific content
Performance and testing
-
Review and add/update tests for this feature/bug. Consider all test levels. See the Test Planning Process. -
Tested in all supported browsers
Security
If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:
-
Label as security and @ mention @gitlab-com/gl-security/appsec
-
The MR includes necessary changes to maintain consistency between UI, API, email, or other methods -
Security reports checked/validated by a reviewer from the AppSec team