1package auth
2
3import (
4	"sync"
5)
6
7type Authenticator interface {
8	Verify(user string, pass string) bool
9	Users() []string
10}
11
12type AuthUser struct {
13	User string
14	Pass string
15}
16
17type inMemoryAuthenticator struct {
18	storage   *sync.Map
19	usernames []string
20}
21
22func (au *inMemoryAuthenticator) Verify(user string, pass string) bool {
23	realPass, ok := au.storage.Load(user)
24	return ok && realPass == pass
25}
26
27func (au *inMemoryAuthenticator) Users() []string { return au.usernames }
28
29func NewAuthenticator(users []AuthUser) Authenticator {
30	if len(users) == 0 {
31		return nil
32	}
33
34	au := &inMemoryAuthenticator{storage: &sync.Map{}}
35	for _, user := range users {
36		au.storage.Store(user.User, user.Pass)
37	}
38	usernames := make([]string, 0, len(users))
39	au.storage.Range(func(key, value interface{}) bool {
40		usernames = append(usernames, key.(string))
41		return true
42	})
43	au.usernames = usernames
44
45	return au
46}
47