Change lisstoragebuilder to use inmemorystorage

This commit is contained in:
mcrakhman 2022-10-28 11:26:39 +02:00 committed by Mikhail Iudin
parent 481e2c52af
commit 5f6e51c15a
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
2 changed files with 101 additions and 131 deletions

View File

@ -9,8 +9,10 @@ import (
) )
type inMemoryACLListStorage struct { type inMemoryACLListStorage struct {
records []*aclrecordproto.RawACLRecordWithId
id string id string
root *aclrecordproto.RawACLRecordWithId
head string
records map[string]*aclrecordproto.RawACLRecordWithId
sync.RWMutex sync.RWMutex
} }
@ -18,48 +20,63 @@ type inMemoryACLListStorage struct {
func NewInMemoryACLListStorage( func NewInMemoryACLListStorage(
id string, id string,
records []*aclrecordproto.RawACLRecordWithId) (ListStorage, error) { records []*aclrecordproto.RawACLRecordWithId) (ListStorage, error) {
allRecords := make(map[string]*aclrecordproto.RawACLRecordWithId)
for _, ch := range records {
allRecords[ch.Id] = ch
}
root := records[0]
head := records[len(records)-1]
return &inMemoryACLListStorage{ return &inMemoryACLListStorage{
id: id, id: root.Id,
records: records, root: root,
head: head.Id,
records: allRecords,
RWMutex: sync.RWMutex{}, RWMutex: sync.RWMutex{},
}, nil }, nil
} }
func (i *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) { func (t *inMemoryACLListStorage) ID() string {
i.RLock() t.RLock()
defer i.RUnlock() defer t.RUnlock()
return i.records[0], nil return t.id
} }
func (i *inMemoryACLListStorage) SetHead(headId string) error { func (t *inMemoryACLListStorage) Root() (*aclrecordproto.RawACLRecordWithId, error) {
panic("implement me") t.RLock()
defer t.RUnlock()
return t.root, nil
} }
func (i *inMemoryACLListStorage) Head() (string, error) { func (t *inMemoryACLListStorage) Head() (string, error) {
i.RLock() t.RLock()
defer i.RUnlock() defer t.RUnlock()
return i.records[len(i.records)-1].Id, nil return t.head, nil
} }
func (i *inMemoryACLListStorage) GetRawRecord(ctx context.Context, id string) (*aclrecordproto.RawACLRecordWithId, error) { func (t *inMemoryACLListStorage) SetHead(head string) error {
i.RLock() t.Lock()
defer i.RUnlock() defer t.Unlock()
for _, rec := range i.records { t.head = head
if rec.Id == id { return nil
return rec, nil }
}
func (t *inMemoryACLListStorage) AddRawRecord(ctx context.Context, record *aclrecordproto.RawACLRecordWithId) error {
t.Lock()
defer t.Unlock()
// TODO: better to do deep copy
t.records[record.Id] = record
return nil
}
func (t *inMemoryACLListStorage) GetRawRecord(ctx context.Context, recordId string) (*aclrecordproto.RawACLRecordWithId, error) {
t.RLock()
defer t.RUnlock()
if res, exists := t.records[recordId]; exists {
return res, nil
} }
return nil, fmt.Errorf("no such record") return nil, fmt.Errorf("could not get record with id: %s", recordId)
}
func (i *inMemoryACLListStorage) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error {
panic("implement me")
}
func (i *inMemoryACLListStorage) ID() string {
i.RLock()
defer i.RUnlock()
return i.id
} }
type inMemoryTreeStorage struct { type inMemoryTreeStorage struct {

View File

@ -3,7 +3,7 @@ package acllistbuilder
import ( import (
"context" "context"
"fmt" "fmt"
aclrecordproto2 "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/storage"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/yamltests" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/testutils/yamltests"
"github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid" "github.com/anytypeio/go-anytype-infrastructure-experiments/common/util/cid"
@ -20,20 +20,12 @@ import (
) )
type ACLListStorageBuilder struct { type ACLListStorageBuilder struct {
aclList string storage.ListStorage
records []*aclrecordproto2.ACLRecord keychain *YAMLKeychain
rawRecords []*aclrecordproto2.RawACLRecordWithId
indexes map[string]int
keychain *YAMLKeychain
rawRoot *aclrecordproto2.RawACLRecordWithId
root *aclrecordproto2.ACLRoot
id string
} }
func NewACLListStorageBuilder(keychain *YAMLKeychain) *ACLListStorageBuilder { func NewACLListStorageBuilder(keychain *YAMLKeychain) *ACLListStorageBuilder {
return &ACLListStorageBuilder{ return &ACLListStorageBuilder{
records: make([]*aclrecordproto2.ACLRecord, 0),
indexes: make(map[string]int),
keychain: keychain, keychain: keychain,
} }
} }
@ -61,7 +53,7 @@ func NewACLListStorageBuilderFromFile(file string) (*ACLListStorageBuilder, erro
return tb, nil return tb, nil
} }
func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) *aclrecordproto2.RawACLRecordWithId { func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) *aclrecordproto.RawACLRecordWithId {
protoMarshalled, err := rec.Marshal() protoMarshalled, err := rec.Marshal()
if err != nil { if err != nil {
panic("should be able to marshal final acl message!") panic("should be able to marshal final acl message!")
@ -72,7 +64,7 @@ func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte)
panic("should be able to sign final acl message!") panic("should be able to sign final acl message!")
} }
rawRec := &aclrecordproto2.RawACLRecord{ rawRec := &aclrecordproto.RawACLRecord{
Payload: protoMarshalled, Payload: protoMarshalled,
Signature: signature, Signature: signature,
} }
@ -84,85 +76,53 @@ func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte)
id, _ := cid.NewCIDFromBytes(rawMarshalled) id, _ := cid.NewCIDFromBytes(rawMarshalled)
return &aclrecordproto2.RawACLRecordWithId{ return &aclrecordproto.RawACLRecordWithId{
Payload: rawMarshalled, Payload: rawMarshalled,
Id: id, Id: id,
} }
} }
func (t *ACLListStorageBuilder) Head() (string, error) {
l := len(t.records)
if l > 0 {
return t.rawRecords[l-1].Id, nil
}
return t.rawRoot.Id, nil
}
func (t *ACLListStorageBuilder) SetHead(headId string) error {
panic("SetHead is not implemented")
}
func (t *ACLListStorageBuilder) Root() (*aclrecordproto2.RawACLRecordWithId, error) {
return t.rawRoot, nil
}
func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*aclrecordproto2.RawACLRecordWithId, error) {
recIdx, ok := t.indexes[id]
if !ok {
if id == t.rawRoot.Id {
return t.rawRoot, nil
}
return nil, fmt.Errorf("no such record")
}
return t.rawRecords[recIdx], nil
}
func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclrecordproto2.RawACLRecordWithId) error {
panic("implement me")
}
func (t *ACLListStorageBuilder) ID() string {
return t.id
}
func (t *ACLListStorageBuilder) GetRawRecords() []*aclrecordproto2.RawACLRecordWithId {
return t.rawRecords
}
func (t *ACLListStorageBuilder) GetKeychain() *YAMLKeychain { func (t *ACLListStorageBuilder) GetKeychain() *YAMLKeychain {
return t.keychain return t.keychain
} }
func (t *ACLListStorageBuilder) Parse(tree *YMLList) { func (t *ACLListStorageBuilder) Parse(l *YMLList) {
// Just to clarify - we are generating new identities for the ones that // Just to clarify - we are generating new identities for the ones that
// are specified in the yml file, because our identities should be Ed25519 // are specified in the yml file, because our identities should be Ed25519
// the same thing is happening for the encryption keys // the same thing is happening for the encryption keys
t.keychain.ParseKeys(&tree.Keys) t.keychain.ParseKeys(&l.Keys)
t.parseRoot(tree.Root) rawRoot := t.parseRoot(l.Root)
prevId := t.id var err error
for idx, rec := range tree.Records { t.ListStorage, err = storage.NewInMemoryACLListStorage(rawRoot.Id, []*aclrecordproto.RawACLRecordWithId{rawRoot})
if err != nil {
panic(err)
}
prevId := rawRoot.Id
for _, rec := range l.Records {
newRecord := t.parseRecord(rec, prevId) newRecord := t.parseRecord(rec, prevId)
rawRecord := t.createRaw(newRecord, newRecord.Identity) rawRecord := t.createRaw(newRecord, newRecord.Identity)
t.records = append(t.records, newRecord) err = t.AddRawRecord(context.Background(), rawRecord)
t.rawRecords = append(t.rawRecords, rawRecord) if err != nil {
t.indexes[rawRecord.Id] = idx panic(err)
}
prevId = rawRecord.Id prevId = rawRecord.Id
} }
t.SetHead(prevId)
} }
func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclrecordproto2.ACLRecord { func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclrecordproto.ACLRecord {
k := t.keychain.GetKey(rec.ReadKey).(*SymKey) k := t.keychain.GetKey(rec.ReadKey).(*SymKey)
var aclChangeContents []*aclrecordproto2.ACLContentValue var aclChangeContents []*aclrecordproto.ACLContentValue
for _, ch := range rec.AclChanges { for _, ch := range rec.AclChanges {
aclChangeContent := t.parseACLChange(ch) aclChangeContent := t.parseACLChange(ch)
aclChangeContents = append(aclChangeContents, aclChangeContent) aclChangeContents = append(aclChangeContents, aclChangeContent)
} }
data := &aclrecordproto2.ACLData{ data := &aclrecordproto.ACLData{
AclContent: aclChangeContents, AclContent: aclChangeContents,
} }
bytes, _ := data.Marshal() bytes, _ := data.Marshal()
return &aclrecordproto2.ACLRecord{ return &aclrecordproto.ACLRecord{
PrevId: prevId, PrevId: prevId,
Identity: []byte(t.keychain.GetIdentity(rec.Identity)), Identity: []byte(t.keychain.GetIdentity(rec.Identity)),
Data: bytes, Data: bytes,
@ -171,7 +131,7 @@ func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclreco
} }
} }
func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecordproto2.ACLContentValue) { func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecordproto.ACLContentValue) {
switch { switch {
case ch.UserAdd != nil: case ch.UserAdd != nil:
add := ch.UserAdd add := ch.UserAdd
@ -179,9 +139,9 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
encKey := t.keychain.GetKey(add.EncryptionKey).(encryptionkey.PrivKey) encKey := t.keychain.GetKey(add.EncryptionKey).(encryptionkey.PrivKey)
rawKey, _ := encKey.GetPublic().Raw() rawKey, _ := encKey.GetPublic().Raw()
convCh = &aclrecordproto2.ACLContentValue{ convCh = &aclrecordproto.ACLContentValue{
Value: &aclrecordproto2.ACLContentValue_UserAdd{ Value: &aclrecordproto.ACLContentValue_UserAdd{
UserAdd: &aclrecordproto2.ACLUserAdd{ UserAdd: &aclrecordproto.ACLUserAdd{
Identity: []byte(t.keychain.GetIdentity(add.Identity)), Identity: []byte(t.keychain.GetIdentity(add.Identity)),
EncryptionKey: rawKey, EncryptionKey: rawKey,
EncryptedReadKeys: t.encryptReadKeysWithPubKey(add.EncryptedReadKeys, encKey), EncryptedReadKeys: t.encryptReadKeysWithPubKey(add.EncryptedReadKeys, encKey),
@ -203,9 +163,9 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
} }
acceptPubKey, _ := signKey.GetPublic().Raw() acceptPubKey, _ := signKey.GetPublic().Raw()
convCh = &aclrecordproto2.ACLContentValue{ convCh = &aclrecordproto.ACLContentValue{
Value: &aclrecordproto2.ACLContentValue_UserJoin{ Value: &aclrecordproto.ACLContentValue_UserJoin{
UserJoin: &aclrecordproto2.ACLUserJoin{ UserJoin: &aclrecordproto.ACLUserJoin{
Identity: []byte(t.keychain.GetIdentity(join.Identity)), Identity: []byte(t.keychain.GetIdentity(join.Identity)),
EncryptionKey: rawKey, EncryptionKey: rawKey,
AcceptSignature: signature, AcceptSignature: signature,
@ -220,9 +180,9 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
hash := t.keychain.GetKey(invite.EncryptionKey).(*SymKey).Hash hash := t.keychain.GetKey(invite.EncryptionKey).(*SymKey).Hash
encKey := t.keychain.ReadKeysByHash[hash] encKey := t.keychain.ReadKeysByHash[hash]
convCh = &aclrecordproto2.ACLContentValue{ convCh = &aclrecordproto.ACLContentValue{
Value: &aclrecordproto2.ACLContentValue_UserInvite{ Value: &aclrecordproto.ACLContentValue_UserInvite{
UserInvite: &aclrecordproto2.ACLUserInvite{ UserInvite: &aclrecordproto.ACLUserInvite{
AcceptPublicKey: rawAcceptKey, AcceptPublicKey: rawAcceptKey,
EncryptSymKeyHash: hash, EncryptSymKeyHash: hash,
EncryptedReadKeys: t.encryptReadKeysWithSymKey(invite.EncryptedReadKeys, encKey.Key), EncryptedReadKeys: t.encryptReadKeysWithSymKey(invite.EncryptedReadKeys, encKey.Key),
@ -233,9 +193,9 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
case ch.UserPermissionChange != nil: case ch.UserPermissionChange != nil:
permissionChange := ch.UserPermissionChange permissionChange := ch.UserPermissionChange
convCh = &aclrecordproto2.ACLContentValue{ convCh = &aclrecordproto.ACLContentValue{
Value: &aclrecordproto2.ACLContentValue_UserPermissionChange{ Value: &aclrecordproto.ACLContentValue_UserPermissionChange{
UserPermissionChange: &aclrecordproto2.ACLUserPermissionChange{ UserPermissionChange: &aclrecordproto.ACLUserPermissionChange{
Identity: []byte(t.keychain.GetIdentity(permissionChange.Identity)), Identity: []byte(t.keychain.GetIdentity(permissionChange.Identity)),
Permissions: t.convertPermission(permissionChange.Permission), Permissions: t.convertPermission(permissionChange.Permission),
}, },
@ -246,7 +206,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
newReadKey := t.keychain.GetKey(remove.NewReadKey).(*SymKey) newReadKey := t.keychain.GetKey(remove.NewReadKey).(*SymKey)
var replaces []*aclrecordproto2.ACLReadKeyReplace var replaces []*aclrecordproto.ACLReadKeyReplace
for _, id := range remove.IdentitiesLeft { for _, id := range remove.IdentitiesLeft {
encKey := t.keychain.EncryptionKeysByYAMLIdentity[id] encKey := t.keychain.EncryptionKeysByYAMLIdentity[id]
rawEncKey, _ := encKey.GetPublic().Raw() rawEncKey, _ := encKey.GetPublic().Raw()
@ -254,16 +214,16 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord
if err != nil { if err != nil {
panic(err) panic(err)
} }
replaces = append(replaces, &aclrecordproto2.ACLReadKeyReplace{ replaces = append(replaces, &aclrecordproto.ACLReadKeyReplace{
Identity: []byte(t.keychain.GetIdentity(id)), Identity: []byte(t.keychain.GetIdentity(id)),
EncryptionKey: rawEncKey, EncryptionKey: rawEncKey,
EncryptedReadKey: encReadKey, EncryptedReadKey: encReadKey,
}) })
} }
convCh = &aclrecordproto2.ACLContentValue{ convCh = &aclrecordproto.ACLContentValue{
Value: &aclrecordproto2.ACLContentValue_UserRemove{ Value: &aclrecordproto.ACLContentValue_UserRemove{
UserRemove: &aclrecordproto2.ACLUserRemove{ UserRemove: &aclrecordproto.ACLUserRemove{
Identity: []byte(t.keychain.GetIdentity(remove.RemovedIdentity)), Identity: []byte(t.keychain.GetIdentity(remove.RemovedIdentity)),
ReadKeyReplaces: replaces, ReadKeyReplaces: replaces,
}, },
@ -303,36 +263,30 @@ func (t *ACLListStorageBuilder) encryptReadKeysWithSymKey(keys []string, key *sy
return return
} }
func (t *ACLListStorageBuilder) convertPermission(perm string) aclrecordproto2.ACLUserPermissions { func (t *ACLListStorageBuilder) convertPermission(perm string) aclrecordproto.ACLUserPermissions {
switch perm { switch perm {
case "admin": case "admin":
return aclrecordproto2.ACLUserPermissions_Admin return aclrecordproto.ACLUserPermissions_Admin
case "writer": case "writer":
return aclrecordproto2.ACLUserPermissions_Writer return aclrecordproto.ACLUserPermissions_Writer
case "reader": case "reader":
return aclrecordproto2.ACLUserPermissions_Reader return aclrecordproto.ACLUserPermissions_Reader
default: default:
panic(fmt.Sprintf("incorrect permission: %s", perm)) panic(fmt.Sprintf("incorrect permission: %s", perm))
} }
} }
func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclrecordproto2.ACLRecord, id string) error) (err error) { func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclrecordproto.ACLRecord, id string) error) (err error) {
for i := len(t.records) - 1; i >= 0; i-- { panic("this was removed, add if needed")
err = f(t.records[i], t.rawRecords[i].Id)
if err != nil {
return err
}
}
return nil
} }
func (t *ACLListStorageBuilder) parseRoot(root *Root) { func (t *ACLListStorageBuilder) parseRoot(root *Root) (rawRoot *aclrecordproto.RawACLRecordWithId) {
rawSignKey, _ := t.keychain.SigningKeysByYAMLIdentity[root.Identity].GetPublic().Raw() rawSignKey, _ := t.keychain.SigningKeysByYAMLIdentity[root.Identity].GetPublic().Raw()
rawEncKey, _ := t.keychain.EncryptionKeysByYAMLIdentity[root.Identity].GetPublic().Raw() rawEncKey, _ := t.keychain.EncryptionKeysByYAMLIdentity[root.Identity].GetPublic().Raw()
readKey, _ := aclrecordproto2.ACLReadKeyDerive(rawSignKey, rawEncKey) readKey, _ := aclrecordproto.ACLReadKeyDerive(rawSignKey, rawEncKey)
hasher := fnv.New64() hasher := fnv.New64()
hasher.Write(readKey.Bytes()) hasher.Write(readKey.Bytes())
t.root = &aclrecordproto2.ACLRoot{ aclRoot := &aclrecordproto.ACLRoot{
Identity: rawSignKey, Identity: rawSignKey,
EncryptionKey: rawEncKey, EncryptionKey: rawEncKey,
SpaceId: root.SpaceId, SpaceId: root.SpaceId,
@ -340,6 +294,5 @@ func (t *ACLListStorageBuilder) parseRoot(root *Root) {
DerivationScheme: "scheme", DerivationScheme: "scheme",
CurrentReadKeyHash: hasher.Sum64(), CurrentReadKeyHash: hasher.Sum64(),
} }
t.rawRoot = t.createRaw(t.root, rawSignKey) return t.createRaw(aclRoot, rawSignKey)
t.id = t.rawRoot.Id
} }