...
 
Commits (3)
......@@ -92,6 +92,10 @@ You may wish to test externally the email address if it is authorized to connect
To do set the environment variable `PORTIER_AUTHORIZE`; on how to use this you can inspect the provided [examples (`authz*.lua`)](examples).
If your function returns `true`, authorization is considered successful. If you return `false` then the user is rejected, though instead you can return a string instead and the value will be returned to the user to communicate the reason for the authorization failed (eg. expired account, time of day, ...).
If your function explodes, then authorization is considered failed and the user is shown the same message as if you returned `false`.
# Development
Almost the easiest thing here is to slum it with a Docker container (sorry, it is awful) where you can run:
......
......@@ -5,33 +5,33 @@ local m = {}
require "lualdap"
local function normalize(str)
local lastAt = str:find("[^%@]+$")
local localPart = str:sub(1, (lastAt - 2)) -- Returns the substring before '@' symbol
local domainPart = str:sub(lastAt, #str) -- Returns the substring after '@' symbol
return localPart .. "@" .. domainPart:lower()
local lastAt = str:find("[^%@]+$")
local localPart = str:sub(1, (lastAt - 2)) -- Returns the substring before '@' symbol
local domainPart = str:sub(lastAt, #str) -- Returns the substring after '@' symbol
return localPart .. "@" .. domainPart:lower()
end
function m.query(email0)
local ld = assert(lualdap.open_simple("ldap.example.com"))
local ld = assert(lualdap.open_simple("ldap.example.com"))
local email = normalize(email0)
local email = normalize(email0)
local params = {
attrs = "1.1",
base = "dc=example,dc=com",
filter = "(&(objectClass=inetOrgPerson)(mail=" .. email .. "))",
scope = "subtree",
sizelimit = 1
}
local params = {
attrs = "1.1",
base = "dc=example,dc=com",
filter = "(&(objectClass=inetOrgPerson)(mail=" .. email .. "))",
scope = "subtree",
sizelimit = 1
}
local count = 0
for dn in ld:search(params) do
count = count + 1
end
local count = 0
for dn in ld:search(params) do
count = count + 1
end
ld:close()
ld:close()
return count > 0
return count > 0
end
return m
......@@ -15,7 +15,7 @@ end
function base64url_decode (s64url)
local s64 = s64url:gsub("-", "+"):gsub("_", "/")
local pad = s64:len() % 4
if pad > 0 then
if pad > 0 then
s64 = s64 .. string.rep("=", 4 - pad)
end
return ngx.decode_base64(s64)
......
......@@ -44,9 +44,12 @@ end
if authorize then
local success, authorized = pcall(authorize.query, args.email)
if not success or not authorized then
ngx.log(ngx.WARN, "not authorized: '" .. args.email .. "'")
error("not authorized, please contact support")
if not success or not authorized == true then
ngx.log(ngx.WARN, "not authorized: '" .. args.email .. "', reason: " .. tostring(authorized))
if type(authorized) ~= 'string' then
authorized = "not authorized, please contact support"
end
error(authorized)
end
end
......
......@@ -24,8 +24,8 @@ end
local valid, header, payload
valid, header = pcall(function () return json.decode(base64url_decode(header_b64url)) end)
if not valid then
ngx.log(ngx.WARN, "header not valid JSON")
ngx.exit(ngx.HTTP_BAD_REQUEST)
ngx.log(ngx.WARN, "header not valid JSON")
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
if header.alg ~= "RS256" then
ngx.log(ngx.WARN, "unsupported alg '" .. header.alg .. "'")
......@@ -34,8 +34,8 @@ end
valid, payload = pcall(function () return json.decode(base64url_decode(payload_b64url)) end)
if not valid then
ngx.log(ngx.WARN, "payload not valid JSON")
ngx.exit(ngx.HTTP_BAD_REQUEST)
ngx.log(ngx.WARN, "payload not valid JSON")
ngx.exit(ngx.HTTP_BAD_REQUEST)
end
if payload.iss ~= broker then
ngx.log(ngx.ERR, "payload iss mismatch, got '" .. payload.iss .. "', expected '" .. broker .. "'")
......