feat(config): implement multi-tenant config system (DAW/furt#89)
- nginx-style furt.conf configuration - Multi-tenant mail routing per API key - Custom SMTP support per customer - Backward compatibility via server.lua adapter WIP: Ready for testing on werner
This commit is contained in:
parent
be3b9614d0
commit
3ed921312f
5 changed files with 625 additions and 86 deletions
90
config/furt.conf.example
Normal file
90
config/furt.conf.example
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
# furt.conf - Multi-Tenant Configuration Example
|
||||
# Dragons@Work Digital Sovereignty Project
|
||||
|
||||
# Server configuration
|
||||
[server]
|
||||
host = 127.0.0.1
|
||||
port = 8080
|
||||
log_level = info
|
||||
|
||||
# Default SMTP settings (used when API keys don't have custom SMTP)
|
||||
[smtp_default]
|
||||
host = mail.dragons-at-work.de
|
||||
port = 465
|
||||
user = noreply@dragons-at-work.de
|
||||
password = your-smtp-password-here
|
||||
use_ssl = true
|
||||
|
||||
# Dragons@Work Website
|
||||
[api_key "daw-frontend-key"]
|
||||
name = "Dragons@Work Website"
|
||||
permissions = mail:send
|
||||
allowed_ips = 127.0.0.1, 10.0.0.0/8, 192.168.0.0/16
|
||||
mail_to = admin@dragons-at-work.de
|
||||
mail_from = noreply@dragons-at-work.de
|
||||
mail_subject_prefix = "[DAW Contact] "
|
||||
|
||||
# Biocodie Website (same SMTP, different recipient)
|
||||
[api_key "bio-frontend-key"]
|
||||
name = "Biocodie Website"
|
||||
permissions = mail:send
|
||||
allowed_ips = 127.0.0.1, 10.0.0.0/8
|
||||
mail_to = contact@biocodie.de
|
||||
mail_from = noreply@biocodie.de
|
||||
mail_subject_prefix = "[Biocodie] "
|
||||
|
||||
# Verlag Website
|
||||
[api_key "verlag-frontend-key"]
|
||||
name = "Verlag Dragons@Work"
|
||||
permissions = mail:send
|
||||
allowed_ips = 127.0.0.1, 10.0.0.0/8
|
||||
mail_to = verlag@dragons-at-work.de
|
||||
mail_from = noreply@verlag.dragons-at-work.de
|
||||
mail_subject_prefix = "[Verlag] "
|
||||
|
||||
# Customer with custom SMTP
|
||||
[api_key "kunde-x-frontend-key"]
|
||||
name = "Kunde X Website"
|
||||
permissions = mail:send
|
||||
allowed_ips = 1.2.3.4/32, 5.6.7.8/32
|
||||
mail_to = info@kunde-x.de
|
||||
mail_from = noreply@kunde-x.de
|
||||
mail_subject_prefix = "[Kunde X] "
|
||||
# Custom SMTP for this customer
|
||||
mail_smtp_host = mail.kunde-x.de
|
||||
mail_smtp_port = 587
|
||||
mail_smtp_user = noreply@kunde-x.de
|
||||
mail_smtp_pass = kunde-x-smtp-password
|
||||
mail_smtp_ssl = true
|
||||
|
||||
# Customer with external provider (e.g., Gmail)
|
||||
[api_key "kunde-y-frontend-key"]
|
||||
name = "Kunde Y Website"
|
||||
permissions = mail:send
|
||||
allowed_ips = 9.10.11.12/32
|
||||
mail_to = support@kunde-y.com
|
||||
mail_from = website@kunde-y.com
|
||||
mail_subject_prefix = "[Kunde Y Support] "
|
||||
# Gmail SMTP example
|
||||
mail_smtp_host = smtp.gmail.com
|
||||
mail_smtp_port = 587
|
||||
mail_smtp_user = website@kunde-y.com
|
||||
mail_smtp_pass = gmail-app-password
|
||||
mail_smtp_ssl = true
|
||||
|
||||
# Admin API key (full access for management)
|
||||
[api_key "admin-management-key"]
|
||||
name = "Admin Access"
|
||||
permissions = *, mail:send, auth:status
|
||||
allowed_ips = 127.0.0.1, 10.0.0.0/8
|
||||
mail_to = admin@dragons-at-work.de
|
||||
mail_from = furt-admin@dragons-at-work.de
|
||||
mail_subject_prefix = "[Furt Admin] "
|
||||
|
||||
# Monitoring key (limited access)
|
||||
[api_key "monitoring-health-key"]
|
||||
name = "Monitoring Service"
|
||||
permissions = health:check
|
||||
allowed_ips = 127.0.0.1, 10.0.0.0/8, 172.16.0.0/12
|
||||
# No mail config needed for monitoring
|
||||
|
||||
|
|
@ -1,25 +1,30 @@
|
|||
-- config/server.lua
|
||||
-- Server configuration for Furt Lua HTTP-Server
|
||||
-- Multi-Tenant server configuration using nginx-style config parser
|
||||
-- Dragons@Work Digital Sovereignty Project
|
||||
|
||||
return {
|
||||
-- HTTP Server settings
|
||||
host = "127.0.0.1",
|
||||
port = 8080,
|
||||
local ConfigParser = require("src.config_parser")
|
||||
|
||||
-- Timeouts (seconds)
|
||||
client_timeout = 10,
|
||||
-- Load configuration from furt.conf
|
||||
local config = ConfigParser.load_config()
|
||||
|
||||
-- Add legacy compatibility and runtime enhancements
|
||||
local server_config = {
|
||||
-- HTTP Server settings (from [server] section)
|
||||
host = config.server.host,
|
||||
port = config.server.port,
|
||||
|
||||
-- Timeouts and limits
|
||||
client_timeout = config.server.client_timeout or 10,
|
||||
|
||||
-- CORS Configuration
|
||||
cors = {
|
||||
-- Default allowed origins for development
|
||||
-- Override in production with CORS_ALLOWED_ORIGINS environment variable
|
||||
allowed_origins = (function()
|
||||
local env_origins = os.getenv("CORS_ALLOWED_ORIGINS")
|
||||
if env_origins then
|
||||
-- Parse comma-separated list from environment
|
||||
local origins = {}
|
||||
for origin in env_origins:gmatch("([^,]+)") do
|
||||
table.insert(origins, origin:match("^%s*(.-)%s*$")) -- trim whitespace
|
||||
table.insert(origins, origin:match("^%s*(.-)%s*$"))
|
||||
end
|
||||
return origins
|
||||
else
|
||||
|
|
@ -35,54 +40,40 @@ return {
|
|||
},
|
||||
|
||||
-- Logging
|
||||
log_level = "info",
|
||||
log_requests = true,
|
||||
log_level = config.server.log_level or "info",
|
||||
log_requests = config.server.log_requests or true,
|
||||
|
||||
-- API-Key-Authentifizierung (PRODUCTION READY)
|
||||
api_keys = {
|
||||
-- Hugo Frontend API-Key (für Website-Formulare)
|
||||
[os.getenv("HUGO_API_KEY") or "hugo-dev-key-change-in-production"] = {
|
||||
name = "Hugo Frontend",
|
||||
permissions = {"mail:send"},
|
||||
allowed_ips = {
|
||||
"127.0.0.1", -- Localhost
|
||||
"10.0.0.0/8", -- Private network
|
||||
"192.168.0.0/16", -- Private network
|
||||
"172.16.0.0/12" -- Private network
|
||||
}
|
||||
},
|
||||
-- API Keys (converted from nginx-style to old format for backward compatibility)
|
||||
api_keys = config.api_keys,
|
||||
|
||||
-- Admin API-Key (für Testing und Management)
|
||||
[os.getenv("ADMIN_API_KEY") or "admin-dev-key-change-in-production"] = {
|
||||
name = "Admin Access",
|
||||
permissions = {"*"}, -- All permissions
|
||||
allowed_ips = {
|
||||
"127.0.0.1", -- Local only for admin
|
||||
"10.0.0.0/8" -- Internal network
|
||||
}
|
||||
},
|
||||
-- Default SMTP config (for legacy compatibility)
|
||||
mail = config.smtp_default,
|
||||
|
||||
-- Optional: Monitoring API-Key (nur Health-Checks)
|
||||
[os.getenv("MONITORING_API_KEY") or "monitoring-dev-key"] = {
|
||||
name = "Monitoring Service",
|
||||
permissions = {"monitoring:health"},
|
||||
allowed_ips = {
|
||||
"127.0.0.1",
|
||||
"10.0.0.0/8",
|
||||
"172.16.0.0/12"
|
||||
}
|
||||
}
|
||||
},
|
||||
-- Multi-tenant mail configuration function
|
||||
get_mail_config_for_api_key = function(api_key)
|
||||
return ConfigParser.get_mail_config_for_api_key(config, api_key)
|
||||
end,
|
||||
|
||||
-- Mail configuration (for SMTP integration)
|
||||
mail = {
|
||||
smtp_server = os.getenv("SMTP_HOST") or "mail.example.org",
|
||||
smtp_port = tonumber(os.getenv("SMTP_PORT")) or 465,
|
||||
use_ssl = true,
|
||||
username = os.getenv("SMTP_USERNAME"),
|
||||
password = os.getenv("SMTP_PASSWORD"),
|
||||
from_address = os.getenv("SMTP_FROM") or "noreply@example.org",
|
||||
to_address = os.getenv("SMTP_TO") or "admin@example.org"
|
||||
}
|
||||
-- Raw config access (for advanced usage)
|
||||
raw_config = config
|
||||
}
|
||||
|
||||
-- Print configuration summary on load
|
||||
print("Furt Multi-Tenant Configuration Loaded:")
|
||||
print(" Server: " .. server_config.host .. ":" .. server_config.port)
|
||||
print(" Log Level: " .. server_config.log_level)
|
||||
print(" Default SMTP: " .. (config.smtp_default.host or "not configured"))
|
||||
|
||||
local api_key_count = 0
|
||||
for key_name, key_config in pairs(config.api_keys) do
|
||||
api_key_count = api_key_count + 1
|
||||
local smtp_info = ""
|
||||
if key_config.mail_smtp_host then
|
||||
smtp_info = " (custom SMTP: " .. key_config.mail_smtp_host .. ")"
|
||||
end
|
||||
print(" API Key: " .. key_config.name .. " -> " .. key_config.mail_to .. smtp_info)
|
||||
end
|
||||
print(" Total API Keys: " .. api_key_count)
|
||||
|
||||
return server_config
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue