[fix] Separate files properly

This commit is contained in:
kload 2015-02-12 12:08:52 +01:00
parent 84015149b9
commit 35e69a1bf2
3 changed files with 189 additions and 178 deletions

View file

@ -6,9 +6,20 @@
-- request is handled: redirected, forbidden, bypassed or served. -- request is handled: redirected, forbidden, bypassed or served.
-- --
-- Get the `cache` persistent shared table
cache = ngx.shared.cache
-- Initialize configuration -- Generate a unique token if it has not been generated yet
require "config" srvkey = cache:get("srvkey")
if not srvkey then
math.randomseed(os.time())
srvkey = tostring(math.random(1111111, 9999999))
cache:add("srvkey", srvkey)
end
-- Initialize and get configuration
config = require "config"
conf = config.get_config()
-- Initialize the non-persistent cookie table -- Initialize the non-persistent cookie table
cookies = {} cookies = {}
@ -32,13 +43,17 @@ if ngx.var.host ~= conf["portal_domain"] and ngx.var.request_method == "GET" the
uri_args = ngx.req.get_uri_args() uri_args = ngx.req.get_uri_args()
if uri_args[conf.login_arg] then if uri_args[conf.login_arg] then
cda_key = uri_args[conf.login_arg] cda_key = uri_args[conf.login_arg]
-- Use the `login` shared table where a username is associated with
-- a CDA key
if login[cda_key] then if login[cda_key] then
set_auth_cookie(login[cda_key], ngx.var.host) hlp.set_auth_cookie(login[cda_key], ngx.var.host)
ngx.log(ngx.NOTICE, "Cross-domain authentication: "..login[cda_key].." connected on "..ngx.var.host) ngx.log(ngx.NOTICE, "Cross-domain authentication: "..login[cda_key].." connected on "..ngx.var.host)
login[cda_key] = nil login[cda_key] = nil
uri_args[conf.login_arg] = nil
return redirect(ngx.var.uri..uri_args_string(uri_args))
end end
uri_args[conf.login_arg] = nil
return hlp.redirect(ngx.var.uri..hlp.uri_args_string(uri_args))
end end
end end
@ -52,26 +67,30 @@ end
-- portal operations -- portal operations
-- --
if ngx.var.host == conf["portal_domain"] if ngx.var.host == conf["portal_domain"]
and string.starts(ngx.var.uri, string.sub(conf["portal_path"], 1, -2)) and hlp.string.starts(ngx.var.uri, string.sub(conf["portal_path"], 1, -2))
then then
-- `GET` method will serve a portal file
if ngx.var.request_method == "GET" then if ngx.var.request_method == "GET" then
-- Force portal scheme -- Force portal scheme
if ngx.var.scheme ~= conf["portal_scheme"] then if ngx.var.scheme ~= conf["portal_scheme"] then
return redirect(portal_url) return hlp.redirect(conf.portal_url)
end end
-- Add a trailing `/` if not present -- Add a trailing `/` if not present
if ngx.var.uri.."/" == conf["portal_path"] then if ngx.var.uri.."/" == conf["portal_path"] then
return redirect(portal_url) return hlp.redirect(conf.portal_url)
end end
uri_args = ngx.req.get_uri_args() uri_args = ngx.req.get_uri_args()
if uri_args.action and uri_args.action == 'logout' then
-- Logout
return do_logout()
elseif is_logged_in() and uri_args.r then -- Logout is also called via a `GET` method
-- TODO: change this ?
if uri_args.action and uri_args.action == 'logout' then
return hlp.logout()
elseif hlp.is_logged_in() and uri_args.r then
back_url = ngx.decode_base64(uri_args.r) back_url = ngx.decode_base64(uri_args.r)
if not string.match(back_url, "^http[s]?://"..ngx.var.host.."/") if not string.match(back_url, "^http[s]?://"..ngx.var.host.."/")
and not string.match(back_url, ".*"..conf.login_arg.."=%d+$") then and not string.match(back_url, ".*"..conf.login_arg.."=%d+$") then
@ -84,38 +103,38 @@ then
end end
back_url = back_url.."sso_login="..cda_key back_url = back_url.."sso_login="..cda_key
end end
return redirect(back_url) return hlp.redirect(back_url)
elseif is_logged_in() -- Authenticated elseif hlp.is_logged_in() -- Authenticated
or ngx.var.uri == conf["portal_path"] -- OR Want to serve portal login or ngx.var.uri == conf["portal_path"] -- OR Want to serve portal login
or (string.starts(ngx.var.uri, conf["portal_path"].."assets") or (string.starts(ngx.var.uri, conf["portal_path"].."assets")
and (not ngx.var.http_referer and (not ngx.var.http_referer
or string.starts(ngx.var.http_referer, portal_url))) -- OR Want to serve assets for portal login or hlp.string.starts(ngx.var.http_referer, conf.portal_url))) -- OR Want to serve assets for portal login
then then
-- Serve normal portal -- Serve normal portal
return serve(ngx.var.uri) return hlp.serve(ngx.var.uri)
else else
-- Redirect to portal -- Redirect to portal
flash("info", t("please_login")) hlp.flash("info", t("please_login"))
return redirect(portal_url) return hlp.redirect(conf.portal_url)
end end
elseif ngx.var.request_method == "POST" then elseif ngx.var.request_method == "POST" then
-- CSRF protection -- CSRF protection
if string.starts(ngx.var.http_referer, portal_url) then if hlp.string.starts(ngx.var.http_referer, conf.portal_url) then
if string.ends(ngx.var.uri, conf["portal_path"].."password.html") if hlp.string.ends(ngx.var.uri, conf["portal_path"].."password.html")
or string.ends(ngx.var.uri, conf["portal_path"].."edit.html") or hlp.string.ends(ngx.var.uri, conf["portal_path"].."edit.html")
then then
return post_edit() return hlp.edit_user()
else else
return post_login() return hlp.login()
end end
else else
-- Redirect to portal -- Redirect to portal
flash("fail", t("please_login_from_portal")) hlp.flash("fail", t("please_login_from_portal"))
return redirect(portal_url) return hlp.redirect(conf.portal_url)
end end
end end
end end
@ -123,21 +142,21 @@ end
-- Redirected urls -- Redirected urls
function detect_redirection(redirect_url) function detect_redirection(redirect_url)
if string.starts(redirect_url, "http://") if hlp.string.starts(redirect_url, "http://")
or string.starts(redirect_url, "https://") then or hlp.string.starts(redirect_url, "https://") then
return redirect(redirect_url) return hlp.redirect(redirect_url)
elseif string.starts(redirect_url, "/") then elseif hlp.string.starts(redirect_url, "/") then
return redirect(ngx.var.scheme.."://"..ngx.var.host..redirect_url) return hlp.redirect(ngx.var.scheme.."://"..ngx.var.host..redirect_url)
else else
return redirect(ngx.var.scheme.."://"..redirect_url) return hlp.redirect(ngx.var.scheme.."://"..redirect_url)
end end
end end
if conf["redirected_urls"] then if conf["redirected_urls"] then
for url, redirect_url in pairs(conf["redirected_urls"]) do for url, redirect_url in pairs(conf["redirected_urls"]) do
if url == ngx.var.host..ngx.var.uri..uri_args_string() if url == ngx.var.host..ngx.var.uri..hlp.uri_args_string()
or url == ngx.var.scheme.."://"..ngx.var.host..ngx.var.uri..uri_args_string() or url == ngx.var.scheme.."://"..ngx.var.host..ngx.var.uri..hlp.uri_args_string()
or url == ngx.var.uri..uri_args_string() then or url == ngx.var.uri..hlp.uri_args_string() then
detect_redirection(redirect_url) detect_redirection(redirect_url)
end end
end end
@ -145,9 +164,9 @@ end
if conf["redirected_regex"] then if conf["redirected_regex"] then
for regex, redirect_url in pairs(conf["redirected_regex"]) do for regex, redirect_url in pairs(conf["redirected_regex"]) do
if string.match(ngx.var.host..ngx.var.uri..uri_args_string(), regex) if string.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or string.match(ngx.var.scheme.."://"..ngx.var.host..ngx.var.uri..uri_args_string(), regex) or string.match(ngx.var.scheme.."://"..ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or string.match(ngx.var.uri..uri_args_string(), regex) then or string.match(ngx.var.uri..hlp.uri_args_string(), regex) then
detect_redirection(redirect_url) detect_redirection(redirect_url)
end end
end end
@ -163,8 +182,8 @@ function is_protected()
end end
for _, url in ipairs(conf["protected_urls"]) do for _, url in ipairs(conf["protected_urls"]) do
if string.starts(ngx.var.host..ngx.var.uri, url) if hlp.string.starts(ngx.var.host..ngx.var.uri, url)
or string.starts(ngx.var.uri, url) then or hlp.string.starts(ngx.var.uri, url) then
return true return true
end end
end end
@ -183,20 +202,20 @@ end
if conf["skipped_urls"] then if conf["skipped_urls"] then
for _, url in ipairs(conf["skipped_urls"]) do for _, url in ipairs(conf["skipped_urls"]) do
if (string.starts(ngx.var.host..ngx.var.uri..uri_args_string(), url) if (hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url)
or string.starts(ngx.var.uri..uri_args_string(), url)) or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), url))
and not is_protected() then and not is_protected() then
return pass() return hlp.pass()
end end
end end
end end
if conf["skipped_regex"] then if conf["skipped_regex"] then
for _, regex in ipairs(conf["skipped_regex"]) do for _, regex in ipairs(conf["skipped_regex"]) do
if (string.match(ngx.var.host..ngx.var.uri..uri_args_string(), regex) if (string.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or string.match(ngx.var.uri..uri_args_string(), regex)) or string.match(ngx.var.uri..hlp.uri_args_string(), regex))
and not is_protected() then and not is_protected() then
return pass() return hlp.pass()
end end
end end
end end
@ -208,26 +227,26 @@ end
if conf["unprotected_urls"] then if conf["unprotected_urls"] then
for _, url in ipairs(conf["unprotected_urls"]) do for _, url in ipairs(conf["unprotected_urls"]) do
if (string.starts(ngx.var.host..ngx.var.uri..uri_args_string(), url) if (hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url)
or string.starts(ngx.var.uri..uri_args_string(), url)) or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), url))
and not is_protected() then and not is_protected() then
if is_logged_in() then if hlp.is_logged_in() then
set_headers() hlp.set_headers()
end end
return pass() return hlp.pass()
end end
end end
end end
if conf["unprotected_regex"] then if conf["unprotected_regex"] then
for _, regex in ipairs(conf["unprotected_regex"]) do for _, regex in ipairs(conf["unprotected_regex"]) do
if (string.match(ngx.var.host..ngx.var.uri..uri_args_string(), regex) if (string.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or string.match(ngx.var.uri..uri_args_string(), regex)) or string.match(ngx.var.uri..hlp.uri_args_string(), regex))
and not is_protected() then and not is_protected() then
if is_logged_in() then if hlp.is_logged_in() then
set_headers() hlp.set_headers()
end end
return pass() return hlp.pass()
end end
end end
end end
@ -235,21 +254,21 @@ end
-- Cookie validation -- Cookie validation
-- --
if is_logged_in() then if hlp.is_logged_in() then
if string.match(ngx.var.uri, "^/ynhpanel.js$") then if string.match(ngx.var.uri, "^/ynhpanel.js$") then
serve("/yunohost/sso/assets/js/ynhpanel.js") hlp.serve("/yunohost/sso/assets/js/ynhpanel.js")
end end
if string.match(ngx.var.uri, "^/ynhpanel.css$") then if string.match(ngx.var.uri, "^/ynhpanel.css$") then
serve("/yunohost/sso/assets/css/ynhpanel.css") hlp.serve("/yunohost/sso/assets/css/ynhpanel.css")
end end
if string.match(ngx.var.uri, "^/ynhpanel.json$") then if string.match(ngx.var.uri, "^/ynhpanel.json$") then
serve("/yunohost/sso/assets/js/ynhpanel.json") hlp.serve("/yunohost/sso/assets/js/ynhpanel.json")
end end
if not has_access() then if not hlp.has_access() then
return redirect(portal_url) return hlp.redirect(conf.portal_url)
end end
set_headers() hlp.set_headers()
return pass() return hlp.pass()
end end
@ -260,16 +279,16 @@ local auth_header = ngx.req.get_headers()["Authorization"]
if auth_header then if auth_header then
_, _, b64_cred = string.find(auth_header, "^Basic%s+(.+)$") _, _, b64_cred = string.find(auth_header, "^Basic%s+(.+)$")
_, _, user, password = string.find(ngx.decode_base64(b64_cred), "^(.+):(.+)$") _, _, user, password = string.find(ngx.decode_base64(b64_cred), "^(.+):(.+)$")
user = authenticate(user, password) user = hlp.authenticate(user, password)
if user then if user then
set_headers(user) hlp.set_headers(user)
return pass() return hlp.pass()
end end
end end
-- Else redirect to portal -- Else redirect to portal
-- --
flash("info", t("please_login")) hlp.flash("info", t("please_login"))
local back_url = ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri .. uri_args_string() local back_url = ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri .. hlp.uri_args_string()
return redirect(portal_url.."?r="..ngx.encode_base64(back_url)) return hlp.redirect(conf.portal_url.."?r="..ngx.encode_base64(back_url))

