local e=require
local o=ipairs
local n=ngx
local a=setmetatable
local r=e("tch.posix")local c=r.clock_gettime
local u=r.CLOCK_MONOTONIC
local d=e"web.network"local t
do
local e=32
local n=("%02x"):rep(e)local r=assert(io.open("/dev/urandom","r"))t=function()local r=r:read(e)return n:format(r:byte(1,e))end
end
local e={}e.__index=e
local l={name="",role="",interface={},}local function r(e)local e=e.user
if not e then
return l
end
return e
end
function e:getusername()return string.taint(r(self).name)end
function e:isdefaultuser()local e=self.mgr.default_user
if not e then
return false
end
return(self.user==e)end
function e:toggleDefaultUser(e)if e then
self.mgr:setDefaultUser(self.user)else
self.mgr:setDefaultUser()end
end
function e:getrole()return r(self).role
end
function e:store(e,n)self.storage[e]=n
end
function e:retrieve(e)return self.storage[e]end
local function l(e)e.sessionid=t()e.CSRFtoken=t()end
function e:changeUser(e)n.log(n.WARN,"changing user to ",e and e.name or"default user")local r=r(self).role
local n=e and e.role
self.user=e
if r~=n then
l(self)end
end
function e:logout()local e=self.mgr
self.storage={}self:changeUser(e.default_user)end
function e:hasAccess(e)return(self.mgr:authorizeRequest(self,e))end
local function t(e,n)for r,e in o(e)do
if e==n then
return true
end
end
return false
end
local function o(e,n)local e=e and e.interface
if e then
local e=d.interfacesToIP(e)return t(e,n)end
return true
end
local function d(e,n)local e=e and e.allowed_ip
if e then
return e[n]~=nil
end
return true
end
local function i(e,n,r,t)if not e then
return true
end
if e.user~=n then
return true
end
if e.interface~=n.interface then
return true
end
if e.interfaceIP~=r then
return true
end
if e.remoteIP~=t then
return true
end
return false
end
local function s(n,e,r,t)if i(n,e,r,t)then
local o=o(e,r)local l=d(e,t)local o=o and l
n={user=e,interface=e.interface,interfaceIP=r,remoteIP=t,allowed=o,}end
return n.allowed,n
end
function e:isUserAllowedByIP(n)local e=self:retrieve("UserAllowedState")local t
n=n or r(self)t,e=s(e,n,self.serverIP,self.remoteIP)self:store("UserAllowedState",e)return t
end
function e:getCSRFtoken()return self.CSRFtoken
end
function e:checkCSRFtoken(e)if e~=self.CSRFtoken then
n.log(n.ERR,"POST without CSRF token")n.exit(n.HTTP_FORBIDDEN)end
return true
end
function e:addUserToManager(e)return self.mgr:addUser(e)end
function e:delUserFromManager(e)return self.mgr:delUser(e)end
function e:reloadAllUsers()self.mgr.sessioncontrol.reloadUsers()end
function e:getUserCount()return self.mgr:getUserCount()end
function e:getLoginPath()return self.mgr.loginpath
end
function e:changePassword(n,e,r)return self.mgr.sessioncontrol.changePassword(self.user,n,e,r)end
local function d(e)local c=function()return e:getusername()end
local u=function()return e:isdefaultuser()end
local o=function(r,n)return e:toggleDefaultUser(n)end
local r=function()return e:getrole()end
local t=function(t,n,r)e:store(n,r)end
local l=function(r,n)return e:retrieve(n)end
local d=function()e:logout()end
local h=function(r,n)return e:hasAccess(n)end
local m=function()return e:getCSRFtoken()end
local U=function(r,n)return e:checkCSRFtoken(n)end
local P=function(r,n)return e:addUserToManager(n)end
local g=function(r,n)return e:delUserFromManager(n)end
local f=function()return e:reloadAllUsers()end
local i=function(o,t,r,n)return e:changePassword(t,r,n)end
local s=function()return e:getUserCount()end
local e=function()return e:getLoginPath()end
local e={getusername=c,isdefaultuser=u,toggleDefaultUser=o,getrole=r,store=t,retrieve=l,logout=d,hasAccess=h,getCSRFtoken=m,checkCSRFtoken=U,addUserToManager=P,delUserFromManager=g,reloadAllUsers=f,changePassword=i,getUserCount=s,getLoginPath=e}return a({},{__index=e,__newindex=function()n.log(n.ERR,"Illegal attempt to modify session object")end,__metatable="ah ah ah, you didn't say the magic word"});end
local o={}function o.new(o,t)local r=t.default_user
n.log(n.WARN,"new session for ",r and r.name or"default user")local n={mgr=t,user=r,remoteIP=o.remote,serverIP=o.server,timestamp=c(u),storage={},}l(n)a(n,e)n.proxy=d(n)return n
end
return o