331 lines
11 KiB
Lua
331 lines
11 KiB
Lua
local ssl_fixtures = require "spec.fixtures.ssl"
|
|
local helpers = require "spec.helpers"
|
|
local cjson = require "cjson"
|
|
|
|
|
|
local ca_cert = [[
|
|
-----BEGIN CERTIFICATE-----
|
|
MIIEvjCCAqagAwIBAgIJALabx/Nup200MA0GCSqGSIb3DQEBCwUAMBMxETAPBgNV
|
|
BAMMCFlvbG80Mi4xMCAXDTE5MDkxNTE2Mjc1M1oYDzIxMTkwODIyMTYyNzUzWjAT
|
|
MREwDwYDVQQDDAhZb2xvNDIuMTCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoC
|
|
ggIBANIW67Ay0AtTeBY2mORaGet/VPL5jnBRz0zkZ4Jt7fEq3lbxYaJBnFI8wtz3
|
|
bHLtLsxkvOFujEMY7HVd+iTqbJ7hLBtK0AdgXDjf+HMmoWM7x0PkZO+3XSqyRBbI
|
|
YNoEaQvYBNIXrKKJbXIU6higQaXYszeN8r3+RIbcTIlZxy28msivEGfGTrNujQFc
|
|
r/eyf+TLHbRqh0yg4Dy/U/T6fqamGhFrjupRmOMugwF/BHMH2JHhBYkkzuZLgV2u
|
|
7Yh1S5FRlh11am5vWuRSbarnx72hkJ99rUb6szOWnJKKew8RSn3CyhXbS5cb0QRc
|
|
ugRc33p/fMucJ4mtCJ2Om1QQe83G1iV2IBn6XJuCvYlyWH8XU0gkRxWD7ZQsl0bB
|
|
8AFTkVsdzb94OM8Y6tWI5ybS8rwl8b3r3fjyToIWrwK4WDJQuIUx4nUHObDyw+KK
|
|
+MmqwpAXQWbNeuAc27FjuJm90yr/163aGuInNY5Wiz6CM8WhFNAi/nkEY2vcxKKx
|
|
irSdSTkbnrmLFAYrThaq0BWTbW2mwkOatzv4R2kZzBUOiSjRLPnbyiPhI8dHLeGs
|
|
wMxiTXwyPi8iQvaIGyN4DPaSEiZ1GbexyYFdP7sJJD8tG8iccbtJYquq3cDaPTf+
|
|
qv5M6R/JuMqtUDheLSpBNK+8vIe5e3MtGFyrKqFXdynJtfHVAgMBAAGjEzARMA8G
|
|
A1UdEwQIMAYBAf8CAQAwDQYJKoZIhvcNAQELBQADggIBAK0BmL5B1fPSMbFy8Hbc
|
|
/ESEunt4HGaRWmZZSa/aOtTjhKyDXLLJZz3C4McugfOf9BvvmAOZU4uYjfHTnNH2
|
|
Z3neBkdTpQuJDvrBPNoCtJns01X/nuqFaTK/Tt9ZjAcVeQmp51RwhyiD7nqOJ/7E
|
|
Hp2rC6gH2ABXeexws4BDoZPoJktS8fzGWdFBCHzf4mCJcb4XkI+7GTYpglR818L3
|
|
dMNJwXeuUsmxxKScBVH6rgbgcEC/6YwepLMTHB9VcH3X5VCfkDIyPYLWmvE0gKV7
|
|
6OU91E2Rs8PzbJ3EuyQpJLxFUQp8ohv5zaNBlnMb76UJOPR6hXfst5V+e7l5Dgwv
|
|
Dh4CeO46exmkEsB+6R3pQR8uOFtubH2snA0S3JA1ji6baP5Y9Wh9bJ5McQUgbAPE
|
|
sCRBFoDLXOj3EgzibohC5WrxN3KIMxlQnxPl3VdQvp4gF899mn0Z9V5dAsGPbxRd
|
|
quE+DwfXkm0Sa6Ylwqrzu2OvSVgbMliF3UnWbNsDD5KcHGIaFxVC1qkwK4cT3pyS
|
|
58i/HAB2+P+O+MltQUDiuw0OSUFDC0IIjkDfxLVffbF+27ef9C5NG81QlwTz7TuN
|
|
zeigcsBKooMJTszxCl6dtxSyWTj7hJWXhy9pXsm1C1QulG6uT4RwCa3m0QZoO7G+
|
|
6Wu6lP/kodPuoNubstIuPdi2
|
|
-----END CERTIFICATE-----
|
|
]]
|
|
|
|
|
|
for _, strategy in helpers.each_strategy() do
|
|
describe("/ca_certificates with DB: #" .. strategy, function()
|
|
local client, bp, db
|
|
|
|
lazy_setup(function()
|
|
bp, db = helpers.get_db_utils(strategy, {
|
|
"ca_certificates",
|
|
"services",
|
|
})
|
|
|
|
assert(helpers.start_kong {
|
|
database = strategy,
|
|
})
|
|
|
|
client = assert(helpers.admin_client(10000))
|
|
end)
|
|
|
|
it("GET", function()
|
|
local res = client:get("/ca_certificates")
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
assert.equal(0, #json.data)
|
|
|
|
res = client:post("/ca_certificates", {
|
|
body = {
|
|
cert = ssl_fixtures.cert_ca,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
assert.res_status(201, res)
|
|
|
|
res = client:get("/ca_certificates")
|
|
body = assert.res_status(200, res)
|
|
json = cjson.decode(body)
|
|
assert.equal(1, #json.data)
|
|
assert.equals(json.data[1].cert, ssl_fixtures.cert_ca)
|
|
end)
|
|
|
|
describe("POST", function()
|
|
it("succeeds", function()
|
|
local res = client:post("/ca_certificates", {
|
|
body = {
|
|
cert = ca_cert,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
assert.res_status(201, res)
|
|
end)
|
|
|
|
it("missing field", function()
|
|
local res = client:post("/ca_certificates", {
|
|
body = { },
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (cert: required field missing)", json.message)
|
|
end)
|
|
|
|
it("non CA cert", function()
|
|
local res = client:post("/ca_certificates", {
|
|
body = {
|
|
cert = ssl_fixtures.cert,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate does not appear to be a CA because it is missing the \"CA\" basic constraint)", json.message)
|
|
end)
|
|
|
|
it("expired cert", function()
|
|
local res = client:post("/ca_certificates", {
|
|
body = {
|
|
cert = ssl_fixtures.cert_alt,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate expired, \"Not After\" time is in the past)", json.message)
|
|
end)
|
|
|
|
it("multiple certs", function()
|
|
local res = client:post("/ca_certificates", {
|
|
body = {
|
|
cert = ssl_fixtures.cert .. "\n" .. ssl_fixtures.cert,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (please submit only one certificate at a time)", json.message)
|
|
end)
|
|
end)
|
|
|
|
describe("DELETE", function()
|
|
local ca
|
|
|
|
lazy_setup(function()
|
|
db:truncate("ca_certificates")
|
|
ca = assert(bp.ca_certificates:insert())
|
|
end)
|
|
|
|
it("not allowed to delete if it is referenced by other entities", function()
|
|
-- add a service that references the ca
|
|
local res = client:post("/services/", {
|
|
body = {
|
|
url = "https://" .. helpers.mock_upstream_host .. ":" .. helpers.mock_upstream_port,
|
|
protocol = "https",
|
|
ca_certificates = { ca.id },
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
local body = assert.res_status(201, res)
|
|
local service = cjson.decode(body)
|
|
|
|
helpers.wait_for_all_config_update()
|
|
|
|
local res = client:delete("/ca_certificates/" .. ca.id)
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("ca certificate " .. ca.id .. " is still referenced by services (id = " .. service.id .. ")", json.message)
|
|
|
|
local res = client:delete("/services/" .. service.id)
|
|
assert.res_status(204, res)
|
|
end)
|
|
|
|
it("works", function()
|
|
local res = client:delete("/ca_certificates/" .. ca.id)
|
|
assert.res_status(204, res)
|
|
|
|
res = client:get("/ca_certificates")
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
assert.equal(0, #json.data)
|
|
end)
|
|
end)
|
|
|
|
describe("PATCH", function()
|
|
local ca
|
|
|
|
lazy_setup(function()
|
|
db:truncate("ca_certificates")
|
|
ca = assert(bp.ca_certificates:insert())
|
|
end)
|
|
|
|
it("non CA cert", function()
|
|
local res = client:patch("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate does not appear to be a CA because it is missing the \"CA\" basic constraint)", json.message)
|
|
end)
|
|
|
|
it("expired cert", function()
|
|
local res = client:patch("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert_alt,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate expired, \"Not After\" time is in the past)", json.message)
|
|
end)
|
|
|
|
it("works", function()
|
|
ngx.sleep(1)
|
|
local res = client:patch("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert_ca,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(200, res)
|
|
local new_ca = assert(cjson.decode(body))
|
|
|
|
assert.truthy(ca.updated_at < new_ca.updated_at)
|
|
end)
|
|
end)
|
|
|
|
describe("PUT", function()
|
|
local ca
|
|
|
|
lazy_setup(function()
|
|
db:truncate("ca_certificates")
|
|
ca = assert(bp.ca_certificates:insert())
|
|
end)
|
|
|
|
it("missing field", function()
|
|
local res = client:put("/ca_certificates/" .. ca.id, {
|
|
body = { },
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (cert: required field missing)", json.message)
|
|
end)
|
|
|
|
it("non CA cert", function()
|
|
local res = client:put("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate does not appear to be a CA because it is missing the \"CA\" basic constraint)", json.message)
|
|
end)
|
|
|
|
it("expired cert", function()
|
|
local res = client:put("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert_alt,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
local body = assert.res_status(400, res)
|
|
local json = cjson.decode(body)
|
|
|
|
assert.equal("schema violation (certificate expired, \"Not After\" time is in the past)", json.message)
|
|
end)
|
|
|
|
it("updates existing cert", function()
|
|
local res = client:put("/ca_certificates/" .. ca.id, {
|
|
body = {
|
|
cert = ssl_fixtures.cert_ca,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
assert.res_status(200, res)
|
|
|
|
res = client:get("/ca_certificates")
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
assert.equal(1, #json.data)
|
|
assert.equals(json.data[1].cert, ssl_fixtures.cert_ca)
|
|
end)
|
|
|
|
it("creates new cert when uuid does not exist", function()
|
|
db:truncate("ca_certificates")
|
|
|
|
local res = client:put("/ca_certificates/123e4567-e89b-12d3-a456-426655440000", {
|
|
body = {
|
|
cert = ssl_fixtures.cert_ca,
|
|
},
|
|
headers = { ["Content-Type"] = "application/json" },
|
|
})
|
|
|
|
assert.res_status(200, res)
|
|
|
|
local res = client:get("/ca_certificates/123e4567-e89b-12d3-a456-426655440000")
|
|
local body = assert.res_status(200, res)
|
|
local json = cjson.decode(body)
|
|
assert.equal(ssl_fixtures.cert_ca, json.cert)
|
|
end)
|
|
end)
|
|
|
|
lazy_teardown(function()
|
|
if client then client:close() end
|
|
helpers.stop_kong()
|
|
end)
|
|
end)
|
|
end
|