mirror of
https://github.com/caiwx86/small-packages.git
synced 2026-11-02 07:03:56 +08:00
update 2026-10-07 11:52:44
This commit is contained in:
1 parent
d6cc6efa77
commit
617f7ca2a6
4898 files changed
-1713675
No files matched your search
@@ -1,177 +0,0 @@
|
||||
local source_root = assert(os.getenv("LINKEASE_AUTH_SOURCE_ROOT"), "LINKEASE_AUTH_SOURCE_ROOT is required")
|
||||
package.path = source_root .. "/?.lua;" .. package.path
|
||||
|
||||
local function equal(actual, expected, message)
|
||||
if actual ~= expected then
|
||||
error((message or "values differ") .. ": got " .. tostring(actual) .. ", want " .. tostring(expected), 2)
|
||||
end
|
||||
end
|
||||
|
||||
local function has_header(headers, pattern)
|
||||
for _, header in ipairs(headers) do
|
||||
if header[1] == "Set-Cookie" and header[2]:match(pattern) then return true end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function scenario(options)
|
||||
options = options or {}
|
||||
local headers = {}
|
||||
local result = {}
|
||||
local cookies = options.cookies or {}
|
||||
local environment = options.environment or { HTTP_HOST = "192.168.30.7:10000" }
|
||||
local forms = options.forms or {}
|
||||
|
||||
package.loaded["luci.model.linkease.auth"] = nil
|
||||
local auth = require "luci.model.linkease.auth"
|
||||
local bridge = auth.new({
|
||||
http = {
|
||||
getcookie = function(name) return cookies[name] end,
|
||||
getenv = function(name) return environment[name] end,
|
||||
formvalue = function(name) return forms[name] end,
|
||||
header = function(name, value) headers[#headers + 1] = { name, value } end,
|
||||
redirect = function(value) result.redirect = value end,
|
||||
status = function(code, message) result.status = code; result.message = message end
|
||||
},
|
||||
ubus = function(object, method, request)
|
||||
if object == "session" and method == "get" and request.ubus_rpc_session == options.valid_sid then
|
||||
return { values = { username = "root" } }
|
||||
end
|
||||
return nil
|
||||
end,
|
||||
lan_ip = function() return "192.168.30.7" end,
|
||||
build_url = function(...)
|
||||
local arguments = {...}
|
||||
local url = "/cgi-bin/luci/admin/services/linkease_auth/auth_finish"
|
||||
if arguments[5] then url = url .. "/" .. arguments[5] end
|
||||
return url
|
||||
end
|
||||
})
|
||||
return bridge, result, headers
|
||||
end
|
||||
|
||||
local bridge, result, headers = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "/apps/dockermanager/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/dockermanager/")
|
||||
equal(has_header(headers, "linkease_openwrt_sid=valid%-session"), true)
|
||||
equal(has_header(headers, "linkease_openwrt_sid=.*Path=/apps"), true)
|
||||
|
||||
bridge, result, headers = scenario({ forms = { ["return"] = "/apps/kaiplus/" } })
|
||||
bridge:auth()
|
||||
local state = result.redirect:match("/auth_finish/([A-Za-z0-9_-]+)$")
|
||||
equal(type(state), "string", "auth begin must encode return intent into the protected path")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session"
|
||||
})
|
||||
bridge:auth_finish(state)
|
||||
equal(result.redirect, "/apps/kaiplus/")
|
||||
|
||||
local first_bridge, first_result = scenario({
|
||||
forms = { ["return"] = "/apps/dockermanager/containers/abc?tab=logs&follow=1" }
|
||||
})
|
||||
first_bridge:auth()
|
||||
local first_state = first_result.redirect:match("/auth_finish/([A-Za-z0-9_-]+)$")
|
||||
equal(type(first_state), "string", "deep link state must be encoded")
|
||||
|
||||
local second_bridge, second_result = scenario({
|
||||
forms = { ["return"] = "/apps/kaiplus/?conversation=second" }
|
||||
})
|
||||
second_bridge:auth()
|
||||
local second_state = second_result.redirect:match("/auth_finish/([A-Za-z0-9_-]+)$")
|
||||
equal(type(second_state), "string", "second tab state must be encoded")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session", linkease_openwrt_pending_return = "%2Fapps%2Fwrong%2F" },
|
||||
valid_sid = "valid-session"
|
||||
})
|
||||
bridge:auth_finish(first_state)
|
||||
equal(result.redirect, "/apps/dockermanager/containers/abc?tab=logs&follow=1", "first tab must use its own path state")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session", linkease_openwrt_pending_return = "%2Fapps%2Fwrong%2F" },
|
||||
valid_sid = "valid-session"
|
||||
})
|
||||
bridge:auth_finish(second_state)
|
||||
equal(result.redirect, "/apps/kaiplus/?conversation=second", "second tab must use its own path state")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session"
|
||||
})
|
||||
bridge:auth_finish("not_base64url_@@")
|
||||
equal(result.redirect, "/apps/", "malformed state must fail closed")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session"
|
||||
})
|
||||
bridge:auth_finish(string.rep("A", 4097))
|
||||
equal(result.redirect, "/apps/", "oversized state must fail closed")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "http://192.168.30.7:8192/apps/dockermanager/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "http://192.168.30.7:8192/apps/dockermanager/")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "http://192.168.30.7:3200/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "http://192.168.30.7:3200/", "same-device external app port must be allowed")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "http://192.168.30.7:10000/cgi-bin/luci/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/", "same-authority non-app path must remain rejected")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "http://evil.example/apps/dockermanager/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "/apps/dockermanager/%0d%0aLocation:%20http://evil.example/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/dockermanager/%0d%0aLocation:%20http://evil.example/")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "/apps/dockermanager/\r\nLocation: http://evil.example/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/", "raw control characters must be rejected")
|
||||
|
||||
bridge, result = scenario({
|
||||
cookies = { sysauth = "valid-session" },
|
||||
valid_sid = "valid-session",
|
||||
forms = { ["return"] = "http://192.168.30.7:8192@evil.example/apps/dockermanager/" }
|
||||
})
|
||||
bridge:auth()
|
||||
equal(result.redirect, "/apps/")
|
||||
|
||||
bridge, result = scenario()
|
||||
bridge:auth_finish()
|
||||
equal(result.status, 403)
|
||||
|
||||
print("linkease auth bridge tests passed")
|
||||
Reference in new issue
Block a user