Skip to content

Commit

Permalink
feat(plugins): add jellyfin plugin (#72)
Browse files Browse the repository at this point in the history
  • Loading branch information
flrgh committed May 15, 2024
1 parent 301a8a4 commit eaa54ec
Show file tree
Hide file tree
Showing 39 changed files with 1,263 additions and 82 deletions.
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

0 comments on commit eaa54ec

Please sign in to comment.