Skip to content

Commit

Permalink
refactor: keyauth/basicauth APIs + their tests
Browse files Browse the repository at this point in the history
- keyauth and basicauth plugins now have their APIs updated and their
  route feels more RESTful too, they are accessible via
  /consumers/:consumer/keyauth
- A migration was needed to be able to retrieve them per consumer.
- Slightly better file structure

Related to #98
  • Loading branch information
thibaultcha committed May 22, 2015
1 parent e54cf0d commit 4c05c13
Show file tree
Hide file tree
Showing 16 changed files with 545 additions and 190 deletions.
19 changes: 19 additions & 0 deletions database/migrations/cassandra/2015-05-22-235608_plugins_fix.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
local Migration = {
name = "2015-05-22-235608_plugins_fix",

up = function(options)
return [[
CREATE INDEX IF NOT EXISTS ON keyauth_credentials(consumer_id);
CREATE INDEX IF NOT EXISTS ON basicauth_credentials(consumer_id);
]]
end,

down = function(options)
return [[
DROP INDEX keyauth_credentials_consumer_id_idx;
DROP INDEX basicauth_credentials_consumer_id_idx;
]]
end
}

return Migration
3 changes: 2 additions & 1 deletion kong-0.3.0-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@ build = {
["kong.plugins.ssl.schema"] = "kong/plugins/ssl/schema.lua",

["kong.api.app"] = "kong/api/app.lua",
["kong.api.crud_helpers"] = "kong/api/crud_helpers.lua",
["kong.api.routes.kong"] = "kong/api/routes/kong.lua",
["kong.api.routes.apis"] = "kong/api/routes/apis.lua",
["kong.api.routes.consumers"] = "kong/api/routes/consumers.lua",
["kong.api.routes.plugins_configurations"] = "kong/api/routes/plugins_configurations.lua",
["kong.api.routes.base_controller"] = "kong/api/routes/base_controller.lua"
},
install = {
conf = { "kong.yml" },
Expand Down
8 changes: 5 additions & 3 deletions kong/api/app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,8 @@ local function parse_params(fn)
end)
end

app.parse_params = parse_params

app.default_route = function(self)
local path = self.req.parsed_url.path:match("^(.*)/$")

Expand Down Expand Up @@ -142,16 +144,16 @@ for _, v in ipairs({"kong", "apis", "consumers", "plugins_configurations"}) do
end

-- Loading plugins routes
--[[if configuration and configuration.plugins_available then
if configuration and configuration.plugins_available then
for _, v in ipairs(configuration.plugins_available) do
local loaded, mod = utils.load_module_if_exists("kong.plugins."..v..".api")
if loaded then
ngx.log(ngx.DEBUG, "Loading API endpoints for plugin: "..v)
mod()
attach_routes(mod)
else
ngx.log(ngx.DEBUG, "No API endpoints loaded for plugin: "..v)
end
end
end]]
end

return app
49 changes: 43 additions & 6 deletions kong/api/crud_helpers.lua
Original file line number Diff line number Diff line change
@@ -1,8 +1,45 @@
local responses = require "kong.tools.responses"
local validations = require "kong.dao.schemas"
local app_helpers = require "lapis.application"

local _M = {}

function _M.find_api_by_name_or_id(self, dao_factory, helpers)
local fetch_keys = {
[validations.is_valid_uuid(self.params.name_or_id) and "id" or "name"] = self.params.name_or_id
}
self.params.name_or_id = nil

-- TODO: make the base_dao more flexible so we can query find_one with key/values
-- https://github.com/Mashape/kong/issues/103
local data, err = dao_factory.apis:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.api = data[1]
if not self.api then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end

function _M.find_consumer_by_username_or_id(self, dao_factory, helpers)
local fetch_keys = {
[validations.is_valid_uuid(self.params.username_or_id) and "id" or "username"] = self.params.username_or_id
}
self.params.username_or_id = nil

local data, err = dao_factory.consumers:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.consumer = data[1]
if not self.consumer then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end

