mirror of
https://github.com/navidrome/navidrome.git
synced 2026-11-04 09:18:39 +01:00
- Fold Allowed into Expand and drop the ErrInsufficientScope sentinel; the gate's scopeError is now the only source of insufficient_scope. - Replace the two-value authKind with a public flag, inline loadUser, and pass the grant to touch. - Read a declared request body once before validation, so the JSON checks and the handler no longer depend on kin-openapi restoring the exact bytes. - Merge the Service tests into one file and drop specs that only covered the removed liveness cache. The revoked-during-password-change spec now revokes after the gate authenticates, so it reaches ChangePassword again. Signed-off-by: Deluan <deluan@navidrome.org>
63 lines
1.5 KiB
Go
63 lines
1.5 KiB
Go
package apiauth
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
)
|
|
|
|
const (
|
|
ScopeAll = "all"
|
|
ScopeRead = "read"
|
|
ScopePassword = "password"
|
|
ScopeAdmin = "admin"
|
|
)
|
|
|
|
// KnownScopes lists the scopes of modules this server implements; `all` expands to these.
|
|
var KnownScopes = []string{ScopeRead, ScopePassword}
|
|
|
|
func known(s string) bool {
|
|
return slices.Contains(KnownScopes, s)
|
|
}
|
|
|
|
func grantable(s string, isAdmin bool) bool {
|
|
return known(s) && (s != ScopeAdmin || isAdmin)
|
|
}
|
|
|
|
func normalize(in []string) []string {
|
|
out := slices.Clone(in)
|
|
slices.Sort(out)
|
|
return slices.Compact(out)
|
|
}
|
|
|
|
// Entitled returns the scopes a new grant stores.
|
|
func Entitled(requested []string, isAdmin bool) []string {
|
|
if requested == nil {
|
|
return []string{ScopeAll}
|
|
}
|
|
var out []string
|
|
for _, s := range requested {
|
|
if s == ScopeAll || grantable(s, isAdmin) {
|
|
out = append(out, s)
|
|
}
|
|
}
|
|
return normalize(out)
|
|
}
|
|
|
|
// Expand turns a grant's stored scopes into the concrete scopes it carries right now.
|
|
func Expand(granted []string, isAdmin bool) []string {
|
|
var out []string
|
|
for _, s := range granted {
|
|
if s == ScopeAll {
|
|
out = append(out, KnownScopes...)
|
|
continue
|
|
}
|
|
out = append(out, s)
|
|
}
|
|
out = slices.DeleteFunc(out, func(s string) bool { return !grantable(s, isAdmin) })
|
|
return normalize(out)
|
|
}
|
|
|
|
func Satisfies(scopes []string, required string) bool {
|
|
return slices.Contains(scopes, required) ||
|
|
(!strings.HasSuffix(required, ":write") && slices.Contains(scopes, required+":write"))
|
|
}
|