From 976c5167e5350f80544ff55f202455170249ab8b Mon Sep 17 00:00:00 2001
From: Garet Halliday <me@garet.holiday>
Date: Thu, 28 Sep 2023 17:33:56 -0500
Subject: [PATCH] rewrites and allowed startup parameters

---
 .../allowed_startup_parameters/module.go      | 47 ++++++++++++++++
 lib/gat/handlers/rewrite_database/module.go   | 34 ++++++++++++
 lib/gat/handlers/rewrite_parameters/module.go | 54 +++++++++++++++++++
 lib/gat/handlers/rewrite_password/module.go   | 37 +++++++++++++
 lib/gat/handlers/rewrite_user/module.go       | 34 ++++++++++++
 lib/gat/standard/standard.go                  |  7 +++
 6 files changed, 213 insertions(+)
 create mode 100644 lib/gat/handlers/allowed_startup_parameters/module.go
 create mode 100644 lib/gat/handlers/rewrite_database/module.go
 create mode 100644 lib/gat/handlers/rewrite_parameters/module.go
 create mode 100644 lib/gat/handlers/rewrite_password/module.go
 create mode 100644 lib/gat/handlers/rewrite_user/module.go

diff --git a/lib/gat/handlers/allowed_startup_parameters/module.go b/lib/gat/handlers/allowed_startup_parameters/module.go
new file mode 100644
index 00000000..5eeadc4e
--- /dev/null
+++ b/lib/gat/handlers/allowed_startup_parameters/module.go
@@ -0,0 +1,47 @@
+package module
+
+import (
+	"fmt"
+
+	"github.com/caddyserver/caddy/v2"
+
+	"gfx.cafe/gfx/pggat/lib/fed"
+	"gfx.cafe/gfx/pggat/lib/gat"
+	"gfx.cafe/gfx/pggat/lib/perror"
+	"gfx.cafe/gfx/pggat/lib/util/slices"
+	"gfx.cafe/gfx/pggat/lib/util/strutil"
+)
+
+func init() {
+	caddy.RegisterModule((*Module)(nil))
+}
+
+type Module struct {
+	Parameters []strutil.CIString `json:"parameters"`
+}
+
+func (T *Module) CaddyModule() caddy.ModuleInfo {
+	return caddy.ModuleInfo{
+		ID: "pggat.handlers.allowed_startup_parameters",
+		New: func() caddy.Module {
+			return new(Module)
+		},
+	}
+}
+
+func (T *Module) Handle(conn *fed.Conn) error {
+	for parameter := range conn.InitialParameters {
+		if !slices.Contains(T.Parameters, parameter) {
+			return perror.New(
+				perror.FATAL,
+				perror.FeatureNotSupported,
+				fmt.Sprintf(`Startup parameter "%s" is not supported`, parameter.String()),
+			)
+		}
+	}
+
+	return nil
+}
+
+var _ gat.Handler = (*Module)(nil)
+var _ caddy.Module = (*Module)(nil)
diff --git a/lib/gat/handlers/rewrite_database/module.go b/lib/gat/handlers/rewrite_database/module.go
new file mode 100644
index 00000000..bd471975
--- /dev/null
+++ b/lib/gat/handlers/rewrite_database/module.go
@@ -0,0 +1,34 @@
+package rewrite_database
+
+import (
+	"github.com/caddyserver/caddy/v2"
+
+	"gfx.cafe/gfx/pggat/lib/fed"
+	"gfx.cafe/gfx/pggat/lib/gat"
+)
+
+func init() {
+	caddy.RegisterModule((*Module)(nil))
+}
+
+type Module struct {
+	Database string `json:"database"`
+}
+
+func (T *Module) CaddyModule() caddy.ModuleInfo {
+	return caddy.ModuleInfo{
+		ID: "pggat.handlers.rewrite_database",
+		New: func() caddy.Module {
+			return new(Module)
+		},
+	}
+}
+
+func (T *Module) Handle(conn *fed.Conn) error {
+	conn.Database = T.Database
+
+	return nil
+}
+
+var _ gat.Handler = (*Module)(nil)
+var _ caddy.Module = (*Module)(nil)
diff --git a/lib/gat/handlers/rewrite_parameters/module.go b/lib/gat/handlers/rewrite_parameters/module.go
new file mode 100644
index 00000000..44a98817
--- /dev/null
+++ b/lib/gat/handlers/rewrite_parameters/module.go
@@ -0,0 +1,54 @@
+package rewrite_parameters
+
+import (
+	"github.com/caddyserver/caddy/v2"
+
+	"gfx.cafe/gfx/pggat/lib/fed"
+	"gfx.cafe/gfx/pggat/lib/gat"
+	"gfx.cafe/gfx/pggat/lib/util/strutil"
+)
+
+func init() {
+	caddy.RegisterModule((*Module)(nil))
+}
+
+type Module struct {
+	Parameters map[string]string `json:"parameters"`
+
+	parameters map[strutil.CIString]string
+}
+
+func (T *Module) CaddyModule() caddy.ModuleInfo {
+	return caddy.ModuleInfo{
+		ID: "pggat.handlers.rewrite_parameters",
+		New: func() caddy.Module {
+			return new(Module)
+		},
+	}
+}
+
+func (T *Module) Provision(ctx caddy.Context) error {
+	T.parameters = make(map[strutil.CIString]string, len(T.Parameters))
+
+	for key, value := range T.Parameters {
+		T.parameters[strutil.MakeCIString(key)] = value
+	}
+
+	return nil
+}
+
+func (T *Module) Handle(conn *fed.Conn) error {
+	if conn.InitialParameters == nil {
+		conn.InitialParameters = make(map[strutil.CIString]string)
+	}
+
+	for key, value := range T.parameters {
+		conn.InitialParameters[key] = value
+	}
+
+	return nil
+}
+
+var _ gat.Handler = (*Module)(nil)
+var _ caddy.Module = (*Module)(nil)
+var _ caddy.Provisioner = (*Module)(nil)
diff --git a/lib/gat/handlers/rewrite_password/module.go b/lib/gat/handlers/rewrite_password/module.go
new file mode 100644
index 00000000..0cec7729
--- /dev/null
+++ b/lib/gat/handlers/rewrite_password/module.go
@@ -0,0 +1,37 @@
+package rewrite_password
+
+import (
+	"github.com/caddyserver/caddy/v2"
+
+	"gfx.cafe/gfx/pggat/lib/auth/credentials"
+	"gfx.cafe/gfx/pggat/lib/bouncer/frontends/v0"
+	"gfx.cafe/gfx/pggat/lib/fed"
+	"gfx.cafe/gfx/pggat/lib/gat"
+)
+
+func init() {
+	caddy.RegisterModule((*Module)(nil))
+}
+
+type Module struct {
+	Password string `json:"password"`
+}
+
+func (T *Module) CaddyModule() caddy.ModuleInfo {
+	return caddy.ModuleInfo{
+		ID: "pggat.handlers.rewrite_password",
+		New: func() caddy.Module {
+			return new(Module)
+		},
+	}
+}
+
+func (T *Module) Handle(conn *fed.Conn) error {
+	return frontends.Authenticate(
+		conn,
+		credentials.FromString(conn.User, T.Password),
+	)
+}
+
+var _ gat.Handler = (*Module)(nil)
+var _ caddy.Module = (*Module)(nil)
diff --git a/lib/gat/handlers/rewrite_user/module.go b/lib/gat/handlers/rewrite_user/module.go
new file mode 100644
index 00000000..a4a301cd
--- /dev/null
+++ b/lib/gat/handlers/rewrite_user/module.go
@@ -0,0 +1,34 @@
+package rewrite_user
+
+import (
+	"github.com/caddyserver/caddy/v2"
+
+	"gfx.cafe/gfx/pggat/lib/fed"
+	"gfx.cafe/gfx/pggat/lib/gat"
+)
+
+func init() {
+	caddy.RegisterModule((*Module)(nil))
+}
+
+type Module struct {
+	User string `json:"user"`
+}
+
+func (T *Module) CaddyModule() caddy.ModuleInfo {
+	return caddy.ModuleInfo{
+		ID: "pggat.handlers.rewrite_user",
+		New: func() caddy.Module {
+			return new(Module)
+		},
+	}
+}
+
+func (T *Module) Handle(conn *fed.Conn) error {
+	conn.User = T.User
+
+	return nil
+}
+
+var _ gat.Handler = (*Module)(nil)
+var _ caddy.Module = (*Module)(nil)
diff --git a/lib/gat/standard/standard.go b/lib/gat/standard/standard.go
index 6deced09..bd4b6fbd 100644
--- a/lib/gat/standard/standard.go
+++ b/lib/gat/standard/standard.go
@@ -13,6 +13,13 @@ import (
 	// ssl clients
 	_ "gfx.cafe/gfx/pggat/lib/gat/ssl/clients/insecure_skip_verify"
 
+	// middlewares
+	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/allowed_startup_parameters"
+	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/rewrite_database"
+	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/rewrite_parameters"
+	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/rewrite_password"
+	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/rewrite_user"
+
 	// handlers
 	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/discovery"
 	_ "gfx.cafe/gfx/pggat/lib/gat/handlers/pgbouncer"
-- 
GitLab