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) {
|
func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRec *consensusproto.RawRecord, err error) {
|
||||||
var aclContent []*aclrecordproto.AclContentValue
|
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 {
|
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 {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -128,7 +135,7 @@ func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRe
|
||||||
aclContent = append(aclContent, content)
|
aclContent = append(aclContent, content)
|
||||||
}
|
}
|
||||||
for _, acc := range payload.Approvals {
|
for _, acc := range payload.Approvals {
|
||||||
content, err := a.buildRequestAccept(acc)
|
content, err := a.buildRequestAccept(acc, payload.Removals.Change.ReadKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -148,13 +155,6 @@ func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRe
|
||||||
}
|
}
|
||||||
aclContent = append(aclContent, content)
|
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)
|
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) {
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return a.buildRecord(content)
|
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
|
var accs []*aclrecordproto.AclAccountAdd
|
||||||
for _, acc := range payload.Additions {
|
for _, acc := range payload.Additions {
|
||||||
if !a.state.Permissions(acc.Identity).NoPermissions() {
|
if !a.state.Permissions(acc.Identity).NoPermissions() {
|
||||||
|
@ -247,9 +247,11 @@ func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *
|
||||||
if acc.Permissions.IsOwner() {
|
if acc.Permissions.IsOwner() {
|
||||||
return nil, ErrIsOwner
|
return nil, ErrIsOwner
|
||||||
}
|
}
|
||||||
mkKey, err := a.state.CurrentMetadataKey()
|
if mkKey == nil {
|
||||||
if err != nil {
|
mkKey, err = a.state.CurrentMetadataKey()
|
||||||
return nil, err
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
encMeta, err := mkKey.Encrypt(acc.Metadata)
|
encMeta, err := mkKey.Encrypt(acc.Metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -258,9 +260,11 @@ func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *
|
||||||
if len(encMeta) > MaxMetadataLen {
|
if len(encMeta) > MaxMetadataLen {
|
||||||
return nil, ErrMetadataTooLarge
|
return nil, ErrMetadataTooLarge
|
||||||
}
|
}
|
||||||
readKey, err := a.state.CurrentReadKey()
|
if readKey == nil {
|
||||||
if err != nil {
|
readKey, err = a.state.CurrentReadKey()
|
||||||
return nil, ErrNoReadKey
|
if err != nil {
|
||||||
|
return nil, ErrNoReadKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
protoKey, err := readKey.Marshall()
|
protoKey, err := readKey.Marshall()
|
||||||
if err != nil {
|
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) {
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return a.buildRecord(content)
|
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() {
|
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||||
err = ErrInsufficientPermissions
|
err = ErrInsufficientPermissions
|
||||||
return
|
return
|
||||||
|
@ -403,9 +407,11 @@ func (a *aclRecordBuilder) buildRequestAccept(payload RequestAcceptPayload) (val
|
||||||
err = ErrNoSuchRequest
|
err = ErrNoSuchRequest
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
readKey, err := a.state.CurrentReadKey()
|
if readKey == nil {
|
||||||
if err != nil {
|
readKey, err = a.state.CurrentReadKey()
|
||||||
return nil, ErrNoReadKey
|
if err != nil {
|
||||||
|
return nil, ErrNoReadKey
|
||||||
|
}
|
||||||
}
|
}
|
||||||
protoKey, err := readKey.Marshall()
|
protoKey, err := readKey.Marshall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -513,6 +519,9 @@ func (a *aclRecordBuilder) buildReadKeyChange(payload ReadKeyChangePayload, remo
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if st.Permissions.NoPermissions() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
protoIdentity, err := st.PubKey.Marshall()
|
protoIdentity, err := st.PubKey.Marshall()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
|
@ -49,6 +49,9 @@ type AclKeys struct {
|
||||||
ReadKey crypto.SymKey
|
ReadKey crypto.SymKey
|
||||||
MetadataPrivKey crypto.PrivKey
|
MetadataPrivKey crypto.PrivKey
|
||||||
MetadataPubKey crypto.PubKey
|
MetadataPubKey crypto.PubKey
|
||||||
|
|
||||||
|
oldEncryptedReadKey []byte
|
||||||
|
encMetadatKey []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
type Invite struct {
|
type Invite struct {
|
||||||
|
@ -360,7 +363,10 @@ func (st *AclState) applyRoot(record *AclRecord) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
st.keys[record.Id] = AclKeys{MetadataPubKey: mkPubKey}
|
st.keys[record.Id] = AclKeys{
|
||||||
|
MetadataPubKey: mkPubKey,
|
||||||
|
encMetadatKey: root.EncryptedMetadataPrivKey,
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// this should be a derived acl
|
// this should be a derived acl
|
||||||
st.keys[record.Id] = AclKeys{}
|
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 {
|
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)
|
identity, err := st.keyStore.PubKeyFromProto(ch.Identity)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -716,42 +726,8 @@ func (st *AclState) unpackAllKeys(rk []byte) error {
|
||||||
}
|
}
|
||||||
for idx := len(st.readKeyChanges) - 1; idx >= 0; idx-- {
|
for idx := len(st.readKeyChanges) - 1; idx >= 0; idx-- {
|
||||||
recId := st.readKeyChanges[idx]
|
recId := st.readKeyChanges[idx]
|
||||||
rec, err := st.list.Get(recId)
|
keys := st.keys[recId]
|
||||||
if err != nil {
|
metadataKey, err := st.unmarshallDecryptPrivKey(keys.encMetadatKey, iterReadKey.Decrypt)
|
||||||
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)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -759,7 +735,16 @@ func (st *AclState) unpackAllKeys(rk []byte) error {
|
||||||
aclKeys.ReadKey = iterReadKey
|
aclKeys.ReadKey = iterReadKey
|
||||||
aclKeys.MetadataPrivKey = metadataKey
|
aclKeys.MetadataPrivKey = metadataKey
|
||||||
st.keys[recId] = aclKeys
|
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
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -871,7 +856,9 @@ func (st *AclState) applyReadKeyChange(ch *aclrecordproto.AclReadKeyChange, reco
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
aclKeys := AclKeys{
|
aclKeys := AclKeys{
|
||||||
MetadataPubKey: mkPubKey,
|
MetadataPubKey: mkPubKey,
|
||||||
|
oldEncryptedReadKey: ch.EncryptedOldReadKey,
|
||||||
|
encMetadatKey: ch.EncryptedMetadataPrivKey,
|
||||||
}
|
}
|
||||||
for _, accKey := range ch.AccountKeys {
|
for _, accKey := range ch.AccountKeys {
|
||||||
identity, _ := st.keyStore.PubKeyFromProto(accKey.Identity)
|
identity, _ := st.keyStore.PubKeyFromProto(accKey.Identity)
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/anyproto/any-sync/app"
|
"github.com/anyproto/any-sync/app"
|
||||||
"github.com/anyproto/any-sync/app/logger"
|
"github.com/anyproto/any-sync/app/logger"
|
||||||
"github.com/anyproto/any-sync/commonspace/object/acl/list"
|
"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/object/acl/syncacl/headupdater"
|
||||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||||
"github.com/anyproto/any-sync/commonspace/sync"
|
"github.com/anyproto/any-sync/commonspace/sync"
|
||||||
|
@ -67,7 +68,8 @@ func (s *syncAcl) Init(a *app.App) (err error) {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
acc := a.MustComponent(accountservice.CName).(accountservice.Service)
|
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 {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue