aboutsummaryrefslogtreecommitdiff
path: root/plugin_auth.go
diff options
context:
space:
mode:
authorHimbeer <himbeer@disroot.org>2024-11-16 23:17:27 +0100
committerHimbeer <himbeer@disroot.org>2024-11-17 16:32:50 +0100
commitd0d39d2f9f3abb68eec146376b3233c8bc7c1cfa (patch)
tree70be515811406cdc3ba1ab8b56d3c6eccb2f0d59 /plugin_auth.go
parente7d92562fcf05e4f9b7f6ba29b7cda529aab49bc (diff)
Allow plugins to implement authentication backends
Design decisions: * Config option specifies which of the registered backends is used * Name conflicts (including with builtins) make the backend registration fail * Builtin backends are not moved to plugins to avoid breaking existing setups confusion in general * Builtin backends are exposed to plugins (and have been for some time); Important information and internal methods are hidden to prevent interference from malicious plugins See doc/auth_backends.md and the related interface and function documentation for details. Closes #127.
Diffstat (limited to 'plugin_auth.go')
-rw-r--r--plugin_auth.go74
1 files changed, 74 insertions, 0 deletions
diff --git a/plugin_auth.go b/plugin_auth.go
new file mode 100644
index 0000000..ec58189
--- /dev/null
+++ b/plugin_auth.go
@@ -0,0 +1,74 @@
+package proxy
+
+import (
+ "errors"
+ "fmt"
+ "sync"
+)
+
+var (
+ ErrEmptyAuthBackendName = errors.New("auth backend name is empty")
+ ErrNilAuthBackend = errors.New("auth backend is nil")
+ ErrBuiltinAuthBackend = errors.New("auth backend name collision with builtin")
+)
+
+var (
+ authBackends map[string]AuthBackend
+ authBackendsMu sync.Mutex
+ authBackendsOnce sync.Once
+)
+
+// Auth returns an authentication backend by name or false if it doesn't exist.
+func Auth(name string) (AuthBackend, bool) {
+ authBackendsMu.Lock()
+ defer authBackendsMu.Unlock()
+
+ ab, ok := authBackends[name]
+ return ab, ok
+}
+
+// RegisterAuthBackend registers a new authentication backend implementation.
+// The name must be unique, non-empty and must not collide
+// with a builtin authentication backend.
+// The authentication backend must be non-nil.
+// Registered backends can be enabled by specifying their name
+// in the AuthBackend config option.
+// Backend-specific configuration is handled by the calling plugin's
+// configuration mechanism at initialization time.
+// Backends must be registered at initialization time
+// (before the init functions return).
+// Backends registered after initialization time will not be available
+// to the user.
+func RegisterAuthBackend(name string, ab AuthBackend) error {
+ initAuthBackends()
+
+ if name == "" {
+ return ErrEmptyAuthBackendName
+ }
+ if ab == nil {
+ return ErrNilAuthBackend
+ }
+
+ if name == "files" || name == "mtsqlite3" || name == "mtpostgresql" {
+ return ErrBuiltinAuthBackend
+ }
+
+ if _, ok := authBackends[name]; ok {
+ return fmt.Errorf("duplicate auth backend %s", name)
+ }
+
+ authBackendsMu.Lock()
+ defer authBackendsMu.Unlock()
+
+ authBackends[name] = ab
+ return nil
+}
+
+func initAuthBackends() {
+ authBackendsOnce.Do(func() {
+ authBackendsMu.Lock()
+ defer authBackendsMu.Unlock()
+
+ authBackends = make(map[string]AuthBackend)
+ })
+}