diff --git a/acl/acl.go b/acl/acl.go index eba12910..e0de0a9d 100644 --- a/acl/acl.go +++ b/acl/acl.go @@ -39,6 +39,7 @@ type AclService interface { 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) OwnerPubKey(ctx context.Context, spaceId string) (ownerIdentity crypto.PubKey, err error) + ReadState(ctx context.Context, spaceId string, f func(s *list.AclState) error) (err error) app.ComponentRunnable } @@ -159,6 +160,16 @@ func (as *aclService) Permissions(ctx context.Context, identity crypto.PubKey, s return acl.AclState().Permissions(identity), nil } +func (as *aclService) ReadState(ctx context.Context, spaceId string, f func(s *list.AclState) error) (err error) { + acl, err := as.get(ctx, spaceId) + if err != nil { + return + } + acl.RLock() + defer acl.RUnlock() + return f(acl.AclState()) +} + func (as *aclService) Run(ctx context.Context) (err error) { return } diff --git a/acl/acl_test.go b/acl/acl_test.go index 3e835a98..0ff4fb81 100644 --- a/acl/acl_test.go +++ b/acl/acl_test.go @@ -149,6 +149,32 @@ func TestAclService(t *testing.T) { }) } +func TestAclService_ReadState(t *testing.T) { + ownerKeys, err := accountdata.NewRandom() + require.NoError(t, err) + spaceId := "spaceId" + ownerAcl, err := list.NewTestDerivedAcl(spaceId, ownerKeys) + require.NoError(t, err) + + fx := newFixture(t) + defer fx.finish(t) + + fx.consCl.EXPECT().Watch(spaceId, gomock.Any()).DoAndReturn(func(spaceId string, w consensusclient.Watcher) error { + go func() { + w.AddConsensusRecords([]*consensusproto.RawRecordWithId{ + ownerAcl.Root(), + }) + }() + return nil + }) + fx.consCl.EXPECT().UnWatch(spaceId) + + require.NoError(t, fx.ReadState(ctx, spaceId, func(s *list.AclState) error { + assert.NotNil(t, s) + return nil + })) +} + func newFixture(t *testing.T) *fixture { ctrl := gomock.NewController(t) fx := &fixture{ diff --git a/acl/mock_acl/mock_acl.go b/acl/mock_acl/mock_acl.go index a70ab70c..8051e62e 100644 --- a/acl/mock_acl/mock_acl.go +++ b/acl/mock_acl/mock_acl.go @@ -131,6 +131,20 @@ func (mr *MockAclServiceMockRecorder) Permissions(arg0, arg1, arg2 any) *gomock. return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Permissions", reflect.TypeOf((*MockAclService)(nil).Permissions), arg0, arg1, arg2) } +// ReadState mocks base method. +func (m *MockAclService) ReadState(arg0 context.Context, arg1 string, arg2 func(*list.AclState) error) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReadState", arg0, arg1, arg2) + ret0, _ := ret[0].(error) + return ret0 +} + +// ReadState indicates an expected call of ReadState. +func (mr *MockAclServiceMockRecorder) ReadState(arg0, arg1, arg2 any) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReadState", reflect.TypeOf((*MockAclService)(nil).ReadState), arg0, arg1, arg2) +} + // RecordsAfter mocks base method. func (m *MockAclService) RecordsAfter(arg0 context.Context, arg1, arg2 string) ([]*consensusproto.RawRecordWithId, error) { m.ctrl.T.Helper()