Merge branch 'stretch-unstable' into noauth

This commit is contained in:
Kayou 2020-03-17 00:02:19 +01:00 committed by GitHub
commit b6c02c5aca
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 135 additions and 189 deletions

View file

@ -239,6 +239,16 @@ if conf["redirected_regex"] then
end
local longest_protected_match = hlp.longest_url_path(hlp.get_matches("protected")) or ""
local longest_skipped_match = hlp.longest_url_path(hlp.get_matches("skipped")) or ""
local longest_unprotected_match = hlp.longest_url_path(hlp.get_matches("unprotected")) or ""
local longest_noauth_match = hlp.longest_url_path(hlp.get_matches("noauth")) or ""
logger.debug("longest skipped "..longest_skipped_match)
logger.debug("longest unprotected "..longest_unprotected_match)
logger.debug("longest protected "..longest_protected_match)
logger.debug("longest noauth "..longest_noauth_match)
--
-- 4. Skipped URLs
--
@ -247,26 +257,11 @@ end
-- has to be sent, even if the user is already authenticated.
--
if conf["skipped_urls"] then
for _, url in ipairs(conf["skipped_urls"]) do
if (hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url)
or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), url))
then
logger.debug("Skipping "..ngx.var.uri)
return hlp.pass()
end
end
end
if conf["skipped_regex"] then
for _, regex in ipairs(conf["skipped_regex"]) do
if (hlp.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or hlp.match(ngx.var.uri..hlp.uri_args_string(), regex))
then
logger.debug("Skipping "..ngx.var.uri)
return hlp.pass()
end
end
if longest_skipped_match ~= ""
and string.len(longest_skipped_match) >= string.len(longest_protected_match)
and string.len(longest_skipped_match) > string.len(longest_unprotected_match) then
logger.debug("Skipping "..ngx.var.uri)
return hlp.pass()
end
--
@ -277,59 +272,17 @@ end
-- has to be sent, even if the user is already authenticated.
--
if conf["noauth_urls"] then
if longest_noauth_match ~= ""
and string.len(longest_noauth_match) >= string.len(longest_protected_match)
and string.len(longest_noauth_match) > string.len(longest_unprotected_match) then
if hlp.is_logged_in() then
for _, noauth in ipairs(conf["noauth_urls"]) do
if (hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), noauth)
or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), noauth))
then
logger.debug("Noauth "..ngx.var.uri)
return hlp.pass()
end
end
logger.debug("Noauth "..ngx.var.uri)
return hlp.pass()
end
end
--
-- 5. Protected URLs
--
-- If the URL matches one of the `protected_urls` in the configuration file,
-- we have to protect it even if the URL is also set in the `unprotected_urls`.
-- It could be useful if you want to unprotect every URL except a few
-- particular ones.
--
function is_protected()
if not conf["protected_urls"] then
conf["protected_urls"] = {}
end
if not conf["protected_regex"] then
conf["protected_regex"] = {}
end
for _, url in ipairs(conf["protected_urls"]) do
if hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url)
or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), url) then
logger.debug(ngx.var.uri.." is in protected_urls")
return true
end
end
for _, regex in ipairs(conf["protected_regex"]) do
if hlp.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or hlp.match(ngx.var.uri..hlp.uri_args_string(), regex) then
logger.debug(ngx.var.uri.." is in protected_regex")
return true
end
end
logger.debug(ngx.var.uri.." is not in protected_urls/regex")
return false
end
--
-- 6. Specific files (used in YunoHost)
-- 5. Specific files (used in YunoHost)
--
-- We want to serve specific portal assets right at the root of the domain.
--
@ -357,7 +310,9 @@ function serveThemeFile(filename)
serveAsset("/ynhtheme/"..filename, "themes/"..conf.theme.."/"..filename)
end
if hlp.is_logged_in() then
function serveYnhpanel()
logger.debug("Serving ynhpanel")
-- serve ynhpanel files
serveAsset("/ynh_portal.js", "js/ynh_portal.js")
serveAsset("/ynh_overlay.css", "css/ynh_overlay.css")
@ -366,6 +321,33 @@ if hlp.is_logged_in() then
-- but I didn't succeed to figure out where is the current location of the script
-- if you call it from "portal/assets/themes/" the ls fails
scandir("/usr/share/ssowat/portal/assets/themes/"..conf.theme, serveThemeFile)
end
--
-- 6. Unprotected URLs
--
-- If the URL matches one of the `unprotected_urls` in the configuration file,
-- it means that the URL should not be protected by the SSO *but* headers have
-- to be sent if the user is already authenticated.
--
-- It means that you can let anyone access to an app, but if a user has already
-- been authenticated on the portal, he can have his authentication headers
-- passed to the app.
--
if longest_unprotected_match ~= ""
and string.len(longest_unprotected_match) > string.len(longest_protected_match) then
if hlp.is_logged_in() then
serveYnhpanel()
hlp.set_headers()
end
logger.debug(ngx.var.uri.." is in unprotected_urls")
return hlp.pass()
end
if hlp.is_logged_in() then
serveYnhpanel()
-- If user has no access to this URL, redirect him to the portal
if not hlp.has_access() then
@ -379,51 +361,8 @@ if hlp.is_logged_in() then
end
--
-- 7. Unprotected URLs
--
-- If the URL matches one of the `unprotected_urls` in the configuration file,
-- it means that the URL should not be protected by the SSO *but* headers have
-- to be sent if the user is already authenticated.
--
-- It means that you can let anyone access to an app, but if a user has already
-- been authenticated on the portal, he can have his authentication headers
-- passed to the app.
--
if conf["unprotected_urls"] then
for _, url in ipairs(conf["unprotected_urls"]) do
if (hlp.string.starts(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), url)
or hlp.string.starts(ngx.var.uri..hlp.uri_args_string(), url))
and not is_protected() then
if hlp.is_logged_in() then
hlp.set_headers()
end
logger.debug(ngx.var.uri.." is in unprotected_urls")
return hlp.pass()
end
end
end
if conf["unprotected_regex"] then
for _, regex in ipairs(conf["unprotected_regex"]) do
if (hlp.match(ngx.var.host..ngx.var.uri..hlp.uri_args_string(), regex)
or hlp.match(ngx.var.uri..hlp.uri_args_string(), regex))
and not is_protected() then
if hlp.is_logged_in() then
hlp.set_headers()
end
logger.debug(ngx.var.uri.." is in unprotected_regex")
return hlp.pass()
end
end
end
--
-- 8. Basic HTTP Authentication
-- 7. Basic HTTP Authentication
--
-- If the `Authorization` header is set before reaching the SSO, we want to
-- match user and password against the user database.
@ -459,7 +398,7 @@ end
--
-- 9. Redirect to login
-- 8. Redirect to login
--
-- If no previous rule has matched, just redirect to the portal login.
-- The default is to protect every URL by default.
@ -475,6 +414,6 @@ end
-- when trying to access http://main.domain.tld/ (SSOwat finds that user aint
-- logged in, therefore redirects to SSO, which redirects to the back_url, which
-- redirect to SSO, ..)
logger.debug("No rule found for this url. By default, redirecting to portal")
logger.debug("No rule found for "..ngx.var.uri..". By default, redirecting to portal")
local back_url = "https://" .. ngx.var.host .. ngx.var.uri .. hlp.uri_args_string()
return hlp.redirect(conf.portal_url.."?r="..ngx.encode_base64(back_url))

