Skip to content

Commit

Permalink
change(ua-restriction): allowlist and denylist can't be enabled at th…
Browse files Browse the repository at this point in the history
…e same time (#9841)
  • Loading branch information
jiangfucheng authored Jul 24, 2023
1 parent 1ded3a8 commit e6adec5
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 225 deletions.
78 changes: 52 additions & 26 deletions apisix/plugins/ua-restriction.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,8 @@ local type = type
local str_strip = stringx.strip
local re_find = ngx.re.find

local MATCH_NONE = 0
local MATCH_ALLOW = 1
local MATCH_DENY = 2

local lrucache_useragent = core.lrucache.new({ ttl = 300, count = 4096 })
local lrucache_allow = core.lrucache.new({ ttl = 300, count = 4096 })
local lrucache_deny = core.lrucache.new({ ttl = 300, count = 4096 })

local schema = {
type = "object",
Expand Down Expand Up @@ -58,6 +55,10 @@ local schema = {
default = "Not allowed"
},
},
oneOf = {
{required = {"allowlist"}},
{required = {"denylist"}}
}
}

local plugin_name = "ua-restriction"
Expand All @@ -69,27 +70,56 @@ local _M = {
schema = schema,
}

local function match_user_agent(user_agent, conf)
user_agent = str_strip(user_agent)
if conf.allowlist then
for _, rule in ipairs(conf.allowlist) do
local function check_with_allow_list(user_agents, allowlist)
local check = function (user_agent)
user_agent = str_strip(user_agent)

for _, rule in ipairs(allowlist) do
if re_find(user_agent, rule, "jo") then
return MATCH_ALLOW
return true
end
end
return false
end

if conf.denylist then
for _, rule in ipairs(conf.denylist) do
if type(user_agents) == "table" then
for _, v in ipairs(user_agents) do
if lrucache_allow(v, allowlist, check, v) then
return true
end
end
return false
else
return lrucache_allow(user_agents, allowlist, check, user_agents)
end
end


local function check_with_deny_list(user_agents, denylist)
local check = function (user_agent)
user_agent = str_strip(user_agent)

for _, rule in ipairs(denylist) do
if re_find(user_agent, rule, "jo") then
return MATCH_DENY
return false
end
end
return true
end

return MATCH_NONE
if type(user_agents) == "table" then
for _, v in ipairs(user_agents) do
if lrucache_deny(v, denylist, check, v) then
return false
end
end
return true
else
return lrucache_deny(user_agents, denylist, check, user_agents)
end
end


function _M.check_schema(conf)
local ok, err = core.schema.check(schema, conf)

Expand Down Expand Up @@ -118,6 +148,7 @@ function _M.check_schema(conf)
return true
end


function _M.access(conf, ctx)
local user_agent = core.request.header(ctx, "User-Agent")

Expand All @@ -128,21 +159,16 @@ function _M.access(conf, ctx)
return 403, { message = conf.message }
end
end
local match = MATCH_NONE
if type(user_agent) == "table" then
for _, v in ipairs(user_agent) do
if type(v) == "string" then
match = lrucache_useragent(v, conf, match_user_agent, v, conf)
if match > MATCH_ALLOW then
break
end
end
end

local is_passed

if conf.allowlist then
is_passed = check_with_allow_list(user_agent, conf.allowlist)
else
match = lrucache_useragent(user_agent, conf, match_user_agent, user_agent, conf)
is_passed = check_with_deny_list(user_agent, conf.denylist)
end

if match > MATCH_ALLOW then
if not is_passed then
return 403, { message = conf.message }
end
end
Expand Down
2 changes: 1 addition & 1 deletion docs/en/latest/plugins/ua-restriction.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ A common scenario is to set crawler rules. `User-Agent` is the identity of the c

:::note

Both `allowlist` and `denylist` can be used on their own. If they are used together, the `allowlist` matches before the `denylist`.
Both `allowlist` and `denylist` can't be used at the same time.

:::

Expand Down
2 changes: 1 addition & 1 deletion docs/zh/latest/plugins/ua-restriction.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ description: 本文介绍了 Apache APISIX ua-restriction 插件的使用方法

:::note

`allowlist``denylist` 可以同时启用。同时启用时,插件会根据 `User-Agent` 先检查 `allowlist`,再检查 `denylist`
`allowlist``denylist` 不可以同时启用

:::

Expand Down
Loading

0 comments on commit e6adec5

Please sign in to comment.