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:
parent
79d0352d6d
commit
a8699f38f9
3 changed files with 60 additions and 62 deletions
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue