authentricity/internal/store/store.go
2022-07-11 21:49:26 +00:00

94 lines
2.7 KiB
Go

package store
import (
"context"
"fmt"
"time"
"github.com/google/uuid"
"go.e43.eu/authentricity/internal/models"
)
type EntryMetadata struct {
LastFetched time.Time
Revision uint64
}
type Store interface {
GetEntity(ctx context.Context, id uuid.UUID) (models.Entity, EntryMetadata, error)
GetEntityIDByName(ctx context.Context, name string) (uuid.UUID, EntryMetadata, error)
GetEntityByName(ctx context.Context, name string) (models.Entity, EntryMetadata, error)
GetEntityIDByEmail(ctx context.Context, name string) (uuid.UUID, EntryMetadata, error)
GetEntityByEmail(ctx context.Context, name string) (models.Entity, EntryMetadata, error)
GetUserGroups(ctx context.Context, userID uuid.UUID) ([]uuid.UUID, EntryMetadata, error)
GetGroupUsers(ctx context.Context, groupID uuid.UUID) ([]uuid.UUID, EntryMetadata, error)
}
type WritableStore interface {
Store
CreateEntity(ctx context.Context, ent models.Entity) (EntryMetadata, error)
UpdateEntitySimple(ctx context.Context, ent models.Entity, oldmd EntryMetadata) error
AddUserToGroup(ctx context.Context, userID, groupID uuid.UUID) error
RemoveUserFromGroup(ctx context.Context, userID, groupID uuid.UUID) error
}
type mustRefetchCtxKey struct{}
func WithMustRefetch(ctx context.Context) context.Context {
return context.WithValue(ctx, mustRefetchCtxKey{}, mustRefetchCtxKey{})
}
func MustRefetch(ctx context.Context) bool {
return ctx.Value(mustRefetchCtxKey{}) != nil
}
func GetEntityIDByAnyName(ctx context.Context, st Store, name string) (id uuid.UUID, err error) {
cls, err := models.ClassifyName(name)
if err != nil {
return id, err
}
switch cls {
case models.NameClassUUID:
id, err = uuid.Parse(name)
case models.NameClassUsername:
id, _, err = st.GetEntityIDByName(ctx, name)
case models.NameClassEmail:
id, _, err = st.GetEntityIDByEmail(ctx, name)
default:
err = fmt.Errorf("Unknown ID class %v", cls)
}
return
}
func GetEntityByAnyName(ctx context.Context, st Store, name string) (models.Entity, EntryMetadata, error) {
id, err := GetEntityIDByAnyName(ctx, st, name)
if err != nil {
return nil, EntryMetadata{}, err
}
return st.GetEntity(ctx, id)
}
func GetUser(ctx context.Context, st Store, id uuid.UUID) (*models.UserRecord, EntryMetadata, error) {
ent, md, err := st.GetEntity(ctx, id)
if err != nil || ent == nil {
return nil, md, err
} else if ent.Type() != models.TypeUser {
return nil, md, ErrNotUser
}
return ent.(*models.UserRecord), md, err
}
func GetGroup(ctx context.Context, st Store, id uuid.UUID) (*models.GroupRecord, EntryMetadata, error) {
ent, md, err := st.GetEntity(ctx, id)
if err != nil || ent == nil {
return nil, md, err
} else if ent.Type() != models.TypeGroup {
return nil, md, ErrNotGroup
}
return ent.(*models.GroupRecord), md, err
}