Documentation
¶
Index ¶
- Variables
- type ExpiryWorker
- type OperatorService
- func (s *OperatorService) ChangePassword(ctx context.Context, operatorID uuid.UUID, currentPassword, newPassword string) error
- func (s *OperatorService) CreateOperator(ctx context.Context, username, password, displayName string) (*model.Operator, error)
- func (s *OperatorService) DeleteOperator(ctx context.Context, callerID, targetID uuid.UUID) error
- func (s *OperatorService) GetCurrentOperator(ctx context.Context, id uuid.UUID) (*model.Operator, error)
- func (s *OperatorService) ListOperators(ctx context.Context, filter store.OperatorFilter) ([]model.Operator, int, error)
- func (s *OperatorService) Login(ctx context.Context, username, password string) (*model.Operator, string, error)
- func (s *OperatorService) NeedsSetup(ctx context.Context) (bool, error)
- func (s *OperatorService) Setup(ctx context.Context, username, password, displayName string) (*model.Operator, string, error)
- func (s *OperatorService) ValidateToken(tokenString string) (*OperatorTokenClaims, error)
- type OperatorTokenClaims
- type PolicyService
- func (s *PolicyService) Create(ctx context.Context, policy *model.Policy) error
- func (s *PolicyService) Delete(ctx context.Context, id uuid.UUID) error
- func (s *PolicyService) DistinctRequestTypes(ctx context.Context) ([]string, error)
- func (s *PolicyService) GetByID(ctx context.Context, id uuid.UUID) (*model.Policy, error)
- func (s *PolicyService) GetByRequestType(ctx context.Context, requestType string) (*model.Policy, error)
- func (s *PolicyService) List(ctx context.Context, filter store.PolicyFilter) ([]model.Policy, int, error)
- func (s *PolicyService) Update(ctx context.Context, policy *model.Policy) error
- type RequestService
- func (s *RequestService) Approve(ctx context.Context, requestID uuid.UUID, checkerID string, roles []string, ...) (*model.Request, error)
- func (s *RequestService) CanViewerAct(ctx context.Context, req *model.Request, viewerID string, ...) bool
- func (s *RequestService) Cancel(ctx context.Context, requestID uuid.UUID, makerID string) (*model.Request, error)
- func (s *RequestService) Create(ctx context.Context, req *model.Request) (*model.Request, error)
- func (s *RequestService) GetByID(ctx context.Context, id uuid.UUID) (*model.Request, error)
- func (s *RequestService) List(ctx context.Context, filter store.RequestFilter) ([]model.Request, int, error)
- func (s *RequestService) Reject(ctx context.Context, requestID uuid.UUID, checkerID string, roles []string, ...) (*model.Request, error)
- func (s *RequestService) SetMetrics(m *metrics.Metrics)
- func (s *RequestService) SetSSESignal(signal func(requestID uuid.UUID))
- func (s *RequestService) SetWebhookDispatch(runInTx func(ctx context.Context, fn func(tx *store.Stores) error) error, ...)
- type TenantService
- func (s *TenantService) Create(ctx context.Context, slug, name string) (*model.Tenant, error)
- func (s *TenantService) Delete(ctx context.Context, id uuid.UUID) error
- func (s *TenantService) GetBySlug(ctx context.Context, slug string) (*model.Tenant, error)
- func (s *TenantService) IsRegistered(slug string) bool
- func (s *TenantService) List(ctx context.Context, filter store.TenantFilter) ([]model.Tenant, int, error)
- func (s *TenantService) LoadCache(ctx context.Context) error
- func (s *TenantService) StartCacheRefresh(ctx context.Context, interval time.Duration)
- type WebhookService
- func (s *WebhookService) Create(ctx context.Context, webhook *model.Webhook) error
- func (s *WebhookService) Delete(ctx context.Context, id uuid.UUID) error
- func (s *WebhookService) GetMatchingWebhooks(ctx context.Context, event string, requestType string) ([]model.Webhook, error)
- func (s *WebhookService) List(ctx context.Context, filter store.WebhookFilter) ([]model.Webhook, int, error)
Constants ¶
This section is empty.
Variables ¶
var ( ErrOperatorNotFound = errors.New("operator not found") ErrUsernameExists = errors.New("username already exists") ErrInvalidCredentials = errors.New("invalid credentials") ErrSetupAlreadyDone = errors.New("setup has already been completed") ErrNoOperatorsExist = errors.New("no operators exist; run setup first") ErrIncorrectPassword = errors.New("current password is incorrect") ErrCannotDeleteSelf = errors.New("cannot delete yourself") ErrLastOperator = errors.New("cannot delete the last operator") )
var ( ErrPolicyNotFound = errors.New("policy not found") ErrPolicyTypeConflict = errors.New("a policy for this request type already exists") ErrNoStages = errors.New("policy must have at least one approval stage") ErrInvalidStageIndex = errors.New("stage indices must be sequential starting from 0") ErrInvalidDisplayTemplate = errors.New("invalid display template") ErrThresholdNoMaxCheckers = errors.New("max_checkers is required when rejection_policy is 'threshold'") ErrInvalidAuthorizationMode = errors.New("authorization_mode must be 'any' or 'all' when both allowed_checker_roles and allowed_permissions are set") )
var ( ErrRequestNotFound = errors.New("request not found") ErrRequestNotPending = errors.New("request is not in pending status") ErrDuplicateRequest = errors.New("a pending request with the same identity already exists") ErrIdempotencyConflict = errors.New("request with this idempotency key already exists") ErrSelfApproval = errors.New("maker cannot approve their own request") ErrAlreadyActioned = errors.New("checker has already acted on this request") ErrInvalidCheckerRole = errors.New("checker does not have a required role") ErrInvalidCheckerPermission = errors.New("checker does not have a required permission") ErrNotEligibleReviewer = errors.New("checker is not in the eligible reviewers list") ErrInvalidStage = errors.New("request is at an invalid stage for this policy") ErrMissingIdentityFields = errors.New("missing identity field in payload") )
var ( ErrTenantNotFound = errors.New("tenant not found") ErrTenantSlugExists = errors.New("tenant slug already exists") ErrTenantSlugInvalid = errors.New("tenant slug must be lowercase alphanumeric with hyphens only") ErrTenantSlugRequired = errors.New("tenant slug is required") ErrTenantNameRequired = errors.New("tenant name is required") )
var ( ErrWebhookNotFound = errors.New("webhook not found") ErrWebhookValidation = errors.New("webhook validation error") )
Functions ¶
This section is empty.
Types ¶
type ExpiryWorker ¶
type ExpiryWorker struct {
// contains filtered or unexported fields
}
func NewExpiryWorker ¶
func NewExpiryWorker(requests store.RequestStore, audits store.AuditStore, checkInterval time.Duration) *ExpiryWorker
func (*ExpiryWorker) SetMetrics ¶
func (w *ExpiryWorker) SetMetrics(m *metrics.Metrics)
SetMetrics sets the optional Prometheus metrics collector.
func (*ExpiryWorker) SetSSESignal ¶
func (w *ExpiryWorker) SetSSESignal(signal func(requestID uuid.UUID))
SetSSESignal configures the callback invoked after a request expires to notify connected SSE clients.
func (*ExpiryWorker) SetWebhookDispatch ¶
func (w *ExpiryWorker) SetWebhookDispatch( runInTx func(ctx context.Context, fn func(tx *store.Stores) error) error, enqueue func(ctx context.Context, outbox store.OutboxStore, webhooks store.WebhookStore, req *model.Request, approvals []model.Approval) error, signal func(), )
SetWebhookDispatch configures transactional webhook dispatch for expired requests.
func (*ExpiryWorker) Start ¶
func (w *ExpiryWorker) Start(ctx context.Context)
type OperatorService ¶
type OperatorService struct {
// contains filtered or unexported fields
}
OperatorService handles operator management and authentication for the admin console.
func NewOperatorService ¶
func NewOperatorService(operators store.OperatorStore, jwtSecret string) *OperatorService
NewOperatorService creates a new OperatorService. If jwtSecret is empty, a random 32-byte secret is generated (sessions won't survive restarts).
func (*OperatorService) ChangePassword ¶
func (s *OperatorService) ChangePassword(ctx context.Context, operatorID uuid.UUID, currentPassword, newPassword string) error
ChangePassword changes an operator's password. Requires the current password for verification.
func (*OperatorService) CreateOperator ¶
func (s *OperatorService) CreateOperator(ctx context.Context, username, password, displayName string) (*model.Operator, error)
CreateOperator creates a new operator (called by an existing operator).
func (*OperatorService) DeleteOperator ¶
DeleteOperator deletes an operator. Cannot delete yourself or the last operator.
func (*OperatorService) GetCurrentOperator ¶
func (s *OperatorService) GetCurrentOperator(ctx context.Context, id uuid.UUID) (*model.Operator, error)
GetCurrentOperator returns the operator for the given ID.
func (*OperatorService) ListOperators ¶
func (s *OperatorService) ListOperators(ctx context.Context, filter store.OperatorFilter) ([]model.Operator, int, error)
func (*OperatorService) Login ¶
func (s *OperatorService) Login(ctx context.Context, username, password string) (*model.Operator, string, error)
Login authenticates an operator and returns a JWT token.
func (*OperatorService) NeedsSetup ¶
func (s *OperatorService) NeedsSetup(ctx context.Context) (bool, error)
NeedsSetup returns true if no operators exist yet.
func (*OperatorService) Setup ¶
func (s *OperatorService) Setup(ctx context.Context, username, password, displayName string) (*model.Operator, string, error)
Setup creates the first operator. Returns ErrSetupAlreadyDone if operators already exist.
func (*OperatorService) ValidateToken ¶
func (s *OperatorService) ValidateToken(tokenString string) (*OperatorTokenClaims, error)
ValidateToken parses and validates a JWT token, returning the claims.
type OperatorTokenClaims ¶
type OperatorTokenClaims struct {
jwt.RegisteredClaims
Username string `json:"username"`
}
OperatorTokenClaims are the JWT claims for console operator sessions.
type PolicyService ¶
type PolicyService struct {
// contains filtered or unexported fields
}
func NewPolicyService ¶
func NewPolicyService(policies store.PolicyStore) *PolicyService
func (*PolicyService) DistinctRequestTypes ¶ added in v0.1.2
func (s *PolicyService) DistinctRequestTypes(ctx context.Context) ([]string, error)
func (*PolicyService) GetByRequestType ¶
type RequestService ¶
type RequestService struct {
// contains filtered or unexported fields
}
func NewRequestService ¶
func NewRequestService( requests store.RequestStore, approvals store.ApprovalStore, policies store.PolicyStore, audits store.AuditStore, authorizationHook *auth.AuthorizationHook, ) *RequestService
func (*RequestService) CanViewerAct ¶
func (s *RequestService) CanViewerAct(ctx context.Context, req *model.Request, viewerID string, viewerRoles, viewerPermissions []string) bool
CanViewerAct determines whether the given viewer can approve or reject the request based on the same checks enforced by processDecision. The dynamic_authorization_url is intentionally skipped (HTTP call not suitable for the read path); it is still enforced on actual approve/reject.
func (*RequestService) List ¶
func (s *RequestService) List(ctx context.Context, filter store.RequestFilter) ([]model.Request, int, error)
func (*RequestService) SetMetrics ¶
func (s *RequestService) SetMetrics(m *metrics.Metrics)
SetMetrics sets the optional Prometheus metrics collector.
func (*RequestService) SetSSESignal ¶
func (s *RequestService) SetSSESignal(signal func(requestID uuid.UUID))
SetSSESignal configures the callback invoked after a request's state changes to notify connected SSE clients. Called post-commit alongside signalWebhooks.
func (*RequestService) SetWebhookDispatch ¶
func (s *RequestService) SetWebhookDispatch( runInTx func(ctx context.Context, fn func(tx *store.Stores) error) error, enqueue func(ctx context.Context, outbox store.OutboxStore, webhooks store.WebhookStore, req *model.Request, approvals []model.Approval) error, signal func(), )
SetWebhookDispatch configures transactional webhook dispatch via an outbox table. enqueue writes outbox rows (should be called inside a transaction), signal wakes the delivery worker (should be called after the transaction commits), and runInTx executes a function within a database transaction.
type TenantService ¶
type TenantService struct {
// contains filtered or unexported fields
}
func NewTenantService ¶
func NewTenantService(tenants store.TenantStore) *TenantService
func (*TenantService) IsRegistered ¶
func (s *TenantService) IsRegistered(slug string) bool
IsRegistered checks whether a tenant slug exists using the in-memory cache, avoiding a database round-trip on every API request.
func (*TenantService) List ¶
func (s *TenantService) List(ctx context.Context, filter store.TenantFilter) ([]model.Tenant, int, error)
func (*TenantService) LoadCache ¶
func (s *TenantService) LoadCache(ctx context.Context) error
LoadCache pre-populates the in-memory slug set from the database. Call this once during server startup.
func (*TenantService) StartCacheRefresh ¶
func (s *TenantService) StartCacheRefresh(ctx context.Context, interval time.Duration)
StartCacheRefresh runs a background goroutine that periodically reloads the tenant slug cache from the database. This keeps instances in sync when tenants are created or deleted on a different instance. The goroutine stops when ctx is cancelled.
type WebhookService ¶
type WebhookService struct {
// contains filtered or unexported fields
}
func NewWebhookService ¶
func NewWebhookService(webhooks store.WebhookStore) *WebhookService