mirror of
https://github.com/coder/coder.git
synced 2025-07-15 22:20:27 +00:00
feat: add API key scopes and application_connect scope (#4067)
This commit is contained in:
@ -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()
|
||||
|
||||
|
Reference in New Issue
Block a user