mongo

package
v1.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 11, 2026 License: Apache-2.0 Imports: 24 Imported by: 0

Documentation

Overview

Package mongo provides a MongoDB Store implementation for the Warden store.

Transactions

SetRolePermissions and AttachPermission touch more than one document (the junction rows, and, for AttachPermission, a role-existence check ahead of the write) and use a session transaction when the server supports one. Multi-document transactions require a replica set or sharded cluster; a standalone mongod (notably the default single-node container the test harness starts when WARDEN_TEST_MONGO_URI is unset) rejects them. Both methods detect this via a one-time, cached `hello` command (checking for "setName" or a mongos "isdbgrid" response) rather than by probing session.StartTransaction/AbortTransaction: those are local, lazy client-side calls in the v2 driver that never touch the wire until the first real command inside the transaction, so they can't actually detect a standalone deployment. They only defer the failure to the first live write. When the deployment doesn't support transactions, the same writes run sequentially against the plain (session-less) context instead, without atomicity. Callers that need the transactional guarantee should run against a replica set (a single-node replica set is enough) or set WARDEN_TEST_MONGO_URI / the production connection string accordingly.

Index

Constants

This section is empty.

Variables

View Source
var Migrations = migrate.NewGroup("warden")

Migrations is the grove migration group for the Warden mongo store.

Functions

This section is empty.

Types

type Option added in v1.7.0

type Option func(*Store)

Option configures a Store at construction time.

func WithCheckLogTTL added in v1.7.0

func WithCheckLogTTL(d time.Duration) Option

WithCheckLogTTL enables MongoDB's background TTL reaper on warden_check_logs: documents are deleted d after their created_at. When this option is not supplied (the default), Migrate creates no TTL index at all and check-log retention is left entirely to the calling engine/job, matching the postgres and sqlite backends, which have no TTL mechanism of their own.

type Store

type Store struct {
	// contains filtered or unexported fields
}

Store is a MongoDB implementation of the composite Warden store.

func New

func New(db *grove.DB, opts ...Option) *Store

New creates a new MongoDB store backed by Grove ORM.

func (*Store) AttachPermission

func (s *Store) AttachPermission(ctx context.Context, tenantID string, roleID id.RoleID, ref permission.Ref) error

func (*Store) CheckDirectRelation

func (s *Store) CheckDirectRelation(ctx context.Context, tenantID string, namespacePaths []string, objectType, objectID, rel, subjectType, subjectID string) (bool, error)

func (*Store) Close

func (s *Store) Close() error

Close closes the database connection.

func (*Store) CountAssignments

func (s *Store) CountAssignments(ctx context.Context, filter *assignment.ListFilter) (int64, error)

func (*Store) CountCheckLogs

func (s *Store) CountCheckLogs(ctx context.Context, filter *checklog.QueryFilter) (int64, error)

func (*Store) CountPermissions

func (s *Store) CountPermissions(ctx context.Context, filter *permission.ListFilter) (int64, error)

func (*Store) CountPolicies

func (s *Store) CountPolicies(ctx context.Context, filter *policy.ListFilter) (int64, error)

func (*Store) CountRelations

func (s *Store) CountRelations(ctx context.Context, filter *relation.ListFilter) (int64, error)

func (*Store) CountResourceTypes

func (s *Store) CountResourceTypes(ctx context.Context, filter *resourcetype.ListFilter) (int64, error)

func (*Store) CountRoles

func (s *Store) CountRoles(ctx context.Context, filter *role.ListFilter) (int64, error)

func (*Store) CreateAssignment

func (s *Store) CreateAssignment(ctx context.Context, a *assignment.Assignment) error

func (*Store) CreateCheckLog

func (s *Store) CreateCheckLog(ctx context.Context, e *checklog.Entry) error

func (*Store) CreatePermission

func (s *Store) CreatePermission(ctx context.Context, p *permission.Permission) error

func (*Store) CreatePolicy

func (s *Store) CreatePolicy(ctx context.Context, p *policy.Policy) error

func (*Store) CreateRelation

func (s *Store) CreateRelation(ctx context.Context, t *relation.Tuple) error

func (*Store) CreateResourceType

func (s *Store) CreateResourceType(ctx context.Context, rt *resourcetype.ResourceType) error

func (*Store) CreateRole

func (s *Store) CreateRole(ctx context.Context, r *role.Role) error

func (*Store) DeleteAssignment

func (s *Store) DeleteAssignment(ctx context.Context, tenantID string, assID id.AssignmentID) error

func (*Store) DeleteAssignmentsByRole

func (s *Store) DeleteAssignmentsByRole(ctx context.Context, tenantID string, roleID id.RoleID) error

func (*Store) DeleteAssignmentsBySubject

func (s *Store) DeleteAssignmentsBySubject(ctx context.Context, tenantID, subjectKind, subjectID string) error

func (*Store) DeleteAssignmentsByTenant

func (s *Store) DeleteAssignmentsByTenant(ctx context.Context, tenantID string) error

func (*Store) DeleteCheckLogsBySubject added in v1.7.0

func (s *Store) DeleteCheckLogsBySubject(ctx context.Context, tenantID, subjectKind, subjectID string) (int64, error)

func (*Store) DeleteCheckLogsByTenant

func (s *Store) DeleteCheckLogsByTenant(ctx context.Context, tenantID string) error

func (*Store) DeleteExpiredAssignments

func (s *Store) DeleteExpiredAssignments(ctx context.Context, t time.Time) (int64, error)

func (*Store) DeleteExpiredAssignmentsForTenant added in v1.7.0

func (s *Store) DeleteExpiredAssignmentsForTenant(ctx context.Context, tenantID string, t time.Time) (int64, error)

func (*Store) DeletePermission

func (s *Store) DeletePermission(ctx context.Context, tenantID string, permID id.PermissionID) error

DeletePermission removes a permission and the junction rows that grant it. The junction stores the permission's natural key, not its ID, so the grants are matched on (namespace_path, name) and narrowed to the tenant's roles.

func (*Store) DeletePermissionsByTenant

func (s *Store) DeletePermissionsByTenant(ctx context.Context, tenantID string) error

func (*Store) DeletePoliciesByTenant

func (s *Store) DeletePoliciesByTenant(ctx context.Context, tenantID string) error

func (*Store) DeletePolicy

func (s *Store) DeletePolicy(ctx context.Context, tenantID string, polID id.PolicyID) error

func (*Store) DeleteRelation

func (s *Store) DeleteRelation(ctx context.Context, tenantID string, relID id.RelationID) error

func (*Store) DeleteRelationTuple

func (s *Store) DeleteRelationTuple(ctx context.Context, tenantID, namespacePath, objectType, objectID, rel, subjectType, subjectID, subjectRelation string) error

func (*Store) DeleteRelationsByObject

func (s *Store) DeleteRelationsByObject(ctx context.Context, tenantID, objectType, objectID string) error

func (*Store) DeleteRelationsBySubject

func (s *Store) DeleteRelationsBySubject(ctx context.Context, tenantID, subjectType, subjectID string) error

func (*Store) DeleteRelationsByTenant

func (s *Store) DeleteRelationsByTenant(ctx context.Context, tenantID string) error

func (*Store) DeleteResourceType

func (s *Store) DeleteResourceType(ctx context.Context, tenantID string, rtID id.ResourceTypeID) error

func (*Store) DeleteResourceTypesByTenant

func (s *Store) DeleteResourceTypesByTenant(ctx context.Context, tenantID string) error

func (*Store) DeleteRole

func (s *Store) DeleteRole(ctx context.Context, tenantID string, roleID id.RoleID) error

DeleteRole removes a role and the rows that hang off it. Mongo has no foreign keys, so the grants and assignments are cleaned up here.

func (*Store) DeleteRolesByTenant

func (s *Store) DeleteRolesByTenant(ctx context.Context, tenantID string) error

func (*Store) DetachPermission

func (s *Store) DetachPermission(ctx context.Context, tenantID string, roleID id.RoleID, ref permission.Ref) error

func (*Store) GetAssignment

