mirror of
https://github.com/Noooste/garage-ui.git
synced 2026-07-26 07:48:13 +00:00
0d804fbd39
* feat(access-control): fine grain tokens * fix(docs): clean wording * test(access-control): add tests for team extraction from access tokens and bucket info permissions * test(vocabulary): add test for ExpandGlob function to reject non-glob patterns * feat(helm): add multi-user access control documentation and schema support
56 lines
1.6 KiB
Go
56 lines
1.6 KiB
Go
package authz
|
|
|
|
import (
|
|
"Noooste/garage-ui/internal/auth"
|
|
)
|
|
|
|
// TeamResolver maps an authenticated identity to an authorization Subject.
|
|
// It is an interface so non-OIDC identity sources (deferred in v1) can plug
|
|
// in later without touching middleware or handlers.
|
|
type TeamResolver interface {
|
|
Resolve(userInfo *auth.UserInfo) Subject
|
|
}
|
|
|
|
type configTeamResolver struct {
|
|
policy *Policy
|
|
adminRoles []string
|
|
}
|
|
|
|
// NewTeamResolver builds the v1 resolver: OIDC identities resolve through the
|
|
// compiled policy; admin/token logins resolve to the synthetic admin subject
|
|
// (non-OIDC team mapping is deferred).
|
|
func NewTeamResolver(policy *Policy, adminRoles []string) TeamResolver {
|
|
return &configTeamResolver{policy: policy, adminRoles: adminRoles}
|
|
}
|
|
|
|
func (r *configTeamResolver) Resolve(userInfo *auth.UserInfo) Subject {
|
|
id := userInfo.Email
|
|
if id == "" {
|
|
id = userInfo.Username
|
|
}
|
|
|
|
// Trust only signed claims, never the transport channel: the auth method
|
|
// is a JWT claim stamped at login. Legacy sessions ("") resolve like OIDC
|
|
// so a replayed cookie can never escalate.
|
|
if userInfo.AuthMethod == "admin" || userInfo.AuthMethod == "token" {
|
|
return AdminSubject(id)
|
|
}
|
|
|
|
for _, role := range userInfo.Roles {
|
|
for _, adminRole := range r.adminRoles {
|
|
if role == adminRole {
|
|
return AdminSubject(id)
|
|
}
|
|
}
|
|
}
|
|
|
|
subj := Subject{ID: id, ClusterPerms: PermSet{}}
|
|
for _, team := range r.policy.TeamsForClaims(userInfo.Teams) {
|
|
subj.Bindings = append(subj.Bindings, team.Bindings...)
|
|
for perm := range team.ClusterPerms {
|
|
subj.ClusterPerms[perm] = struct{}{}
|
|
}
|
|
}
|
|
return subj
|
|
}
|