Skip to content

Commit

Permalink
feat(http-log) Add basic auth header if credentials provided (Kong#2432)
Browse files Browse the repository at this point in the history
* Add Authorization header if userinfo is present
* test(http-log) test Authorization header
  • Loading branch information
Tieske authored Apr 21, 2017
1 parent ff3abad commit bd3858f
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
6 changes: 5 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,15 @@
requests. The added functionality is now described in
[#2211](https://github.com/Mashape/kong/issues/2211), and was implemented in
[#2315](https://github.com/Mashape/kong/pull/2315).
- The http-log plugin will now set a basic-auth authorization header if the
configured log target-url includes credentials. Thanks to
[Amir M. Saeid](https://github.com/amir) for the contribution.
[#2430](https://github.com/Mashape/kong/pull/2430)
- Plugins:
- :fireworks: **New Request termination plugin**. This plugin allows to
temporarily disable an API and return a pre-configured response status and
body to your client. Useful for use-cases such as maintenance mode for your
upstream services. Thanks [Paul Austin](https://github.com/pauldaustin)
upstream services. Thanks to [Paul Austin](https://github.com/pauldaustin)
for the contribution.
[#2051](https://github.com/Mashape/kong/pull/2051)
- Logging plugins: The produced logs now include a `consumer` field,
Expand Down
21 changes: 17 additions & 4 deletions kong/plugins/http-log/handler.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@ local BasePlugin = require "kong.plugins.base_plugin"
local cjson = require "cjson"
local url = require "socket.url"

local string_format = string.format
local cjson_encode = cjson.encode

local HttpLogHandler = BasePlugin:extend()

HttpLogHandler.PRIORITY = 1
Expand All @@ -23,9 +26,19 @@ local function generate_post_payload(method, content_type, parsed_url, body)
else
url = parsed_url.path
end
return string.format(
"%s %s HTTP/1.1\r\nHost: %s\r\nConnection: Keep-Alive\r\nContent-Type: %s\r\nContent-Length: %s\r\n\r\n%s",
method:upper(), url, parsed_url.host, content_type, #body, body)
local headers = string_format(
"%s %s HTTP/1.1\r\nHost: %s\r\nConnection: Keep-Alive\r\nContent-Type: %s\r\nContent-Length: %s\r\n",
method:upper(), url, parsed_url.host, content_type, #body)

if parsed_url.userinfo then
local auth_header = string_format(
"Authorization: Basic %s\r\n",
ngx.encode_base64(parsed_url.userinfo)
)
headers = headers .. auth_header
end

return string_format("%s\r\n%s", headers, body)
end

-- Parse host url.
Expand Down Expand Up @@ -99,7 +112,7 @@ end
-- @param `conf` plugin configuration table, holds http endpoint details
-- @return html body as string
function HttpLogHandler:serialize(ngx, conf)
return cjson.encode(basic_serializer.serialize(ngx))
return cjson_encode(basic_serializer.serialize(ngx))
end

function HttpLogHandler:log(conf)
Expand Down
47 changes: 47 additions & 0 deletions spec/03-plugins/03-http-log/01-log_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ end

local mock_bin_http = create_mock_bin()
local mock_bin_https = create_mock_bin()
local mock_bin_http_basic_auth = create_mock_bin()

describe("Plugin: http-log (log)", function()
local client
Expand Down Expand Up @@ -54,7 +55,21 @@ describe("Plugin: http-log (log)", function()
}
})

local api3 = assert(helpers.dao.apis:insert {
name = "api-3",
hosts = { "http_basic_auth_logging.com" },
upstream_url = "http://mockbin.com"
})
assert(helpers.dao.plugins:insert {
api_id = api3.id,
name = "http-log",
config = {
http_endpoint = "http://testuser:[email protected]/bin/"..mock_bin_http_basic_auth
}
})

assert(helpers.start_kong())

end)
teardown(function()
helpers.stop_kong()
Expand Down Expand Up @@ -124,4 +139,36 @@ describe("Plugin: http-log (log)", function()
end
end, 10)
end)

it("adds authorization if userinfo is present", function()
local res = assert(client:send({
method = "GET",
path = "/status/200",
headers = {
["Host"] = "http_basic_auth_logging.com"
}
}))
assert.res_status(200, res)

helpers.wait_until(function()
local client = assert(helpers.http_client(mockbin_ip, 80))
local res = assert(client:send {
method = "GET",
path = "/bin/"..mock_bin_http_basic_auth.."/log",
headers = {
Host = "mockbin.org",
Accept = "application/json"
}
})
local body = cjson.decode(assert.res_status(200, res))
if #body.log.entries == 1 then
for key, value in pairs(body.log.entries[1].request.headers) do
if value.name == "authorization" then
assert.same("Basic dGVzdHVzZXI6dGVzdHBhc3N3b3Jk", value.value)
return true
end
end
end
end, 10)
end)
end)

0 comments on commit bd3858f

Please sign in to comment.