kong/spec/03-plugins/29-acme/01-client_spec.lua (238 lines of code) (raw):
local util = require("resty.acme.util")
local helpers = require "spec.helpers"
local cjson = require "cjson"
local pkey = require("resty.openssl.pkey")
local x509 = require("resty.openssl.x509")
local client
local function new_cert_key_pair(expire)
local key = pkey.new(nil, 'EC', 'prime256v1')
local crt = x509.new()
crt:set_pubkey(key)
crt:set_version(3)
if expire then
crt:set_not_after(expire)
end
crt:sign(key)
return key:to_PEM("private"), crt:to_PEM()
end
local strategies = {}
for _, strategy in helpers.each_strategy() do
table.insert(strategies, strategy)
end
table.insert(strategies, "off")
local proper_config = {
account_email = "someone@somedomain.com",
api_uri = "http://api.someacme.org",
storage = "shm",
storage_config = {
shm = { shm_name = "kong" },
},
renew_threshold_days = 30,
}
for _, strategy in ipairs(strategies) do
local _, db
lazy_setup(function()
_, db = helpers.get_db_utils(strategy, {
"acme_storage"
}, { "acme", })
client = require("kong.plugins.acme.client")
local account_name = client._account_name(proper_config)
local fake_cache = {
[account_name] = {
key = util.create_pkey(),
kid = "fake kid url",
},
}
kong.cache = {
get = function(_, _, _, f, _, k)
return fake_cache[k]
end
}
db.acme_storage:insert {
key = account_name,
value = fake_cache[account_name],
}
end)
describe("Plugin: acme (client.new) [#" .. strategy .. "]", function()
it("rejects invalid account config", function()
local c, err = client.new({
storage = "shm",
storage_config = {
shm = nil,
},
api_uri = proper_config.api_uri,
account_email = "notme@exmaple.com",
})
assert.is_nil(c)
assert.equal(err, "shm is not defined in plugin storage config")
end)
it("creates acme client properly", function()
local c, err = client.new(proper_config)
assert.is_nil(err)
assert.not_nil(c)
end)
end)
end
for _, strategy in helpers.each_strategy() do
describe("Plugin: acme (client.save) [#" .. strategy .. "]", function()
local bp, db
local cert, sni
local host = "test1.com"
lazy_setup(function()
bp, db = helpers.get_db_utils(strategy, {
"certificates",
"snis",
}, { "acme", })
local key, crt = new_cert_key_pair()
cert = bp.certificates:insert {
cert = crt,
key = key,
tags = { "managed-by-acme" },
}
sni = bp.snis:insert {
name = host,
certificate = cert,
tags = { "managed-by-acme" },
}
end)
describe("creates new cert", function()
local key, crt = new_cert_key_pair()
local new_sni, new_cert, err
local new_host = "test2.com"
it("returns no error", function()
err = client._save_dao(new_host, key, crt)
assert.is_nil(err)
end)
it("create new sni", function()
new_sni, err = db.snis:select_by_name(new_host)
assert.is_nil(err)
assert.not_nil(new_sni.certificate.id)
end)
it("create new certificate", function()
new_cert, err = db.certificates:select({ id = new_sni.certificate.id })
assert.is_nil(err)
assert.same(new_cert.key, key)
assert.same(new_cert.cert, crt)
end)
end)
describe("update", function()
local key, crt = new_cert_key_pair()
local new_sni, new_cert, err
it("returns no error", function()
err = client._save_dao(host, key, crt)
assert.is_nil(err)
end)
it("updates existing sni", function()
new_sni, err = db.snis:select_by_name(host)
assert.is_nil(err)
assert.same(new_sni.id, sni.id)
assert.not_nil(new_sni.certificate.id)
assert.not_same(new_sni.certificate.id, sni.certificate.id)
end)
it("creates new certificate", function()
new_cert, err = db.certificates:select({ id = new_sni.certificate.id })
assert.is_nil(err)
assert.same(new_cert.key, key)
assert.same(new_cert.cert, crt)
end)
it("deletes old certificate", function()
new_cert, err = db.certificates:select({ id = cert.id })
assert.is_nil(err)
assert.is_nil(new_cert)
end)
end)
end)
end
for _, strategy in ipairs({"off"}) do
describe("Plugin: acme (client.renew) [#" .. strategy .. "]", function()
local bp
local cert
local host = "test1.com"
local host_not_expired = "test2.com"
-- make it due for renewal
local key, crt = new_cert_key_pair(ngx.time() - 23333)
-- make it not due for renewal
local key_not_expired, crt_not_expired = new_cert_key_pair(ngx.time() + 365 * 86400)
lazy_setup(function()
bp, _ = helpers.get_db_utils(strategy, {
"certificates",
"snis",
}, { "acme", })
cert = bp.certificates:insert {
cert = crt,
key = key,
tags = { "managed-by-acme" },
}
bp.snis:insert {
name = host,
certificate = cert,
tags = { "managed-by-acme" },
}
cert = bp.certificates:insert {
cert = crt_not_expired,
key = key_not_expired,
tags = { "managed-by-acme" },
}
bp.snis:insert {
name = host_not_expired,
certificate = cert,
tags = { "managed-by-acme" },
}
client = require("kong.plugins.acme.client")
-- hack in unit test mode
client._set_is_dbless(strategy == "off")
end)
describe("", function()
it("deletes renew config is cert is deleted", function()
local c, err = client.new(proper_config)
assert.is_nil(err)
local host = "dne.konghq.com"
-- write a dummy renew config
err = c.storage:set(client._renew_key_prefix .. host, cjson.encode({
host = host,
-- make it due for renewal
expire_at = ngx.time() - 23333,
}))
assert.is_nil(err)
-- do the renewal
err = client._renew_certificate_storage(proper_config)
assert.is_nil(err)
-- the dummy config should now be deleted
local v, err = c.storage:get(client._renew_key_prefix .. host)
assert.is_nil(err)
assert.is_nil(v)
end)
it("renews a certificate when it's expired", function()
local c, err = client.new(proper_config)
assert.is_nil(err)
if strategy == "off" then
err = c.storage:set(client._certkey_key_prefix .. host, cjson.encode({
cert = crt,
key = key,
}))
assert.is_nil(err)
end
local certkey, err = client.load_certkey(proper_config, host)
assert.is_nil(err)
assert.not_nil(certkey)
assert.not_nil(certkey.cert)
assert.not_nil(certkey.key)
-- check renewal
local renew, err = client._check_expire(certkey.cert, 30 * 86400)
assert.is_nil(err)
assert.is_truthy(renew)
end)
it("does not renew a certificate when it's not expired", function()
local c, err = client.new(proper_config)
assert.is_nil(err)
if strategy == "off" then
err = c.storage:set(client._certkey_key_prefix .. host_not_expired, cjson.encode({
cert = crt_not_expired,
key = key_not_expired,
}))
assert.is_nil(err)
end
local certkey, err = client.load_certkey(proper_config, host_not_expired)
assert.is_nil(err)
assert.not_nil(certkey)
assert.not_nil(certkey.cert)
assert.not_nil(certkey.key)
-- check renewal
local renew, err = client._check_expire(certkey.cert, 30 * 86400)
assert.is_nil(err)
assert.is_falsy(renew)
end)
end)
end)
end