View file

@ -5,26 +5,7 @@
-- --
-- Get the `cache` persistent shared table function get_config ()
cache = ngx.shared.cache
-- Generate a unique token if it has not been generated yet
srvkey = cache:get("srvkey")
if not srvkey then
math.randomseed(os.time())
srvkey = tostring(math.random(1111111, 9999999))
cache:add("srvkey", srvkey)
end
-- Set the prefered language from the `Accept-Language` header
lang = ngx.req.get_headers()["Accept-Language"]
if lang then
lang = string.sub(lang, 1, 2)
end
-- Load the configuration file -- Load the configuration file
local conf_file = assert(io.open(conf_path, "r"), "Configuration file is missing") local conf_file = assert(io.open(conf_path, "r"), "Configuration file is missing")
@ -90,10 +71,21 @@ end
-- Build portal full URL out of the configuration values -- Build portal full URL out of the configuration values
local portal_url = conf["portal_scheme"].."://".. conf.portal_url = conf["portal_scheme"].."://"..
conf["portal_domain"].. conf["portal_domain"]..
conf["portal_path"] conf["portal_path"]
-- Always skip the portal to avoid redirection looping. -- Always skip the portal to avoid redirection looping.
table.insert(conf["skipped_urls"], conf["portal_domain"]..conf["portal_path"]) table.insert(conf["skipped_urls"], conf["portal_domain"]..conf["portal_path"])
-- Set the prefered language from the `Accept-Language` header
conf.lang = ngx.req.get_headers()["Accept-Language"]
if conf.lang then
conf.lang = string.sub(lang, 1, 2)
end
return conf
end

