Files
2026-07-13 12:32:21 +08:00

232 lines
7.9 KiB
Lua

local declarative = require "kong.db.declarative"
local hybrid_helper = require "spec.hybrid"
local crypto = require "kong.plugins.basic-auth.crypto"
local cjson = require "cjson"
hybrid_helper.run_for_each_deploy({ }, function(helpers, strategy, deploy, rpc, rpc_sync)
describe("basic-auth declarative config " .. helpers.format_tags(), function()
local db
lazy_setup(function()
local _
_, db = helpers.get_db_utils(strategy)
-- _G.kong.db = db
end)
lazy_teardown(function()
-- assert(helpers.stop_kong())
end)
local service_def = {
_tags = ngx.null,
connect_timeout = 60000,
created_at = 1549025889,
host = helpers.mock_upstream_hostname,
id = "3b9c2302-a610-4925-a7b9-25942309335d",
name = "foo",
path = ngx.null,
port = helpers.mock_upstream_port,
protocol = helpers.mock_upstream_protocol,
read_timeout = 60000,
retries = 5,
updated_at = 1549025889,
write_timeout = 60000,
}
local route_def = {
_tags = ngx.null,
created_at = 1549025889,
id = "eb88ccb8-274d-4e7e-b4cb-0d673a4fa93b",
name = "bar",
protocols = { "http" },
methods = ngx.null,
hosts = ngx.null,
paths = { "/status/200" },
regex_priority = 0,
strip_path = true,
preserve_host = false,
snis = ngx.null,
sources = ngx.null,
destinations = ngx.null,
service = { id = service_def.id },
}
local consumer_def = {
_tags = ngx.null,
created_at = 1549476023,
id = "ad06b77c-0d2f-407a-8d6d-07f272a92d6a",
username = "andru",
custom_id = "donalds",
}
local basicauth_credential_def = {
id = "ad06b77c-0d2f-407a-8d6d-07f272a92d9a",
consumer = {
id = consumer_def.id,
},
username = "james",
password = "secret",
}
local basicauth_hashed_credential_def = {
id = "caa33a6f-8e6b-4b02-9f55-0e2cffd26fb5",
consumer = {
id = consumer_def.id,
},
username = "bond",
password = crypto.hash(consumer_def.id, "MI6"),
}
local plugin_def = {
_tags = ngx.null,
created_at = 1547047308,
id = "389ad9bd-b158-4e19-aed7-c9b040f7f312",
service = { id = service_def.id },
enabled = true,
name = "basic-auth",
config = {
hide_credentials = true,
realm = "service",
}
}
before_each(function()
db.plugins:truncate()
db.routes:truncate()
db.services:truncate()
db.basicauth_credentials:truncate()
db.consumers:truncate()
assert(declarative.load_into_db({
routes = { [route_def.id] = route_def },
services = { [service_def.id] = service_def },
consumers = { [consumer_def.id] = consumer_def },
plugins = { [plugin_def.id] = plugin_def },
basicauth_credentials = { [basicauth_credential_def.id] = basicauth_credential_def },
}, { _transform = true }))
assert(declarative.load_into_db({
basicauth_credentials = { [basicauth_hashed_credential_def.id] = basicauth_hashed_credential_def },
}, { _transform = false }))
end)
describe("load_into_db", function()
it("imports base and custom entities with associations", function()
local service = assert(db.services:select_by_name("foo"))
assert.equals(service_def.id, service.id)
assert.equals(helpers.mock_upstream_hostname, service.host)
assert.equals("http", service.protocol)
local route = assert(db.routes:select_by_name("bar"))
assert.equals(route_def.id, route.id)
assert.equals("/status/200", route.paths[1])
assert.same({ "http" }, route.protocols)
assert.equals(service_def.id, route.service.id)
local consumer = assert(db.consumers:select_by_username("andru"))
assert.equals(consumer_def.id, consumer.id)
assert.equals("andru", consumer_def.username)
assert.equals("donalds", consumer_def.custom_id)
local plugin = assert(db.plugins:select(plugin_def))
assert.equals(plugin_def.id, plugin.id)
assert.equals(service.id, plugin.service.id)
assert.equals("basic-auth", plugin.name)
assert.same(plugin_def.config, plugin.config)
local basicauth_credential = assert(db.basicauth_credentials:select(basicauth_credential_def))
assert.equals(basicauth_credential_def.id, basicauth_credential.id)
assert.equals(consumer.id, basicauth_credential.consumer.id)
assert.equals("james", basicauth_credential.username)
assert.equals(crypto.hash(consumer.id, "secret"), basicauth_credential.password)
local basicauth_hashed_credential = assert(db.basicauth_credentials:select(basicauth_hashed_credential_def))
assert.equals(basicauth_hashed_credential_def.id, basicauth_hashed_credential.id)
assert.equals(consumer.id, basicauth_hashed_credential.consumer.id)
assert.equals("bond", basicauth_hashed_credential.username)
assert.equals(basicauth_hashed_credential_def.password, basicauth_hashed_credential.password)
end)
end)
describe("access", function()
local proxy_client
before_each(function()
helpers.wait_for_all_config_update()
end)
lazy_setup(function()
assert(helpers.start_kong({
nginx_conf = "spec/fixtures/custom_nginx.template",
database = strategy,
}))
proxy_client = helpers.proxy_client()
end)
lazy_teardown(function()
if proxy_client then
proxy_client:close()
end
assert(helpers.stop_kong())
end)
describe("Unauthorized", function()
it("returns 401 Unauthorized on invalid credentials in Authorization", function()
local res = assert(proxy_client:get("/status/200", {
headers = {
["Authorization"] = "foobar",
}
}))
local body = assert.res_status(401, res)
local json = cjson.decode(body)
assert.not_nil(json)
assert.matches("Unauthorized", json.message)
end)
end)
describe("Authorized", function()
it("Accepts valid credentials", function()
local creds = "Basic " .. ngx.encode_base64(
string.format("%s:%s", basicauth_credential_def.username,
basicauth_credential_def.password))
local res = assert(proxy_client:get("/status/200", {
headers = {
["Authorization"] = creds,
}
}))
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equal(consumer_def.id, json.headers["x-consumer-id"])
assert.equal(consumer_def.username, json.headers["x-consumer-username"])
assert.equal(consumer_def.custom_id, json.headers["x-consumer-custom-id"])
assert.equal(basicauth_credential_def.username, json.headers["x-credential-identifier"])
end)
it("Accepts valid credentials (introduced with a hashed password)", function()
local creds = "Basic " .. ngx.encode_base64(
string.format("%s:%s", basicauth_hashed_credential_def.username,
"MI6"))
local res = assert(proxy_client:get("/status/200", {
headers = {
["Authorization"] = creds,
}
}))
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equal(consumer_def.id, json.headers["x-consumer-id"])
assert.equal(consumer_def.username, json.headers["x-consumer-username"])
assert.equal(consumer_def.custom_id, json.headers["x-consumer-custom-id"])
assert.equal(basicauth_hashed_credential_def.username, json.headers["x-credential-identifier"])
end)
end)
end)
end)
end)