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

97 lines
1.7 KiB
Go

package models
import (
"encoding/json"
"errors"
"github.com/google/uuid"
"github.com/mitchellh/mapstructure"
)
func decode(src, dst interface{}) error {
d, err := mapstructure.NewDecoder(&mapstructure.DecoderConfig{
DecodeHook: mapstructure.TextUnmarshallerHookFunc(),
Result: dst,
})
if err != nil {
return err
}
return d.Decode(src)
}
type EntityType string
const (
TypeUser EntityType = "user"
TypeGroup EntityType = "group"
)
type Entity interface {
ID() uuid.UUID
SetID(uuid.UUID)
Type() EntityType
Name() string
Email() string
StripPrivileged()
}
type UnknownEntity struct {
UUID uuid.UUID `mapstructure:"uuid"`
EntityType EntityType `mapstructure:"-"`
Other map[string]interface{} `mapstructure:",remain"`
}
func (ue *UnknownEntity) ID() uuid.UUID {
return ue.UUID
}
func (ue *UnknownEntity) SetID(id uuid.UUID) {
ue.UUID = id
}
func (ue *UnknownEntity) Type() EntityType {
return ue.EntityType
}
func (ue *UnknownEntity) Name() string {
return ""
}
func (ue *UnknownEntity) Email() string {
return ""
}
func (ue *UnknownEntity) StripPrivileged() {
delete(ue.Other, "privileged")
}
func NewEntityOfType(t EntityType) Entity {
switch t {
case TypeUser:
return new(UserRecord)
case TypeGroup:
return new(GroupRecord)
default:
return &UnknownEntity{
EntityType: t,
}
}
}
func ParseEntityJSON(buf []byte) (Entity, error) {
m := make(map[string]interface{})
if err := json.Unmarshal(buf, &m); err != nil {
return nil, err
}
t, ok := m["@type"].(string)
if !ok {
return nil, errors.New("Entity lacks @type")
}
ent := NewEntityOfType(EntityType(t))
delete(m, "@type")
return ent, decode(m, ent)
}