store

package
v0.3.0 Latest Latest
Warning

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

Go to latest
Published: Dec 1, 2025 License: Apache-2.0 Imports: 8 Imported by: 0

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func RunDeleteBackendTests

func RunDeleteBackendTests(t *testing.T, tests []DeleteBackendTestCase, storeFactory func() EntityStoreInterface)

RunDeleteBackendTests runs table-driven tests for DeleteBackend operation

func RunDeleteTests

func RunDeleteTests(t *testing.T, tests []DeleteTestCase, storeFactory func() EntityStoreInterface)

RunDeleteTests runs table-driven tests for Delete operation

func RunExistsTests

func RunExistsTests(t *testing.T, tests []ExistsTestCase, storeFactory func() EntityStoreInterface)

RunExistsTests runs table-driven tests for Exists operation

func RunGetBackendsTests

func RunGetBackendsTests(
	t *testing.T,
	tests []GetBackendsTestCase,
	storeFactory func() (EntityStoreInterface, cache.Cache),
)

RunGetBackendsTests runs table-driven tests for GetBackends operation

func RunSetBackendTests

func RunSetBackendTests(t *testing.T, tests []SetBackendTestCase, storeFactory func() EntityStoreInterface)

RunSetBackendTests runs table-driven tests for SetBackend operation

Types

type BackendInfo

type BackendInfo struct {
	ID   string `json:"id"`
	Name string `json:"name"`
	Type string `json:"type"`
}

BackendInfo represents backend metadata stored for a group

type DeleteBackendTestCase

type DeleteBackendTestCase struct {
	Name        string
	Identifier  string
	BackendKey  string
	SetupFunc   func(t *testing.T, store EntityStoreInterface)
	VerifyFunc  func(t *testing.T, store EntityStoreInterface)
	WantErr     bool
	ErrContains string
}

DeleteBackendTestCase defines a test case for DeleteBackend operations

type DeleteTestCase

type DeleteTestCase struct {
	Name       string
	Identifier string
	SetupFunc  func(t *testing.T, store EntityStoreInterface)
	WantErr    bool
}

DeleteTestCase defines a test case for Delete operations

type EntityStoreInterface

type EntityStoreInterface interface {
	GetBackends(ctx context.Context, identifier string) (map[string]string, error)
	SetBackend(ctx context.Context, identifier, backendKey, backendID string) error
	DeleteBackend(ctx context.Context, identifier, backendKey string) error
	Delete(ctx context.Context, identifier string) error
	Exists(ctx context.Context, identifier string) (bool, error)
}

EntityStoreInterface defines common operations for both UserStore and TeamStore This is used for test helpers to avoid duplication

type ExistsTestCase

type ExistsTestCase struct {
	Name       string
	Identifier string
	SetupFunc  func(t *testing.T, store EntityStoreInterface)
	WantExist  bool
}

ExistsTestCase defines a test case for Exists operations

type GetBackendsTestCase

type GetBackendsTestCase struct {
	Name        string
	Identifier  string
	SetupFunc   func(t *testing.T, store EntityStoreInterface, c cache.Cache)
	Want        map[string]string
	WantErr     bool
	ErrContains string
}

GetBackendsTestCase defines a test case for GetBackends operations

type GroupData

type GroupData struct {
	Members  []string               `json:"members"`
	Backends map[string]BackendInfo `json:"backends"` // key: "backendName_backendType"
}

GroupData represents the consolidated data stored for a group Key format: "group:<groupName>"

type GroupStore

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

GroupStore handles consolidated group cache operations Key format: "group:<groupName>" Value: JSON object with members and backends NOTE: This store does NOT handle locking - callers must ensure proper synchronization

func (*GroupStore) BackendExists

func (s *GroupStore) BackendExists(ctx context.Context, groupName, backendName, backendType string) (bool, error)

BackendExists checks if a specific backend exists for a group NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) Delete

func (s *GroupStore) Delete(ctx context.Context, groupName string) error

Delete removes a group entirely from cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) DeleteBackend

func (s *GroupStore) DeleteBackend(ctx context.Context, groupName, backendName, backendType string) error

DeleteBackend removes a specific backend from a group's record NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) Exists

func (s *GroupStore) Exists(ctx context.Context, groupName string) (bool, error)

Exists checks if a group exists in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) Get

func (s *GroupStore) Get(ctx context.Context, groupName string) (*GroupData, error)

Get retrieves the full group data from cache Returns empty GroupData if the group is not found in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) GetBackendID

func (s *GroupStore) GetBackendID(ctx context.Context, groupName, backendName, backendType string) (string, error)

GetBackendID returns the backend ID for a specific backend Returns empty string if the backend is not found NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) GetBackends

