mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-07 21:47:02 +09:00
Add verifier logic
This commit is contained in:
parent
ab01e874bb
commit
c2dc1770b6
7 changed files with 73 additions and 15 deletions
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"github.com/anyproto/any-sync/app/logger"
|
||||
"github.com/anyproto/any-sync/commonspace/deletionstate"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/synctree"
|
||||
"github.com/anyproto/any-sync/commonspace/object/tree/treestorage"
|
||||
"github.com/anyproto/any-sync/commonspace/object/treemanager"
|
||||
"github.com/anyproto/any-sync/commonspace/spacestorage"
|
||||
|
@ -43,7 +44,7 @@ func (d *deleter) Delete(ctx context.Context) {
|
|||
}
|
||||
} else {
|
||||
err = d.getter.DeleteTree(ctx, spaceId, id)
|
||||
if err != nil && !errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) {
|
||||
if err != nil && !errors.Is(err, spacestorage.ErrTreeStorageAlreadyDeleted) && !errors.Is(err, synctree.ErrSyncTreeDeleted) {
|
||||
log.Error("failed to delete object", zap.Error(err))
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -86,7 +86,8 @@ type AclState struct {
|
|||
|
||||
func newAclStateWithKeys(
|
||||
rootRecord *AclRecord,
|
||||
key crypto.PrivKey) (st *AclState, err error) {
|
||||
key crypto.PrivKey,
|
||||
verifier AcceptorVerifier) (st *AclState, err error) {
|
||||
st = &AclState{
|
||||
id: rootRecord.Id,
|
||||
key: key,
|
||||
|
@ -98,10 +99,7 @@ func newAclStateWithKeys(
|
|||
pendingRequests: make(map[string]string),
|
||||
keyStore: crypto.NewKeyStorage(),
|
||||
}
|
||||
st.contentValidator = &contentValidator{
|
||||
keyStore: st.keyStore,
|
||||
aclState: st,
|
||||
}
|
||||
st.contentValidator = newContentValidator(st.keyStore, st, verifier)
|
||||
err = st.applyRoot(rootRecord)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -109,7 +107,7 @@ func newAclStateWithKeys(
|
|||
return st, nil
|
||||
}
|
||||
|
||||
func newAclState(rootRecord *AclRecord) (st *AclState, err error) {
|
||||
func newAclState(rootRecord *AclRecord, verifier AcceptorVerifier) (st *AclState, err error) {
|
||||
st = &AclState{
|
||||
id: rootRecord.Id,
|
||||
keys: make(map[string]AclKeys),
|
||||
|
@ -119,10 +117,7 @@ func newAclState(rootRecord *AclRecord) (st *AclState, err error) {
|
|||
pendingRequests: make(map[string]string),
|
||||
keyStore: crypto.NewKeyStorage(),
|
||||
}
|
||||
st.contentValidator = &contentValidator{
|
||||
keyStore: st.keyStore,
|
||||
aclState: st,
|
||||
}
|
||||
st.contentValidator = newContentValidator(st.keyStore, st, verifier)
|
||||
err = st.applyRoot(rootRecord)
|
||||
if err != nil {
|
||||
return
|
||||
|
@ -418,7 +413,7 @@ func (st *AclState) Copy() *AclState {
|
|||
newSt.readKeyChanges = append(newSt.readKeyChanges, st.readKeyChanges...)
|
||||
newSt.list = st.list
|
||||
newSt.lastRecordId = st.lastRecordId
|
||||
newSt.contentValidator = newContentValidator(newSt.keyStore, newSt)
|
||||
newSt.contentValidator = newContentValidator(newSt.keyStore, newSt, st.list.verifier)
|
||||
return newSt
|
||||
}
|
||||
|
||||
|
|
|
@ -29,12 +29,12 @@ func (sb *aclStateBuilder) Build(records []*AclRecord, list *aclList) (state *Ac
|
|||
return nil, ErrIncorrectRecordSequence
|
||||
}
|
||||
if sb.privKey != nil {
|
||||
state, err = newAclStateWithKeys(records[0], sb.privKey)
|
||||
state, err = newAclStateWithKeys(records[0], sb.privKey, list.verifier)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
} else {
|
||||
state, err = newAclState(records[0])
|
||||
state, err = newAclState(records[0], list.verifier)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ type RWLocker interface {
|
|||
|
||||
type AcceptorVerifier interface {
|
||||
VerifyAcceptor(rec *consensusproto.RawRecord) (err error)
|
||||
ShouldValidate() bool
|
||||
}
|
||||
|
||||
type NoOpAcceptorVerifier struct {
|
||||
|
@ -37,6 +38,10 @@ func (n NoOpAcceptorVerifier) VerifyAcceptor(rec *consensusproto.RawRecord) (err
|
|||
return nil
|
||||
}
|
||||
|
||||
func (n NoOpAcceptorVerifier) ShouldValidate() bool {
|
||||
return true
|
||||
}
|
||||
|
||||
type AclList interface {
|
||||
RWLocker
|
||||
Id() string
|
||||
|
@ -75,6 +80,7 @@ type aclList struct {
|
|||
keyStorage crypto.KeyStorage
|
||||
aclState *AclState
|
||||
storage Storage
|
||||
verifier AcceptorVerifier
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
|
@ -159,6 +165,7 @@ func build(deps internalDeps) (list AclList, err error) {
|
|||
stateBuilder: stateBuilder,
|
||||
recordBuilder: recBuilder,
|
||||
storage: storage,
|
||||
verifier: deps.acceptorVerifier,
|
||||
id: id,
|
||||
}
|
||||
stateBuilder.Init(id)
|
||||
|
|
|
@ -27,16 +27,21 @@ type ContentValidator interface {
|
|||
type contentValidator struct {
|
||||
keyStore crypto.KeyStorage
|
||||
aclState *AclState
|
||||
verifier AcceptorVerifier
|
||||
}
|
||||
|
||||
func newContentValidator(keyStore crypto.KeyStorage, aclState *AclState) ContentValidator {
|
||||
func newContentValidator(keyStore crypto.KeyStorage, aclState *AclState, verifier AcceptorVerifier) ContentValidator {
|
||||
return &contentValidator{
|
||||
keyStore: keyStore,
|
||||
aclState: aclState,
|
||||
verifier: verifier,
|
||||
}
|
||||
}
|
||||
|
||||
func (c *contentValidator) ValidatePermissionChanges(ch *aclrecordproto.AclAccountPermissionChanges, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
for _, ch := range ch.Changes {
|
||||
err := c.ValidatePermissionChange(ch, authorIdentity)
|
||||
if err != nil {
|
||||
|
@ -47,6 +52,9 @@ func (c *contentValidator) ValidatePermissionChanges(ch *aclrecordproto.AclAccou
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateAccountsAdd(ch *aclrecordproto.AclAccountsAdd, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -70,6 +78,9 @@ func (c *contentValidator) ValidateAccountsAdd(ch *aclrecordproto.AclAccountsAdd
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateInviteJoin(ch *aclrecordproto.AclAccountInviteJoin, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).NoPermissions() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -111,6 +122,9 @@ func (c *contentValidator) ValidateInviteJoin(ch *aclrecordproto.AclAccountInvit
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateAclRecordContents(ch *AclRecord) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if ch.PrevId != c.aclState.lastRecordId {
|
||||
return ErrIncorrectRecordSequence
|
||||
}
|
||||
|
@ -156,6 +170,9 @@ func (c *contentValidator) validateAclRecordContent(ch *aclrecordproto.AclConten
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccountPermissionChange, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -195,6 +212,9 @@ func (c *contentValidator) ValidatePermissionChange(ch *aclrecordproto.AclAccoun
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -207,6 +227,9 @@ func (c *contentValidator) ValidateInvite(ch *aclrecordproto.AclAccountInvite, a
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInviteRevoke, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -218,6 +241,9 @@ func (c *contentValidator) ValidateInviteRevoke(ch *aclrecordproto.AclAccountInv
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequestJoin, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
invite, exists := c.aclState.invites[ch.InviteRecordId]
|
||||
if !exists {
|
||||
return ErrNoSuchInvite
|
||||
|
@ -253,6 +279,9 @@ func (c *contentValidator) ValidateRequestJoin(ch *aclrecordproto.AclAccountRequ
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRequestAccept, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -274,6 +303,9 @@ func (c *contentValidator) ValidateRequestAccept(ch *aclrecordproto.AclAccountRe
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountRequestDecline, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -285,6 +317,9 @@ func (c *contentValidator) ValidateRequestDecline(ch *aclrecordproto.AclAccountR
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateRequestCancel(ch *aclrecordproto.AclAccountRequestCancel, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
rec, exists := c.aclState.requestRecords[ch.RecordId]
|
||||
if !exists {
|
||||
return ErrNoSuchRequest
|
||||
|
@ -296,6 +331,9 @@ func (c *contentValidator) ValidateRequestCancel(ch *aclrecordproto.AclAccountRe
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRemove, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if !c.aclState.Permissions(authorIdentity).CanManageAccounts() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -325,6 +363,9 @@ func (c *contentValidator) ValidateAccountRemove(ch *aclrecordproto.AclAccountRe
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRequestRemove, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
if c.aclState.Permissions(authorIdentity).NoPermissions() {
|
||||
return ErrInsufficientPermissions
|
||||
}
|
||||
|
@ -338,10 +379,16 @@ func (c *contentValidator) ValidateRequestRemove(ch *aclrecordproto.AclAccountRe
|
|||
}
|
||||
|
||||
func (c *contentValidator) ValidateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, authorIdentity crypto.PubKey) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
return c.validateReadKeyChange(ch, nil)
|
||||
}
|
||||
|
||||
func (c *contentValidator) validateReadKeyChange(ch *aclrecordproto.AclReadKeyChange, removedUsers map[string]struct{}) (err error) {
|
||||
if !c.verifier.ShouldValidate() {
|
||||
return nil
|
||||
}
|
||||
_, err = c.keyStore.PubKeyFromProto(ch.MetadataPubKey)
|
||||
if err != nil {
|
||||
return ErrNoMetadataKey
|
||||
|
|
|
@ -22,3 +22,7 @@ func (a *AlwaysAccept) Name() string {
|
|||
func (a *AlwaysAccept) VerifyAcceptor(_ *consensusproto.RawRecord) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (a *AlwaysAccept) ShouldValidate() bool {
|
||||
return true
|
||||
}
|
||||
|
|
|
@ -50,3 +50,7 @@ func (r *recordVerifier) VerifyAcceptor(rec *consensusproto.RawRecord) (err erro
|
|||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (r *recordVerifier) ShouldValidate() bool {
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue