Skip to content

Commit

Permalink
WIP: Upgrading to lua-resty-session v4.
Browse files Browse the repository at this point in the history
  • Loading branch information
GUI committed Nov 5, 2024
1 parent d9064a9 commit 70916a6
Show file tree
Hide file tree
Showing 14 changed files with 126 additions and 245 deletions.
12 changes: 4 additions & 8 deletions src/api-umbrella/web-app/actions/admin/sessions.lua
Original file line number Diff line number Diff line change
Expand Up @@ -139,12 +139,8 @@ end

function _M.destroy(self)
self:init_session_db()
local _, _, open_err = self.session_db:start()
if open_err then
ngx.log(ngx.ERR, "session open error: ", open_err)
end

local sign_in_provider = self.session_db.data["sign_in_provider"]
self.session_db:open()
local sign_in_provider = self.session_db:get("sign_in_provider")
self.session_db:destroy()

flash.session(self, "info", t("Signed out successfully."))
Expand Down Expand Up @@ -173,8 +169,8 @@ function _M.logout_callback(self)
local state = ngx.var.arg_state
if state then
self:init_session_cookie()
self.session_cookie:start()
local session_state = self.session_cookie.data["openid_connect_state"]
self.session_cookie:open()
local session_state = self.session_cookie:get("openid_connect_state")
if state ~= session_state then
ngx.log(ngx.WARN, "state from argument: " .. (state or "nil") .. " does not match state restored from session: " .. (session_state or "nil"))

Expand Down
62 changes: 20 additions & 42 deletions src/api-umbrella/web-app/app.lua
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,6 @@ local resty_session = require "resty.session"
local t = require("api-umbrella.web-app.utils.gettext").gettext
local table_keys = require("pl.tablex").keys

require "resty.session.ciphers.api_umbrella"
require "resty.session.hmac.api_umbrella"
require "resty.session.identifiers.api_umbrella"
require "resty.session.storage.api_umbrella_db"
require "resty.session.serializers.api_umbrella"

local supported_languages = table_keys(LOCALE_DATA)

-- Custom error handler so we only show the default lapis debug details in
Expand Down Expand Up @@ -78,24 +72,15 @@ end
-- server-side control on expiring sessions, and it can't be spoofed even with
-- knowledge of the encryption secret key.
local session_db_options = {
storage = "api_umbrella_db",
cipher = "api_umbrella",
hmac = "api_umbrella",
serializer = "api_umbrella",
identifier = "api_umbrella",
name = "_api_umbrella_session",
storage = "postgres",
postgres = pg_utils.db_config,
secret = assert(config["secret_key"]),
random = {
length = 40,
},
cookie = {
samesite = "Lax",
secure = true,
httponly = true,
idletime = 30 * 60, -- 30 minutes
lifetime = 12 * 60 * 60, -- 12 hours
renew = -1, -- Disable renew
},
cookie_name = "_api_umbrella_session",
cookie_same_site = "Lax",
cookie_secure = true,
cookie_http_only = true,
idling_timeout = 30 * 60, -- 30 minutes
absolute_timeout = 12 * 60 * 60, -- 12 hours
}
local function init_session_db(self)
if not self.session_db then
Expand All @@ -113,22 +98,13 @@ end
-- session records in the database for the CSRF token).
local session_cookie_options = {
storage = "cookie",
cipher = "api_umbrella",
hmac = "api_umbrella",
serializer = "api_umbrella",
identifier = "api_umbrella",
name = "_api_umbrella_session_client",
secret = assert(config["secret_key"]),
random = {
length = 40,
},
cookie = {
samesite = "Lax",
secure = true,
httponly = true,
lifetime = 48 * 60 * 60, -- 48 hours
renew = 1 * 60 * 60, -- 1 hour
},
cookie_name = "_api_umbrella_session_client",
cookie_same_site = "Lax",
cookie_secure = true,
cookie_http_only = true,
rolling_timeout = 1 * 60 * 60, -- 1 hour
absolute_timeout = 48 * 60 * 60, -- 48 hours
}
local function init_session_cookie(self)
if not self.session_cookie then
Expand All @@ -139,17 +115,19 @@ end
local function current_admin_from_session(self)
local current_admin
self:init_session_db()
local _, _, open_err = self.session_db:start()
if open_err then
local _, open_err = self.session_db:open()
if open_err and open_err ~= "missing session cookie" then
if open_err == "session cookie idle time has passed" or open_err == "session cookie has expired" then
flash.session(self, "info", t("Your session expired. Please sign in again to continue."))
else
ngx.log(ngx.ERR, "session open error: ", open_err)
end