func (s *Store) GetAssignment(ctx context.Context, tenantID string, assID id.AssignmentID) (*assignment.Assignment, error)

func (*Store) GetCheckLog

func (s *Store) GetCheckLog(ctx context.Context, tenantID string, logID id.CheckLogID) (*checklog.Entry, error)

func (*Store) GetPermission

func (s *Store) GetPermission(ctx context.Context, tenantID string, permID id.PermissionID) (*permission.Permission, error)

func (*Store) GetPermissionByName

func (s *Store) GetPermissionByName(ctx context.Context, tenantID, namespacePath, name string) (*permission.Permission, error)

func (*Store) GetPolicy

func (s *Store) GetPolicy(ctx context.Context, tenantID string, polID id.PolicyID) (*policy.Policy, error)

func (*Store) GetPolicyByName

func (s *Store) GetPolicyByName(ctx context.Context, tenantID, namespacePath, name string) (*policy.Policy, error)

func (*Store) GetRelation added in v1.7.0

func (s *Store) GetRelation(ctx context.Context, tenantID string, relID id.RelationID) (*relation.Tuple, error)

func (*Store) GetResourceType

func (s *Store) GetResourceType(ctx context.Context, tenantID string, rtID id.ResourceTypeID) (*resourcetype.ResourceType, error)

func (*Store) GetResourceTypeByName

func (s *Store) GetResourceTypeByName(ctx context.Context, tenantID, namespacePath, name string) (*resourcetype.ResourceType, error)

func (*Store) GetRole

func (s *Store) GetRole(ctx context.Context, tenantID string, roleID id.RoleID) (*role.Role, error)

func (*Store) GetRoleBySlug

func (s *Store) GetRoleBySlug(ctx context.Context, tenantID, namespacePath, slug string) (*role.Role, error)

func (*Store) GetRoles added in v1.7.0

func (s *Store) GetRoles(ctx context.Context, tenantID string, roleIDs []id.RoleID) ([]*role.Role, error)

func (*Store) ListActivePolicies

func (s *Store) ListActivePolicies(ctx context.Context, tenantID string, namespacePaths []string) ([]*policy.Policy, error)

func (*Store) ListAssignments

func (s *Store) ListAssignments(ctx context.Context, filter *assignment.ListFilter) ([]*assignment.Assignment, error)

func (*Store) ListCheckLogs

func (s *Store) ListCheckLogs(ctx context.Context, filter *checklog.QueryFilter) ([]*checklog.Entry, error)

func (*Store) ListChildRoles

func (s *Store) ListChildRoles(ctx context.Context, tenantID, parentSlug string) ([]*role.Role, error)

func (*Store) ListExpiringAssignments added in v1.7.0

func (s *Store) ListExpiringAssignments(ctx context.Context, tenantID string, before time.Time, limit int) ([]*assignment.Assignment, error)

func (*Store) ListPermissions

func (s *Store) ListPermissions(ctx context.Context, filter *permission.ListFilter) ([]*permission.Permission, error)

func (*Store) ListPermissionsByRole

func (s *Store) ListPermissionsByRole(ctx context.Context, tenantID string, roleID id.RoleID) ([]*permission.Permission, error)

func (*Store) ListPermissionsBySubject

func (s *Store) ListPermissionsBySubject(ctx context.Context, tenantID, subjectKind, subjectID string) ([]*permission.Permission, error)

func (*Store) ListPolicies

func (s *Store) ListPolicies(ctx context.Context, filter *policy.ListFilter) ([]*policy.Policy, error)

func (*Store) ListRelationObjects

func (s *Store) ListRelationObjects(ctx context.Context, tenantID, namespacePath, subjectType, subjectID, rel string, limit int) ([]*relation.Tuple, error)

func (*Store) ListRelationSubjects

func (s *Store) ListRelationSubjects(ctx context.Context, tenantID string, namespacePaths []string, objectType, objectID, rel string, limit int) ([]*relation.Tuple, error)

func (*Store) ListRelations

func (s *Store) ListRelations(ctx context.Context, filter *relation.ListFilter) ([]*relation.Tuple, error)

func (*Store) ListResourceTypes

