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:
parent
d499647a98
commit
045ab61962
2 changed files with 37 additions and 6 deletions
29
acl/acl.go
29
acl/acl.go
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue