352 lines
10 KiB
Lua
352 lines
10 KiB
Lua
local constants = require "kong.constants"
|
|
local helpers = require "spec.helpers"
|
|
local cjson = require "cjson"
|
|
local lower = string.lower
|
|
local splitn = require("kong.tools.string").splitn
|
|
|
|
local REMEMBER_ROLLING_TIMEOUT = 3600
|
|
|
|
for _, strategy in helpers.each_strategy() do
|
|
describe("Plugin: Session (access) [#" .. strategy .. "]", function()
|
|
local client, consumer, credential
|
|
|
|
lazy_setup(function()
|
|
local bp, db = helpers.get_db_utils(strategy, {
|
|
"plugins",
|
|
"routes",
|
|
"services",
|
|
"consumers",
|
|
"keyauth_credentials"
|
|
}, { "ctx-checker" })
|
|
|
|
local route1 = bp.routes:insert {
|
|
paths = {"/test1"},
|
|
hosts = {"konghq.test"},
|
|
}
|
|
|
|
local route2 = bp.routes:insert {
|
|
paths = {"/test2"},
|
|
hosts = {"konghq.test"},
|
|
}
|
|
|
|
local route3 = bp.routes:insert {
|
|
paths = {"/headers"},
|
|
hosts = {"konghq.test"},
|
|
}
|
|
|
|
local route4 = bp.routes:insert {
|
|
paths = {"/headers"},
|
|
hosts = {"mockbin.test"},
|
|
}
|
|
|
|
local route5 = bp.routes:insert {
|
|
paths = {"/test5"},
|
|
hosts = {"httpbin.test"},
|
|
}
|
|
|
|
assert(bp.plugins:insert {
|
|
name = "session",
|
|
route = {
|
|
id = route1.id,
|
|
},
|
|
})
|
|
|
|
assert(bp.plugins:insert {
|
|
name = "session",
|
|
route = {
|
|
id = route2.id,
|
|
},
|
|
config = {
|
|
cookie_name = "da_cookie",
|
|
cookie_same_site = "Lax",
|
|
cookie_http_only = false,
|
|
cookie_secure = false,
|
|
}
|
|
})
|
|
|
|
assert(bp.plugins:insert {
|
|
name = "session",
|
|
route = {
|
|
id = route3.id,
|
|
},
|
|
})
|
|
|
|
assert(bp.plugins:insert {
|
|
name = "session",
|
|
route = {
|
|
id = route4.id,
|
|
},
|
|
})
|
|
|
|
bp.plugins:insert {
|
|
name = "ctx-checker",
|
|
route = { id = route4.id },
|
|
config = {
|
|
ctx_kind = "ngx.ctx",
|
|
ctx_set_field = "authenticated_groups",
|
|
ctx_set_array = { "agents", "doubleagents" },
|
|
}
|
|
}
|
|
|
|
assert(bp.plugins:insert {
|
|
name = "session",
|
|
route = {
|
|
id = route5.id,
|
|
},
|
|
config = {
|
|
remember_rolling_timeout = REMEMBER_ROLLING_TIMEOUT,
|
|
remember = true,
|
|
},
|
|
})
|
|
|
|
consumer = db.consumers:insert({username = "coop"})
|
|
|
|
credential = bp.keyauth_credentials:insert {
|
|
key = "kong",
|
|
consumer = {
|
|
id = consumer.id,
|
|
},
|
|
}
|
|
|
|
local anonymous = bp.consumers:insert { username = "anon", }
|
|
bp.plugins:insert {
|
|
name = "key-auth",
|
|
route = {
|
|
id = route1.id,
|
|
},
|
|
config = {
|
|
anonymous = anonymous.id
|
|
}
|
|
}
|
|
|
|
bp.plugins:insert {
|
|
name = "key-auth",
|
|
route = {
|
|
id = route2.id,
|
|
},
|
|
config = {
|
|
anonymous = anonymous.id
|
|
}
|
|
}
|
|
|
|
bp.plugins:insert {
|
|
name = "key-auth",
|
|
route = {
|
|
id = route3.id,
|
|
},
|
|
config = {
|
|
anonymous = anonymous.id
|
|
}
|
|
}
|
|
|
|
bp.plugins:insert {
|
|
name = "key-auth",
|
|
route = {
|
|
id = route4.id,
|
|
},
|
|
config = {
|
|
anonymous = anonymous.id
|
|
}
|
|
}
|
|
|
|
bp.plugins:insert {
|
|
name = "key-auth",
|
|
route = {
|
|
id = route5.id,
|
|
},
|
|
config = {
|
|
anonymous = anonymous.id
|
|
}
|
|
}
|
|
|
|
bp.plugins:insert {
|
|
name = "request-termination",
|
|
consumer = {
|
|
id = anonymous.id,
|
|
},
|
|
config = {
|
|
status_code = 403,
|
|
message = "So it goes.",
|
|
}
|
|
}
|
|
|
|
assert(helpers.start_kong {
|
|
plugins = "bundled, session, ctx-checker",
|
|
database = strategy,
|
|
nginx_conf = "spec/fixtures/custom_nginx.template",
|
|
})
|
|
end)
|
|
|
|
lazy_teardown(function()
|
|
helpers.stop_kong()
|
|
end)
|
|
|
|
describe("request", function()
|
|
it("plugin attaches Set-Cookie and cookie response headers", function()
|
|
client = helpers.proxy_ssl_client()
|
|
local res = assert(client:send {
|
|
method = "GET",
|
|
path = "/test1/status/200",
|
|
headers = {
|
|
host = "konghq.test",
|
|
apikey = "kong",
|
|
},
|
|
})
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
local cookie = assert.response(res).has.header("Set-Cookie")
|
|
local cookie_name = splitn(cookie, "=", 2)[1]
|
|
assert.equal("session", cookie_name)
|
|
|
|
-- e.g. ["Set-Cookie"] =
|
|
-- "da_cookie=m1EL96jlDyQztslA4_6GI20eVuCmsfOtd6Y3lSo4BTY|15434724
|
|
-- 06|U5W4A6VXhvqvBSf4G_v0-Q|DFJMMSR1HbleOSko25kctHZ44oo; Path=/
|
|
-- ; SameSite=Lax; Secure; HttpOnly"
|
|
local cookie_parts = splitn(cookie, "; ")
|
|
assert.equal("SameSite=Strict", cookie_parts[3])
|
|
assert.equal("Secure", cookie_parts[4])
|
|
assert.equal("HttpOnly", cookie_parts[5])
|
|
end)
|
|
|
|
it("cookie works as authentication after initial auth plugin", function()
|
|
local res, cookie
|
|
local request = {
|
|
method = "GET",
|
|
path = "/test2/status/200",
|
|
headers = { host = "konghq.test", },
|
|
}
|
|
|
|
-- make sure the anonymous consumer can't get in (request termination)
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(403)
|
|
client:close()
|
|
|
|
-- make a request with a valid key, grab the cookie for later
|
|
request.headers.apikey = "kong"
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
cookie = assert.response(res).has.header("Set-Cookie")
|
|
assert.equal("da_cookie", splitn(cookie, "=", 2)[1])
|
|
|
|
local cookie_parts = splitn(cookie, "; ")
|
|
assert.equal("SameSite=Lax", cookie_parts[3])
|
|
assert.equal(nil, cookie_parts[4])
|
|
assert.equal(nil, cookie_parts[5])
|
|
|
|
-- use the cookie without the key to ensure cookie still lets them in
|
|
request.headers.apikey = nil
|
|
request.headers.cookie = cookie
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
end)
|
|
|
|
it("plugin attaches Set-Cookie with max-age/expiry when cookie_persistent is true", function()
|
|
client = helpers.proxy_ssl_client()
|
|
local res = assert(client:send {
|
|
method = "GET",
|
|
path = "/test5/status/200",
|
|
headers = {
|
|
host = "httpbin.test",
|
|
apikey = "kong",
|
|
},
|
|
})
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
local cookie = assert.response(res).has.header("Set-Cookie")
|
|
local cookie_name = splitn(cookie[1], "=", 2)[1]
|
|
assert.equal("session", cookie_name)
|
|
|
|
-- e.g. ["Set-Cookie"] =
|
|
-- "session=m1EL96jlDyQztslA4_6GI20eVuCmsfOtd6Y3lSo4BTY|15434724
|
|
-- 06|U5W4A6VXhvqvBSf4G_v0-Q|DFJMMSR1HbleOSko25kctHZ44oo; Expires=Mon, 06 Jun 2022 08:30:27 GMT;
|
|
-- Max-Age=3600; Path=/; SameSite=Lax; Secure; HttpOnly"
|
|
local cookie_parts = splitn(cookie[2], "; ")
|
|
print(cookie[2])
|
|
assert.equal("Path=/", cookie_parts[2])
|
|
assert.equal("SameSite=Strict", cookie_parts[3])
|
|
assert.equal("Secure", cookie_parts[4])
|
|
assert.equal("HttpOnly", cookie_parts[5])
|
|
assert.truthy(string.match(cookie_parts[6], "^Expires=(.*)"))
|
|
assert.equal("Max-Age=" .. REMEMBER_ROLLING_TIMEOUT, cookie_parts[7])
|
|
end)
|
|
|
|
it("consumer headers are set correctly on request", function()
|
|
local res, cookie
|
|
local request = {
|
|
method = "GET",
|
|
path = "/headers",
|
|
headers = { host = "konghq.test", },
|
|
}
|
|
|
|
-- make a request with a valid key, grab the cookie for later
|
|
request.headers.apikey = "kong"
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
cookie = assert.response(res).has.header("Set-Cookie")
|
|
|
|
request.headers.apikey = nil
|
|
request.headers.cookie = cookie
|
|
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal(consumer.id, json.headers[lower(constants.HEADERS.CONSUMER_ID)])
|
|
assert.equal(consumer.username, json.headers[lower(constants.HEADERS.CONSUMER_USERNAME)])
|
|
if constants.HEADERS.CREDENTIAL_IDENTIFIER then
|
|
assert.equal(credential.id, json.headers[lower(constants.HEADERS.CREDENTIAL_IDENTIFIER)])
|
|
end
|
|
assert.equal(nil, json.headers[lower(constants.HEADERS.ANONYMOUS)])
|
|
assert.equal(nil, json.headers[lower(constants.HEADERS.CONSUMER_CUSTOM_ID)])
|
|
assert.equal(nil, json.headers[lower(constants.HEADERS.AUTHENTICATED_GROUPS)])
|
|
end)
|
|
end)
|
|
|
|
describe("authenticated_groups", function()
|
|
it("groups are retrieved from session and headers are set", function()
|
|
local res, cookie
|
|
local request = {
|
|
method = "GET",
|
|
path = "/headers",
|
|
headers = { host = "mockbin.test", },
|
|
}
|
|
|
|
-- make a request with a valid key, grab the cookie for later
|
|
request.headers.apikey = "kong"
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
cookie = assert.response(res).has.header("Set-Cookie")
|
|
|
|
request.headers.apikey = nil
|
|
request.headers.cookie = cookie
|
|
|
|
client = helpers.proxy_ssl_client()
|
|
res = assert(client:send(request))
|
|
assert.response(res).has.status(200)
|
|
client:close()
|
|
|
|
local json = cjson.decode(assert.res_status(200, res))
|
|
assert.equal('agents, doubleagents', json.headers[lower(constants.HEADERS.AUTHENTICATED_GROUPS)])
|
|
end)
|
|
end)
|
|
end)
|
|
end
|