summaryrefslogtreecommitdiffstats
path: root/server/resty/session
diff options
context:
space:
mode:
authorFiete Ostkamp <Fiete.Ostkamp@telekom.de>2024-03-01 13:03:12 +0100
committerFiete Ostkamp <Fiete.Ostkamp@telekom.de>2024-03-01 13:03:12 +0100
commit97d7de9af2cb6cc3bbbcae18ada738ace7771903 (patch)
treea7c6221348272e82406bba446b6b00b1d1b8e608 /server/resty/session
parentbf25efd6d3ed28266ed916c0ebe9dd3a45a4affb (diff)
portal-ng pods run under root user
- switch base image from openresty to nginx-unprivileged - remove custom lua plugin code - dynamically determine dns resolver ip during container startup Issue-ID: PORTALNG-67 Change-Id: I23fb5e684dbb98a326afb00911a1f5ae78e2536d Signed-off-by: Fiete Ostkamp <Fiete.Ostkamp@telekom.de>
Diffstat (limited to 'server/resty/session')
-rw-r--r--server/resty/session/ciphers/aes.lua113
-rw-r--r--server/resty/session/ciphers/none.lua15
-rw-r--r--server/resty/session/compressors/none.lua15
-rw-r--r--server/resty/session/compressors/zlib.lua43
-rw-r--r--server/resty/session/encoders/base16.lua29
-rw-r--r--server/resty/session/encoders/base64.lua39
-rw-r--r--server/resty/session/encoders/hex.lua1
-rw-r--r--server/resty/session/hmac/sha1.lua1
-rw-r--r--server/resty/session/identifiers/random.lua13
-rw-r--r--server/resty/session/serializers/json.lua6
-rw-r--r--server/resty/session/storage/cookie.lua7
-rw-r--r--server/resty/session/storage/dshm.lua163
-rw-r--r--server/resty/session/storage/memcache.lua303
-rw-r--r--server/resty/session/storage/memcached.lua1
-rw-r--r--server/resty/session/storage/redis.lua478
-rw-r--r--server/resty/session/storage/shm.lua125
-rw-r--r--server/resty/session/strategies/default.lua232
-rw-r--r--server/resty/session/strategies/regenerate.lua43
18 files changed, 0 insertions, 1627 deletions
diff --git a/server/resty/session/ciphers/aes.lua b/server/resty/session/ciphers/aes.lua
deleted file mode 100644
index 9a088ad..0000000
--- a/server/resty/session/ciphers/aes.lua
+++ /dev/null
@@ -1,113 +0,0 @@
-local aes = require "resty.aes"
-
-local setmetatable = setmetatable
-local tonumber = tonumber
-local ceil = math.ceil
-local var = ngx.var
-local sub = string.sub
-local rep = string.rep
-
-local HASHES = aes.hash
-
-local CIPHER_MODES = {
- ecb = "ecb",
- cbc = "cbc",
- cfb1 = "cfb1",
- cfb8 = "cfb8",
- cfb128 = "cfb128",
- ofb = "ofb",
- ctr = "ctr",
- gcm = "gcm",
-}
-
-local CIPHER_SIZES = {
- [128] = 128,
- [192] = 192,
- [256] = 256,
-}
-
-local defaults = {
- size = CIPHER_SIZES[tonumber(var.session_aes_size, 10)] or 256,
- mode = CIPHER_MODES[var.session_aes_mode] or "cbc",
- hash = HASHES[var.session_aes_hash] or HASHES.sha512,
- rounds = tonumber(var.session_aes_rounds, 10) or 1,
-}
-
-local function adjust_salt(salt)
- if not salt then
- return nil
- end
-
- local z = #salt
- if z < 8 then
- return sub(rep(salt, ceil(8 / z)), 1, 8)
- end
- if z > 8 then
- return sub(salt, 1, 8)
- end
-
- return salt
-end
-
-local function get_cipher(self, key, salt)
- local mode = aes.cipher(self.size, self.mode)
- if not mode then
- return nil, "invalid cipher mode " .. self.mode .. "(" .. self.size .. ")"
- end
-
- return aes:new(key, adjust_salt(salt), mode, self.hash, self.rounds)
-end
-
-local cipher = {}
-
-cipher.__index = cipher
-
-function cipher.new(session)
- local config = session.aes or defaults
- return setmetatable({
- size = CIPHER_SIZES[tonumber(config.size, 10)] or defaults.size,
- mode = CIPHER_MODES[config.mode] or defaults.mode,
- hash = HASHES[config.hash] or defaults.hash,
- rounds = tonumber(config.rounds, 10) or defaults.rounds,
- }, cipher)
-end
-
-function cipher:encrypt(data, key, salt, _)
- local cip, err = get_cipher(self, key, salt)
- if not cip then
- return nil, err or "unable to aes encrypt data"
- end
-
- local encrypted_data
- encrypted_data, err = cip:encrypt(data)
- if not encrypted_data then
- return nil, err or "aes encryption failed"
- end
-
- if self.mode == "gcm" then
- return encrypted_data[1], nil, encrypted_data[2]
- end
-
- return encrypted_data
-end
-
-function cipher:decrypt(data, key, salt, _, tag)
- local cip, err = get_cipher(self, key, salt)
- if not cip then
- return nil, err or "unable to aes decrypt data"
- end
-
- local decrypted_data
- decrypted_data, err = cip:decrypt(data, tag)
- if not decrypted_data then
- return nil, err or "aes decryption failed"
- end
-
- if self.mode == "gcm" then
- return decrypted_data, nil, tag
- end
-
- return decrypted_data
-end
-
-return cipher
diff --git a/server/resty/session/ciphers/none.lua b/server/resty/session/ciphers/none.lua
deleted file mode 100644
index b29bb88..0000000
--- a/server/resty/session/ciphers/none.lua
+++ /dev/null
@@ -1,15 +0,0 @@
-local cipher = {}
-
-function cipher.new()
- return cipher
-end
-
-function cipher.encrypt(_, data, _, _)
- return data
-end
-
-function cipher.decrypt(_, data, _, _, _)
- return data
-end
-
-return cipher
diff --git a/server/resty/session/compressors/none.lua b/server/resty/session/compressors/none.lua
deleted file mode 100644
index 3d14a5c..0000000
--- a/server/resty/session/compressors/none.lua
+++ /dev/null
@@ -1,15 +0,0 @@
-local compressor = {}
-
-function compressor.new()
- return compressor
-end
-
-function compressor.compress(_, data)
- return data
-end
-
-function compressor.decompress(_, data)
- return data
-end
-
-return compressor
diff --git a/server/resty/session/compressors/zlib.lua b/server/resty/session/compressors/zlib.lua
deleted file mode 100644
index 1d23be0..0000000
--- a/server/resty/session/compressors/zlib.lua
+++ /dev/null
@@ -1,43 +0,0 @@
-local zlib = require "ffi-zlib"
-local sio = require "pl.stringio"
-
-local concat = table.concat
-
-local function gzip(func, input)
- local stream = sio.open(input)
- local output = {}
- local n = 0
-
- local ok, err = func(function(size)
- return stream:read(size)
- end, function(data)
- n = n + 1
- output[n] = data
- end, 8192)
-
- if not ok then
- return nil, err
- end
-
- if n == 0 then
- return ""
- end
-
- return concat(output, nil, 1, n)
-end
-
-local compressor = {}
-
-function compressor.new()
- return compressor
-end
-
-function compressor.compress(_, data)
- return gzip(zlib.deflateGzip, data)
-end
-
-function compressor.decompress(_, data)
- return gzip(zlib.inflateGzip, data)
-end
-
-return compressor
diff --git a/server/resty/session/encoders/base16.lua b/server/resty/session/encoders/base16.lua
deleted file mode 100644
index 552f50e..0000000
--- a/server/resty/session/encoders/base16.lua
+++ /dev/null
@@ -1,29 +0,0 @@
-local to_hex = require "resty.string".to_hex
-
-local tonumber = tonumber
-local gsub = string.gsub
-local char = string.char
-
-local function chr(c)
- return char(tonumber(c, 16) or 0)
-end
-
-local encoder = {}
-
-function encoder.encode(value)
- if not value then
- return nil, "unable to base16 encode value"
- end
-
- return to_hex(value)
-end
-
-function encoder.decode(value)
- if not value then
- return nil, "unable to base16 decode value"
- end
-
- return (gsub(value, "..", chr))
-end
-
-return encoder
diff --git a/server/resty/session/encoders/base64.lua b/server/resty/session/encoders/base64.lua
deleted file mode 100644
index ddaf4e8..0000000
--- a/server/resty/session/encoders/base64.lua
+++ /dev/null
@@ -1,39 +0,0 @@
-local encode_base64 = ngx.encode_base64
-local decode_base64 = ngx.decode_base64
-
-local gsub = string.gsub
-
-local ENCODE_CHARS = {
- ["+"] = "-",
- ["/"] = "_",
-}
-
-local DECODE_CHARS = {
- ["-"] = "+",
- ["_"] = "/",
-}
-
-local encoder = {}
-
-function encoder.encode(value)
- if not value then
- return nil, "unable to base64 encode value"
- end
-
- local encoded = encode_base64(value, true)
- if not encoded then
- return nil, "unable to base64 encode value"
- end
-
- return gsub(encoded, "[+/]", ENCODE_CHARS)
-end
-
-function encoder.decode(value)
- if not value then
- return nil, "unable to base64 decode value"
- end
-
- return decode_base64((gsub(value, "[-_]", DECODE_CHARS)))
-end
-
-return encoder
diff --git a/server/resty/session/encoders/hex.lua b/server/resty/session/encoders/hex.lua
deleted file mode 100644
index 1b94a5a..0000000
--- a/server/resty/session/encoders/hex.lua
+++ /dev/null
@@ -1 +0,0 @@
-return require "resty.session.encoders.base16" \ No newline at end of file
diff --git a/server/resty/session/hmac/sha1.lua b/server/resty/session/hmac/sha1.lua
deleted file mode 100644
index 1753412..0000000
--- a/server/resty/session/hmac/sha1.lua
+++ /dev/null
@@ -1 +0,0 @@
-return ngx.hmac_sha1
diff --git a/server/resty/session/identifiers/random.lua b/server/resty/session/identifiers/random.lua
deleted file mode 100644
index a2f9739..0000000
--- a/server/resty/session/identifiers/random.lua
+++ /dev/null
@@ -1,13 +0,0 @@
-local tonumber = tonumber
-local random = require "resty.random".bytes
-local var = ngx.var
-
-local defaults = {
- length = tonumber(var.session_random_length, 10) or 16
-}
-
-return function(session)
- local config = session.random or defaults
- local length = tonumber(config.length, 10) or defaults.length
- return random(length, true) or random(length)
-end
diff --git a/server/resty/session/serializers/json.lua b/server/resty/session/serializers/json.lua
deleted file mode 100644
index 960c4d8..0000000
--- a/server/resty/session/serializers/json.lua
+++ /dev/null
@@ -1,6 +0,0 @@
-local json = require "cjson.safe"
-
-return {
- serialize = json.encode,
- deserialize = json.decode,
-}
diff --git a/server/resty/session/storage/cookie.lua b/server/resty/session/storage/cookie.lua
deleted file mode 100644
index 95e26d1..0000000
--- a/server/resty/session/storage/cookie.lua
+++ /dev/null
@@ -1,7 +0,0 @@
-local storage = {}
-
-function storage.new()
- return storage
-end
-
-return storage
diff --git a/server/resty/session/storage/dshm.lua b/server/resty/session/storage/dshm.lua
deleted file mode 100644
index e6d887f..0000000
--- a/server/resty/session/storage/dshm.lua
+++ /dev/null
@@ -1,163 +0,0 @@
-local dshm = require "resty.dshm"
-
-local setmetatable = setmetatable
-local tonumber = tonumber
-local concat = table.concat
-local var = ngx.var
-
-local defaults = {
- region = var.session_dshm_region or "sessions",
- connect_timeout = tonumber(var.session_dshm_connect_timeout, 10),
- read_timeout = tonumber(var.session_dshm_read_timeout, 10),
- send_timeout = tonumber(var.session_dshm_send_timeout, 10),
- host = var.session_dshm_host or "127.0.0.1",
- port = tonumber(var.session_dshm_port, 10) or 4321,
- pool = {
- name = var.session_dshm_pool_name,
- size = tonumber(var.session_dshm_pool_size, 10) or 100,
- timeout = tonumber(var.session_dshm_pool_timeout, 10) or 1000,
- backlog = tonumber(var.session_dshm_pool_backlog, 10),
- },
-}
-
-local storage = {}
-
-storage.__index = storage
-
-function storage.new(session)
- local config = session.dshm or defaults
- local pool = config.pool or defaults.pool
-
- local connect_timeout = tonumber(config.connect_timeout, 10) or defaults.connect_timeout
-
- local store = dshm:new()
- if store.set_timeouts then
- local send_timeout = tonumber(config.send_timeout, 10) or defaults.send_timeout
- local read_timeout = tonumber(config.read_timeout, 10) or defaults.read_timeout
-
- if connect_timeout then
- if send_timeout and read_timeout then
- store:set_timeouts(connect_timeout, send_timeout, read_timeout)
- else
- store:set_timeout(connect_timeout)
- end
- end
-
- elseif store.set_timeout and connect_timeout then
- store:set_timeout(connect_timeout)
- end
-
-
- local self = {
- store = store,
- encoder = session.encoder,
- region = config.region or defaults.region,
- host = config.host or defaults.host,
- port = tonumber(config.port, 10) or defaults.port,
- pool_timeout = tonumber(pool.timeout, 10) or defaults.pool.timeout,
- connect_opts = {
- pool = pool.name or defaults.pool.name,
- pool_size = tonumber(pool.size, 10) or defaults.pool.size,
- backlog = tonumber(pool.backlog, 10) or defaults.pool.backlog,
- },
- }
-
- return setmetatable(self, storage)
-end
-
-function storage:connect()
- return self.store:connect(self.host, self.port, self.connect_opts)
-end
-
-function storage:set_keepalive()
- return self.store:set_keepalive(self.pool_timeout)
-end
-
-function storage:key(id)
- return concat({ self.region, id }, "::")
-end
-
-function storage:set(key, ttl, data)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- data, err = self.encoder.encode(data)
-
- if not data then
- self:set_keepalive()
- return nil, err
- end
-
- ok, err = self.store:set(key, data, ttl)
-
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:get(key)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local data
- data, err = self.store:get(key)
- if data then
- data, err = self.encoder.decode(data)
- end
-
- self:set_keepalive()
-
- return data, err
-end
-
-function storage:delete(key)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- ok, err = self.store:delete(key)
-
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:touch(key, ttl)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- ok, err = self.store:touch(key, ttl)
-
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:open(id)
- local key = self:key(id)
- return self:get(key)
-end
-
-function storage:save(id, ttl, data)
- local key = self:key(id)
- return self:set(key, ttl, data)
-end
-
-function storage:destroy(id)
- local key = self:key(id)
- return self:delete(key)
-end
-
-function storage:ttl(id, ttl)
- local key = self:key(id)
- return self:touch(key, ttl)
-end
-
-return storage
diff --git a/server/resty/session/storage/memcache.lua b/server/resty/session/storage/memcache.lua
deleted file mode 100644
index da44ba7..0000000
--- a/server/resty/session/storage/memcache.lua
+++ /dev/null
@@ -1,303 +0,0 @@
-local memcached = require "resty.memcached"
-local setmetatable = setmetatable
-local tonumber = tonumber
-local concat = table.concat
-local sleep = ngx.sleep
-local null = ngx.null
-local var = ngx.var
-
-local function enabled(value)
- if value == nil then
- return nil
- end
-
- return value == true
- or value == "1"
- or value == "true"
- or value == "on"
-end
-
-local function ifnil(value, default)
- if value == nil then
- return default
- end
-
- return enabled(value)
-end
-
-local defaults = {
- prefix = var.session_memcache_prefix or "sessions",
- socket = var.session_memcache_socket,
- host = var.session_memcache_host or "127.0.0.1",
- uselocking = enabled(var.session_memcache_uselocking or true),
- connect_timeout = tonumber(var.session_memcache_connect_timeout, 10),
- read_timeout = tonumber(var.session_memcache_read_timeout, 10),
- send_timeout = tonumber(var.session_memcache_send_timeout, 10),
- port = tonumber(var.session_memcache_port, 10) or 11211,
- spinlockwait = tonumber(var.session_memcache_spinlockwait, 10) or 150,
- maxlockwait = tonumber(var.session_memcache_maxlockwait, 10) or 30,
- pool = {
- name = var.session_memcache_pool_name,
- timeout = tonumber(var.session_memcache_pool_timeout, 10),
- size = tonumber(var.session_memcache_pool_size, 10),
- backlog = tonumber(var.session_memcache_pool_backlog, 10),
- },
-}
-
-local storage = {}
-
-storage.__index = storage
-
-function storage.new(session)
- local config = session.memcache or defaults
- local pool = config.pool or defaults.pool
- local locking = ifnil(config.uselocking, defaults.uselocking)
-
- local connect_timeout = tonumber(config.connect_timeout, 10) or defaults.connect_timeout
-
- local memcache = memcached:new()
- if memcache.set_timeouts then
- local send_timeout = tonumber(config.send_timeout, 10) or defaults.send_timeout
- local read_timeout = tonumber(config.read_timeout, 10) or defaults.read_timeout
-
- if connect_timeout then
- if send_timeout and read_timeout then
- memcache:set_timeouts(connect_timeout, send_timeout, read_timeout)
- else
- memcache:set_timeout(connect_timeout)
- end
- end
-
- elseif memcache.set_timeout and connect_timeout then
- memcache:set_timeout(connect_timeout)
- end
-
- local self = {
- memcache = memcache,
- prefix = config.prefix or defaults.prefix,
- uselocking = locking,
- spinlockwait = tonumber(config.spinlockwait, 10) or defaults.spinlockwait,
- maxlockwait = tonumber(config.maxlockwait, 10) or defaults.maxlockwait,
- pool_timeout = tonumber(pool.timeout, 10) or defaults.pool.timeout,
- connect_opts = {
- pool = pool.name or defaults.pool.name,
- pool_size = tonumber(pool.size, 10) or defaults.pool.size,
- backlog = tonumber(pool.backlog, 10) or defaults.pool.backlog,
- },
- }
-
- local socket = config.socket or defaults.socket
- if socket and socket ~= "" then
- self.socket = socket
- else
- self.host = config.host or defaults.host
- self.port = config.port or defaults.port
- end
-
- return setmetatable(self, storage)
-end
-
-function storage:connect()
- local socket = self.socket
- if socket then
- return self.memcache:connect(socket, self.connect_opts)
- end
- return self.memcache:connect(self.host, self.port, self.connect_opts)
-end
-
-function storage:set_keepalive()
- return self.memcache:set_keepalive(self.pool_timeout)
-end
-
-function storage:key(id)
- return concat({ self.prefix, id }, ":" )
-end
-
-function storage:lock(key)
- if not self.uselocking or self.locked then
- return true
- end
-
- if not self.token then
- self.token = var.request_id
- end
-
- local lock_key = concat({ key, "lock" }, "." )
- local lock_ttl = self.maxlockwait + 1
- local attempts = (1000 / self.spinlockwait) * self.maxlockwait
- local waittime = self.spinlockwait / 1000
-
- for _ = 1, attempts do
- local ok = self.memcache:add(lock_key, self.token, lock_ttl)
- if ok then
- self.locked = true
- return true
- end
-
- sleep(waittime)
- end
-
- return false, "unable to acquire a session lock"
-end
-
-function storage:unlock(key)
- if not self.uselocking or not self.locked then
- return true
- end
-
- local lock_key = concat({ key, "lock" }, "." )
- local token = self:get(lock_key)
-
- if token == self.token then
- self.memcache:delete(lock_key)
- self.locked = nil
- end
-end
-
-function storage:get(key)
- local data, err = self.memcache:get(key)
- if not data then
- return nil, err
- end
-
- if data == null then
- return nil
- end
-
- return data
-end
-
-function storage:set(key, data, ttl)
- return self.memcache:set(key, data, ttl)
-end
-
-function storage:expire(key, ttl)
- return self.memcache:touch(key, ttl)
-end
-
-function storage:delete(key)
- return self.memcache:delete(key)
-end
-
-function storage:open(id, keep_lock)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:lock(key)
- if not ok then
- self:set_keepalive()
- return nil, err
- end
-
- local data
- data, err = self:get(key)
-
- if err or not data or not keep_lock then
- self:unlock(key)
- end
-
- self:set_keepalive()
-
- return data, err
-end
-
-function storage:start(id)
- if not self.uselocking or not self.locked then
- return true
- end
-
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:lock(key)
-
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:save(id, ttl, data, close)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:set(key, data, ttl)
-
- if close then
- self:unlock(key)
- end
-
- self:set_keepalive()
-
- if not ok then
- return nil, err
- end
-
- return true
-end
-
-function storage:close(id)
- if not self.uselocking or not self.locked then
- return true
- end
-
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- self:unlock(key)
- self:set_keepalive()
-
- return true
-end
-
-function storage:destroy(id)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:delete(key)
-
- self:unlock(key)
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:ttl(id, ttl, close)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:expire(key, ttl)
-
- if close then
- self:unlock(key)
- end
-
- self:set_keepalive()
-
- return ok, err
-end
-
-return storage
diff --git a/server/resty/session/storage/memcached.lua b/server/resty/session/storage/memcached.lua
deleted file mode 100644
index 0ecc508..0000000
--- a/server/resty/session/storage/memcached.lua
+++ /dev/null
@@ -1 +0,0 @@
-return require "resty.session.storage.memcache"
diff --git a/server/resty/session/storage/redis.lua b/server/resty/session/storage/redis.lua
deleted file mode 100644
index 3de0472..0000000
--- a/server/resty/session/storage/redis.lua
+++ /dev/null
@@ -1,478 +0,0 @@
-local setmetatable = setmetatable
-local tonumber = tonumber
-local type = type
-local reverse = string.reverse
-local gmatch = string.gmatch
-local find = string.find
-local byte = string.byte
-local sub = string.sub
-local concat = table.concat
-local sleep = ngx.sleep
-local null = ngx.null
-local var = ngx.var
-
-local LB = byte("[")
-local RB = byte("]")
-
-local function parse_cluster_nodes(nodes)
- if not nodes or nodes == "" then
- return nil
- end
-
- if type(nodes) == "table" then
- return nodes
- end
-
- local addrs
- local i
- for node in gmatch(nodes, "%S+") do
- local ip = node
- local port = 6379
- local pos = find(reverse(ip), ":", 2, true)
- if pos then
- local p = tonumber(sub(ip, -pos + 1), 10)
- if p >= 1 and p <= 65535 then
- local addr = sub(ip, 1, -pos - 1)
- if find(addr, ":", 1, true) then
- if byte(addr, -1) == RB then
- ip = addr
- port = p
- end
-
- else
- ip = addr
- port = p
- end
- end
- end
-
- if byte(ip, 1, 1) == LB then
- ip = sub(ip, 2)
- end
-
- if byte(ip, -1) == RB then
- ip = sub(ip, 1, -2)
- end
-
- if not addrs then
- i = 1
- addrs = {{
- ip = ip,
- port = port,
- }}
- else
- i = i + 1
- addrs[i] = {
- ip = ip,
- port = port,
- }
- end
- end
-
- if not i then
- return
- end
-
- return addrs
-end
-
-local redis_single = require "resty.redis"
-local redis_cluster
-do
- local pcall = pcall
- local require = require
- local ok
- ok, redis_cluster = pcall(require, "resty.rediscluster")
- if not ok then
- ok, redis_cluster = pcall(require, "rediscluster")
- if not ok then
- redis_cluster = nil
- end
- end
-end
-
-local UNLOCK = [[
-if redis.call("GET", KEYS[1]) == ARGV[1] then
- return redis.call("DEL", KEYS[1])
-else
- return 0
-end
-]]
-
-local function enabled(value)
- if value == nil then return nil end
- return value == true or (value == "1" or value == "true" or value == "on")
-end
-
-local function ifnil(value, default)
- if value == nil then
- return default
- end
-
- return enabled(value)
-end
-
-local defaults = {
- prefix = var.session_redis_prefix or "sessions",
- socket = var.session_redis_socket,
- host = var.session_redis_host or "127.0.0.1",
- username = var.session_redis_username,
- password = var.session_redis_password or var.session_redis_auth,
- server_name = var.session_redis_server_name,
- ssl = enabled(var.session_redis_ssl) or false,
- ssl_verify = enabled(var.session_redis_ssl_verify) or false,
- uselocking = enabled(var.session_redis_uselocking or true),
- port = tonumber(var.session_redis_port, 10) or 6379,
- database = tonumber(var.session_redis_database, 10) or 0,
- connect_timeout = tonumber(var.session_redis_connect_timeout, 10),
- read_timeout = tonumber(var.session_redis_read_timeout, 10),
- send_timeout = tonumber(var.session_redis_send_timeout, 10),
- spinlockwait = tonumber(var.session_redis_spinlockwait, 10) or 150,
- maxlockwait = tonumber(var.session_redis_maxlockwait, 10) or 30,
- pool = {
- name = var.session_redis_pool_name,
- timeout = tonumber(var.session_redis_pool_timeout, 10),
- size = tonumber(var.session_redis_pool_size, 10),
- backlog = tonumber(var.session_redis_pool_backlog, 10),
- },
-}
-
-
-if redis_cluster then
- defaults.cluster = {
- name = var.session_redis_cluster_name,
- dict = var.session_redis_cluster_dict,
- maxredirections = tonumber(var.session_redis_cluster_maxredirections, 10),
- nodes = parse_cluster_nodes(var.session_redis_cluster_nodes),
- }
-end
-
-local storage = {}
-
-storage.__index = storage
-
-function storage.new(session)
- local config = session.redis or defaults
- local pool = config.pool or defaults.pool
- local cluster = config.cluster or defaults.cluster
- local locking = ifnil(config.uselocking, defaults.uselocking)
-
- local self = {
- prefix = config.prefix or defaults.prefix,
- uselocking = locking,
- spinlockwait = tonumber(config.spinlockwait, 10) or defaults.spinlockwait,
- maxlockwait = tonumber(config.maxlockwait, 10) or defaults.maxlockwait,
- }
-
- local username = config.username or defaults.username
- if username == "" then
- username = nil
- end
- local password = config.password or config.auth or defaults.password
- if password == "" then
- password = nil
- end
-
- local connect_timeout = tonumber(config.connect_timeout, 10) or defaults.connect_timeout
-
- local cluster_nodes
- if redis_cluster then
- cluster_nodes = parse_cluster_nodes(cluster.nodes or defaults.cluster.nodes)
- end
-
- local connect_opts = {
- pool = pool.name or defaults.pool.name,
- pool_size = tonumber(pool.size, 10) or defaults.pool.size,
- backlog = tonumber(pool.backlog, 10) or defaults.pool.backlog,
- server_name = config.server_name or defaults.server_name,
- ssl = ifnil(config.ssl, defaults.ssl),
- ssl_verify = ifnil(config.ssl_verify, defaults.ssl_verify),
- }
-
- if cluster_nodes then
- self.redis = redis_cluster:new({
- name = cluster.name or defaults.cluster.name,
- dict_name = cluster.dict or defaults.cluster.dict,
- username = var.session_redis_username,
- password = var.session_redis_password or defaults.password,
- connection_timout = connect_timeout, -- typo in library
- connection_timeout = connect_timeout,
- keepalive_timeout = tonumber(pool.timeout, 10) or defaults.pool.timeout,
- keepalive_cons = tonumber(pool.size, 10) or defaults.pool.size,
- max_redirection = tonumber(cluster.maxredirections, 10) or defaults.cluster.maxredirections,
- serv_list = cluster_nodes,
- connect_opts = connect_opts,
- })
- self.cluster = true
-
- else
- local redis = redis_single:new()
-
- if redis.set_timeouts then
- local send_timeout = tonumber(config.send_timeout, 10) or defaults.send_timeout
- local read_timeout = tonumber(config.read_timeout, 10) or defaults.read_timeout
-
- if connect_timeout then
- if send_timeout and read_timeout then
- redis:set_timeouts(connect_timeout, send_timeout, read_timeout)
- else
- redis:set_timeout(connect_timeout)
- end
- end
-
- elseif redis.set_timeout and connect_timeout then
- redis:set_timeout(connect_timeout)
- end
-
- self.redis = redis
- self.username = username
- self.password = password
- self.database = tonumber(config.database, 10) or defaults.database
- self.pool_timeout = tonumber(pool.timeout, 10) or defaults.pool.timeout
- self.connect_opts = connect_opts
-
- local socket = config.socket or defaults.socket
- if socket and socket ~= "" then
- self.socket = socket
- else
- self.host = config.host or defaults.host
- self.port = config.port or defaults.port
- end
- end
-
- return setmetatable(self, storage)
-end
-
-function storage:connect()
- if self.cluster then
- return true -- cluster handles this on its own
- end
-
- local ok, err
- if self.socket then
- ok, err = self.redis:connect(self.socket, self.connect_opts)
- else
- ok, err = self.redis:connect(self.host, self.port, self.connect_opts)
- end
-
- if not ok then
- return nil, err
- end
-
- if self.password and self.redis:get_reused_times() == 0 then
- -- usernames are supported only on Redis 6+, so use new AUTH form only when absolutely necessary
- if self.username then
- ok, err = self.redis:auth(self.username, self.password)
- else
- ok, err = self.redis:auth(self.password)
- end
- if not ok then
- self.redis:close()
- return nil, err
- end
- end
-
- if self.database ~= 0 then
- ok, err = self.redis:select(self.database)
- if not ok then
- self.redis:close()
- end
- end
-
- return ok, err
-end
-
-function storage:set_keepalive()
- if self.cluster then
- return true -- cluster handles this on its own
- end
-
- return self.redis:set_keepalive(self.pool_timeout)
-end
-
-function storage:key(id)
- return concat({ self.prefix, id }, ":" )
-end
-
-function storage:lock(key)
- if not self.uselocking or self.locked then
- return true
- end
-
- if not self.token then
- self.token = var.request_id
- end
-
- local lock_key = concat({ key, "lock" }, "." )
- local lock_ttl = self.maxlockwait + 1
- local attempts = (1000 / self.spinlockwait) * self.maxlockwait
- local waittime = self.spinlockwait / 1000
-
- for _ = 1, attempts do
- local ok = self.redis:set(lock_key, self.token, "EX", lock_ttl, "NX")
- if ok ~= null then
- self.locked = true
- return true
- end
-
- sleep(waittime)
- end
-
- return false, "unable to acquire a session lock"
-end
-
-function storage:unlock(key)
- if not self.uselocking or not self.locked then
- return
- end
-
- local lock_key = concat({ key, "lock" }, "." )
-
- self.redis:eval(UNLOCK, 1, lock_key, self.token)
- self.locked = nil
-end
-
-function storage:get(key)
- local data, err = self.redis:get(key)
- if not data then
- return nil, err
- end
-
- if data == null then
- return nil
- end
-
- return data
-end
-
-function storage:set(key, data, lifetime)
- return self.redis:setex(key, lifetime, data)
-end
-
-function storage:expire(key, lifetime)
- return self.redis:expire(key, lifetime)
-end
-
-function storage:delete(key)
- return self.redis:del(key)
-end
-
-function storage:open(id, keep_lock)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:lock(key)
- if not ok then
- self:set_keepalive()
- return nil, err
- end
-
- local data
- data, err = self:get(key)
-
- if err or not data or not keep_lock then
- self:unlock(key)
- end
- self:set_keepalive()
-
- return data, err
-end
-
-function storage:start(id)
- if not self.uselocking or not self.locked then
- return true
- end
-
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- ok, err = self:lock(self:key(id))
-
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:save(id, ttl, data, close)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:set(key, data, ttl)
-
- if close then
- self:unlock(key)
- end
-
- self:set_keepalive()
-
- if not ok then
- return nil, err
- end
-
- return true
-end
-
-function storage:close(id)
- if not self.uselocking or not self.locked then
- return true
- end
-
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- self:unlock(key)
- self:set_keepalive()
-
- return true
-end
-
-function storage:destroy(id)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:delete(key)
-
- self:unlock(key)
- self:set_keepalive()
-
- return ok, err
-end
-
-function storage:ttl(id, ttl, close)
- local ok, err = self:connect()
- if not ok then
- return nil, err
- end
-
- local key = self:key(id)
-
- ok, err = self:expire(key, ttl)
-
- if close then
- self:unlock(key)
- end
-
- self:set_keepalive()
-
- return ok, err
-end
-
-return storage
diff --git a/server/resty/session/storage/shm.lua b/server/resty/session/storage/shm.lua
deleted file mode 100644
index 6f81435..0000000
--- a/server/resty/session/storage/shm.lua
+++ /dev/null
@@ -1,125 +0,0 @@
-local lock = require "resty.lock"
-
-local setmetatable = setmetatable
-local tonumber = tonumber
-local concat = table.concat
-local var = ngx.var
-local shared = ngx.shared
-
-local function enabled(value)
- if value == nil then return nil end
- return value == true or (value == "1" or value == "true" or value == "on")
-end
-
-local function ifnil(value, default)
- if value == nil then
- return default
- end
-
- return enabled(value)
-end
-
-local defaults = {
- store = var.session_shm_store or "sessions",
- uselocking = enabled(var.session_shm_uselocking or true),
- lock = {
- exptime = tonumber(var.session_shm_lock_exptime, 10) or 30,
- timeout = tonumber(var.session_shm_lock_timeout, 10) or 5,
- step = tonumber(var.session_shm_lock_step, 10) or 0.001,
- ratio = tonumber(var.session_shm_lock_ratio, 10) or 2,
- max_step = tonumber(var.session_shm_lock_max_step, 10) or 0.5,
- }
-}
-
-local storage = {}
-
-storage.__index = storage
-
-function storage.new(session)
- local config = session.shm or defaults
- local store = config.store or defaults.store
- local locking = ifnil(config.uselocking, defaults.uselocking)
-
- local self = {
- store = shared[store],
- uselocking = locking,
- }
-
- if locking then
- local lock_opts = config.lock or defaults.lock
- local opts = {
- exptime = tonumber(lock_opts.exptime, 10) or defaults.exptime,
- timeout = tonumber(lock_opts.timeout, 10) or defaults.timeout,
- step = tonumber(lock_opts.step, 10) or defaults.step,
- ratio = tonumber(lock_opts.ratio, 10) or defaults.ratio,
- max_step = tonumber(lock_opts.max_step, 10) or defaults.max_step,
- }
- self.lock = lock:new(store, opts)
- end
-
- return setmetatable(self, storage)
-end
-
-function storage:open(id, keep_lock)
- if self.uselocking then
- local ok, err = self.lock:lock(concat{ id, ".lock" })
- if not ok then
- return nil, err
- end
- end
-
- local data, err = self.store:get(id)
-
- if self.uselocking and (err or not data or not keep_lock) then
- self.lock:unlock()
- end
-
- return data, err
-end
-
-function storage:start(id)
- if self.uselocking then
- return self.lock:lock(concat{ id, ".lock" })
- end
-
- return true
-end
-
-function storage:save(id, ttl, data, close)
- local ok, err = self.store:set(id, data, ttl)
- if close and self.uselocking then
- self.lock:unlock()
- end
-
- return ok, err
-end
-
-function storage:close()
- if self.uselocking then
- self.lock:unlock()
- end
-
- return true
-end
-
-function storage:destroy(id)
- self.store:delete(id)
-
- if self.uselocking then
- self.lock:unlock()
- end
-
- return true
-end
-
-function storage:ttl(id, lifetime, close)
- local ok, err = self.store:expire(id, lifetime)
-
- if close and self.uselocking then
- self.lock:unlock()
- end
-
- return ok, err
-end
-
-return storage
diff --git a/server/resty/session/strategies/default.lua b/server/resty/session/strategies/default.lua
deleted file mode 100644
index a43ef5a..0000000
--- a/server/resty/session/strategies/default.lua
+++ /dev/null
@@ -1,232 +0,0 @@
-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
deleted file mode 100644
index f2a97dd..0000000
--- a/server/resty/session/strategies/regenerate.lua
+++ /dev/null
@@ -1,43 +0,0 @@
-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