feat: add API key scopes and application_connect scope (#4067)

This commit is contained in:
Dean Sheather
2022-09-20 03:39:02 +10:00
committed by GitHub
parent adad347902
commit 29d804e692
42 changed files with 476 additions and 88 deletions

View File

@ -11,6 +11,59 @@ import (
)
type PartialAuthorizer struct {
// mainAuthorizer is used for the user's roles. It is always not-nil.
mainAuthorizer *subPartialAuthorizer
// scopeAuthorizer is used for the API key scope. It may be nil.
scopeAuthorizer *subPartialAuthorizer
}
var _ PreparedAuthorized = (*PartialAuthorizer)(nil)
func (pa *PartialAuthorizer) Authorize(ctx context.Context, object Object) error {
ctx, span := tracing.StartSpan(ctx)
defer span.End()
err := pa.mainAuthorizer.Authorize(ctx, object)
if err != nil {
return err
}
if pa.scopeAuthorizer != nil {
return pa.scopeAuthorizer.Authorize(ctx, object)
}
return nil
}
func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, scope Scope, action Action, objectType string) (*PartialAuthorizer, error) {
ctx, span := tracing.StartSpan(ctx)
defer span.End()
pAuth, err := newSubPartialAuthorizer(ctx, subjectID, roles, action, objectType)
if err != nil {
return nil, err
}
var scopeAuth *subPartialAuthorizer
if scope != ScopeAll {
scopeRole, err := ScopeRole(scope)
if err != nil {
return nil, xerrors.Errorf("unknown scope %q", scope)
}
scopeAuth, err = newSubPartialAuthorizer(ctx, subjectID, []Role{scopeRole}, action, objectType)
if err != nil {
return nil, err
}
}
return &PartialAuthorizer{
mainAuthorizer: pAuth,
scopeAuthorizer: scopeAuth,
}, nil
}
type subPartialAuthorizer struct {
// partialQueries is mainly used for unit testing to assert our rego policy
// can always be compressed into a set of queries.
partialQueries *rego.PartialQueries
@ -25,7 +78,7 @@ type PartialAuthorizer struct {
alwaysTrue bool
}
func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, action Action, objectType string) (*PartialAuthorizer, error) {
func newSubPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, action Action, objectType string) (*subPartialAuthorizer, error) {
ctx, span := tracing.StartSpan(ctx)
defer span.End()
@ -55,7 +108,7 @@ func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, a
return nil, xerrors.Errorf("prepare: %w", err)
}
pAuth := &PartialAuthorizer{
pAuth := &subPartialAuthorizer{
partialQueries: partialQueries,
preparedQueries: []rego.PreparedEvalQuery{},
input: input,
@ -87,7 +140,7 @@ func newPartialAuthorizer(ctx context.Context, subjectID string, roles []Role, a
}
// Authorize authorizes a single object using the partially prepared queries.
func (a PartialAuthorizer) Authorize(ctx context.Context, object Object) error {
func (a subPartialAuthorizer) Authorize(ctx context.Context, object Object) error {
ctx, span := tracing.StartSpan(ctx)
defer span.End()