libs/web: rework luci.sauth
- perform decoding/encoding transparently in read() and write() - remove decode() and encode() helpers - introduce reap() to kill expired sessions
This commit is contained in:
parent
a58370ab74
commit
abef50b852
1 changed files with 49 additions and 46 deletions
|
@ -34,76 +34,68 @@ function prepare()
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
function encode(t)
|
|
||||||
return luci.util.get_bytecode({
|
|
||||||
user=t.user,
|
|
||||||
token=t.token,
|
|
||||||
secret=t.secret,
|
|
||||||
atime=luci.sys.uptime()
|
|
||||||
})
|
|
||||||
end
|
|
||||||
|
|
||||||
function decode(blob)
|
|
||||||
local t = loadstring(blob)()
|
|
||||||
return {
|
|
||||||
user = t.user,
|
|
||||||
token = t.token,
|
|
||||||
secret = t.secret,
|
|
||||||
atime = t.atime
|
|
||||||
}
|
|
||||||
end
|
|
||||||
|
|
||||||
--- Read a session and return its content.
|
|
||||||
-- @param id Session identifier
|
|
||||||
-- @return Session data
|
|
||||||
local function _read(id)
|
local function _read(id)
|
||||||
local blob = fs.readfile(sessionpath .. "/" .. id)
|
local blob = fs.readfile(sessionpath .. "/" .. id)
|
||||||
return blob
|
return blob
|
||||||
end
|
end
|
||||||
|
|
||||||
--- Write session data to a session file.
|
|
||||||
-- @param id Session identifier
|
|
||||||
-- @param data Session data
|
|
||||||
local function _write(id, data)
|
local function _write(id, data)
|
||||||
local f = nixio.open(sessionpath .. "/" .. id, "w", 600)
|
local f = nixio.open(sessionpath .. "/" .. id, "w", 600)
|
||||||
f:writeall(data)
|
f:writeall(data)
|
||||||
f:close()
|
f:close()
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function _checkid(id)
|
||||||
|
return not not (id and #id == 32 and id:match("^[a-fA-F0-9]+$"))
|
||||||
|
end
|
||||||
|
|
||||||
|
--- Write session data to a session file.
|
||||||
|
-- @param id Session identifier
|
||||||
|
-- @param data Session data table
|
||||||
function write(id, data)
|
function write(id, data)
|
||||||
if not sane() then
|
if not sane() then
|
||||||
prepare()
|
prepare()
|
||||||
end
|
end
|
||||||
|
|
||||||
if not id or #id == 0 or not id:match("^%w+$") then
|
assert(_checkid(id), "Security Exception: Session ID is invalid!")
|
||||||
error("Session ID is not sane!")
|
assert(type(data) == "table", "Security Exception: Session data invalid!")
|
||||||
end
|
|
||||||
|
data.atime = luci.sys.uptime()
|
||||||
_write(id, data)
|
|
||||||
|
_write(id, luci.util.get_bytecode(data))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Read a session and return its content.
|
||||||
|
-- @param id Session identifier
|
||||||
|
-- @return Session data table or nil if the given id is not found
|
||||||
function read(id)
|
function read(id)
|
||||||
if not id or #id == 0 then
|
if not id or #id == 0 then
|
||||||
return
|
return nil
|
||||||
end
|
|
||||||
if not id:match("^%w+$") then
|
|
||||||
error("Session ID is not sane!")
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
assert(_checkid(id), "Security Exception: Session ID is invalid!")
|
||||||
|
|
||||||
if not sane(sessionpath .. "/" .. id) then
|
if not sane(sessionpath .. "/" .. id) then
|
||||||
return
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
local blob = _read(id)
|
local blob = _read(id)
|
||||||
if decode(blob).atime + sessiontime < luci.sys.uptime()then
|
local func = loadstring(blob)
|
||||||
fs.unlink(sessionpath .. "/" .. id)
|
setfenv(func, {})
|
||||||
return
|
|
||||||
end
|
local sess = func()
|
||||||
-- refresh atime in session
|
assert(type(sess) == "table", "Session data invalid!")
|
||||||
refreshed = encode(decode(blob))
|
|
||||||
write(id, refreshed)
|
if sess.atime and sess.atime + sessiontime < luci.sys.uptime() then
|
||||||
return blob
|
kill(id)
|
||||||
|
return nil
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- refresh atime in session
|
||||||
|
write(id, sess)
|
||||||
|
|
||||||
|
return sess
|
||||||
|
end
|
||||||
|
|
||||||
--- Check whether Session environment is sane.
|
--- Check whether Session environment is sane.
|
||||||
-- @return Boolean status
|
-- @return Boolean status
|
||||||
|
@ -117,8 +109,19 @@ end
|
||||||
--- Kills a session
|
--- Kills a session
|
||||||
-- @param id Session identifier
|
-- @param id Session identifier
|
||||||
function kill(id)
|
function kill(id)
|
||||||
if not id:match("^%w+$") then
|
assert(_checkid(id), "Security Exception: Session ID is invalid!")
|
||||||
error("Session ID is not sane!")
|
|
||||||
end
|
|
||||||
fs.unlink(sessionpath .. "/" .. id)
|
fs.unlink(sessionpath .. "/" .. id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
--- Remove all expired session data files
|
||||||
|
function reap()
|
||||||
|
if sane() then
|
||||||
|
local id
|
||||||
|
for id in nixio.fs.dir(sessionpath) do
|
||||||
|
if _checkid(id) then
|
||||||
|
-- reading the session will kill it if it is expired
|
||||||
|
read(id)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
Loading…
Reference in a new issue