View file

@ -38,8 +38,8 @@ end
-- Find a string by its translate key in the right language -- Find a string by its translate key in the right language
function t (key) function t (key)
if lang and i18n[lang] then if conf.lang and i18n[conf.lang] then
return i18n[lang][key] or "" return i18n[conf.lang][key] or ""
else else
return i18n[conf["default_language"]][key] or "" return i18n[conf["default_language"]][key] or ""
end end
@ -261,7 +261,7 @@ function set_headers (user)
if not cache:get(user.."-password") then if not cache:get(user.."-password") then
flash("info", t("please_login")) flash("info", t("please_login"))
local back_url = ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri .. uri_args_string() local back_url = ngx.var.scheme .. "://" .. ngx.var.host .. ngx.var.uri .. uri_args_string()
return redirect(portal_url.."?r="..ngx.encode_base64(back_url)) return redirect(conf.portal_url.."?r="..ngx.encode_base64(back_url))
end end
-- If the user information is not in cache, open an LDAP connection and -- If the user information is not in cache, open an LDAP connection and
@ -425,8 +425,8 @@ function get_data_for(view)
local data = {} local data = {}
-- Pass all the translated strings to the view (to use with t_<key>) -- Pass all the translated strings to the view (to use with t_<key>)
if lang and i18n[lang] then if conf.lang and i18n[conf.lang] then
translate_table = i18n[lang] translate_table = i18n[conf.lang]
else else
translate_table = i18n[conf["default_language"]] translate_table = i18n[conf["default_language"]]
end end
@ -456,7 +456,7 @@ function get_data_for(view)
local mails = get_mails(user) local mails = get_mails(user)
data = { data = {
connected = true, connected = true,
portal_url = portal_url, portal_url = conf.portal_url,
uid = user, uid = user,
cn = cache:get(user.."-cn"), cn = cache:get(user.."-cn"),
sn = cache:get(user.."-sn"), sn = cache:get(user.."-sn"),
@ -485,7 +485,7 @@ end
-- Compute the user modification POST request -- Compute the user modification POST request
-- It has to update cached information and edit the LDAP user entry -- It has to update cached information and edit the LDAP user entry
-- according to the changes detected. -- according to the changes detected.
function post_edit () function edit_user ()
-- We need these calls since we are in a POST request -- We need these calls since we are in a POST request
ngx.req.read_body() ngx.req.read_body()
@ -522,7 +522,7 @@ function post_edit ()
-- Reset the password cache -- Reset the password cache
cache:set(user.."-password", args.newpassword, conf["session_timeout"]) cache:set(user.."-password", args.newpassword, conf["session_timeout"])
return redirect(portal_url.."info.html") return redirect(conf.portal_url.."info.html")
else else
flash("fail", t("password_changed_error")) flash("fail", t("password_changed_error"))
end end
@ -532,7 +532,7 @@ function post_edit ()
else else
flash("fail", t("wrong_current_password")) flash("fail", t("wrong_current_password"))
end end
return redirect(portal_url.."password.html") return redirect(conf.portal_url.."password.html")
-- In case of profile modification -- In case of profile modification
@ -607,7 +607,7 @@ function post_edit ()
-- Check the mail pattern -- Check the mail pattern
if not mail:match(mail_pattern) then if not mail:match(mail_pattern) then
flash("fail", t("invalid_mail")..": "..mail) flash("fail", t("invalid_mail")..": "..mail)
return redirect(portal_url.."edit.html") return redirect(conf.portal_url.."edit.html")
-- Check that the domain is known and allowed -- Check that the domain is known and allowed
else else
@ -623,7 +623,7 @@ function post_edit ()
filter = filter.."(mail="..mail..")" filter = filter.."(mail="..mail..")"
else else
flash("fail", t("invalid_domain").." "..mail) flash("fail", t("invalid_domain").." "..mail)
return redirect(portal_url.."edit.html") return redirect(conf.portal_url.."edit.html")
end end
end end
end end
@ -640,7 +640,7 @@ function post_edit ()
if mail ~= "" then if mail ~= "" then
if not mail:match(mail_pattern) then if not mail:match(mail_pattern) then
flash("fail", t("invalid_mailforward")..": "..mail) flash("fail", t("invalid_mailforward")..": "..mail)
return redirect(portal_url.."edit.html") return redirect(conf.portal_url.."edit.html")
end end
table.insert(drops, mail) table.insert(drops, mail)
end end
@ -671,7 +671,7 @@ function post_edit ()
flash("fail", t("mail_already_used").." "..mail) flash("fail", t("mail_already_used").." "..mail)
end end
end end
return redirect(portal_url.."edit.html") return redirect(conf.portal_url.."edit.html")
end end
end end
@ -700,7 +700,7 @@ function post_edit ()
-- Ugly trick to force cache reloading -- Ugly trick to force cache reloading
set_headers(user) set_headers(user)
flash("win", t("information_updated")) flash("win", t("information_updated"))
return redirect(portal_url.."info.html") return redirect(conf.portal_url.."info.html")
else else
flash("fail", t("user_saving_fail")) flash("fail", t("user_saving_fail"))
@ -708,7 +708,7 @@ function post_edit ()
else else
flash("fail", t("missing_required_fields")) flash("fail", t("missing_required_fields"))
end end
return redirect(portal_url.."edit.html") return redirect(conf.portal_url.."edit.html")
end end
end end
end end
@ -716,7 +716,7 @@ end
-- Compute the user login POST request -- Compute the user login POST request
-- It authenticates the user against the LDAP base then redirects to the portal -- It authenticates the user against the LDAP base then redirects to the portal
function do_login () function login ()
-- We need these calls since we are in a POST request -- We need these calls since we are in a POST request
ngx.req.read_body() ngx.req.read_body()
@ -735,17 +735,17 @@ function do_login ()
-- Forward the `r` URI argument if it exists to redirect -- Forward the `r` URI argument if it exists to redirect
-- the user properly after a successful login. -- the user properly after a successful login.
if uri_args.r then if uri_args.r then
return redirect(portal_url.."?r="..uri_args.r) return redirect(conf.portal_url.."?r="..uri_args.r)
else else
return redirect(portal_url) return redirect(conf.portal_url)
end end
end end
-- Compute the user logout POST request -- Compute the user logout request
-- It deletes session cached information to invalidate client side cookie -- It deletes session cached information to invalidate client side cookie
-- information. -- information.
function do_logout() function logout()
-- We need this call since we are in a POST request -- We need this call since we are in a POST request
local args = ngx.req.get_uri_args() local args = ngx.req.get_uri_args()
@ -754,7 +754,7 @@ function do_logout()
cache:delete("session_"..ngx.var.cookie_SSOwAuthUser) cache:delete("session_"..ngx.var.cookie_SSOwAuthUser)
cache:delete(ngx.var.cookie_SSOwAuthUser.."-"..conf["ldap_identifier"]) -- Ugly trick to reload cache cache:delete(ngx.var.cookie_SSOwAuthUser.."-"..conf["ldap_identifier"]) -- Ugly trick to reload cache
flash("info", t("logged_out")) flash("info", t("logged_out"))
return redirect(portal_url) return redirect(conf.portal_url)
end end
end end