function _M.paginated_set(self, dao_collection)
local size = self.params.size and tonumber(self.params.size) or 100
local offset = self.params.offset and ngx.decode_base64(self.params.offset) or nil
Expand Down Expand Up @@ -35,17 +72,17 @@ function _M.paginated_set(self, dao_collection)
return responses.send_HTTP_OK(result, type(result) ~= "table")
end

function _M.put(self, dao_collection)
function _M.put(params, dao_collection)
local new_entity, err
if self.params.id then
new_entity, err = dao_collection:update(self.params)
if params.id then
new_entity, err = dao_collection:update(params)
if not err and new_entity then
return responses.send_HTTP_OK(new_entity)
elseif not new_entity then
return responses.send_HTTP_NOT_FOUND()
end
else
new_entity, err = dao_collection:insert(self.params)
new_entity, err = dao_collection:insert(params)
if not err then
return responses.send_HTTP_CREATED(new_entity)
end
Expand All @@ -56,8 +93,8 @@ function _M.put(self, dao_collection)
end
end

function _M.post(self, dao_collection)
local data, err = dao_collection:insert(self.params)
function _M.post(params, dao_collection)
local data, err = dao_collection:insert(params)
if err then
return app_helpers.yield_error(err)
else
Expand Down
67 changes: 22 additions & 45 deletions kong/api/routes/apis.lua
Original file line number Diff line number Diff line change
@@ -1,60 +1,23 @@
local validations = require "kong.dao.schemas"
local crud = require "kong.api.crud_helpers"

local function find_api_by_name_or_id(self, dao_factory, helpers)
local fetch_keys = {
[validations.is_valid_uuid(self.params.name_or_id) and "id" or "name"] = self.params.name_or_id
}
self.params.name_or_id = nil

-- TODO: make the base_dao more flexible so we can query find_one with key/values
-- https://github.com/Mashape/kong/issues/103
local data, err = dao_factory.apis:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.api = data[1]
if not self.api then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end

local function find_plugin_by_name_or_id(self, dao_factory, helpers)
local fetch_keys = {
api_id = self.api.id,
[validations.is_valid_uuid(self.params.plugin_name_or_id) and "id" or "name"] = self.params.plugin_name_or_id
}
self.params.plugin_name_or_id = nil

local data, err = dao_factory.plugins_configurations:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.plugin = data[1]
if not self.plugin then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end

