mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-02-18 00:17:39 +01:00
90 lines
2.6 KiB
Go
90 lines
2.6 KiB
Go
package auth
|
|
|
|
import "context"
|
|
|
|
// Authorizer defines the interface for making access control decisions.
|
|
type Authorizer interface {
|
|
// Authorize checks if a subject (from context) can perform an action on a resource.
|
|
// Returns true if allowed, false if denied, and an error if the check failed due to a system issue.
|
|
Authorize(ctx context.Context, action string, resource string) (bool, error)
|
|
}
|
|
|
|
type contextKey string
|
|
|
|
const (
|
|
contextKeyUser contextKey = "user"
|
|
contextKeyAPIToken contextKey = "apiToken"
|
|
)
|
|
|
|
// APITokenInfo is a minimal interface for checking token scopes without circular dependencies.
|
|
type APITokenInfo interface {
|
|
HasScope(scope string) bool
|
|
}
|
|
|
|
// WithUser adds a username to the context
|
|
func WithUser(ctx context.Context, username string) context.Context {
|
|
return context.WithValue(ctx, contextKeyUser, username)
|
|
}
|
|
|
|
// GetUser extracts the username from the context
|
|
func GetUser(ctx context.Context) string {
|
|
if user, ok := ctx.Value(contextKeyUser).(string); ok {
|
|
return user
|
|
}
|
|
return ""
|
|
}
|
|
|
|
// WithAPIToken adds an API token record to the context
|
|
func WithAPIToken(ctx context.Context, token APITokenInfo) context.Context {
|
|
return context.WithValue(ctx, contextKeyAPIToken, token)
|
|
}
|
|
|
|
// GetAPIToken extracts the API token record from the context
|
|
func GetAPIToken(ctx context.Context) APITokenInfo {
|
|
if token, ok := ctx.Value(contextKeyAPIToken).(APITokenInfo); ok {
|
|
return token
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// GetAPITokenContextKey returns the context key used for API tokens (for testing purposes)
|
|
func GetAPITokenContextKey() any {
|
|
return contextKeyAPIToken
|
|
}
|
|
|
|
// DefaultAuthorizer is a pass-through implementation that allows everything.
|
|
// Used in OSS version and when enterprise features are disabled.
|
|
type DefaultAuthorizer struct{}
|
|
|
|
func (d *DefaultAuthorizer) Authorize(ctx context.Context, action string, resource string) (bool, error) {
|
|
return true, nil
|
|
}
|
|
|
|
var globalAuthorizer Authorizer = &DefaultAuthorizer{}
|
|
|
|
// SetAuthorizer sets the global authorizer instance.
|
|
// This is used by pulse-enterprise to register the real RBAC implementation.
|
|
func SetAuthorizer(auth Authorizer) {
|
|
globalAuthorizer = auth
|
|
}
|
|
|
|
// AdminConfigurable is an optional interface for authorizers that can have an admin user set.
|
|
type AdminConfigurable interface {
|
|
SetAdminUser(username string)
|
|
}
|
|
|
|
// SetAdminUser sets the admin user on the global authorizer if it supports it.
|
|
func SetAdminUser(username string) {
|
|
if username == "" {
|
|
return
|
|
}
|
|
if configurable, ok := globalAuthorizer.(AdminConfigurable); ok {
|
|
configurable.SetAdminUser(username)
|
|
}
|
|
}
|
|
|
|
// GetAuthorizer returns the global authorizer instance.
|
|
func GetAuthorizer() Authorizer {
|
|
return globalAuthorizer
|
|
}
|