graphvent/user.go

142 lines
2.8 KiB
Go

2023-07-20 22:08:28 -06:00
package graphvent
import (
"time"
"fmt"
"encoding/json"
"crypto/ecdsa"
"crypto/x509"
)
2023-07-25 09:51:55 -06:00
type GroupNode interface {
Node
Users() map[NodeID]*User
}
2023-07-20 22:08:28 -06:00
type User struct {
2023-07-24 16:04:56 -06:00
Lockable
2023-07-20 22:08:28 -06:00
Granted time.Time
Pubkey *ecdsa.PublicKey
Shared []byte
2023-07-21 13:33:04 -06:00
Tags []string
2023-07-20 22:08:28 -06:00
}
type UserJSON struct {
2023-07-24 16:04:56 -06:00
LockableJSON
2023-07-20 22:08:28 -06:00
Granted time.Time `json:"granted"`
Pubkey []byte `json:"pubkey"`
Shared []byte `json:"shared"`
}
func (user *User) Type() NodeType {
2023-07-20 22:08:45 -06:00
return NodeType("user")
2023-07-20 22:08:28 -06:00
}
func (user *User) Serialize() ([]byte, error) {
2023-07-24 16:04:56 -06:00
lockable_json := NewLockableJSON(&user.Lockable)
2023-07-20 22:08:28 -06:00
pubkey, err := x509.MarshalPKIXPublicKey(user.Pubkey)
if err != nil {
return nil, err
}
return json.MarshalIndent(&UserJSON{
2023-07-24 16:04:56 -06:00
LockableJSON: lockable_json,
2023-07-20 22:08:28 -06:00
Granted: user.Granted,
Shared: user.Shared,
Pubkey: pubkey,
}, "", " ")
}
2023-07-25 09:51:55 -06:00
var LoadUser = LoadJSONNode(func(id NodeID, j UserJSON) (Node, error) {
2023-07-20 22:08:28 -06:00
pub, err := x509.ParsePKIXPublicKey(j.Pubkey)
if err != nil {
return nil, err
}
var pubkey *ecdsa.PublicKey
switch pub.(type) {
case *ecdsa.PublicKey:
pubkey = pub.(*ecdsa.PublicKey)
default:
return nil, fmt.Errorf("Invalid key type")
}
2023-07-24 22:52:15 -06:00
user := NewUser(j.Name, j.Granted, pubkey, j.Shared)
2023-07-20 22:08:28 -06:00
return &user, nil
2023-07-25 09:51:55 -06:00
}, func(ctx *Context, user *User, j UserJSON, nodes NodeMap) error {
return RestoreLockable(ctx, user, j.LockableJSON, nodes)
})
2023-07-20 22:08:28 -06:00
2023-07-24 22:52:15 -06:00
func NewUser(name string, granted time.Time, pubkey *ecdsa.PublicKey, shared []byte) User {
2023-07-20 22:08:28 -06:00
id := KeyID(pubkey)
return User{
2023-07-24 16:04:56 -06:00
Lockable: NewLockable(id, name),
2023-07-20 22:08:28 -06:00
Granted: granted,
Pubkey: pubkey,
Shared: shared,
}
}
2023-07-25 09:51:55 -06:00
type Group struct {
Lockable
UserMap map[NodeID]*User
}
func NewGroup(id NodeID, name string) Group {
return Group{
Lockable: NewLockable(id, name),
UserMap: map[NodeID]*User{},
}
}
type GroupJSON struct {
LockableJSON
Users []string `json:"users"`
}
func (group *Group) Type() NodeType {
return NodeType("group")
}
func (group *Group) Serialize() ([]byte, error) {
users := make([]string, len(group.UserMap))
i := 0
for id, _ := range(group.UserMap) {
users[i] = id.String()
i += 1
}
return json.MarshalIndent(&GroupJSON{
LockableJSON: NewLockableJSON(&group.Lockable),
Users: users,
}, "", " ")
}
var LoadGroup = LoadJSONNode(func(id NodeID, j GroupJSON) (Node, error) {
group := NewGroup(id, j.Name)
return &group, nil
}, func(ctx *Context, group *Group, j GroupJSON, nodes NodeMap) error {
for _, id_str := range(j.Users) {
id, err := ParseID(id_str)
if err != nil {
return err
}
user_node, err := LoadNodeRecurse(ctx, id, nodes)
if err != nil {
return err
}
user, ok := user_node.(*User)
if ok == false {
return fmt.Errorf("%s is not a *User", id_str)
}
group.UserMap[id] = user
}
return RestoreLockable(ctx, group, j.LockableJSON, nodes)
})