Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(plugins): add jellyfin plugin #72

Merged
merged 1 commit into from
May 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion assets/nginx.include/http.shm.conf
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ lua_shared_dict approvals 1m;
lua_shared_dict doorbell 8m;
lua_shared_dict locks 1m;
lua_shared_dict metrics 16m;
lua_shared_dict mlcache_main 8m;
lua_shared_dict mlcache_ipc 1m;
lua_shared_dict mlcache_locks 1m;
lua_shared_dict mlcache_main 8m;
lua_shared_dict mlcache_miss 1m;
lua_shared_dict nginx 1m;
lua_shared_dict pending 1m;
lua_shared_dict plugins 4m;
lua_shared_dict rules 32m;
lua_shared_dict stats 8m;
4 changes: 4 additions & 0 deletions doorbell-dev-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,10 @@ build = {
["doorbell.notify.strategies.pushover"] = "lib/doorbell/notify/strategies/pushover.lua",

["doorbell.ota"] = "lib/doorbell/ota.lua",

["doorbell.plugins"] = "lib/doorbell/plugins.lua",
["doorbell.plugins.jellyfin"] = "lib/doorbell/plugins/jellyfin.lua",

["doorbell.request"] = "lib/doorbell/request.lua",

["doorbell.auth"] = "lib/doorbell/auth.lua",
Expand Down
2 changes: 2 additions & 0 deletions lib/doorbell.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ local ota = require "doorbell.ota"
local env = require "doorbell.env"
local middleware = require "doorbell.middleware"
local nginx = require "doorbell.nginx"
local plugins = require "doorbell.plugins"

local ngx = ngx
local var = ngx.var
Expand Down Expand Up @@ -69,6 +70,7 @@ local submodules = {
request,
ota,
routes,
plugins,
}

function _M.init()
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/api/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local routes = {}

local access = require "doorbell.auth.access"
local config = require "doorbell.config"
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("api.access")
local mw = require "doorbell.middleware"
local request = require "doorbell.request"
local schema = require "doorbell.schema"
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/api/rules.lua
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ local routes = {}
local api = require "doorbell.api"
local const = require "doorbell.constants"
local http = require "doorbell.http"
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("api.rules")
local mw = require "doorbell.middleware"
local request = require "doorbell.request"
local rules = require "doorbell.rules.api"
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/auth.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
local _M = {}

local metrics = require "doorbell.metrics"
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("auth")
local http = require "doorbell.http"
local access = require "doorbell.auth.access"
local openid = require "doorbell.auth.openid"
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/auth/access.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
local _M = {}

local const = require "doorbell.constants"
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("auth.access")
local rules = require "doorbell.rules.manager"
local notify = require "doorbell.notify"
local util = require "doorbell.util"
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/auth/openid.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
local _M = {}

local http = require "doorbell.http"
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("openid")
local request = require "doorbell.request"
local cache = require "doorbell.cache.shared"
local util = require "doorbell.util"
Expand Down
46 changes: 44 additions & 2 deletions lib/doorbell/auth/ring.lua
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("ring")
local const = require "doorbell.constants"
local access = require "doorbell.auth.access"
local forward = require "doorbell.auth.forwarded-request"
Expand Down Expand Up @@ -31,7 +31,6 @@ local ENDPOINTS = const.endpoints
---@type doorbell.unauthorized
local UNAUTHORIZED


local sleep = ngx.sleep
local fmt = string.format

Expand Down Expand Up @@ -184,6 +183,46 @@ local HANDLERS = {
end,
}

local run_hooks
do
local hooks = {}
local hooks_by_name = {}
local n_hooks = #hooks

---@param name string
---@param hook fun(doorbell.forwarded_request, doorbell.ctx, doorbell.auth.access.state) doorbell.auth.access.state?
function _M.add_hook(name, hook)
if hooks_by_name[name] then
error("hook " .. name .. " already exists")
end

log.notice("added hook: ", name)
table.insert(hooks, hook)
hooks_by_name[name] = true
n_hooks = #hooks
end

---@param req doorbell.forwarded_request
---@param ctx doorbell.ctx
---@param state doorbell.auth.access.state
---@return doorbell.auth.access.state?
function run_hooks(req, ctx, state)
local res
for i = 1, n_hooks do
res = hooks[i](req, ctx, state)
if res == STATES.deny then
return STATES.deny

elseif res then
state = res
end
end

return state
end
end


function _M.GET(ctx)
UNAUTHORIZED = UNAUTHORIZED or config.unauthorized

Expand Down Expand Up @@ -213,6 +252,9 @@ function _M.GET(ctx)
if err then
log.err("error checking auth state: ", err)
state = STATES.error

else
state = run_hooks(req, ctx, state) or state
end

return HANDLERS[state](req, ctx, token)
Expand Down
6 changes: 3 additions & 3 deletions lib/doorbell/cache.lua
Original file line number Diff line number Diff line change
Expand Up @@ -41,14 +41,14 @@ function cache:raw_get(key)
local value, stale = self.lru:get(key)

if value ~= nil then
debugf("[%s] cache HIT for %s => %q", self.name, key, tostring(value))
debugf("[cache.%s] cache HIT for %s => %q", self.name, key, tostring(value))
self.hit = self.hit + 1
else
if stale == nil then
debugf("[%s] cache MISS for %s", self.name, key)
debugf("[cache.%s] cache MISS for %s", self.name, key)
self.miss = self.miss + 1
else
debugf("[%s] cache EXPIRE for %s", self.name, key)
debugf("[cache.%s] cache EXPIRE for %s", self.name, key)
self.expire = self.expire + 1
end
end
Expand Down
2 changes: 1 addition & 1 deletion lib/doorbell/cache/shared.lua
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ do

cache, err = mlcache.new("db", const.shm.mlcache_main, {
ipc = nil,
ipc_shm = nil,
ipc_shm = const.shm.mlcache_ipc,
l1_serializer = nil,
lru = nil,
lru_size = 1000,
Expand Down
1 change: 1 addition & 0 deletions lib/doorbell/config.lua
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
---@field trusted string[]
---@field unauthorized doorbell.unauthorized
---@field utc_offset integer
---@field plugins table<string, any>
local _M = {}

local util = require "doorbell.util"
Expand Down
9 changes: 7 additions & 2 deletions lib/doorbell/constants.lua
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ const.actions = {
deny = "deny",
}

---@alias doorbell.source "config"|"user"|"ota"|"api"
---@alias doorbell.source "config"|"user"|"ota"|"api"|"plugin"


--- lookup table of valid doorbell rule sources
Expand All @@ -19,6 +19,7 @@ const.sources = {
user = "user",
ota = "ota",
api = "api",
plugin = "plugin",
}

---@alias doorbell.deny_action "exit"|"tarpit"
Expand Down Expand Up @@ -111,9 +112,13 @@ const.shm = {
pending = "pending",

-- doorbell.cache.shared / lua-resty-mlcache
mlcache_ipc = "mlcache_ipc",
mlcache_locks = "mlcache_locks",
mlcache_main = "mlcache_main",
mlcache_miss = "mlcache_miss",
mlcache_locks = "mlcache_locks",

-- shared plugin storage
plugins = "plugins",
}

---@enum doorbell.unauthorized
Expand Down
19 changes: 17 additions & 2 deletions lib/doorbell/http.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local _M = {}

local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("util.http")

local cjson = require "cjson"
local safe_decode = require("cjson.safe").decode
Expand Down Expand Up @@ -346,6 +346,9 @@ do
return false
end

---@param a doorbell.http.accept.entry
---@param b doorbell.http.accept.entry
---@return boolean
local function weight_sort(a, b)
if a[2] ~= b[2] then
return a[2] > b[2]
Expand All @@ -354,10 +357,22 @@ do
end
end

--- mime type
---@alias doorbell.http.accept.mime_type string

--- client-specified weight of the mime-type (e.g. q=1.0)
---@alias doorbell.http.accept.weight number

--- position of the mime type in the Accept header
---@alias doorbell.http.accept.position integer

---@alias doorbell.http.accept.entry [doorbell.http.accept.mime_type, doorbell.http.accept.weight, doorbell.http.accept.position]

---@type doorbell.http.accept.entry[]|string[]
local buf = {}

---@param accept string
---@param available string[]
---@param available doorbell.http.accept.mime_type[]
---@return string?
local function negotiate(accept, available)
split(accept, ", *", "jo", nil, nil, buf)
Expand Down
17 changes: 15 additions & 2 deletions lib/doorbell/ip.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local _M = {}

local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("ip")
local util = require "doorbell.util"

---@class doorbell.cache
Expand All @@ -12,7 +12,20 @@ local cache_basic
---@class doorbell.cache
local cache_geo

local ipmatcher = require "resty.ipmatcher"
---@class resty.ipmatcher
local ipmatcher
do
-- resty.ipmatcher logs a bunch of things at INFO level.
--
--- hack it to DEBUG to preserve our sanity

local ngx_info = ngx.INFO
ngx.INFO = ngx.DEBUG -- luacheck: ignore
package.loaded["resty.ipmatcher"] = nil
ipmatcher = require "resty.ipmatcher"
ngx.INFO = ngx_info -- luacheck: ignore
end

local split = require("ngx.re").split

local assert = assert
Expand Down
64 changes: 56 additions & 8 deletions lib/doorbell/log.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ if ngx.config.is_console then
end
end

local function noop() end
local function NOOP() end

local log_varargs
do
Expand Down Expand Up @@ -128,13 +128,6 @@ end
---@field emergf doorbell.log.fnf
local log = {}

setmetatable(log, {
__index = function(self, k)
rawset(self, k, noop)
return noop
end,
})

do
for name, lvl in pairs(levels_by_name) do
if get_level() >= lvl then
Expand All @@ -143,6 +136,11 @@ do

-- add a vararg index by numeric log level
rawset(log, lvl, make_log(lvl, log_varargs))

else
rawset(log, name, NOOP)
rawset(log, name .. "f", NOOP)
rawset(log, lvl, NOOP)
end
end
end
Expand Down Expand Up @@ -174,4 +172,54 @@ end
log.LEVEL = LEVEL
log.IS_DEBUG = IS_DEBUG

---@param ns string
---@return doorbell.log
function log.with_namespace(ns)
assert(type(ns) == "string" and #ns > 0)

local namespaced = {}

ns = "[" .. ns .. "] "

for k, v in pairs(log) do
namespaced[k] = v

if type(v) == "function" and v ~= NOOP then
if k == "debugf"
or k == "infof"
or k == "noticef"
or k == "warnf"
or k == "errf"
or k == "alertf"
or k == "critf"
or k == "emergf"
or k == "stdoutf"
or k == "stderrf"
then
namespaced[k] = function(f, ...)
f = "%s" .. f
return v(f, ns, ...)
end

elseif k == "debug"
or k == "info"
or k == "notice"
or k == "warn"
or k == "err"
or k == "alert"
or k == "crit"
or k == "emerg"
or k == "stdout"
or k == "stderr"
then
namespaced[k] = function(...)
return v(ns, ...)
end
end
end
end

return namespaced
end

return log
2 changes: 1 addition & 1 deletion lib/doorbell/log/request.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
local _M = {}

local log = require "doorbell.log"
local log = require("doorbell.log").with_namespace("logger")
local util = require "doorbell.util"
local timer = require "doorbell.util.timer"

Expand Down
Loading
Loading