1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 05:57:03 +09:00

Rewrite batch requests

This commit is contained in:
Mikhail Rakhmanov 2025-05-11 14:32:15 +02:00
parent 79d0352d6d
commit a8699f38f9
No known key found for this signature in database
GPG key ID: DED12CFEF5B8396B
3 changed files with 60 additions and 62 deletions

View file

@ -113,8 +113,15 @@ func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountd
func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRec *consensusproto.RawRecord, err error) {
var aclContent []*aclrecordproto.AclContentValue
if len(payload.Removals.Identities) > 0 {
content, err := a.buildAccountRemove(payload.Removals)
if err != nil {
return nil, err
}
aclContent = append(aclContent, content)
}
if len(payload.Additions) > 0 {
content, err := a.buildAccountsAdd(AccountsAddPayload{Additions: payload.Additions})
content, err := a.buildAccountsAdd(AccountsAddPayload{Additions: payload.Additions}, payload.Removals.Change.MetadataKey.GetPublic(), payload.Removals.Change.ReadKey)
if err != nil {
return nil, err
}
@ -128,7 +135,7 @@ func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRe
aclContent = append(aclContent, content)
}
for _, acc := range payload.Approvals {
content, err := a.buildRequestAccept(acc)
content, err := a.buildRequestAccept(acc, payload.Removals.Change.ReadKey)
if err != nil {
return nil, err
}
@ -148,13 +155,6 @@ func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRe
}
aclContent = append(aclContent, content)
}
if len(payload.Removals.Identities) > 0 {
content, err := a.buildAccountRemove(payload.Removals)
if err != nil {
return nil, err
}
aclContent = append(aclContent, content)
}
return a.buildRecords(aclContent)
}
@ -231,14 +231,14 @@ func (a *aclRecordBuilder) buildPermissionChanges(payload PermissionChangesPaylo
}
func (a *aclRecordBuilder) BuildAccountsAdd(payload AccountsAddPayload) (rawRecord *consensusproto.RawRecord, err error) {
content, err := a.buildAccountsAdd(payload)
content, err := a.buildAccountsAdd(payload, nil, nil)
if err != nil {
return
}
return a.buildRecord(content)
}
func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *aclrecordproto.AclContentValue, err error) {
func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload, mkKey crypto.PubKey, readKey crypto.SymKey) (value *aclrecordproto.AclContentValue, err error) {
var accs []*aclrecordproto.AclAccountAdd
for _, acc := range payload.Additions {
if !a.state.Permissions(acc.Identity).NoPermissions() {
@ -247,9 +247,11 @@ func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *
if acc.Permissions.IsOwner() {
return nil, ErrIsOwner
}
mkKey, err := a.state.CurrentMetadataKey()
if err != nil {
return nil, err
if mkKey == nil {
mkKey, err = a.state.CurrentMetadataKey()
if err != nil {
return nil, err
}
}
encMeta, err := mkKey.Encrypt(acc.Metadata)
if err != nil {
@ -258,9 +260,11 @@ func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *
if len(encMeta) > MaxMetadataLen {
return nil, ErrMetadataTooLarge
}
readKey, err := a.state.CurrentReadKey()
if err != nil {
return nil, ErrNoReadKey
if readKey == nil {
readKey, err = a.state.CurrentReadKey()
if err != nil {
return nil, ErrNoReadKey
}
}
protoKey, err := readKey.Marshall()
if err != nil {
@ -386,14 +390,14 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco
}
func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *consensusproto.RawRecord, err error) {
content, err := a.buildRequestAccept(payload)
content, err := a.buildRequestAccept(payload, nil)
if err != nil {
return
}
return a.buildRecord(content)
}
func (a *aclRecordBuilder) buildRequestAccept(payload RequestAcceptPayload) (value *aclrecordproto.AclContentValue, err error) {
func (a *aclRecordBuilder) buildRequestAccept(payload RequestAcceptPayload, readKey crypto.SymKey) (value *aclrecordproto.AclContentValue, err error) {
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
err = ErrInsufficientPermissions
return
@ -403,9 +407,11 @@ func (a *aclRecordBuilder) buildRequestAccept(payload RequestAcceptPayload) (val
err = ErrNoSuchRequest
return
}
readKey, err := a.state.CurrentReadKey()
if err != nil {
return nil, ErrNoReadKey
if readKey == nil {
readKey, err = a.state.CurrentReadKey()
if err != nil {
return nil, ErrNoReadKey
}
}
protoKey, err := readKey.Marshall()
if err != nil {
@ -513,6 +519,9 @@ func (a *aclRecordBuilder) buildReadKeyChange(payload ReadKeyChangePayload, remo
continue
}
}
if st.Permissions.NoPermissions() {
continue
}
protoIdentity, err := st.PubKey.Marshall()
if err != nil {
return nil, err

View file

@ -49,6 +49,9 @@ type AclKeys struct {
ReadKey crypto.SymKey
MetadataPrivKey crypto.PrivKey
MetadataPubKey crypto.PubKey
oldEncryptedReadKey []byte
encMetadatKey []byte
}
type Invite struct {
@ -360,7 +363,10 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) {
if err != nil {
return err
}
st.keys[record.Id] = AclKeys{MetadataPubKey: mkPubKey}
st.keys[record.Id] = AclKeys{
MetadataPubKey: mkPubKey,
encMetadatKey: root.EncryptedMetadataPrivKey,
}
} else {
// this should be a derived acl
st.keys[record.Id] = AclKeys{}
@ -672,6 +678,10 @@ func (st *AclState) applyRequestAccept(ch *aclrecordproto.AclAccountRequestAccep
}
func (st *AclState) applyInviteJoin(ch *aclrecordproto.AclInviteJoin, record *AclRecord) error {
err := st.contentValidator.ValidateInviteJoin(ch, record.Identity)
if err != nil {
return err
}
identity, err := st.keyStore.PubKeyFromProto(ch.Identity)
if err != nil {
return err
@ -716,42 +726,8 @@ func (st *AclState) unpackAllKeys(rk []byte) error {
}
for idx := len(st.readKeyChanges) - 1; idx >= 0; idx-- {
recId := st.readKeyChanges[idx]
rec, err := st.list.Get(recId)
if err != nil {
return err
}
// if this is a first key change
if recId == st.id {
ch := rec.Model.(*aclrecordproto.AclRoot)
metadataKey, err := st.unmarshallDecryptPrivKey(ch.EncryptedMetadataPrivKey, iterReadKey.Decrypt)
if err != nil {
return err
}
aclKeys := st.keys[recId]
aclKeys.ReadKey = iterReadKey
aclKeys.MetadataPrivKey = metadataKey
st.keys[recId] = aclKeys
break
}
model := rec.Model.(*aclrecordproto.AclData)
content := model.GetAclContent()
var readKeyChange *aclrecordproto.AclReadKeyChange
for _, ch := range content {
switch {
case ch.GetReadKeyChange() != nil:
readKeyChange = ch.GetReadKeyChange()
case ch.GetAccountRemove() != nil:
readKeyChange = ch.GetAccountRemove().GetReadKeyChange()
}
}
if readKeyChange == nil {
return ErrIncorrectReadKey
}
oldReadKey, err := st.unmarshallDecryptReadKey(readKeyChange.EncryptedOldReadKey, iterReadKey.Decrypt)
if err != nil {
return err
}
metadataKey, err := st.unmarshallDecryptPrivKey(readKeyChange.EncryptedMetadataPrivKey, iterReadKey.Decrypt)
keys := st.keys[recId]
metadataKey, err := st.unmarshallDecryptPrivKey(keys.encMetadatKey, iterReadKey.Decrypt)
if err != nil {
return err
}
@ -759,7 +735,16 @@ func (st *AclState) unpackAllKeys(rk []byte) error {
aclKeys.ReadKey = iterReadKey
aclKeys.MetadataPrivKey = metadataKey
st.keys[recId] = aclKeys
iterReadKey = oldReadKey
if idx != 0 {
if keys.oldEncryptedReadKey == nil {
return ErrIncorrectReadKey
}
oldReadKey, err := st.unmarshallDecryptReadKey(keys.oldEncryptedReadKey, iterReadKey.Decrypt)
if err != nil {
return err
}
iterReadKey = oldReadKey
}
}
return nil
}
@ -871,7 +856,9 @@ func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, reco
return err
}
aclKeys := AclKeys{
MetadataPubKey: mkPubKey,
MetadataPubKey: mkPubKey,
oldEncryptedReadKey: ch.EncryptedOldReadKey,
encMetadatKey: ch.EncryptedMetadataPrivKey,
}
for _, accKey := range ch.AccountKeys {
identity, _ := st.keyStore.PubKeyFromProto(accKey.Identity)

View file

@ -11,6 +11,7 @@ import (
"github.com/anyproto/any-sync/app"
"github.com/anyproto/any-sync/app/logger"
"github.com/anyproto/any-sync/commonspace/object/acl/list"
"github.com/anyproto/any-sync/commonspace/object/acl/recordverifier"
"github.com/anyproto/any-sync/commonspace/object/acl/syncacl/headupdater"
"github.com/anyproto/any-sync/commonspace/spacestorage"
"github.com/anyproto/any-sync/commonspace/sync"
@ -67,7 +68,8 @@ func (s *syncAcl) Init(a *app.App) (err error) {
return err
}
acc := a.MustComponent(accountservice.CName).(accountservice.Service)
s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage, list.NoOpAcceptorVerifier{})
verifier := a.MustComponent(recordverifier.CName).(recordverifier.RecordVerifier)
s.AclList, err = list.BuildAclListWithIdentity(acc.Account(), aclStorage, verifier)
if err != nil {
return
}