diff --git a/pkg/acl/list/aclstate.go b/pkg/acl/list/aclstate.go index 7caf345a..a8df8c53 100644 --- a/pkg/acl/list/aclstate.go +++ b/pkg/acl/list/aclstate.go @@ -7,7 +7,6 @@ import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/app/logger" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/aclrecordproto" "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/common" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/symmetric" @@ -50,6 +49,7 @@ type ACLState struct { } func newACLStateWithKeys( + id string, signingKey signingkey.PrivKey, encryptionKey encryptionkey.PrivKey) (*ACLState, error) { identity, err := signingKey.Raw() @@ -57,6 +57,7 @@ func newACLStateWithKeys( return nil, err } return &ACLState{ + id: id, identity: string(identity), signingKey: signingKey, encryptionKey: encryptionKey, @@ -67,8 +68,9 @@ func newACLStateWithKeys( }, nil } -func newACLState(decoder keys.Decoder) *ACLState { +func newACLState(id string) *ACLState { return &ACLState{ + id: id, userReadKeys: make(map[uint64]*symmetric.Key), userStates: make(map[string]*aclrecordproto.ACLUserState), userInvites: make(map[string]*aclrecordproto.ACLUserInvite), diff --git a/pkg/acl/list/aclstatebuilder.go b/pkg/acl/list/aclstatebuilder.go index 2d7693fb..75b606af 100644 --- a/pkg/acl/list/aclstatebuilder.go +++ b/pkg/acl/list/aclstatebuilder.go @@ -2,7 +2,6 @@ package list import ( "github.com/anytypeio/go-anytype-infrastructure-experiments/pkg/acl/account" - "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/encryptionkey" "github.com/anytypeio/go-anytype-infrastructure-experiments/util/keys/asymmetric/signingkey" ) @@ -10,31 +9,32 @@ import ( type aclStateBuilder struct { signPrivKey signingkey.PrivKey encPrivKey encryptionkey.PrivKey - decoder keys.Decoder + id string } -func newACLStateBuilderWithIdentity(decoder keys.Decoder, accountData *account.AccountData) *aclStateBuilder { +func newACLStateBuilderWithIdentity(accountData *account.AccountData) *aclStateBuilder { return &aclStateBuilder{ - decoder: decoder, signPrivKey: accountData.SignKey, encPrivKey: accountData.EncKey, } } -func newACLStateBuilder(decoder keys.Decoder) *aclStateBuilder { - return &aclStateBuilder{ - decoder: decoder, - } +func newACLStateBuilder() *aclStateBuilder { + return &aclStateBuilder{} +} + +func (sb *aclStateBuilder) Init(id string) { + sb.id = id } func (sb *aclStateBuilder) Build(records []*ACLRecord) (state *ACLState, err error) { if sb.encPrivKey != nil && sb.signPrivKey != nil { - state, err = newACLStateWithKeys(sb.signPrivKey, sb.encPrivKey) + state, err = newACLStateWithKeys(sb.id, sb.signPrivKey, sb.encPrivKey) if err != nil { return } } else { - state = newACLState(sb.decoder) + state = newACLState(sb.id) } for _, rec := range records { err = state.applyRecord(rec) diff --git a/pkg/acl/list/list.go b/pkg/acl/list/list.go index aad93a8f..f940e4b4 100644 --- a/pkg/acl/list/list.go +++ b/pkg/acl/list/list.go @@ -54,7 +54,7 @@ func BuildACLListWithIdentity(acc *account.AccountData, storage storage.ListStor if err != nil { return nil, err } - builder := newACLStateBuilderWithIdentity(acc.Decoder, acc) + builder := newACLStateBuilderWithIdentity(acc) return build(id, builder, newACLRecordBuilder(id, common.NewKeychain()), storage) } @@ -63,7 +63,7 @@ func BuildACLList(decoder keys.Decoder, storage storage.ListStorage) (ACLList, e if err != nil { return nil, err } - return build(id, newACLStateBuilder(decoder), newACLRecordBuilder(id, common.NewKeychain()), storage) + return build(id, newACLStateBuilder(), newACLRecordBuilder(id, common.NewKeychain()), storage) } func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder, storage storage.ListStorage) (list ACLList, err error) { @@ -87,7 +87,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder } records := []*ACLRecord{record} - for record.PrevId != "" { + for record.PrevId != "" && record.PrevId != id { rawRecordWithId, err = storage.GetRawRecord(context.Background(), record.PrevId) if err != nil { return @@ -99,6 +99,8 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder } records = append(records, record) } + // adding root in the end, because we already parsed it + records = append(records, aclRecRoot) indexes := make(map[string]int) for i, j := 0, len(records)-1; i < j; i, j = i+1, j-1 { @@ -111,6 +113,7 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder indexes[records[len(records)/2].Id] = len(records) / 2 } + stateBuilder.Init(id) state, err := stateBuilder.Build(records) if err != nil { return diff --git a/pkg/acl/testutils/acllistbuilder/keychain.go b/pkg/acl/testutils/acllistbuilder/keychain.go index 0a32293e..e26f389b 100644 --- a/pkg/acl/testutils/acllistbuilder/keychain.go +++ b/pkg/acl/testutils/acllistbuilder/keychain.go @@ -15,30 +15,30 @@ type SymKey struct { Key *symmetric.Key } -type Keychain struct { - SigningKeys map[string]signingkey.PrivKey - SigningKeysByIdentity map[string]signingkey.PrivKey - EncryptionKeys map[string]encryptionkey.PrivKey - ReadKeys map[string]*SymKey - ReadKeysByHash map[uint64]*SymKey - GeneratedIdentities map[string]string - DerivedIdentity string - coder signingkey.PubKeyDecoder +type YAMLKeychain struct { + SigningKeysByYAMLIdentity map[string]signingkey.PrivKey + SigningKeysByRealIdentity map[string]signingkey.PrivKey + EncryptionKeysByYAMLIdentity map[string]encryptionkey.PrivKey + ReadKeysByYAMLIdentity map[string]*SymKey + ReadKeysByHash map[uint64]*SymKey + GeneratedIdentities map[string]string + DerivedIdentity string + coder signingkey.PubKeyDecoder } -func NewKeychain() *Keychain { - return &Keychain{ - SigningKeys: map[string]signingkey.PrivKey{}, - SigningKeysByIdentity: map[string]signingkey.PrivKey{}, - EncryptionKeys: map[string]encryptionkey.PrivKey{}, - GeneratedIdentities: map[string]string{}, - ReadKeys: map[string]*SymKey{}, - ReadKeysByHash: map[uint64]*SymKey{}, - coder: signingkey.NewEd25519PubKeyDecoder(), +func NewKeychain() *YAMLKeychain { + return &YAMLKeychain{ + SigningKeysByYAMLIdentity: map[string]signingkey.PrivKey{}, + SigningKeysByRealIdentity: map[string]signingkey.PrivKey{}, + EncryptionKeysByYAMLIdentity: map[string]encryptionkey.PrivKey{}, + GeneratedIdentities: map[string]string{}, + ReadKeysByYAMLIdentity: map[string]*SymKey{}, + ReadKeysByHash: map[uint64]*SymKey{}, + coder: signingkey.NewEd25519PubKeyDecoder(), } } -func (k *Keychain) ParseKeys(keys *Keys) { +func (k *YAMLKeychain) ParseKeys(keys *Keys) { k.DerivedIdentity = keys.Derived for _, encKey := range keys.Enc { k.AddEncryptionKey(encKey) @@ -53,8 +53,8 @@ func (k *Keychain) ParseKeys(keys *Keys) { } } -func (k *Keychain) AddEncryptionKey(key *Key) { - if _, exists := k.EncryptionKeys[key.Name]; exists { +func (k *YAMLKeychain) AddEncryptionKey(key *Key) { + if _, exists := k.EncryptionKeysByYAMLIdentity[key.Name]; exists { return } var ( @@ -74,11 +74,11 @@ func (k *Keychain) AddEncryptionKey(key *Key) { } newPrivKey = privKey.(encryptionkey.PrivKey) } - k.EncryptionKeys[key.Name] = newPrivKey + k.EncryptionKeysByYAMLIdentity[key.Name] = newPrivKey } -func (k *Keychain) AddSigningKey(key *Key) { - if _, exists := k.SigningKeys[key.Name]; exists { +func (k *YAMLKeychain) AddSigningKey(key *Key) { + if _, exists := k.SigningKeysByYAMLIdentity[key.Name]; exists { return } var ( @@ -101,19 +101,19 @@ func (k *Keychain) AddSigningKey(key *Key) { pubKey = newPrivKey.GetPublic() } - k.SigningKeys[key.Name] = newPrivKey + k.SigningKeysByYAMLIdentity[key.Name] = newPrivKey rawPubKey, err := pubKey.Raw() if err != nil { panic(err) } encoded := string(rawPubKey) - k.SigningKeysByIdentity[encoded] = newPrivKey + k.SigningKeysByRealIdentity[encoded] = newPrivKey k.GeneratedIdentities[key.Name] = encoded } -func (k *Keychain) AddReadKey(key *Key) { - if _, exists := k.ReadKeys[key.Name]; exists { +func (k *YAMLKeychain) AddReadKey(key *Key) { + if _, exists := k.ReadKeysByYAMLIdentity[key.Name]; exists { return } @@ -127,8 +127,8 @@ func (k *Keychain) AddReadKey(key *Key) { panic("should be able to generate symmetric key") } } else if key.Value == "derived" { - signKey, _ := k.SigningKeys[k.DerivedIdentity].Raw() - encKey, _ := k.EncryptionKeys[k.DerivedIdentity].Raw() + signKey, _ := k.SigningKeysByYAMLIdentity[k.DerivedIdentity].Raw() + encKey, _ := k.EncryptionKeysByYAMLIdentity[k.DerivedIdentity].Raw() rkey, err = aclrecordproto.ACLReadKeyDerive(signKey, encKey) if err != nil { panic("should be able to derive symmetric key") @@ -143,7 +143,7 @@ func (k *Keychain) AddReadKey(key *Key) { hasher := fnv.New64() hasher.Write(rkey.Bytes()) - k.ReadKeys[key.Name] = &SymKey{ + k.ReadKeysByYAMLIdentity[key.Name] = &SymKey{ Hash: hasher.Sum64(), Key: rkey, } @@ -153,7 +153,7 @@ func (k *Keychain) AddReadKey(key *Key) { } } -func (k *Keychain) AddKey(key *Key) { +func (k *YAMLKeychain) AddKey(key *Key) { parts := strings.Split(key.Name, ".") if len(parts) != 3 { panic("cannot parse a key") @@ -171,7 +171,7 @@ func (k *Keychain) AddKey(key *Key) { } } -func (k *Keychain) GetKey(key string) interface{} { +func (k *YAMLKeychain) GetKey(key string) interface{} { parts := strings.Split(key, ".") if len(parts) != 3 { panic("cannot parse a key") @@ -180,15 +180,15 @@ func (k *Keychain) GetKey(key string) interface{} { switch parts[1] { case "Sign": - if key, exists := k.SigningKeys[name]; exists { + if key, exists := k.SigningKeysByYAMLIdentity[name]; exists { return key } case "Enc": - if key, exists := k.EncryptionKeys[name]; exists { + if key, exists := k.EncryptionKeysByYAMLIdentity[name]; exists { return key } case "Read": - if key, exists := k.ReadKeys[name]; exists { + if key, exists := k.ReadKeysByYAMLIdentity[name]; exists { return key } default: @@ -197,6 +197,6 @@ func (k *Keychain) GetKey(key string) interface{} { return nil } -func (k *Keychain) GetIdentity(name string) string { +func (k *YAMLKeychain) GetIdentity(name string) string { return k.GeneratedIdentities[name] } diff --git a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go index ca1b1649..d855ac99 100644 --- a/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go +++ b/pkg/acl/testutils/acllistbuilder/liststoragebuilder.go @@ -23,13 +23,13 @@ type ACLListStorageBuilder struct { records []*aclrecordproto.ACLRecord rawRecords []*aclrecordproto.RawACLRecordWithId indexes map[string]int - keychain *Keychain + keychain *YAMLKeychain rawRoot *aclrecordproto.RawACLRecordWithId root *aclrecordproto.ACLRoot id string } -func NewACLListStorageBuilder(keychain *Keychain) *ACLListStorageBuilder { +func NewACLListStorageBuilder(keychain *YAMLKeychain) *ACLListStorageBuilder { return &ACLListStorageBuilder{ records: make([]*aclrecordproto.ACLRecord, 0), indexes: make(map[string]int), @@ -66,7 +66,7 @@ func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) panic("should be able to marshal final acl message!") } - signature, err := t.keychain.SigningKeysByIdentity[string(identity)].Sign(protoMarshalled) + signature, err := t.keychain.SigningKeysByRealIdentity[string(identity)].Sign(protoMarshalled) if err != nil { panic("should be able to sign final acl message!") } @@ -89,17 +89,10 @@ func (t *ACLListStorageBuilder) createRaw(rec proto.Marshaler, identity []byte) } } -func (t *ACLListStorageBuilder) getRecord(idx int) *aclrecordproto.RawACLRecordWithId { - if idx > 0 { - return t.rawRecords[idx-1] - } - return t.rawRoot -} - func (t *ACLListStorageBuilder) Head() (*aclrecordproto.RawACLRecordWithId, error) { l := len(t.records) - if l > 1 { - return t.rawRecords[l-2], nil + if l > 0 { + return t.rawRecords[l-1], nil } return t.rawRoot, nil } @@ -116,7 +109,7 @@ func (t *ACLListStorageBuilder) GetRawRecord(ctx context.Context, id string) (*a } return nil, fmt.Errorf("no such record") } - return t.getRecord(recIdx), nil + return t.rawRecords[recIdx], nil } func (t *ACLListStorageBuilder) AddRawRecord(ctx context.Context, rec *aclrecordproto.RawACLRecordWithId) error { @@ -131,7 +124,7 @@ func (t *ACLListStorageBuilder) GetRawRecords() []*aclrecordproto.RawACLRecordWi return t.rawRecords } -func (t *ACLListStorageBuilder) GetKeychain() *Keychain { +func (t *ACLListStorageBuilder) GetKeychain() *YAMLKeychain { return t.keychain } @@ -140,7 +133,8 @@ func (t *ACLListStorageBuilder) Parse(tree *YMLList) { // are specified in the yml file, because our identities should be Ed25519 // the same thing is happening for the encryption keys t.keychain.ParseKeys(&tree.Keys) - prevId := "" + t.parseRoot(tree.Root) + prevId := t.id for idx, rec := range tree.Records { newRecord := t.parseRecord(rec, prevId) rawRecord := t.createRaw(newRecord, newRecord.Identity) @@ -149,8 +143,6 @@ func (t *ACLListStorageBuilder) Parse(tree *YMLList) { t.indexes[rawRecord.Id] = idx prevId = rawRecord.Id } - - t.parseRoot(tree.Root) } func (t *ACLListStorageBuilder) parseRecord(rec *Record, prevId string) *aclrecordproto.ACLRecord { @@ -199,7 +191,7 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord GetKey(join.EncryptionKey).(encryptionkey.PrivKey) rawKey, _ := encKey.GetPublic().Raw() - idKey, _ := t.keychain.SigningKeys[join.Identity].GetPublic().Raw() + idKey, _ := t.keychain.SigningKeysByYAMLIdentity[join.Identity].GetPublic().Raw() signKey := t.keychain.GetKey(join.AcceptSignature).(signingkey.PrivKey) signature, err := signKey.Sign(idKey) if err != nil { @@ -253,15 +245,14 @@ func (t *ACLListStorageBuilder) parseACLChange(ch *ACLChange) (convCh *aclrecord var replaces []*aclrecordproto.ACLReadKeyReplace for _, id := range remove.IdentitiesLeft { - identity := t.keychain.GetIdentity(id) - encKey := t.keychain.EncryptionKeys[id] + encKey := t.keychain.EncryptionKeysByYAMLIdentity[id] rawEncKey, _ := encKey.GetPublic().Raw() encReadKey, err := encKey.GetPublic().Encrypt(newReadKey.Key.Bytes()) if err != nil { panic(err) } replaces = append(replaces, &aclrecordproto.ACLReadKeyReplace{ - Identity: []byte(identity), + Identity: []byte(t.keychain.GetIdentity(id)), EncryptionKey: rawEncKey, EncryptedReadKey: encReadKey, }) @@ -320,8 +311,8 @@ func (t *ACLListStorageBuilder) traverseFromHead(f func(rec *aclrecordproto.ACLR } func (t *ACLListStorageBuilder) parseRoot(root *Root) { - rawSignKey, _ := t.keychain.GetKey(root.Identity).(signingkey.PrivKey).GetPublic().Raw() - rawEncKey, _ := t.keychain.GetKey(root.EncryptionKey).(encryptionkey.PrivKey).GetPublic().Raw() + rawSignKey, _ := t.keychain.SigningKeysByYAMLIdentity[root.Identity].GetPublic().Raw() + rawEncKey, _ := t.keychain.EncryptionKeysByYAMLIdentity[root.Identity].GetPublic().Raw() readKey, _ := aclrecordproto.ACLReadKeyDerive(rawSignKey, rawEncKey) hasher := fnv.New64() hasher.Write(readKey.Bytes()) @@ -334,7 +325,5 @@ func (t *ACLListStorageBuilder) parseRoot(root *Root) { CurrentReadKeyHash: hasher.Sum64(), } t.rawRoot = t.createRaw(t.root, rawSignKey) - bytes, _ := t.rawRoot.Marshal() - id, _ := cid.NewCIDFromBytes(bytes) - t.id = id + t.id = t.rawRoot.Id } diff --git a/pkg/acl/testutils/acllistbuilder/ymlentities.go b/pkg/acl/testutils/acllistbuilder/ymlentities.go index 2b77c698..df1e43c6 100644 --- a/pkg/acl/testutils/acllistbuilder/ymlentities.go +++ b/pkg/acl/testutils/acllistbuilder/ymlentities.go @@ -60,9 +60,8 @@ type Header struct { } type Root struct { - Identity string `yaml:"identity"` - EncryptionKey string `yaml:"encryptionKey"` - SpaceId string `yaml:"spaceId"` + Identity string `yaml:"identity"` + SpaceId string `yaml:"spaceId"` } type YMLList struct { diff --git a/pkg/acl/testutils/yamltests/userjoinexample.yml b/pkg/acl/testutils/yamltests/userjoinexample.yml index 45abf458..6d7bb48e 100644 --- a/pkg/acl/testutils/yamltests/userjoinexample.yml +++ b/pkg/acl/testutils/yamltests/userjoinexample.yml @@ -1,7 +1,6 @@ root: - - identity: A - encryptionKey: key.Enc.A - spaceId: space + identity: A + spaceId: space records: - identity: A aclChanges: diff --git a/pkg/acl/testutils/yamltests/userremoveexample.yml b/pkg/acl/testutils/yamltests/userremoveexample.yml index 39a30f25..6cf51b84 100644 --- a/pkg/acl/testutils/yamltests/userremoveexample.yml +++ b/pkg/acl/testutils/yamltests/userremoveexample.yml @@ -1,7 +1,6 @@ root: - - identity: A - encryptionKey: key.Enc.A - spaceId: space + identity: A + spaceId: space records: - identity: A aclChanges: