-- -- 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. -- local ipairs = ipairs local core = require("apisix.core") local ngx = ngx local schema = { type = "object", properties = { type = { type = "string", enum = {"consumer_name", "service_id", "route_id", "consumer_group_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 = core.schema.method_schema, } } } }, rejected_code = {type = "integer", minimum = 200, default = 403}, rejected_msg = {type = "string"} }, anyOf = { {required = {"blacklist"}}, {required = {"whitelist"}}, {required = {"allowed_by_methods"}} }, } local plugin_name = "consumer-restriction" local _M = { version = 0.1, priority = 2400, name = plugin_name, schema = schema, } local fetch_val_funcs = { ["route_id"] = function(ctx) return ctx.route_id end, ["service_id"] = function(ctx) return ctx.service_id end, ["consumer_name"] = function(ctx) return ctx.consumer_name end, ["consumer_group_id"] = function (ctx) return ctx.consumer_group_id end } local function is_include(value, tab) for k,v in ipairs(tab) do if v == value then return true end end return false end local function is_method_allowed(allowed_methods, method, user) for _, value in ipairs(allowed_methods) do if value.user == user then for _, allowed_method in ipairs(value.methods) do if allowed_method == method then return true end end return false end end return true end local function reject(conf) if conf.rejected_msg then return conf.rejected_code , { message = conf.rejected_msg } end return conf.rejected_code , { message = "The " .. conf.type .. " is forbidden."} end function _M.check_schema(conf) local ok, err = core.schema.check(schema, conf) if not ok then return false, err end return true end function _M.access(conf, ctx) local value = fetch_val_funcs[conf.type](ctx) local method = ngx.req.get_method() if not value then local err_msg = "The request is rejected, please check the " .. conf.type .. " for this request" return 401, { message = err_msg} end core.log.info("value: ", value) local block = false local whitelisted = false if conf.blacklist and #conf.blacklist > 0 then if is_include(value, conf.blacklist) then return reject(conf) end end if conf.whitelist and #conf.whitelist > 0 then whitelisted = is_include(value, conf.whitelist) if not whitelisted then block = true end end if conf.allowed_by_methods and #conf.allowed_by_methods > 0 and not whitelisted then if not is_method_allowed(conf.allowed_by_methods, method, value) then block = true end end if block then return reject(conf) end end return _M