Skip to content

Commit

Permalink
fix(admin) proper support for `PUT /{entities}/{entity}/plugins/{plug…
Browse files Browse the repository at this point in the history
…in}`

Prior to this patch, `PUT` requests to plugins under their associated
resources (e.g. `/services/{service}/plugins/{plugin}`) would
systematically return `404`, instead of creating the plugin if it did
not exist. This was because the `before` Lapis hook attempts to retrieve
the plugin in the database before modifying it. Those endpoints are
preserved for backwards-compatibility purposes (being too nested to be
auto-generated), so that workaround is fine.

This patch ensures that we skip this logic with `PUT` requests, plus
makes sure that we set the `self.args.post` arguments according to the
`self.params` arguments (path segments with foreign UUIDs).

Thanks @gszr for the report.

From #4288
  • Loading branch information
thibaultcha authored Feb 7, 2019
1 parent 61112d3 commit 6c1fb39
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 7 deletions.
40 changes: 33 additions & 7 deletions kong/api/routes/plugins.lua
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ local setmetatable = setmetatable


local get_plugin = endpoints.get_entity_endpoint(kong.db.plugins.schema)
local put_plugin = endpoints.put_entity_endpoint(kong.db.plugins.schema)
local delete_plugin = endpoints.delete_entity_endpoint(kong.db.plugins.schema)


local function before_plugin_for_entity(entity_name, plugin_field)
return function(self, db, helpers)
if kong.request.get_method() == "PUT" then
return
end

local entity, _, err_t = endpoints.select_entity(self, db, kong.db[entity_name].schema)
if err_t then
return endpoints.handle_error(err_t)
Expand All @@ -44,8 +47,10 @@ local function before_plugin_for_entity(entity_name, plugin_field)
end


local function fill_plugin_data(args, plugin)
local post = args.post
local function fill_plugin_data(self, plugin)
plugin = plugin or {}

local post = self.args.post

post.name = post.name or plugin.name

Expand All @@ -57,19 +62,40 @@ local function fill_plugin_data(args, plugin)
post.service = post.service or plugin.service
post.consumer = post.consumer or plugin.consumer

args.post = post
if not post.route and self.params.routes then
post.route = { id = self.params.routes }
end

if not post.service and self.params.services then
post.service = { id = self.params.services }
end

if not post.consumer and self.params.consumers then
post.consumer = { id = self.params.consumers }
end

self.args.post = post
end


local patch_plugin
local put_plugin
do
local patch_plugin_endpoint = endpoints.patch_entity_endpoint(kong.db.plugins.schema)
local schema = kong.db.plugins.schema

local patch_plugin_endpoint = endpoints.patch_entity_endpoint(schema)
local put_plugin_endpoint = endpoints.put_entity_endpoint(schema)

patch_plugin = function(self, db, helpers)
local plugin = self.plugin
fill_plugin_data(self.args, plugin)
fill_plugin_data(self, plugin)
return patch_plugin_endpoint(self, db, helpers)
end

put_plugin = function(self, db, helpers)
fill_plugin_data(self)
return put_plugin_endpoint(self, db, helpers)
end
end


Expand Down Expand Up @@ -206,7 +232,7 @@ return {
return kong.response.exit(404, { message = "Not found" })
end

fill_plugin_data(self.args, plugin)
fill_plugin_data(self, plugin)
end
return parent()
end,
Expand Down
59 changes: 59 additions & 0 deletions spec/02-integration/04-admin_api/03-consumers_routes_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -899,6 +899,65 @@ describe("Admin API (#" .. strategy .. "): ", function()
end)
end)

describe("PUT", function()
local inputs = {
["application/x-www-form-urlencoded"] = {
name = "rewriter",
["config.value"] = "updated",
},
["application/json"] = {
name = "rewriter",
config = {
value = "updated",
}
}
}

for content_type, input in pairs(inputs) do
it("creates if not found with " .. content_type, function()
local consumer = bp.consumers:insert()
local plugin_id = utils.uuid()

local res = assert(client:send {
method = "PUT",
path = "/consumers/" .. consumer.id .. "/plugins/" .. plugin_id,
body = input,
headers = { ["Content-Type"] = content_type },
})
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equal("updated", json.config.value)
assert.equal(plugin_id, json.id)

local in_db = assert(db.plugins:select({
id = plugin_id,
}, { nulls = true }))
assert.same(json, in_db)
end)

it("updates if found with " .. content_type, function()
local consumer = bp.consumers:insert()
local plugin = bp.rewriter_plugins:insert({ consumer = { id = consumer.id }})

local res = assert(client:send {
method = "PUT",
path = "/consumers/" .. consumer.id .. "/plugins/" .. plugin.id,
body = input,
headers = { ["Content-Type"] = content_type },
})
local body = assert.res_status(200, res)
local json = cjson.decode(body)
assert.equal("updated", json.config.value)
assert.equal(plugin.id, json.id)

local in_db = assert(db.plugins:select({
id = plugin.id,
}, { nulls = true }))
assert.same(json, in_db)
end)
end
end)

describe("DELETE", function()
it("deletes a plugin configuration", function()
local consumer = bp.consumers:insert()
Expand Down

0 comments on commit 6c1fb39

Please sign in to comment.