13
debian/changelog vendored
View file

@ -1,8 +1,19 @@
ssowat (3.7.0.2) testing; urgency=low
- [fix] Match undefined function (SSOwat#151)
- [fix] Cohabitation between the old and the new permission system (SSOwat#156)
- [i18n] Improved translations for French, Basque, Hindi, Turkish, Bengali (Bangladesh), Arabic, Hungarian, Polish, Catalan, Dutch, Portuguese, Italian, German, Swedish, Russian, Esperanto, Occitan, Nepali
Thanks to all contributors (amirale qt, Quenti, Filip Bengtsson, elie gavoty, xaloc33, ButterflyOfFire, Kay0u) <3 !
-- Kay0u <pierre@kayou.io> Sun, 15 Mar 2020 15:48:58 +0000
ssowat (3.7.0.1) testing; urgency=low
- [mod] Check skipped_urls before protected_urls (#149)
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 03 Dev 2019 12:07:00 +0000
-- Alexandre Aubin <alex.aubin@mailoo.org> Tue, 03 Dec 2019 12:07:00 +0000
ssowat (3.7.0) testing; urgency=low

View file

@ -262,100 +262,92 @@ function log_access(user, uri)
end
-- Check whether a user is allowed to access a URL using the `users` directive
-- Check whether a user is allowed to access a URL using the `permissions` directive
-- of the configuration file
function has_access(user)
user = user or authUser
if not conf["users"][user] then
conf = config.get_config()
end
logger.debug("User "..user.." try to access "..ngx.var.uri)
-- Get the longest url permission
longest_permission_match = longest_url_path(permission_matches()) or ""
-- If there are no `users` directive, or if the user has no ACL set, he can
-- access the URL by default
if not conf["users"] or not conf["users"][user] then
logger.debug("No access rules defined for user "..user..", assuming it can access..")
return true
end
logger.debug("Longest permission match : "..longest_permission_match)
-- Loop through user's ACLs and return if the URL is authorized.
allowed_url_matches = {}
for url, app in pairs(conf["users"][user]) do
-- Replace the original domain by a local one if you are connected from
-- a non-global domain name.
if ngx.var.host == conf["local_portal_domain"] then
url = string.gsub(url, conf["original_portal_domain"], conf["local_portal_domain"])
end
if string.ends(url, "/") then
url = string.sub(url, 1, -1)
end
if string.starts(ngx.var.host..ngx.var.uri, url) then
logger.debug("User is allowed to access this match : "..url)
table.insert(allowed_url_matches,url)
end
end
-- Keep only the longest match and compare it to the longest protected
-- match e.g. we don't want to allow the user to access /foo/admin if
-- /foo/admin is protected, but this user is only allowed to access /foo
local longest_allowed_match = longest_url_path(allowed_url_matches) or ""
local longest_protected_match = longest_url_path(protected_matches()) or ""
logger.debug("Longest allowed match : "..longest_allowed_match)
logger.debug("Longest protected match : "..longest_protected_match)
-- For the user to be able to access the content, at least one rule should
-- exist and it should be the longest match
if longest_allowed_match ~= ""
and string.len(longest_allowed_match) >= string.len(longest_protected_match) then
logger.debug("Logged-in user can access "..ngx.var.uri)
log_access(user, longest_allowed_match)
return true
else
logger.debug("Logged-in user cannot access "..ngx.var.uri)
-- If no permission matches, it means that there is no permission defined for this url.
if longest_permission_match == "" then
logger.debug("No access rules defined for user "..user..", assuming it cannot access.")
return false
end
-- All user in this permission
allowed_users = conf["permissions"][longest_permission_match]
-- The user has permission to access the content if he is in the list of this one
if allowed_users then
for _, u in pairs(allowed_users) do
if u == user then
logger.debug("User "..user.." can access "..ngx.var.uri)
log_access(user, longest_permission_match)
return true
end
end
end
logger.debug("User "..user.." cannot access "..ngx.var.uri)
return false
end
function protected_matches()
if not conf["protected_urls"] then
conf["protected_urls"] = {}
end
if not conf["protected_regex"] then
conf["protected_regex"] = {}
function permission_matches()
if not conf["permissions"] then
conf["permissions"] = {}
end
local url_matches = {}
for _, url in ipairs(conf["protected_urls"]) do
if string.starts(ngx.var.host..ngx.var.uri..uri_args_string(), url)
or string.starts(ngx.var.uri..uri_args_string(), url) then
logger.debug("protected_url match current uri : "..url)
for url, permission in pairs(conf["permissions"]) do
if string.starts(ngx.var.host..ngx.var.uri..uri_args_string(), url) then
logger.debug("Url permission match current uri : "..url)
table.insert(url_matches, url)
else
logger.debug("no match from "..url.." to "..ngx.var.uri)
end
end
for _, regex in ipairs(conf["protected_regex"]) do
local m1 = match(ngx.var.host..ngx.var.uri..uri_args_string(), regex)
local m2 = match(ngx.var.uri..uri_args_string(), regex)
if m1 then
logger.debug("protected_regex match current uri : "..regex.." with "..m1)
table.insert(url_matches, m1)
end
if m2 then
logger.debug("protected_regex match current uri : "..regex.." with "..m2)
table.insert(url_matches, m2)
end
end
return url_matches
end
function get_matches(section)
if not conf[section.."_urls"] then
conf[section.."_urls"] = {}
end
if not conf[section.."_regex"] then
conf[section.."_regex"] = {}
end
local url_matches = {}
for _, url in ipairs(conf[section.."_urls"]) do
if string.starts(ngx.var.host..ngx.var.uri..uri_args_string(), url)
or string.starts(ngx.var.uri..uri_args_string(), url) then
logger.debug(section.."_url match current uri : "..url)
table.insert(url_matches, url)
end
end
for _, regex in ipairs(conf[section.."_regex"]) do
local m1 = match(ngx.var.host..ngx.var.uri..uri_args_string(), regex)
local m2 = match(ngx.var.uri..uri_args_string(), regex)
if m1 then
logger.debug(section.."_regex match current uri : "..regex.." with "..m1)
table.insert(url_matches, m1)
end
if m2 then
logger.debug(section.."_regex match current uri : "..regex.." with "..m2)
table.insert(url_matches, m2)
end
end
return url_matches
end
function longest_url_path(urls)
local longest = nil
@ -369,6 +361,9 @@ function longest_url_path(urls)
longest = current
end
end
if longest and string.ends(longest, "/") then
longest = string.sub(longest, 1, -2)
end
return longest
end

1
portal/locales/ne.json Normal file
View file

@ -0,0 +1 @@
{}