You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@apisix.apache.org by sp...@apache.org on 2022/12/27 06:10:47 UTC
[apisix] branch master updated: feat: consumer-restriction plugin support consumer_group_id type (#8567)
This is an automated email from the ASF dual-hosted git repository.
spacewander pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/apisix.git
The following commit(s) were added to refs/heads/master by this push:
new 053c53a58 feat: consumer-restriction plugin support consumer_group_id type (#8567)
053c53a58 is described below
commit 053c53a588a371f83b3c18d8bd3a5ebcfbdd1298
Author: Ashing Zheng <ax...@gmail.com>
AuthorDate: Tue Dec 27 14:10:40 2022 +0800
feat: consumer-restriction plugin support consumer_group_id type (#8567)
Fixes https://github.com/apache/apisix/issues/8563
---
apisix/plugins/consumer-restriction.lua | 5 +-
docs/en/latest/plugins/consumer-restriction.md | 3 +-
docs/zh/latest/plugins/consumer-restriction.md | 3 +-
t/plugin/consumer-restriction2.t | 275 +++++++++++++++++++++++++
4 files changed, 283 insertions(+), 3 deletions(-)
diff --git a/apisix/plugins/consumer-restriction.lua b/apisix/plugins/consumer-restriction.lua
index a9f7363a5..93f3b9f59 100644
--- a/apisix/plugins/consumer-restriction.lua
+++ b/apisix/plugins/consumer-restriction.lua
@@ -22,7 +22,7 @@ local schema = {
properties = {
type = {
type = "string",
- enum = {"consumer_name", "service_id", "route_id"},
+ enum = {"consumer_name", "service_id", "route_id", "consumer_group_id"},
default = "consumer_name"
},
blacklist = {
@@ -79,6 +79,9 @@ local fetch_val_funcs = {
end,
["consumer_name"] = function(ctx)
return ctx.consumer_name
+ end,
+ ["consumer_group_id"] = function (ctx)
+ return ctx.consumer_group_id
end
}
diff --git a/docs/en/latest/plugins/consumer-restriction.md b/docs/en/latest/plugins/consumer-restriction.md
index 5b1fe10b0..d2daa0a40 100644
--- a/docs/en/latest/plugins/consumer-restriction.md
+++ b/docs/en/latest/plugins/consumer-restriction.md
@@ -34,7 +34,7 @@ The `consumer-restriction` Plugin allows users to set access restrictions based
| Name | Type | Required | Default | Valid values | Description |
|--------------------|---------------|----------|---------------|---------------|-------------|
-| type | string | False | consumer_name | ["consumer_name", "service_id", "route_id"] | Type of object to base the restriction on. |
+| type | string | False | consumer_name | ["consumer_name", "consumer_group_id", "service_id", "route_id"] | Type of object to base the restriction on. |
| whitelist | array[string] | True | | | List of objects to whitelist. Has a higher priority than `allowed_by_methods`. |
| blacklist | array[string] | True | | | List of objects to blacklist. Has a higher priority than `whitelist`. |
| rejected_code | integer | False | 403 | [200,...] | HTTP status code returned when the request is rejected. |
@@ -46,6 +46,7 @@ The `consumer-restriction` Plugin allows users to set access restrictions based
The different values in the `type` attribute have these meanings:
- `consumer_name`: Username of the Consumer to restrict access to a Route or a Service.
+- `consumer_group_id`: ID of the Consumer Group to restrict access to a Route or a Service.
- `service_id`: ID of the Service to restrict access from a Consumer. Need to be used with an Authentication Plugin.
- `route_id`: ID of the Route to restrict access from a Consumer.
diff --git a/docs/zh/latest/plugins/consumer-restriction.md b/docs/zh/latest/plugins/consumer-restriction.md
index c7926f12b..a2b885b46 100644
--- a/docs/zh/latest/plugins/consumer-restriction.md
+++ b/docs/zh/latest/plugins/consumer-restriction.md
@@ -34,7 +34,7 @@ description: Consumer Restriction 插件允许用户根据 Route、Service 或 C
| 名称 | 类型 | 必选项 | 默认值 | 有效值 | 描述 |
| --------- | ------------- | ------ | -----------------| -------------------------|------------------------|
-| type | string | 否 | consumer_name | ["consumer_name", "service_id", "route_id"] | 支持设置访问限制的对象类型。 |
+| type | string | 否 | consumer_name | ["consumer_name", "consumer_group_id", "service_id", "route_id"] | 支持设置访问限制的对象类型。 |
| whitelist | array[string] | 是 | | | 加入白名单的对象,优先级高于 `allowed_by_methods`。 |
| blacklist | array[string] | 是 | | | 加入黑名单的对象,优先级高于 `whitelist`。 |
| rejected_code | integer | 否 | 403 | [200,...] | 当请求被拒绝时,返回的 HTTP 状态码。 |
@@ -46,6 +46,7 @@ description: Consumer Restriction 插件允许用户根据 Route、Service 或 C
不同的 `type` 属性值分别代表以下含义:
- `consumer_name`:把 Consumer 的 `username` 列入白名单或黑名单来限制 Consumer 对 Route 或 Service 的访问。
+- `consumer_group_id`: 把 Consumer Group 的 `id` 列入白名单或黑名单来限制 Consumer 对 Route 或 Service 的访问。
- `service_id`:把 Service 的 `id` 列入白名单或黑名单来限制 Consumer 对 Service 的访问,需要结合授权插件一起使用。
- `route_id`:把 Route 的 `id` 列入白名单或黑名单来限制 Consumer 对 Route 的访问。
diff --git a/t/plugin/consumer-restriction2.t b/t/plugin/consumer-restriction2.t
new file mode 100644
index 000000000..6fdba1daa
--- /dev/null
+++ b/t/plugin/consumer-restriction2.t
@@ -0,0 +1,275 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+use t::APISIX 'no_plan';
+
+repeat_each(1);
+no_long_string();
+no_shuffle();
+no_root_location();
+
+run_tests;
+
+__DATA__
+
+=== TEST 1: create consumer group(group1)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumer_groups/group1',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {}
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 2: create consumer group(group2)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumer_groups/group2',
+ ngx.HTTP_PUT,
+ [[{
+ "plugins": {}
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 3: consumer jack1 with consumer group(group1)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack1",
+ "plugins": {
+ "basic-auth": {
+ "username": "jack2019",
+ "password": "123456"
+ }
+ },
+ "group_id": "group1"
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 4: consumer jack2 with consumer group(group2)
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/consumers',
+ ngx.HTTP_PUT,
+ [[{
+ "username": "jack2",
+ "plugins": {
+ "basic-auth": {
+ "username": "jack2020",
+ "password": "123456"
+ }
+ },
+ "group_id": "group2"
+ }]]
+ )
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 5: set whitelist
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/hello",
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:1980": 1
+ }
+ },
+ "plugins": {
+ "basic-auth": {},
+ "consumer-restriction": {
+ "type": "consumer_group_id",
+ "whitelist": [
+ "group1"
+ ]
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 6: verify unauthorized
+--- request
+GET /hello
+--- error_code: 401
+--- response_body
+{"message":"Missing authorization in request"}
+
+
+
+=== TEST 7: verify jack1
+--- request
+GET /hello
+--- more_headers
+Authorization: Basic amFjazIwMTk6MTIzNDU2
+--- response_body
+hello world
+
+
+
+=== TEST 8: verify jack2
+--- request
+GET /hello
+--- more_headers
+Authorization: Basic amFjazIwMjA6MTIzNDU2
+--- error_code: 403
+--- response_body
+{"message":"The consumer_group_id is forbidden."}
+
+
+
+=== TEST 9: set blacklist
+--- config
+ location /t {
+ content_by_lua_block {
+ local t = require("lib.test_admin").test
+ local code, body = t('/apisix/admin/routes/1',
+ ngx.HTTP_PUT,
+ [[{
+ "uri": "/hello",
+ "upstream": {
+ "type": "roundrobin",
+ "nodes": {
+ "127.0.0.1:1980": 1
+ }
+ },
+ "plugins": {
+ "basic-auth": {},
+ "consumer-restriction": {
+ "type": "consumer_group_id",
+ "blacklist": [
+ "group1"
+ ],
+ "rejected_msg": "request is forbidden"
+ }
+ }
+ }]]
+ )
+
+ if code >= 300 then
+ ngx.status = code
+ end
+ ngx.say(body)
+ }
+ }
+--- request
+GET /t
+--- response_body
+passed
+
+
+
+=== TEST 10: verify unauthorized
+--- request
+GET /hello
+--- error_code: 401
+--- response_body
+{"message":"Missing authorization in request"}
+
+
+
+=== TEST 11: verify jack1
+--- request
+GET /hello
+--- more_headers
+Authorization: Basic amFjazIwMTk6MTIzNDU2
+--- error_code: 403
+--- response_body
+{"message":"request is forbidden"}
+
+
+
+=== TEST 12: verify jack2
+--- request
+GET /hello
+--- more_headers
+Authorization: Basic amFjazIwMjA6MTIzNDU2
+--- response_body
+hello world