add option to limit access to subscription users only

This commit is contained in:
Karol Wypchlo 2022-01-21 17:43:30 +01:00
parent 08c050694e
commit 4e240f2ad8
No known key found for this signature in database
GPG Key ID: B515DE9EEBE241E1
7 changed files with 52 additions and 5 deletions

View File

@ -68,6 +68,11 @@ access_by_lua_block {
return require("skynet.account").exit_access_unauthorized() return require("skynet.account").exit_access_unauthorized()
end end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
-- get account limits of currently authenticated user -- get account limits of currently authenticated user
local limits = require("skynet.account").get_account_limits() local limits = require("skynet.account").get_account_limits()

View File

@ -16,6 +16,11 @@ access_by_lua_block {
return require("skynet.account").exit_access_unauthorized() return require("skynet.account").exit_access_unauthorized()
end end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
-- get account limits of currently authenticated user -- get account limits of currently authenticated user
local limits = require("skynet.account").get_account_limits() local limits = require("skynet.account").get_account_limits()

View File

@ -3,4 +3,9 @@ access_by_lua_block {
if require("skynet.account").is_access_unauthorized() then if require("skynet.account").is_access_unauthorized() then
return require("skynet.account").exit_access_unauthorized() return require("skynet.account").exit_access_unauthorized()
end end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
} }

View File

@ -260,6 +260,11 @@ location /skynet/tus {
if require("skynet.account").is_access_unauthorized() then if require("skynet.account").is_access_unauthorized() then
return require("skynet.account").exit_access_unauthorized() return require("skynet.account").exit_access_unauthorized()
end end
-- check if portal is in subscription only mode
if require("skynet.account").is_access_forbidden() then
return require("skynet.account").exit_access_forbidden()
end
-- get account limits of currently authenticated user -- get account limits of currently authenticated user
local limits = require("skynet.account").get_account_limits() local limits = require("skynet.account").get_account_limits()

View File

@ -6,8 +6,10 @@ local anon_limits = { ["tierName"] = "anonymous", ["upload"] = 655360, ["downloa
-- no limits applied -- no limits applied
local no_limits = { ["tierName"] = "internal", ["upload"] = 0, ["download"] = 0, ["maxUploadSize"] = 0, ["registry"] = 0 } local no_limits = { ["tierName"] = "internal", ["upload"] = 0, ["download"] = 0, ["maxUploadSize"] = 0, ["registry"] = 0 }
-- handle request exit when access to portal should be restricted -- free tier name
-- currently handles only HTTP_UNAUTHORIZED but can be extended in future local free_tier = "free"
-- handle request exit when access to portal should be restricted to authenticated users only
function _M.exit_access_unauthorized(message) function _M.exit_access_unauthorized(message)
ngx.status = ngx.HTTP_UNAUTHORIZED ngx.status = ngx.HTTP_UNAUTHORIZED
ngx.header["content-type"] = "text/plain" ngx.header["content-type"] = "text/plain"
@ -15,6 +17,14 @@ function _M.exit_access_unauthorized(message)
return ngx.exit(ngx.status) return ngx.exit(ngx.status)
end end
-- handle request exit when access to portal should be restricted to subscription users only
function _M.exit_access_forbidden(message)
ngx.status = ngx.HTTP_FORBIDDEN
ngx.header["content-type"] = "text/plain"
ngx.say(message or "Portal operator restricted access to users with active subscription only")
return ngx.exit(ngx.status)
end
function _M.accounts_enabled() function _M.accounts_enabled()
return os.getenv("PORTAL_MODULES"):match("a") ~= nil return os.getenv("PORTAL_MODULES"):match("a") ~= nil
end end
@ -57,14 +67,31 @@ function _M.is_authenticated()
return limits.tierName ~= anon_limits.tierName return limits.tierName ~= anon_limits.tierName
end end
-- detect whether current user has active subscription
function _M.is_subscription_account()
local limits = _M.get_account_limits()
return limits.tierName ~= anon_limits.tierName and limits.tierName ~= free_tier
end
function _M.is_auth_required() function _M.is_auth_required()
return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated" return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "authenticated"
end end
-- check whether access to portal should be restricted function _M.is_subscription_required()
return os.getenv("ACCOUNTS_LIMIT_ACCESS") == "subscription"
end
-- check whether access to portal should be restricted to authenticated users only
-- based on the configurable environment variable -- based on the configurable environment variable
function _M.is_access_unauthorized() function _M.is_access_unauthorized()
return _M.accounts_enabled() and _M.is_auth_required() and not _M.is_authenticated() return _M.accounts_enabled() and _M.is_auth_required() and not _M.is_authenticated()
end end
-- check whether access to portal should be restricted to users with active subscription
-- based on the configurable environment variable
function _M.is_access_forbidden()
return _M.accounts_enabled() and _M.is_subscription_required() and not _M.is_subscription_account()
end
return _M return _M

View File

@ -8,7 +8,7 @@ if (process.env.ACCOUNTS_ENABLED === "true") {
if (!process.env.SKYNET_DASHBOARD_URL) { if (!process.env.SKYNET_DASHBOARD_URL) {
throw new Error("You need to provide SKYNET_DASHBOARD_URL environment variable when accounts are enabled"); throw new Error("You need to provide SKYNET_DASHBOARD_URL environment variable when accounts are enabled");
} }
if (process.env.ACCOUNTS_LIMIT_ACCESS === "authenticated") { if (["authenticated", "subscription"].includes(process.env.ACCOUNTS_LIMIT_ACCESS)) {
if (!process.env.ACCOUNTS_TEST_USER_EMAIL) { if (!process.env.ACCOUNTS_TEST_USER_EMAIL) {
throw new Error("ACCOUNTS_TEST_USER_EMAIL cannot be empty"); throw new Error("ACCOUNTS_TEST_USER_EMAIL cannot be empty");
} }

View File

@ -51,7 +51,7 @@ function getAuthCookie() {
if (getAuthCookie.cache) return getAuthCookie.cache; if (getAuthCookie.cache) return getAuthCookie.cache;
// do not authenticate if it is not necessary // do not authenticate if it is not necessary
if (process.env.ACCOUNTS_LIMIT_ACCESS !== "authenticated") return {}; if (!["authenticated", "subscription"].includes(process.env.ACCOUNTS_LIMIT_ACCESS)) return {};
const email = process.env.ACCOUNTS_TEST_USER_EMAIL; const email = process.env.ACCOUNTS_TEST_USER_EMAIL;
const password = process.env.ACCOUNTS_TEST_USER_PASSWORD; const password = process.env.ACCOUNTS_TEST_USER_PASSWORD;