aboutsummaryrefslogtreecommitdiff
path: root/plugin_auth.go
blob: ec581897337ddf9d5646cc9678784438190807e3 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
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)
	})
}