func (s *GroupStore) GetBackends(ctx context.Context, groupName string) (map[string]BackendInfo, error)

GetBackends returns a map of backend info for a group Returns an empty map if the group is not found in cache Map format: {"backend_name_type": BackendInfo{ID, Name, Type}} NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) GetMembers

func (s *GroupStore) GetMembers(ctx context.Context, groupName string) ([]string, error)

GetMembers returns the list of user emails for a group Returns an empty slice if the group is not found in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) Set

func (s *GroupStore) Set(ctx context.Context, groupName string, data *GroupData) error

Set stores the full group data in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) SetBackend

func (s *GroupStore) SetBackend(ctx context.Context, groupName, backendName, backendType, backendID string) error

SetBackend sets a backend for a group If the group doesn't exist, it will be created If the backend exists, it will be updated NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*GroupStore) SetMembers

func (s *GroupStore) SetMembers(ctx context.Context, groupName string, members []string) error

SetMembers sets the complete list of user emails for a group This replaces any existing members while preserving backends NOTE: Caller must hold appropriate lock if concurrent access is possible

type GroupStoreInterface

type GroupStoreInterface interface {
	// Get retrieves the full group data from cache
	// Returns empty GroupData if the group is not found in cache
	Get(ctx context.Context, groupName string) (*GroupData, error)

	// Set stores the full group data in cache
	Set(ctx context.Context, groupName string, data *GroupData) error

	// Delete removes a group entirely from cache
	Delete(ctx context.Context, groupName string) error

	// Exists checks if a group exists in cache
	Exists(ctx context.Context, groupName string) (bool, error)

	// GetMembers returns the list of user emails for a group
	// Returns an empty slice if the group is not found in cache
	GetMembers(ctx context.Context, groupName string) ([]string, error)

	// SetMembers sets the complete list of user emails for a group
	// This replaces any existing members while preserving backends
	SetMembers(ctx context.Context, groupName string, members []string) error

	// GetBackends returns a map of backend info for a group
	// Returns an empty map if the group is not found in cache
	// Map format: {"backend_name_type": BackendInfo{ID, Name, Type}}
	GetBackends(ctx context.Context, groupName string) (map[string]BackendInfo, error)

	// GetBackendID returns the backend ID for a specific backend
	// Returns empty string if the backend is not found
	GetBackendID(ctx context.Context, groupName, backendName, backendType string) (string, error)

	// SetBackend sets a backend for a group
	// If the group doesn't exist, it will be created
	// If the backend exists, it will be updated
	SetBackend(ctx context.Context, groupName, backendName, backendType, backendID string) error

	// DeleteBackend removes a specific backend from a group's record
	DeleteBackend(ctx context.Context, groupName, backendName, backendType string) error

	// BackendExists checks if a specific backend exists for a group
	BackendExists(ctx context.Context, groupName, backendName, backendType string) (bool, error)
}

GroupStoreInterface defines operations for consolidated group cache operations Key format: "group:<groupName>" Value: JSON object containing members and backends

type MetaStore

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

MetaStore handles all metadata-related cache operations with "meta:" prefix Metadata includes things like user lists, configuration, etc. NOTE: This store does NOT handle locking - callers must ensure proper synchronization

func (*MetaStore) Delete

func (s *MetaStore) Delete(ctx context.Context, key string) error

Delete removes a metadata entry NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*MetaStore) Get

func (s *MetaStore) Get(ctx context.Context, key string) (string, error)

Get retrieves a generic metadata value by key NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*MetaStore) GetUserList

func (s *MetaStore) GetUserList(ctx context.Context) ([]string, error)

GetUserList returns the list of active users Returns an empty slice if the list doesn't exist NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*MetaStore) Set

func (s *MetaStore) Set(ctx context.Context, key, value string) error

Set stores a generic metadata value by key NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*MetaStore) SetUserList

func (s *MetaStore) SetUserList(ctx context.Context, users []string) error

SetUserList sets the list of active users NOTE: Caller must hold appropriate lock if concurrent access is possible

type MetaStoreInterface

type MetaStoreInterface interface {
	// GetUserList retrieves the list of user IDs from cache
	// Returns empty slice if not found
	GetUserList(ctx context.Context) ([]string, error)

	// SetUserList stores the list of user IDs in cache
	SetUserList(ctx context.Context, users []string) error
}

MetaStoreInterface defines operations for metadata cache operations

type SetBackendTestCase

type SetBackendTestCase struct {
	Name        string
	Identifier  string // email for users, name for teams
	BackendKey  string
	BackendID   string
	SetupFunc   func(t *testing.T, store EntityStoreInterface)
	VerifyFunc  func(t *testing.T, store EntityStoreInterface)
	WantErr     bool
	ErrContains string
}

SetBackendTestCase defines a test case for SetBackend operations

type Store

type Store struct {
	User       UserStoreInterface
	Team       TeamStoreInterface  // For preload with transformed team names
	Group      GroupStoreInterface // For reconciliation with original group names
	Meta       MetaStoreInterface
	UserGroups UserGroupsStoreInterface
}

Store provides a high-level interface for managing users, teams, groups, and metadata in cache It encapsulates key prefixing and JSON serialization NOTE: This store does NOT handle locking - callers are responsible for proper synchronization

func New

func New(cache cache.Cache) *Store

New creates a new Store instance with all sub-stores initialized

type StoreInterface

type StoreInterface interface {
	// GetUserStore returns the user store operations
	GetUserStore() UserStoreInterface

	// GetTeamStore returns the team store operations (for preload with transformed names)
	GetTeamStore() TeamStoreInterface

	// GetGroupStore returns the group store operations (for reconciliation with original names)
	GetGroupStore() GroupStoreInterface

	// GetMetaStore returns the metadata store operations
	GetMetaStore() MetaStoreInterface

	// GetUserGroupsStore returns the user groups store operations
	GetUserGroupsStore() UserGroupsStoreInterface
}

StoreInterface is the main interface that combines all store operations This is the primary interface that should be used by consumers

type TeamStore

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

TeamStore handles team-related cache operations with "team:" prefix Key format: "team:<transformedTeamName>" Value: JSON map of {"backend_name_type": "backend_team_id"} This store is used for preloading team data from backends where teams are identified by their transformed names. NOTE: This store does NOT handle locking - callers must ensure proper synchronization

func (*TeamStore) Delete

func (s *TeamStore) Delete(ctx context.Context, teamName string) error

Delete removes a team entirely from cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*TeamStore) DeleteBackend

func (s *TeamStore) DeleteBackend(ctx context.Context, teamName, backendKey string) error

DeleteBackend removes a specific backend ID from a team's record If this was the last backend, the entire team entry is deleted NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*TeamStore) Exists

func (s *TeamStore) Exists(ctx context.Context, teamName string) (bool, error)

Exists checks if a team exists in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*TeamStore) GetBackends

func (s *TeamStore) GetBackends(ctx context.Context, teamName string) (map[string]string, error)

GetBackends returns a map of backend IDs for a team Returns an empty map if the team is not found in cache Map format: {"backend_name_type": "backend_team_id"} NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*TeamStore) SetBackend

func (s *TeamStore) SetBackend(ctx context.Context, teamName, backendKey, teamID string) error

SetBackend sets a backend ID for a team If the team doesn't exist, it will be created If the team exists, the backend ID will be added/updated in the map NOTE: Caller must hold appropriate lock if concurrent access is possible

type TeamStoreInterface

type TeamStoreInterface interface {
	// GetBackends returns a map of backend IDs for a team
	// Returns an empty map if the team is not found in cache
	// Map format: {"backend_name_type": "backend_team_id"}
	GetBackends(ctx context.Context, teamName string) (map[string]string, error)

	// SetBackend sets a backend ID for a team
	// If the team doesn't exist, it will be created
	// If the team exists, the backend ID will be added/updated in the map
	SetBackend(ctx context.Context, teamName, backendKey, teamID string) error

	// DeleteBackend removes a specific backend ID from a team's record
	// If this was the last backend, the entire team entry is deleted
	DeleteBackend(ctx context.Context, teamName, backendKey string) error

	// Delete removes a team entirely from cache
	Delete(ctx context.Context, teamName string) error

	// Exists checks if a team exists in cache
	Exists(ctx context.Context, teamName string) (bool, error)
}

TeamStoreInterface defines operations for team-related cache operations Key format: "team:<transformedTeamName>" This store is used for preloading team data from backends where teams are identified by their transformed names.

type UserGroupsStore

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

UserGroupsStore handles user-to-groups reverse index cache operations Key format: "user:groups:<email>" Value: JSON array of group names NOTE: This store does NOT handle locking - callers must ensure proper synchronization

func (*UserGroupsStore) AddGroup

func (s *UserGroupsStore) AddGroup(ctx context.Context, email, groupName string) error

AddGroup adds a group to a user's group list if not already present NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserGroupsStore) Delete

func (s *UserGroupsStore) Delete(ctx context.Context, email string) error

Delete removes the user's groups entry entirely NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserGroupsStore) Exists

func (s *UserGroupsStore) Exists(ctx context.Context, email string) (bool, error)

Exists checks if a user has any groups in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserGroupsStore) GetGroups

func (s *UserGroupsStore) GetGroups(ctx context.Context, email string) ([]string, error)

GetGroups returns the list of groups for a user Returns an empty slice if the user is not found in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserGroupsStore) RemoveGroup

func (s *UserGroupsStore) RemoveGroup(ctx context.Context, email, groupName string) error

RemoveGroup removes a specific group from a user's group list If this was the last group, the entry is deleted NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserGroupsStore) SetGroups

func (s *UserGroupsStore) SetGroups(ctx context.Context, email string, groups []string) error

SetGroups sets the complete list of groups for a user This replaces any existing groups NOTE: Caller must hold appropriate lock if concurrent access is possible

type UserGroupsStoreInterface

type UserGroupsStoreInterface interface {
	// GetGroups returns the list of groups for a user
	// Returns an empty slice if the user is not found in cache
	GetGroups(ctx context.Context, email string) ([]string, error)

	// AddGroup adds a group to a user's group list if not already present
	AddGroup(ctx context.Context, email, groupName string) error

	// SetGroups sets the complete list of groups for a user
	// This replaces any existing groups
	SetGroups(ctx context.Context, email string, groups []string) error

	// RemoveGroup removes a specific group from a user's group list
	// If this was the last group, the entry is deleted
	RemoveGroup(ctx context.Context, email, groupName string) error

	// Delete removes the user's groups entry entirely
	Delete(ctx context.Context, email string) error

	// Exists checks if a user has any groups in cache
	Exists(ctx context.Context, email string) (bool, error)
}

UserGroupsStoreInterface defines operations for user-to-groups reverse index Key format: "user:groups:<email>"

type UserStore

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

UserStore handles all user-related cache operations with "user:" prefix NOTE: This store does NOT handle locking - callers must ensure proper synchronization

func (*UserStore) Delete

func (s *UserStore) Delete(ctx context.Context, email string) error

Delete removes a user entirely from cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserStore) DeleteBackend

func (s *UserStore) DeleteBackend(ctx context.Context, email, backendKey string) error

DeleteBackend removes a specific backend ID from a user's record If this was the last backend, the entire user entry is deleted NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserStore) Exists

func (s *UserStore) Exists(ctx context.Context, email string) (bool, error)

Exists checks if a user exists in cache NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserStore) GetBackends

func (s *UserStore) GetBackends(ctx context.Context, email string) (map[string]string, error)

GetBackends returns a map of backend IDs for a user Returns an empty map if the user is not found in cache Map format: {"backend_name_type": "backend_user_id"} NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserStore) GetByPattern

func (s *UserStore) GetByPattern(ctx context.Context, pattern string) (map[string]map[string]string, error)

GetByPattern searches for users matching a pattern and returns their data Pattern should NOT include the "user:" prefix - it will be added automatically Example: pattern "*@example.com" searches for "user:*@example.com" Returns: map[email]backends where backends is map[backendKey]backendID NOTE: Caller must hold appropriate lock if concurrent access is possible

func (*UserStore) SetBackend

func (s *UserStore) SetBackend(ctx context.Context, email, backendKey, backendID string) error

SetBackend sets a backend ID for a user If the user doesn't exist, it will be created If the user exists, the backend ID will be added/updated in the map NOTE: Caller must hold appropriate lock if concurrent access is possible

type UserStoreInterface

type UserStoreInterface interface {
	// GetBackends returns a map of backend IDs for a user
	// Returns an empty map if the user is not found in cache
	// Map format: {"backend_name_type": "backend_user_id"}
	GetBackends(ctx context.Context, email string) (map[string]string, error)

	// SetBackend sets a backend ID for a user
	// If the user doesn't exist, it will be created
	// If the user exists, the backend ID will be added/updated in the map
	SetBackend(ctx context.Context, email, backendKey, backendID string) error

	// DeleteBackend removes a specific backend ID from a user's record
	// If this was the last backend, the entire user entry is deleted
	DeleteBackend(ctx context.Context, email, backendKey string) error

	// Delete removes a user entirely from cache
	Delete(ctx context.Context, email string) error

	// Exists checks if a user exists in cache
	Exists(ctx context.Context, email string) (bool, error)

	// GetByPattern searches for users matching a pattern and returns their data
	// Pattern should NOT include the "user:" prefix - it will be added automatically
	// Example: pattern "*@example.com" searches for "user:*@example.com"
	// Returns: map[email]backends where backends is map[backendKey]backendID
	GetByPattern(ctx context.Context, pattern string) (map[string]map[string]string, error)
}

UserStoreInterface defines operations for user-related cache operations This interface enables mocking in tests and follows the dependency inversion principle

Jump to

Keyboard shortcuts

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