forked from authentricity/authentricity
94 lines
2.7 KiB
Go
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
|
|
}
|