return {
["/apis/"] = {
GET = function(self, dao_factory)
crud.paginated_set(self, dao_factory.apis)
end,

PUT = function(self, dao_factory)
crud.put(self, dao_factory.apis)
crud.put(self.params, dao_factory.apis)
end,

POST = function(self, dao_factory)
crud.post(self, dao_factory.apis)
crud.post(self.params, dao_factory.apis)
end
},

["/apis/:name_or_id"] = {
before = find_api_by_name_or_id,
before = crud.find_api_by_name_or_id,

GET = function(self, dao_factory, helpers)
return helpers.responses.send_HTTP_OK(self.api)
Expand All @@ -72,7 +35,7 @@ return {

["/apis/:name_or_id/plugins/"] = {
before = function(self, dao_factory, helpers)
find_api_by_name_or_id(self, dao_factory, helpers)
crud.find_api_by_name_or_id(self, dao_factory, helpers)
self.params.api_id = self.api.id
end,

Expand All @@ -81,20 +44,34 @@ return {
end,

POST = function(self, dao_factory, helpers)
crud.post(self, dao_factory.plugins_configurations)
crud.post(self.params, dao_factory.plugins_configurations)
end,

PUT = function(self, dao_factory, helpers)
crud.put(self, dao_factory.plugins_configurations)
crud.put(self.params, dao_factory.plugins_configurations)
end
},

["/apis/:name_or_id/plugins/:plugin_name_or_id"] = {
before = function(self, dao_factory, helpers)
find_api_by_name_or_id(self, dao_factory, helpers)
crud.find_api_by_name_or_id(self, dao_factory, helpers)
self.params.api_id = self.api.id

find_plugin_by_name_or_id(self, dao_factory, helpers)
local fetch_keys = {
api_id = self.api.id,
[validations.is_valid_uuid(self.params.plugin_name_or_id) and "id" or "name"] = self.params.plugin_name_or_id
}
self.params.plugin_name_or_id = nil

local data, err = dao_factory.plugins_configurations:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.plugin = data[1]
if not self.plugin then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end,

GET = function(self, dao_factory, helpers)
Expand Down
20 changes: 3 additions & 17 deletions kong/api/routes/consumers.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
local validations = require("kong.dao.schemas")
local crud = require "kong.api.crud_helpers"

return {
Expand All @@ -8,30 +7,17 @@ return {
end,

PUT = function(self, dao_factory)
crud.put(self, dao_factory.consumers)
crud.put(self.params, dao_factory.consumers)
end,

POST = function(self, dao_factory)
crud.post(self, dao_factory.consumers)
crud.post(self.params, dao_factory.consumers)
end
},

["/consumers/:username_or_id"] = {
before = function(self, dao_factory, helpers)
local fetch_keys = {
[validations.is_valid_uuid(self.params.username_or_id) and "id" or "username"] = self.params.username_or_id
}
self.params.username_or_id = nil

local data, err = dao_factory.consumers:find_by_keys(fetch_keys)
if err then
return helpers.yield_error(err)
end

self.consumer = data[1]
if not self.consumer then
return helpers.responses.send_HTTP_NOT_FOUND()
end
crud.find_consumer_by_username_or_id(self, dao_factory, helpers)
end,

GET = function(self, dao_factory, helpers)
Expand Down
4 changes: 2 additions & 2 deletions kong/api/routes/plugins_configurations.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ return {
end,

PUT = function(self, dao_factory)
crud.put(self, dao_factory.plugins_configurations)
crud.put(self.params, dao_factory.plugins_configurations)
end,

POST = function(self, dao_factory)
crud.post(self, dao_factory.plugins_configurations)
crud.post(self.params, dao_factory.plugins_configurations)
end
},

Expand Down
54 changes: 47 additions & 7 deletions kong/plugins/basicauth/api.lua
Original file line number Diff line number Diff line change
@@ -1,11 +1,51 @@
-- Copyright (C) Mashape, Inc.
local crud = require "kong.api.crud_helpers"

local BaseController = require "kong.api.routes.base_controller"
return {
["/consumers/:username_or_id/basicauth/"] = {
before = function(self, dao_factory, helpers)
crud.find_consumer_by_username_or_id(self, dao_factory, helpers)
self.params.consumer_id = self.consumer.id
end,

local BasicAuthCredentials = BaseController:extend()
GET = function(self, dao_factory, helpers)
crud.paginated_set(self, dao_factory.basicauth_credentials)
end,

function BasicAuthCredentials:new()
BasicAuthCredentials.super.new(self, dao.basicauth_credentials, "basicauth_credentials")
end
PUT = function(self, dao_factory)
crud.put(self.params, dao_factory.basicauth_credentials)
end,

return BasicAuthCredentials
POST = function(self, dao_factory)
crud.post(self.params, dao_factory.basicauth_credentials)
end
},

["/consumers/:username_or_id/basicauth/:id"] = {
before = function(self, dao_factory, helpers)
crud.find_consumer_by_username_or_id(self, dao_factory, helpers)
self.params.consumer_id = self.consumer.id

local data, err = dao_factory.basicauth_credentials:find_by_keys({ id = self.params.id })
if err then
return helpers.yield_error(err)
end

self.credential = data[1]
if not self.credential then
return helpers.responses.send_HTTP_NOT_FOUND()
end
end,

GET = function(self, dao_factory, helpers)
return helpers.responses.send_HTTP_OK(self.credential)
end,

PATCH = function(self, dao_factory)
crud.patch(self.params, dao_factory.basicauth_credentials)
end,

DELETE = function(self, dao_factory)
crud.delete(self.credential.id, dao_factory.basicauth_credentials)
end
}
}
Loading

0 comments on commit 4c05c13

Please sign in to comment.