return nil
end

if self.session_db and self.session_db.data and self.session_db.data["admin_id"] then
local admin_id = self.session_db.data["admin_id"]
local admin_id = self.session_db:get("admin_id")
if admin_id then
local admin = Admin:find({ id = admin_id })
if admin and not admin:is_access_locked() then
current_admin = admin
Expand Down
5 changes: 0 additions & 5 deletions src/api-umbrella/web-app/hooks/init_preload_modules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -178,11 +178,6 @@ require "resty.http"
require "resty.mlcache"
require "resty.openidc"
require "resty.session"
require "resty.session.ciphers.api_umbrella"
require "resty.session.hmac.api_umbrella"
require "resty.session.identifiers.api_umbrella"
require "resty.session.serializers.api_umbrella"
require "resty.session.storage.api_umbrella_db"
require "resty.uuid"
require "resty.validation"
require "resty.validation.ngx"
13 changes: 5 additions & 8 deletions src/api-umbrella/web-app/utils/auth_external_oauth2.lua
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,8 @@ end
function _M.authorize(self, strategy_name, url, params)
local state = random_token(64)
self:init_session_cookie()
self.session_cookie:start()
self.session_cookie.data["oauth2_state"] = state
self.session_cookie:open()
self.session_cookie:set("oauth2_state", state)
self.session_cookie:save()

local callback_url = build_url(auth_external_path(strategy_name, "/callback"))
Expand Down Expand Up @@ -119,17 +119,14 @@ function _M.userinfo(self, strategy_name, options)
end

self:init_session_cookie()
local _, _, open_err = self.session_cookie:start()
if open_err then
ngx.log(ngx.ERR, "session open error: ", open_err)
end
self.session_cookie:open()
local stored_state = self.session_cookie:get("oauth2_state")

if not self.session_cookie or not self.session_cookie.data or not self.session_cookie.data["oauth2_state"] then
if not stored_state then
ngx.log(ngx.ERR, "oauth2 state not available")
return nil, t("Cross-site request forgery detected")
end

local stored_state = self.session_cookie.data["oauth2_state"]
local state = self.params["state"]
if state ~= stored_state then
ngx.log(ngx.ERR, "oauth2 state does not match")
Expand Down
11 changes: 6 additions & 5 deletions src/api-umbrella/web-app/utils/auth_external_openid_connect.lua
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ function _M.authenticate(self, strategy_name, callback)
-- Call the provider-specific callback logic, which should handle
-- authorizing the API Umbrella session and redirecting as appropriate.
callback({
id_token = session["data"]["id_token"],
user = session["data"]["user"],
id_token = session:get("id_token"),
user = session:get("user"),
})

-- This shouldn't get hit, since callback should perform it's own
Expand Down Expand Up @@ -82,14 +82,15 @@ function _M.authenticate(self, strategy_name, callback)
end
if discovery and discovery["end_session_endpoint"] then
-- Generate the state parameter to send.
local openid_connect_state = random_token(64)
self:init_session_cookie()
self.session_cookie:start()
self.session_cookie.data["openid_connect_state"] = random_token(64)
self.session_cookie:open()
self.session_cookie:set("openid_connect_state", openid_connect_state)
self.session_cookie:save()

-- Add the "state" param to the logout URL.
local extra_logout_args = {
state = self.session_cookie.data["openid_connect_state"]
state = openid_connect_state,
}

-- Add the "client_id" param to the logout URL if id_token_hint won't be
Expand Down
23 changes: 12 additions & 11 deletions src/api-umbrella/web-app/utils/csrf.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,20 @@ local _M = {}

function _M.generate_token(self)
self:init_session_cookie()
self.session_cookie:start()
local csrf_token_key = self.session_cookie.data["csrf_token_key"]
local csrf_token_iv = self.session_cookie.data["csrf_token_iv"]
self.session_cookie:open()
local csrf_token_key = self.session_cookie:get("csrf_token_key")
ngx.log(ngx.ERR, "-DEBUG- GET generate csrf_token_key: ", csrf_token_key)
local csrf_token_iv = self.session_cookie:get("csrf_token_iv")
if not csrf_token_key or not csrf_token_iv then
if not csrf_token_key then
csrf_token_key = random_token(40)
self.session_cookie.data["csrf_token_key"] = csrf_token_key
ngx.log(ngx.ERR, "-DEBUG- SET generate csrf_token_key: ", csrf_token_key)
self.session_cookie:set("csrf_token_key", csrf_token_key)
end

if not csrf_token_iv then
csrf_token_iv = random_token(12)
self.session_cookie.data["csrf_token_iv"] = csrf_token_iv
self.session_cookie:set("csrf_token_iv", csrf_token_iv)
end

self.session_cookie:save()
Expand All @@ -41,12 +43,11 @@ end

local function validate_token(self)
self:init_session_cookie()
local _, _, open_err = self.session_cookie:start()
if open_err then
ngx.log(ngx.ERR, "session open error: ", open_err)
end

local key = self.session_cookie.data["csrf_token_key"]
self.session_cookie:open()
local key = self.session_cookie:get("csrf_token_key")
ngx.log(ngx.ERR, "-DEBUG- GET csrf_token_key: ", key)
ngx.log(ngx.ERR, "-DEBUG- ngx.var.cookie__api_umbrella_session_client", ngx.var.cookie__api_umbrella_session_client)
ngx.log(ngx.ERR, "-DEBUG- ngx.var.cookie__api_umbrella_session", ngx.var.cookie__api_umbrella_session)
if not key then
return false, "Missing CSRF token key"
end
Expand Down
23 changes: 11 additions & 12 deletions src/api-umbrella/web-app/utils/flash.lua
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@ function _M.session(self, flash_type, message, options)
data["message"] = message

self:init_session_cookie()
self.session_cookie:start()
if not self.session_cookie.data["flash"] then
self.session_cookie.data["flash"] = {}
self.session_cookie:open()
local flash = self.session_cookie:get("flash")
if not flash then
flash = {}
end
self.session_cookie.data["flash"][flash_type] = data
flash[flash_type] = data
self.session_cookie:set("flash", flash)
self.session_cookie:save()
end

Expand All @@ -27,17 +29,14 @@ function _M.setup(self)

self.restore_flashes = function()
self:init_session_cookie()
local _, _, open_err = self.session_cookie:start()
if open_err then
ngx.log(ngx.ERR, "session open error: ", open_err)
end

if self.session_cookie.data and not is_empty(self.session_cookie.data["flash"]) then
for flash_type, data in pairs(self.session_cookie.data["flash"]) do
self.session_cookie:open()
local flash_value = self.session_cookie:get("flash")
if not is_empty(flash_value) then
for flash_type, data in pairs(flash_value) do
_M.now(self, flash_type, data["message"], data)
end

self.session_cookie.data["flash"] = nil
self.session_cookie:set("flash", nil)
self.session_cookie:save()
end

Expand Down
6 changes: 3 additions & 3 deletions src/api-umbrella/web-app/utils/login_admin.lua
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ return function(self, admin, provider)
db.query("COMMIT")

self:init_session_db()
self.session_db:start()
self.session_db.data["admin_id"] = admin_id
self.session_db.data["sign_in_provider"] = provider
self.session_db:open()
self.session_db:set("admin_id", admin_id)
self.session_db:set("sign_in_provider", provider)
self.session_db:save()

return build_url("/admin/#/login")
Expand Down
27 changes: 0 additions & 27 deletions src/resty/session/ciphers/api_umbrella.lua

This file was deleted.

13 changes: 0 additions & 13 deletions src/resty/session/hmac/api_umbrella.lua

This file was deleted.

11 changes: 0 additions & 11 deletions src/resty/session/identifiers/api_umbrella.lua

This file was deleted.

16 changes: 0 additions & 16 deletions src/resty/session/serializers/api_umbrella.lua

This file was deleted.

Loading

0 comments on commit 70916a6

Please sign in to comment.