1
0
Fork 0
mirror of https://github.com/anyproto/any-sync.git synced 2025-06-08 14:07:02 +09:00

acl.AddRecord check limits

This commit is contained in:
Sergey Cherepanov 2024-03-18 14:30:43 +01:00
parent d499647a98
commit 045ab61962
No known key found for this signature in database
GPG key ID: 87F8EDE8FBDF637C
2 changed files with 37 additions and 6 deletions

View file

@ -3,6 +3,7 @@ package acl
import ( import (
"context" "context"
"errors"
"time" "time"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
@ -22,12 +23,19 @@ const CName = "coordinator.acl"
var log = logger.NewNamed(CName) var log = logger.NewNamed(CName)
var ErrLimitExceed = errors.New("limit exceed")
type Limits struct {
ReadMembers uint32
WriteMembers uint32
}
func New() AclService { func New() AclService {
return &aclService{} return &aclService{}
} }
type AclService interface { type AclService interface {
AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (result *consensusproto.RawRecordWithId, err error) AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord, limits Limits) (result *consensusproto.RawRecordWithId, err error)
RecordsAfter(ctx context.Context, spaceId, aclHead string) (result []*consensusproto.RawRecordWithId, err error) RecordsAfter(ctx context.Context, spaceId, aclHead string) (result []*consensusproto.RawRecordWithId, err error)
Permissions(ctx context.Context, identity crypto.PubKey, spaceId string) (res list.AclPermissions, err error) Permissions(ctx context.Context, identity crypto.PubKey, spaceId string) (res list.AclPermissions, err error)
OwnerPubKey(ctx context.Context, spaceId string) (ownerIdentity crypto.PubKey, err error) OwnerPubKey(ctx context.Context, spaceId string) (ownerIdentity crypto.PubKey, err error)
@ -74,14 +82,29 @@ func (as *aclService) get(ctx context.Context, spaceId string) (list.AclList, er
return aObj.AclList, nil return aObj.AclList, nil
} }
func (as *aclService) AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord) (result *consensusproto.RawRecordWithId, err error) { func (as *aclService) AddRecord(ctx context.Context, spaceId string, rec *consensusproto.RawRecord, limits Limits) (result *consensusproto.RawRecordWithId, err error) {
acl, err := as.get(ctx, spaceId) acl, err := as.get(ctx, spaceId)
if err != nil { if err != nil {
return nil, err return nil, err
} }
acl.RLock() acl.RLock()
defer acl.RUnlock() defer acl.RUnlock()
err = acl.ValidateRawRecord(rec, nil) err = acl.ValidateRawRecord(rec, func(state *list.AclState) error {
var readers, writers int
for _, acc := range state.CurrentAccounts() {
readers++
if acc.Permissions.CanWrite() {
writers++
}
if uint32(readers) > limits.ReadMembers {
return ErrLimitExceed
}
if uint32(writers) > limits.WriteMembers {
return ErrLimitExceed
}
}
return nil
})
if err != nil { if err != nil {
return return
} }

View file

@ -48,7 +48,10 @@ func TestAclService_AddRecord(t *testing.T) {
fx.consCl.EXPECT().AddRecord(ctx, spaceId, inv.InviteRec).Return(expRes, nil) fx.consCl.EXPECT().AddRecord(ctx, spaceId, inv.InviteRec).Return(expRes, nil)
fx.consCl.EXPECT().UnWatch(spaceId) fx.consCl.EXPECT().UnWatch(spaceId)
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec) res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
ReadMembers: 10,
WriteMembers: 10,
})
assert.Equal(t, expRes, res) assert.Equal(t, expRes, res)
assert.NoError(t, err) assert.NoError(t, err)
@ -71,11 +74,16 @@ func TestAclService_AddRecord(t *testing.T) {
}) })
fx.consCl.EXPECT().UnWatch(spaceId) fx.consCl.EXPECT().UnWatch(spaceId)
res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec) res, err := fx.AddRecord(ctx, spaceId, inv.InviteRec, Limits{
ReadMembers: 10,
WriteMembers: 10,
})
assert.Nil(t, res) assert.Nil(t, res)
assert.EqualError(t, err, testErr.Error()) assert.EqualError(t, err, testErr.Error())
}) })
t.Run("limit exceed", func(t *testing.T) {
// TODO:
})
} }
func TestAclService_RecordsAfter(t *testing.T) { func TestAclService_RecordsAfter(t *testing.T) {