diff options
author | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-04-14 11:59:32 +0000 |
---|---|---|
committer | Fiete Ostkamp <Fiete.Ostkamp@telekom.de> | 2023-04-14 11:59:32 +0000 |
commit | d68841d9f75636575cd778838a8ceea5fd5aada3 (patch) | |
tree | 778c84203ed9bfa4dc1c8234e4e2cf60da6ebd8c /server/resty/session/strategies | |
parent | 42af09588f1f839b9ab36356f02f34c89559bcfa (diff) |
Upload ui
Issue-ID: PORTAL-1084
Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Change-Id: Id0c94859a775094e67b0bb9c91ca5e776a08c068
Diffstat (limited to 'server/resty/session/strategies')
-rw-r--r-- | server/resty/session/strategies/default.lua | 232 | ||||
-rw-r--r-- | server/resty/session/strategies/regenerate.lua | 43 |
2 files changed, 275 insertions, 0 deletions
diff --git a/server/resty/session/strategies/default.lua b/server/resty/session/strategies/default.lua new file mode 100644 index 0000000..a43ef5a --- /dev/null +++ b/server/resty/session/strategies/default.lua @@ -0,0 +1,232 @@ +local type = type +local concat = table.concat + +local strategy = {} + +function strategy.load(session, cookie, key, keep_lock) + local storage = session.storage + local id = cookie.id + local id_encoded = session.encoder.encode(id) + + local data, err, tag + if storage.open then + data, err = storage:open(id_encoded, keep_lock) + if not data then + return nil, err or "cookie data was not found" + end + + else + data = cookie.data + end + + local expires = cookie.expires + local usebefore = cookie.usebefore + local hash = cookie.hash + + if not key then + key = concat{ id, expires, usebefore } + end + + local hkey = session.hmac(session.secret, key) + + data, err, tag = session.cipher:decrypt(data, hkey, id, session.key, hash) + if not data then + if storage.close then + storage:close(id_encoded) + end + + return nil, err or "unable to decrypt data" + end + + if tag then + if tag ~= hash then + if storage.close then + storage:close(id_encoded) + end + + return nil, "cookie has invalid tag" + end + + else + local input = concat{ key, data, session.key } + if session.hmac(hkey, input) ~= hash then + if storage.close then + storage:close(id_encoded) + end + + return nil, "cookie has invalid signature" + end + end + + data, err = session.compressor:decompress(data) + if not data then + if storage.close then + storage:close(id_encoded) + end + + return nil, err or "unable to decompress data" + end + + data, err = session.serializer.deserialize(data) + if not data then + if storage.close then + storage:close(id_encoded) + end + + return nil, err or "unable to deserialize data" + end + + session.id = id + session.expires = expires + session.usebefore = usebefore + session.data = type(data) == "table" and data or {} + session.present = true + + return true +end + +function strategy.open(session, cookie, keep_lock) + return strategy.load(session, cookie, nil, keep_lock) +end + +function strategy.start(session) + local storage = session.storage + if not storage.start then + return true + end + + local id_encoded = session.encoder.encode(session.id) + + local ok, err = storage:start(id_encoded) + if not ok then + return nil, err or "unable to start session" + end + + return true +end + +function strategy.modify(session, action, close, key) + local id = session.id + local id_encoded = session.encoder.encode(id) + local storage = session.storage + local expires = session.expires + local usebefore = session.usebefore + local ttl = expires - session.now + + if ttl <= 0 then + if storage.close then + storage:close(id_encoded) + end + + return nil, "session is already expired" + end + + if not key then + key = concat{ id, expires, usebefore } + end + + local data, err = session.serializer.serialize(session.data) + if not data then + if close and storage.close then + storage:close(id_encoded) + end + + return nil, err or "unable to serialize data" + end + + data, err = session.compressor:compress(data) + if not data then + if close and storage.close then + storage:close(id_encoded) + end + + return nil, err or "unable to compress data" + end + + local hkey = session.hmac(session.secret, key) + + local encrypted_data, tag + encrypted_data, err, tag = session.cipher:encrypt(data, hkey, id, session.key) + if not encrypted_data then + if close and storage.close then + storage:close(id_encoded) + end + + return nil, err + end + + local hash + if tag then + hash = tag + else + -- it would be better to calculate signature from encrypted_data, + -- but this is kept for backward compatibility + hash = session.hmac(hkey, concat{ key, data, session.key }) + end + + if action == "save" and storage.save then + local ok + ok, err = storage:save(id_encoded, ttl, encrypted_data, close) + if not ok then + return nil, err + end + elseif close and storage.close then + local ok + ok, err = storage:close(id_encoded) + if not ok then + return nil, err + end + end + + if usebefore then + expires = expires .. ":" .. usebefore + end + + hash = session.encoder.encode(hash) + + local cookie + if storage.save then + cookie = concat({ id_encoded, expires, hash }, "|") + else + local encoded_data = session.encoder.encode(encrypted_data) + cookie = concat({ id_encoded, expires, encoded_data, hash }, "|") + end + + return cookie +end + +function strategy.touch(session, close) + return strategy.modify(session, "touch", close) +end + +function strategy.save(session, close) + return strategy.modify(session, "save", close) +end + +function strategy.destroy(session) + local id = session.id + if id then + local storage = session.storage + if storage.destroy then + return storage:destroy(session.encoder.encode(id)) + elseif storage.close then + return storage:close(session.encoder.encode(id)) + end + end + + return true +end + +function strategy.close(session) + local id = session.id + if id then + local storage = session.storage + if storage.close then + return storage:close(session.encoder.encode(id)) + end + end + + return true +end + +return strategy diff --git a/server/resty/session/strategies/regenerate.lua b/server/resty/session/strategies/regenerate.lua new file mode 100644 index 0000000..f2a97dd --- /dev/null +++ b/server/resty/session/strategies/regenerate.lua @@ -0,0 +1,43 @@ +local default = require "resty.session.strategies.default" + +local concat = table.concat + +local strategy = { + regenerate = true, + start = default.start, + destroy = default.destroy, + close = default.close, +} + +local function key(source) + if source.usebefore then + return concat{ source.id, source.usebefore } + end + + return source.id +end + +function strategy.open(session, cookie, keep_lock) + return default.load(session, cookie, key(cookie), keep_lock) +end + +function strategy.touch(session, close) + return default.modify(session, "touch", close, key(session)) +end + +function strategy.save(session, close) + if session.present then + local storage = session.storage + if storage.ttl then + storage:ttl(session.encoder.encode(session.id), session.cookie.discard, true) + elseif storage.close then + storage:close(session.encoder.encode(session.id)) + end + + session.id = session:identifier() + end + + return default.modify(session, "save", close, key(session)) +end + +return strategy |