-
Notifications
You must be signed in to change notification settings - Fork 2.5k
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
feat: Add filter on HTTP methods for consumer-restriction plugin #3691
Conversation
@@ -114,12 +161,16 @@ function _M.access(conf, ctx) | |||
if not is_include(value, conf.whitelist) then | |||
block = true | |||
end | |||
if conf.allowed_methods and #conf.allowed_methods > 0 then | |||
if not is_method_allow(conf.allowed_methods, method, value) 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_method_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.
agree
{ | ||
title = "allowed_methods", | ||
properties = { | ||
type = { |
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.
Can we extra this part and share across the components with different titles?
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.
Sorry, I'm not sure to understand what you mean by extra
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.
Sorry, it is my typo. It should be extract
.
@@ -53,6 +53,38 @@ local schema = { | |||
rejected_code = {type = "integer", minimum = 200, default = 403} | |||
}, | |||
required = {"whitelist"}, | |||
}, | |||
{ | |||
title = "allowed_methods", |
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.
Would it be better to use allowed_by_methods
?
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.
agree
"plugins": { | ||
"basic-auth": {}, | ||
"consumer-restriction": { | ||
"whitelist": [ |
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.
"consumer-restriction": {
"allowed_by_methods":[{
"user": "jack1",
"methods": ["POST"]
}]
}
is enough. There is no need to configure jack1
in two places. And the allow
already has the meaning of whitelist
.
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.
Ok so i completely drop the whitelist part in favor of allowed_by_methods ?
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.
If so that would mean some rework of the whole plugin.
Right now the allowed_by_methods
required to set the list of methods , so if we drop whitelist
we need a quick setup . Like if there is no method , then full access ? or the user still has to set the list of method but we take into account a *
wildcard ?
"consumer-restriction": {
"allowed_by_methods":[{
"user": "jack1",
"methods": [] ---> Full access or full restriction ?
}]
}
"consumer-restriction": {
"allowed_by_methods":[{
"user": "jack1",
"methods": ["*"] ---> Full access instead of putting the full list ?
}]
}
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 we can use the schema below to allow both whitelist
and allowed_by_methods
:
local schema = {
type = "object",
properties = {
type = {
type = "string",
enum = {"consumer_name", "service_id"},
default = "consumer_name"
},
blacklist = {
type = "array",
minItems = 1,
items = {type = "string"}
},
whitelist = {
type = "array",
minItems = 1,
items = {type = "string"}
},
allowed_by_methods = {
type = "array",
items = {
type = "object",
properties = {
user = {
type = "string"
},
methods = {
type = "array",
minItems = 1,
items = {
type = "string",
enum = {"GET", "POST", "PUT", "DELETE", "PATCH", "HEAD",
"OPTIONS", "CONNECT", "TRACE"},
}
}
}
}
},
rejected_code = {type = "integer", minimum = 200, default = 403}
},
anyOf = {
{required = {"blacklist"}},
{required = {"whitelist"}},
{required = {"allowed_by_methods"}}
},
}
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 change the title of
apisix/t/plugin/consumer-restriction.t
Line 57 in 29b1e2d
=== TEST 2: whitelist and blacklist mutual exclusive |
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.
It is a large change but I think it is flexible for the users.
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.
Ok , no problem.
So allowed_by_methods
could exist without whitelist
.
If whitelist is set it will override what could be specified in the allowed_by_methods
section
@@ -16,7 +16,7 @@ | |||
-- | |||
local ipairs = ipairs | |||
local core = require("apisix.core") | |||
|
|||
local ngx = ngx |
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 it is better to align with the above format, for example:
local ipairs = ipairs
local core = require("apisix.core")
local ngx = ngx
@@ -84,20 +116,35 @@ local function is_include(value, tab) | |||
return false | |||
end | |||
|
|||
local function is_method_allow(allowed_methods, method, user) | |||
for key,value in ipairs(allowed_methods) 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.
There should be a space after ,
, and key
is not used, it should be replaced with a placeholder. like this:
for _, value in ipairs(allowed_methods) do
local function is_method_allow(allowed_methods, method, user) | ||
for key,value in ipairs(allowed_methods) do | ||
if value.user == user then | ||
for k,allowed_method in ipairs(value.methods) 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.
ditto.
…hod_allow to is_method_allowed, add indentation for import. replace unused key in pairs and ipairs call by _
…e all set , the priority is blacklist > whitelist > allowed_by_methods. update test case accordingly and update the documentation with this new behavior
I made the following update : There is now a direct reject of the connection if the user is blacklisted
The overall behavior stay the same is you set only |
t/plugin/consumer-restriction.t
Outdated
|
||
|
||
|
||
=== TEST 28: test blacklist priority |
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.
test whitelist priority
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.
Ah yes my bad
@@ -475,7 +474,7 @@ Authorization: Basic amFjazIwMjA6MTIzNDU2 | |||
|
|||
|
|||
|
|||
=== TEST 21: remove consumer-restriction |
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.
Why change this 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.
I bump the remove restriction to test 31 due to the tests i added and to remains consistent .
What this PR does / why we need it:
Fix for #3635
Add the possibility to add
allowed_methods
for a user whenwhitelist
is set.This will restrict the user to only performed the HTTP action matching the list specified in
allowed_method.methods
This is the format :
I choose to add a dedicated section instead of modifying the existing
whitelist
one because i think it's more readable.When nothing is set , then only the whitelist is applied .
And in order to set
allowed_methods
,whitelist
is required.Pre-submission checklist:
Test case updated with 2 basics tests
post
on resources and try toget
the resource -> unauthorizedget
capability to the user and try toget
the resource -> authorizedAdd 2 test cases for testing the plugin scheme
allowed_methods
is set -> failedallowed_methods
is set withblacklist
-> failedEnglish documentation updated , any help for the Chineese one would be appreciated.