feat(server): role based authentication system (#2434)

- Parse toml configuration file, see https://github.com/qdm12/gluetun-wiki/blob/main/setup/advanced/control-server.md#authentication
- Retro-compatible with existing AND documented routes, until after v3.41 release
- Log a warning if an unprotected-by-default route is accessed unprotected
- Authentication methods: none, apikey, basic
- `genkey` command to generate API keys

Co-authored-by: Joe Jose <45399349+joejose97@users.noreply.github.com>
This commit is contained in:
Quentin McGaw
2024-09-18 13:29:36 +02:00
committed by GitHub
parent 07651683f9
commit a2e76e1683
25 changed files with 920 additions and 10 deletions

View File

@@ -0,0 +1,37 @@
package auth
import (
"crypto/sha256"
"crypto/subtle"
"net/http"
)
type basicAuthMethod struct {
authDigest [32]byte
}
func newBasicAuthMethod(username, password string) *basicAuthMethod {
return &basicAuthMethod{
authDigest: sha256.Sum256([]byte(username + password)),
}
}
// equal returns true if another auth checker is equal.
// This is used to deduplicate checkers for a particular route.
func (a *basicAuthMethod) equal(other authorizationChecker) bool {
otherBasicMethod, ok := other.(*basicAuthMethod)
if !ok {
return false
}
return a.authDigest == otherBasicMethod.authDigest
}
func (a *basicAuthMethod) isAuthorized(headers http.Header, request *http.Request) bool {
username, password, ok := request.BasicAuth()
if !ok {
headers.Set("WWW-Authenticate", `Basic realm="restricted", charset="UTF-8"`)
return false
}
requestAuthDigest := sha256.Sum256([]byte(username + password))
return subtle.ConstantTimeCompare(a.authDigest[:], requestAuthDigest[:]) == 1
}