some
This commit is contained in:
1 parent
1c33ef4002
commit
0db9705063
2 files changed
+37
-1
No files matched your search
@@ -36,6 +36,7 @@ var ErrNoCredentials = errors.New("auth: no credentials")
|
|||||||
type Principal struct {
|
type Principal struct {
|
||||||
Subject string `json:"subject"` // OIDC sub or API key id
|
Subject string `json:"subject"` // OIDC sub or API key id
|
||||||
Scopes []string `json:"scopes,omitempty"` // e.g. ["write","admin"]
|
Scopes []string `json:"scopes,omitempty"` // e.g. ["write","admin"]
|
||||||
|
Roles []string `json:"roles,omitempty"` // e.g. ["editor","publisher","admin"]
|
||||||
Kind string `json:"kind"` // KindOIDC | KindAPIKey | KindAnonymous
|
Kind string `json:"kind"` // KindOIDC | KindAPIKey | KindAnonymous
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,6 +45,32 @@ func (p *Principal) HasScope(scope string) bool {
|
|||||||
return slices.Contains(p.Scopes, scope)
|
return slices.Contains(p.Scopes, scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// HasRole reports whether the principal carries the given role (or is an admin).
|
||||||
|
func (p *Principal) HasRole(role string) bool {
|
||||||
|
if role == "" || role == "*" {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, r := range p.Roles {
|
||||||
|
if r == "admin" || r == role {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
// HasAnyRole reports whether the principal carries at least one of the given roles.
|
||||||
|
func (p *Principal) HasAnyRole(roles ...string) bool {
|
||||||
|
if len(roles) == 0 {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
for _, r := range roles {
|
||||||
|
if p.HasRole(r) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
// Authenticator inspects request credentials and returns the caller, or an
|
// Authenticator inspects request credentials and returns the caller, or an
|
||||||
// error if authentication fails.
|
// error if authentication fails.
|
||||||
type Authenticator interface {
|
type Authenticator interface {
|
||||||
|
|||||||
+10
-1
@@ -67,7 +67,7 @@ func (o *OIDC) Authenticate(r *http.Request) (*Principal, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return &Principal{Subject: c.Subject, Scopes: c.Scopes, Kind: KindOIDC}, nil
|
return &Principal{Subject: c.Subject, Scopes: c.Scopes, Roles: c.Roles, Kind: KindOIDC}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Claims is the parsed, verified claim set returned by VerifyClaims. Only
|
// Claims is the parsed, verified claim set returned by VerifyClaims. Only
|
||||||
@@ -83,6 +83,7 @@ type Claims struct {
|
|||||||
Expires int64 `json:"exp"`
|
Expires int64 `json:"exp"`
|
||||||
NotBefore int64 `json:"nbf"`
|
NotBefore int64 `json:"nbf"`
|
||||||
Scopes []string `json:"scope,omitempty"` // parsed from "scope" space-separated claim
|
Scopes []string `json:"scope,omitempty"` // parsed from "scope" space-separated claim
|
||||||
|
Roles []string `json:"roles,omitempty"` // parsed from "roles" or "groups" claim
|
||||||
}
|
}
|
||||||
|
|
||||||
// Audience unmarshals the `aud` claim, which RFC 7519 allows to be either a
|
// Audience unmarshals the `aud` claim, which RFC 7519 allows to be either a
|
||||||
@@ -187,6 +188,8 @@ func (o *OIDC) VerifyClaims(token string) (*Claims, error) {
|
|||||||
Expires int64 `json:"exp"`
|
Expires int64 `json:"exp"`
|
||||||
NotBefore int64 `json:"nbf"`
|
NotBefore int64 `json:"nbf"`
|
||||||
Scope string `json:"scope"`
|
Scope string `json:"scope"`
|
||||||
|
Roles []string `json:"roles"`
|
||||||
|
Groups []string `json:"groups"`
|
||||||
}
|
}
|
||||||
if err := json.Unmarshal(payloadJSON, &raw); err != nil {
|
if err := json.Unmarshal(payloadJSON, &raw); err != nil {
|
||||||
return nil, fmt.Errorf("oidc: bad claims: %w", err)
|
return nil, fmt.Errorf("oidc: bad claims: %w", err)
|
||||||
@@ -209,6 +212,11 @@ func (o *OIDC) VerifyClaims(token string) (*Claims, error) {
|
|||||||
if raw.Scope != "" {
|
if raw.Scope != "" {
|
||||||
scopes = strings.Fields(raw.Scope)
|
scopes = strings.Fields(raw.Scope)
|
||||||
}
|
}
|
||||||
|
roles := raw.Roles
|
||||||
|
if len(roles) == 0 && len(raw.Groups) > 0 {
|
||||||
|
roles = raw.Groups
|
||||||
|
}
|
||||||
|
|
||||||
return &Claims{
|
return &Claims{
|
||||||
Issuer: raw.Issuer,
|
Issuer: raw.Issuer,
|
||||||
Subject: raw.Subject,
|
Subject: raw.Subject,
|
||||||
@@ -218,6 +226,7 @@ func (o *OIDC) VerifyClaims(token string) (*Claims, error) {
|
|||||||
Expires: raw.Expires,
|
Expires: raw.Expires,
|
||||||
NotBefore: raw.NotBefore,
|
NotBefore: raw.NotBefore,
|
||||||
Scopes: scopes,
|
Scopes: scopes,
|
||||||
|
Roles: roles,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user