kong/spec/03-plugins/30-session/02-kong_storage_adapter_spec.lua (270 lines of code) (raw):
local helpers = require "spec.helpers"
local utils = require "kong.tools.utils"
local cjson = require "cjson"
local function get_sid_from_cookie(cookie)
local cookie_parts = utils.split(cookie, "; ")
return utils.split(utils.split(cookie_parts[1], "|")[1], "=")[2]
end
for _, strategy in helpers.each_strategy() do
describe("Plugin: Session (kong storage adapter) [#" .. strategy .. "]", function()
local client, bp, db
lazy_setup(function()
bp, db = helpers.get_db_utils(strategy, {
"sessions",
"plugins",
"routes",
"services",
"consumers",
"keyauth_credentials",
}, { "ctx-checker" })
local route1 = bp.routes:insert {
paths = {"/test1"},
hosts = {"httpbin.org"}
}
local route2 = bp.routes:insert {
paths = {"/test2"},
hosts = {"httpbin.org"}
}
local route3 = bp.routes:insert {
paths = {"/headers"},
hosts = {"httpbin.org"},
}
assert(bp.plugins:insert {
name = "session",
route = {
id = route1.id,
},
config = {
storage = "kong",
secret = "ultra top secret session",
}
})
assert(bp.plugins:insert {
name = "session",
route = {
id = route2.id,
},
config = {
secret = "super secret session secret",
storage = "kong",
cookie_renew = 600,
cookie_lifetime = 604,
}
})
assert(bp.plugins:insert {
name = "session",
route = {
id = route3.id,
},
config = {
storage = "kong",
secret = "ultra top secret session",
}
})
bp.plugins:insert {
name = "ctx-checker",
route = { id = route3.id },
config = {
ctx_kind = "ngx.ctx",
ctx_set_field = "authenticated_groups",
ctx_set_array = { "beatles", "ramones" },
}
}
local consumer = bp.consumers:insert { username = "coop" }
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 = "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("kong adapter - ", function()
it("kong adapter stores consumer", function()
local res, cookie
local request = {
method = "GET",
path = "/test1/status/200",
headers = { host = "httpbin.org", },
}
-- 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)
cookie = assert.response(res).has.header("Set-Cookie")
client:close()
ngx.sleep(2)
-- 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()
-- one more time to ensure session was not destroyed or errored out
client = helpers.proxy_ssl_client()
res = assert(client:send(request))
assert.response(res).has.status(200)
client:close()
-- make sure it's in the db
local sid = get_sid_from_cookie(cookie)
assert.equal(sid, db.sessions:select_by_session_id(sid).session_id)
end)
it("renews cookie", function()
local res, cookie
local request = {
method = "GET",
path = "/test2/status/200",
headers = { host = "httpbin.org", },
}
local function send_requests(request, number, step)
local did_renew = false
cookie = request.headers.cookie
for _ = 1, number do
request.headers.cookie = cookie
client = helpers.proxy_ssl_client()
res = assert(client:send(request))
assert.response(res).has.status(200)
did_renew = did_renew or res.headers['Set-Cookie'] ~= nil
client:close()
cookie = res.headers['Set-Cookie'] or cookie
ngx.sleep(step)
end
return did_renew
end
-- 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")
ngx.sleep(2)
-- 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()
-- renewal period, make sure requests still come through and
-- if set-cookie header comes through, attach it to subsequent requests
assert.is_true(send_requests(request, 7, 0.5))
end)
it("destroys session on logout", function()
local res, cookie
local request = {
method = "GET",
path = "/test2/status/200",
headers = { host = "httpbin.org", },
}
-- 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)
cookie = assert.response(res).has.header("Set-Cookie")
client:close()
ngx.sleep(2)
-- 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()
-- session should be in the table initially
local sid = get_sid_from_cookie(cookie)
assert.equal(sid, db.sessions:select_by_session_id(sid).session_id)
-- logout request
client = helpers.proxy_ssl_client()
res = assert(client:send({
method = "DELETE",
path = "/test2/status/200?session_logout=true",
headers = {
cookie = cookie,
host = "httpbin.org",
}
}))
assert.response(res).has.status(200)
client:close()
local found, err = db.sessions:select_by_session_id(sid)
-- logged out, no sessions should be in the table, without errors
assert.is_nil(found)
assert.is_nil(err)
end)
it("stores authenticated_groups", function()
local res, cookie
local request = {
method = "GET",
path = "/headers",
headers = { host = "httpbin.org", },
}
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)
cookie = assert.response(res).has.header("Set-Cookie")
client:close()
ngx.sleep(2)
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('beatles, ramones', json.headers['x-authenticated-groups'])
end)
end)
end)
end