refactor: clean repository structure for v0.1.0 open source release
- Remove Go artifacts (cmd/, internal/, pkg/, go.mod) - Move furt-lua/* content to repository root - Restructure as clean src/, config/, scripts/, tests/ layout - Rewrite README.md as practical tool documentation - Remove timeline references and marketing language - Clean .gitignore from Go-era artifacts - Update config/server.lua with example.org defaults - Add .env.production to .gitignore for security Repository now ready for open source distribution with minimal, focused structure and generic configuration templates. close issue DAW/furt#86
This commit is contained in:
parent
87c935379b
commit
be3b9614d0
38 changed files with 280 additions and 5892 deletions
|
|
@ -1,117 +0,0 @@
|
|||
-- furt-lua/src/ip_utils.lua
|
||||
-- IP address and CIDR utilities
|
||||
-- Dragons@Work Digital Sovereignty Project
|
||||
|
||||
local IpUtils = {}
|
||||
|
||||
-- Simple bitwise AND for Lua 5.1 compatibility
|
||||
local function bitwise_and(a, b)
|
||||
local result = 0
|
||||
local bit = 1
|
||||
while a > 0 or b > 0 do
|
||||
if (a % 2 == 1) and (b % 2 == 1) then
|
||||
result = result + bit
|
||||
end
|
||||
a = math.floor(a / 2)
|
||||
b = math.floor(b / 2)
|
||||
bit = bit * 2
|
||||
end
|
||||
return result
|
||||
end
|
||||
|
||||
-- Create subnet mask for given CIDR bits
|
||||
local function create_mask(mask_bits)
|
||||
if mask_bits >= 32 then
|
||||
return 0xFFFFFFFF
|
||||
elseif mask_bits <= 0 then
|
||||
return 0
|
||||
else
|
||||
-- Create mask: 32-bit with 'mask_bits' ones from left
|
||||
local mask = 0
|
||||
for i = 0, mask_bits - 1 do
|
||||
mask = mask + math.pow(2, 31 - i)
|
||||
end
|
||||
return mask
|
||||
end
|
||||
end
|
||||
|
||||
-- CIDR IP matching function (Lua 5.1 compatible)
|
||||
function IpUtils.ip_matches_cidr(ip, cidr)
|
||||
if not cidr:find("/") then
|
||||
-- No subnet mask, direct comparison
|
||||
return ip == cidr
|
||||
end
|
||||
|
||||
local network, mask_bits = cidr:match("([^/]+)/(%d+)")
|
||||
if not network or not mask_bits then
|
||||
return false
|
||||
end
|
||||
|
||||
mask_bits = tonumber(mask_bits)
|
||||
|
||||
-- Simple IPv4 CIDR matching
|
||||
if ip:find("%.") and network:find("%.") then
|
||||
-- Convert IPv4 to number
|
||||
local function ip_to_num(ip_str)
|
||||
local parts = {}
|
||||
for part in ip_str:gmatch("(%d+)") do
|
||||
table.insert(parts, tonumber(part))
|
||||
end
|
||||
if #parts == 4 then
|
||||
return (parts[1] * 16777216) + (parts[2] * 65536) + (parts[3] * 256) + parts[4]
|
||||
end
|
||||
return 0
|
||||
end
|
||||
|
||||
local ip_num = ip_to_num(ip)
|
||||
local network_num = ip_to_num(network)
|
||||
|
||||
-- Create subnet mask
|
||||
local mask = create_mask(mask_bits)
|
||||
|
||||
-- Apply mask to both IPs and compare
|
||||
return bitwise_and(ip_num, mask) == bitwise_and(network_num, mask)
|
||||
end
|
||||
|
||||
-- Fallback: if CIDR parsing fails, allow if IP matches network part
|
||||
return ip == network or ip:find("^" .. network:gsub("%.", "%%."))
|
||||
end
|
||||
|
||||
-- Check if IP is in allowed list
|
||||
function IpUtils.is_ip_allowed(client_ip, allowed_ips)
|
||||
if not allowed_ips or #allowed_ips == 0 then
|
||||
return true -- No restrictions
|
||||
end
|
||||
|
||||
for _, allowed_cidr in ipairs(allowed_ips) do
|
||||
if IpUtils.ip_matches_cidr(client_ip, allowed_cidr) then
|
||||
return true
|
||||
end
|
||||
end
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
-- Extract client IP (considering proxies)
|
||||
function IpUtils.get_client_ip(request)
|
||||
-- Check for forwarded IP headers first
|
||||
local forwarded_for = request.headers["x-forwarded-for"]
|
||||
if forwarded_for then
|
||||
-- Take first IP from comma-separated list
|
||||
local first_ip = forwarded_for:match("([^,]+)")
|
||||
if first_ip then
|
||||
return first_ip:match("^%s*(.-)%s*$") -- trim whitespace
|
||||
end
|
||||
end
|
||||
|
||||
local real_ip = request.headers["x-real-ip"]
|
||||
if real_ip then
|
||||
return real_ip
|
||||
end
|
||||
|
||||
-- Fallback to connection IP (would need socket info, defaulting to localhost for now)
|
||||
return "127.0.0.1"
|
||||
end
|
||||
|
||||
return IpUtils
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue