-
Notifications
You must be signed in to change notification settings - Fork 2.6k
fix: consumer key duplication check #12040
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
base: master
Are you sure you want to change the base?
Conversation
@@ -110,7 +110,7 @@ passed | |||
"desc": "basic-auth for jack", | |||
"plugins": { | |||
"basic-auth": { | |||
"username": "the-user", | |||
"username": "the-new-user", |
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.
After adding the duplicate judgment, it cannot be added here again, so I made a modification.
@@ -314,3 +314,5 @@ GET /t | |||
} | |||
--- response_body | |||
all done | |||
--- error_log |
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.
The testing of these changes is an expected change. These tests have an admin api call to the consumer and use a non-existent secret reference, which in the new logic triggers a secret lookup failure and an error log. It didn't break the original test path.
apisix/admin/consumers.lua
Outdated
@@ -32,7 +34,50 @@ local function check_conf(username, conf, need_username, schema) | |||
if conf.plugins then | |||
ok, err = plugins.check_schema(conf.plugins, core.schema.TYPE_CONSUMER) | |||
if not ok then | |||
return nil, {error_msg = "invalid plugins configuration: " .. err} | |||
return nil, { | |||
error_msg = "invalid plugins configuration: " .. err |
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 can keep this line unchanged.
apisix/admin/consumers.lua
Outdated
local consumer, _, err = consumer | ||
.find_consumer(plugin_name, key_field, key_value) | ||
if err then | ||
core.log.warn("failed to find consumer: ", err) |
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 don't understand the logic here. In the find_consumer()
method call above. We are checking if the given consumer key already exists, no? If it doesn't exist then the duplication check should be successful (no duplicate found), right?
If yes, then there is no point in printing a warn log.
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.
When fixing the failure test, I found that when calling the find_consumer()
method, its internal call will do a secret find and replace, and when given a non-existing secret, there will be an internal error log, where the err data is captured and printed.
It is also possible to remove this log.
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 think you can add this info as a comment in the code.
apisix/admin/consumers.lua
Outdated
core.log.warn("failed to find consumer: ", err) | ||
end | ||
|
||
if consumer and consumer.username ~= conf.username then |
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.
-
Is it guaranteed that the returned consumer will have the field
username
in it? Different consumers have different key fields right? Take your own code snippet for example:
-
This block will execute only if a consumer with given
key_field
already exists. So, if it does, we should directly raise an error, no?
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.
The purpose of this is to allow the user to edit a pre-existing consumer. If the consuner being edited matches the username of the consumer being looked up, then the same consumer is being edited, and this behavior should be allowed.
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.
got it. What about my first question?
Is it guaranteed that the returned consumer will have the field username in it? Different consumers have different key fields right? Take your own code snippet for example:
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.
username is a unique field for the consumer and must exist. https://apisix.apache.org/docs/apisix/terminology/consumer/#configuration-options
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.
Do we not need to check for duplicate keys when watching etcd data?
Do you mean that etcd can have duplicate keys written to it by other components ? @AlinsRan |
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.
Copilot wasn't able to review any files in this pull request.
Files not reviewed (8)
- apisix/admin/consumers.lua: Language not supported
- apisix/admin/credentials.lua: Language not supported
- apisix/admin/utils.lua: Language not supported
- t/admin/consumers2.t: Language not supported
- t/admin/credentials.t: Language not supported
- t/secret/aws.t: Language not supported
- t/secret/gcp.t: Language not supported
- t/secret/secret_lru.t: Language not supported
apisix/admin/credentials.lua
Outdated
if plugin_obj.type ~= "auth" then | ||
return nil, {error_msg = "only supports auth type plugins in consumer credential"} | ||
end | ||
|
||
-- check duplicate key | ||
local decrypted_conf = core.table.deepcopy(plugin_conf) |
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.
There are too many nested judgments inside, but I think we can extract this logic into a universal function that can be used by both consumers and credentials.
Components that do not use admin API, such as dashboard. |
I think it can be discussed in a new issue, and this PR only deals with the admin api section |
} | ||
|
||
|
||
function _M.check_duplicate_key(plugins_conf, username, credential_id) |
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 suggest putting the check_deuplicate_key
function in apisix/consumer.lua
Description
This PR adds a duplicate consumer key check when creating consumers and credentials using the admin api to prevent different consumers from having the same key.
Fixes #11197
Checklist