Skip to content

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

Open
wants to merge 23 commits into
base: master
Choose a base branch
from

Conversation

Baoyuantop
Copy link
Contributor

@Baoyuantop Baoyuantop commented Mar 11, 2025

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

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (If not, please discuss on the APISIX mailing list first)

@Baoyuantop Baoyuantop marked this pull request as ready for review March 12, 2025 09:51
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. enhancement New feature or request labels Mar 12, 2025
@@ -110,7 +110,7 @@ passed
"desc": "basic-auth for jack",
"plugins": {
"basic-auth": {
"username": "the-user",
"username": "the-new-user",
Copy link
Contributor Author

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
Copy link
Contributor Author

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.

@Baoyuantop Baoyuantop requested a review from membphis March 17, 2025 01:31
@@ -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
Copy link
Contributor

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.

local consumer, _, err = consumer
.find_consumer(plugin_name, key_field, key_value)
if err then
core.log.warn("failed to find consumer: ", err)
Copy link
Contributor

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.

Copy link
Contributor Author

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.

Copy link
Contributor

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.

core.log.warn("failed to find consumer: ", err)
end

if consumer and consumer.username ~= conf.username then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. 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:
    image

  2. 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?

Copy link
Contributor Author

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.

Copy link
Contributor

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:

Copy link
Contributor Author

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

@Baoyuantop Baoyuantop changed the title feat: consumer key duplication check fix: consumer key duplication check Mar 21, 2025
@Baoyuantop Baoyuantop requested a review from AlinsRan March 25, 2025 08:32
Copy link
Contributor

@AlinsRan AlinsRan left a 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?

@Baoyuantop
Copy link
Contributor Author

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

@Baoyuantop Baoyuantop requested a review from AlinsRan March 27, 2025 09:52
@nic-6443 nic-6443 requested a review from Copilot March 27, 2025 10:02
Copy link

@Copilot Copilot AI left a 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

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)
Copy link
Contributor

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.

@AlinsRan
Copy link
Contributor

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

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

Components that do not use admin API, such as dashboard.

@Baoyuantop Baoyuantop moved this to 🏗 In progress in Apache APISIX backlog Mar 28, 2025
@Baoyuantop Baoyuantop moved this from 🏗 In progress to 👀 In review in Apache APISIX backlog Mar 28, 2025
@dosubot dosubot bot added size:XL This PR changes 500-999 lines, ignoring generated files. and removed size:L This PR changes 100-499 lines, ignoring generated files. labels Apr 2, 2025
@dosubot dosubot bot added size:L This PR changes 100-499 lines, ignoring generated files. and removed size:XL This PR changes 500-999 lines, ignoring generated files. labels Apr 2, 2025
@Baoyuantop Baoyuantop requested a review from nic-6443 April 2, 2025 03:29
nic-6443
nic-6443 previously approved these changes Apr 3, 2025
nic-6443
nic-6443 previously approved these changes Apr 3, 2025
@Baoyuantop
Copy link
Contributor Author

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

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)
Copy link
Contributor

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request size:L This PR changes 100-499 lines, ignoring generated files.
Projects
Status: 👀 In review
Development

Successfully merging this pull request may close these issues.

API KEY Unique
4 participants