func (s *Store) ListResourceTypes(ctx context.Context, filter *resourcetype.ListFilter) ([]*resourcetype.ResourceType, error)

func (*Store) ListRolePermissions

func (s *Store) ListRolePermissions(ctx context.Context, tenantID string, roleID id.RoleID) ([]*permission.Permission, error)

ListRolePermissions walks the junction's natural keys (perm_namespace_path, perm_name) into the permissions collection, scoped to the role's tenant. Mongo doesn't have JOINs, so we do the lookup in two steps: junction rows for this role, then a single permissions Find with $in.

func (*Store) ListRolePermissionsForRoles added in v1.7.0

func (s *Store) ListRolePermissionsForRoles(ctx context.Context, tenantID string, roleIDs []id.RoleID) (map[id.RoleID][]*permission.Permission, error)

ListRolePermissionsForRoles resolves the grants of several roles at once. Mongo has no JOINs, so it runs in three steps: the roles that really are in the tenant, their junction rows, then one permissions lookup for every distinct natural key those rows name.

func (*Store) ListRoles

func (s *Store) ListRoles(ctx context.Context, filter *role.ListFilter) ([]*role.Role, error)

func (*Store) ListRolesForSubject

func (s *Store) ListRolesForSubject(ctx context.Context, tenantID string, namespacePaths []string, subjectKind, subjectID string) ([]id.RoleID, error)

func (*Store) ListRolesForSubjectOnResource

func (s *Store) ListRolesForSubjectOnResource(ctx context.Context, tenantID string, namespacePaths []string, subjectKind, subjectID, resourceType, resourceID string) ([]id.RoleID, error)

func (*Store) ListSubjectsForRole

func (s *Store) ListSubjectsForRole(ctx context.Context, tenantID string, roleID id.RoleID) ([]*assignment.Assignment, error)

func (*Store) Migrate

func (s *Store) Migrate(ctx context.Context) error

Migrate runs the versioned migration group through the grove orchestrator (collection creation, indexes, and the namespace-scoped uniqueness fix all live in migrations.go), then, only when the store was constructed with WithCheckLogTTL, ensures the check-log TTL index.

func (*Store) Ping

func (s *Store) Ping(ctx context.Context) error

Ping verifies the database connection.

func (*Store) PurgeCheckLogs

func (s *Store) PurgeCheckLogs(ctx context.Context, before time.Time) (int64, error)

func (*Store) PurgeCheckLogsForTenant added in v1.7.0

func (s *Store) PurgeCheckLogsForTenant(ctx context.Context, tenantID string, before time.Time) (int64, error)

func (*Store) SetPolicyVersion

func (s *Store) SetPolicyVersion(ctx context.Context, tenantID string, polID id.PolicyID, version int) error

func (*Store) SetRolePermissions

func (s *Store) SetRolePermissions(ctx context.Context, tenantID string, roleID id.RoleID, refs []permission.Ref) error

func (*Store) UpdatePermission

func (s *Store) UpdatePermission(ctx context.Context, p *permission.Permission) error

func (*Store) UpdatePolicy

func (s *Store) UpdatePolicy(ctx context.Context, p *policy.Policy) error

func (*Store) UpdatePolicyIfVersion added in v1.7.0

func (s *Store) UpdatePolicyIfVersion(ctx context.Context, p *policy.Policy, expected int) error

UpdatePolicyIfVersion writes p as UpdatePolicy does, only if the stored policy is at version expected. The version is part of the update's filter, and a single-document update is atomic, so the comparison and the write are one step: of two writers holding the same version, the second's filter no longer matches. When nothing matches, a read picks the error: not found if the policy is absent from p's tenant, a version conflict otherwise. That read only chooses the error; the refusal itself was atomic.

p.UpdatedAt is set only once the write has happened, so a refused caller's struct does not claim a write that did not happen.

func (*Store) UpdateResourceType

func (s *Store) UpdateResourceType(ctx context.Context, rt *resourcetype.ResourceType) error

func (*Store) UpdateRole

func (s *Store) UpdateRole(ctx context.Context, r *role.Role) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL