Skip to content

Commit

Permalink
feat(pdk) add consumer, service, route handling
Browse files Browse the repository at this point in the history
Adds getters/setters to the PDK for the consumer (+credential),
service, and route entities.
  • Loading branch information
Tieske committed Oct 31, 2018
1 parent 2cf739f commit cd11e54
Show file tree
Hide file tree
Showing 11 changed files with 622 additions and 0 deletions.
1 change: 1 addition & 0 deletions kong-1.0.0rc2-0.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ build = {
["kong.pdk.service"] = "kong/pdk/service.lua",
["kong.pdk.service.request"] = "kong/pdk/service/request.lua",
["kong.pdk.service.response"] = "kong/pdk/service/response.lua",
["kong.pdk.router"] = "kong/pdk/router.lua",
["kong.pdk.request"] = "kong/pdk/request.lua",
["kong.pdk.response"] = "kong/pdk/response.lua",
["kong.pdk.table"] = "kong/pdk/table.lua",
Expand Down
75 changes: 75 additions & 0 deletions kong/pdk/client.lua
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ local phase_checker = require "kong.pdk.private.phases"

local ngx = ngx
local tonumber = tonumber
local check_phase = phase_checker.check
local check_not_phase = phase_checker.check_not


local PHASES = phase_checker.phases
local AUTH_AND_LATER = phase_checker.new(PHASES.access,
PHASES.header_filter,
PHASES.body_filter,
PHASES.log)
local TABLE_OR_NIL = { ["table"] = true, ["nil"] = true }


local function new(self)
Expand Down Expand Up @@ -121,6 +127,75 @@ local function new(self)
end


---
-- Returns the credentials of the currently authenticated consumer.
-- If not set yet, it returns `nil`.
-- @function kong.client.get_credential
-- @phases access, header_filter, body_filter, log
-- @return the authenticated credential
-- @usage
-- local credential = kong.client.get_credential()
-- if credential then
-- consumer_id = credential.consumer_id
-- else
-- -- request not authenticated yet
-- end
function _CLIENT.get_credential()
check_phase(AUTH_AND_LATER)

return ngx.ctx.authenticated_credential
end


---
-- Returns the `consumer` entity of the currently authenticated consumer.
-- If not set yet, it returns `nil`.
-- @function kong.client.get_consumer
-- @phases access, header_filter, body_filter, log
-- @treturn table the authenticated consumer entity
-- @usage
-- local consumer = kong.client.get_consumer()
-- if consumer then
-- consumer_id = consumer.id
-- else
-- -- request not authenticated yet, or a credential
-- -- without a consumer (external auth)
-- end
function _CLIENT.get_consumer()
check_phase(AUTH_AND_LATER)

return ngx.ctx.authenticated_consumer
end


---
-- Sets the authenticated consumer (and credential) for the current request.
-- @function kong.client.authenticate
-- @phases access
-- @tparam table|nil consumer The consumer to set. Note: if no
-- value is provided, then any existing value will be cleared!
-- @tparam table|nil credential The credential to set. Note: if
-- no value is provided, then any existing value will be cleared!
-- @usage
-- -- assuming `credential` and `consumer` have been set by some authentication code
-- kong.client.authenticate(consumer, credentials)
function _CLIENT.authenticate(consumer, credential)
check_phase(PHASES.access)

if not TABLE_OR_NIL[type(consumer)] then
error("consumer must be a table or nil", 2)
elseif not TABLE_OR_NIL[type(credential)] then
error("credential must be a table or nil", 2)
elseif credential == nil and consumer == nil then
error("either credential or consumer must be provided", 2)
end

local ctx = ngx.ctx
ctx.authenticated_consumer = consumer
ctx.authenticated_credential = credential
end


return _CLIENT
end

Expand Down
6 changes: 6 additions & 0 deletions kong/pdk/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,11 @@
-- @redirect kong.response


--- Router module
-- @field kong.router
-- @redirect kong.router


--- Singletons
-- @section singletons

Expand Down Expand Up @@ -226,6 +231,7 @@ local MAJOR_VERSIONS = {
"service.request",
"service.response",
"response",
"router",
},
},

Expand Down
70 changes: 70 additions & 0 deletions kong/pdk/router.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
--- Router module
-- A set of functions to access the routing properties of the request.
--
-- @module kong.router


local phase_checker = require "kong.pdk.private.phases"


local ngx = ngx
local check_phase = phase_checker.check


local PHASES = phase_checker.phases
local ROUTER_PHASES = phase_checker.new(PHASES.access,
PHASES.header_filter,
PHASES.body_filter,
PHASES.log)

local function new(self)
local _ROUTER = {}


---
-- Returns the current `route` entity. The request was matched against this
-- route.
--
-- @function kong.router.get_route
-- @phases access, header_filter, body_filter, log
-- @treturn table the `route` entity.
-- @usage
-- if kong.router.get_route() then
-- -- routed by route & service entities
-- else
-- -- routed by a legacy API entity
-- end
function _ROUTER.get_route()
check_phase(ROUTER_PHASES)

return ngx.ctx.route
end


---
-- Returns the current `service` entity. The request will be targetted to this
-- upstream service.
--
-- @function kong.router.get_service
-- @phases access, header_filter, body_filter, log
-- @treturn table the `service` entity.
-- @usage
-- if kong.router.get_service() then
-- -- routed by route & service entities
-- else
-- -- routed by a legacy API entity
-- end
function _ROUTER.get_service()
check_phase(ROUTER_PHASES)

return ngx.ctx.service
end


return _ROUTER
end


return {
new = new,
}
33 changes: 33 additions & 0 deletions t/01-pdk/05-client/00-phase_checks.t
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,39 @@ qq{
body_filter = true,
log = true,
admin_api = true,
}, {
method = "get_credential",
args = {},
init_worker = "forced false",
certificate = "pending",
rewrite = "forced false",
access = true,
header_filter = true,
body_filter = true,
log = true,
admin_api = "forced false",
}, {
method = "get_consumer",
args = {},
init_worker = "forced false",
certificate = "pending",
rewrite = "forced false",
access = true,
header_filter = true,
body_filter = true,
log = true,
admin_api = "forced false",
}, {
method = "authenticate",
args = {{}, {}},
init_worker = "forced false",
certificate = "pending",
rewrite = "forced false",
access = true,
header_filter = "forced false",
body_filter = "forced false",
log = "forced false",
admin_api = "forced false",
},
}
Expand Down
57 changes: 57 additions & 0 deletions t/01-pdk/05-client/05-get_credential.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use strict;
use warnings FATAL => 'all';
use Test::Nginx::Socket::Lua;
use t::Util;

$ENV{TEST_NGINX_NXSOCK} ||= html_dir();

plan tests => repeat_each() * (blocks() * 3);

run_tests();

__DATA__
=== TEST 1: client.get_credential() returns selected credential
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
content_by_lua_block {
ngx.ctx.authenticated_credential = setmetatable({},{
__tostring = function() return "this credential" end,
})
local PDK = require "kong.pdk"
local pdk = PDK.new()
ngx.say("credential: ", tostring(pdk.client.get_credential()))
}
}
--- request
GET /t
--- response_body
credential: this credential
--- no_error_log
[error]
=== TEST 2: client.get_service() returns nil if not set
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
content_by_lua_block {
ngx.ctx.authenticated_credential = nil
local PDK = require "kong.pdk"
local pdk = PDK.new()
ngx.say("credential: ", tostring(pdk.client.get_credential()))
}
}
--- request
GET /t
--- response_body
credential: nil
--- no_error_log
[error]
57 changes: 57 additions & 0 deletions t/01-pdk/05-client/06-get_consumer.t
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use strict;
use warnings FATAL => 'all';
use Test::Nginx::Socket::Lua;
use t::Util;

$ENV{TEST_NGINX_NXSOCK} ||= html_dir();

plan tests => repeat_each() * (blocks() * 3);

run_tests();

__DATA__
=== TEST 1: client.get_consumer() returns selected consumer
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
content_by_lua_block {
ngx.ctx.authenticated_consumer = setmetatable({},{
__tostring = function() return "this consumer" end,
})
local PDK = require "kong.pdk"
local pdk = PDK.new()
ngx.say("consumer: ", tostring(pdk.client.get_consumer()))
}
}
--- request
GET /t
--- response_body
consumer: this consumer
--- no_error_log
[error]
=== TEST 2: client.get_service() returns nil if not set
--- http_config eval: $t::Util::HttpConfig
--- config
location = /t {
content_by_lua_block {
ngx.ctx.authenticated_consumer = nil
local PDK = require "kong.pdk"
local pdk = PDK.new()
ngx.say("consumer: ", tostring(pdk.client.get_consumer()))
}
}
--- request
GET /t
--- response_body
consumer: nil
--- no_error_log
[error]
Loading

0 comments on commit cd11e54

Please sign in to comment.