Add raw record to list

This commit is contained in:
mcrakhman 2022-10-28 12:04:23 +02:00 committed by Mikhail Iudin
parent 5f6e51c15a
commit 2946c050b9
No known key found for this signature in database
GPG Key ID: FAAAA8BAABDFF1C0
5 changed files with 93 additions and 13 deletions

View File

@ -11,6 +11,7 @@ import (
type ACLRecordBuilder interface { type ACLRecordBuilder interface {
ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error) ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error)
BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *ACLState) (rec *aclrecordproto.RawACLRecord, err error)
} }
type aclRecordBuilder struct { type aclRecordBuilder struct {

View File

@ -30,6 +30,7 @@ var ErrInsufficientPermissions = errors.New("insufficient permissions")
var ErrNoReadKey = errors.New("acl state doesn't have a read key") var ErrNoReadKey = errors.New("acl state doesn't have a read key")
var ErrInvalidSignature = errors.New("signature is invalid") var ErrInvalidSignature = errors.New("signature is invalid")
var ErrIncorrectRoot = errors.New("incorrect root") var ErrIncorrectRoot = errors.New("incorrect root")
var ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record")
type UserPermissionPair struct { type UserPermissionPair struct {
Identity string Identity string
@ -48,6 +49,7 @@ type ACLState struct {
identity string identity string
permissionsAtRecord map[string][]UserPermissionPair permissionsAtRecord map[string][]UserPermissionPair
lastRecordId string
keychain *common.Keychain keychain *common.Keychain
} }
@ -114,15 +116,28 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
} }
func (st *ACLState) applyRecord(record *ACLRecord) (err error) { func (st *ACLState) applyRecord(record *ACLRecord) (err error) {
defer func() {
if err == nil {
st.lastRecordId = record.Id
}
}()
if st.lastRecordId != record.PrevId {
err = ErrIncorrectRecordSequence
return
}
if record.Id == st.id { if record.Id == st.id {
root, ok := record.Model.(*aclrecordproto.ACLRoot) root, ok := record.Model.(*aclrecordproto.ACLRoot)
if !ok { if !ok {
return ErrIncorrectRoot return ErrIncorrectRoot
} }
err = st.applyRoot(root)
if err != nil {
return
}
st.permissionsAtRecord[record.Id] = []UserPermissionPair{ st.permissionsAtRecord[record.Id] = []UserPermissionPair{
{Identity: string(root.Identity), Permission: aclrecordproto.ACLUserPermissions_Admin}, {Identity: string(root.Identity), Permission: aclrecordproto.ACLUserPermissions_Admin},
} }
return st.applyRoot(root) return
} }
aclData := &aclrecordproto.ACLData{} aclData := &aclrecordproto.ACLData{}
@ -152,7 +167,7 @@ func (st *ACLState) applyRecord(record *ACLRecord) (err error) {
} }
st.permissionsAtRecord[record.Id] = permissions st.permissionsAtRecord[record.Id] = permissions
return nil return
} }
func (st *ACLState) applyRoot(root *aclrecordproto.ACLRoot) (err error) { func (st *ACLState) applyRoot(root *aclrecordproto.ACLRoot) (err error) {
@ -170,6 +185,7 @@ func (st *ACLState) applyRoot(root *aclrecordproto.ACLRoot) (err error) {
Permissions: aclrecordproto.ACLUserPermissions_Admin, Permissions: aclrecordproto.ACLUserPermissions_Admin,
} }
st.userStates[string(root.Identity)] = userState st.userStates[string(root.Identity)] = userState
st.totalReadKeys++
return return
} }
@ -203,7 +219,6 @@ func (st *ACLState) saveReadKeyFromRoot(root *aclrecordproto.ACLRoot) (err error
} }
st.currentReadKeyHash = root.CurrentReadKeyHash st.currentReadKeyHash = root.CurrentReadKeyHash
st.userReadKeys[root.CurrentReadKeyHash] = readKey st.userReadKeys[root.CurrentReadKeyHash] = readKey
st.totalReadKeys++
return return
} }

View File

@ -45,3 +45,13 @@ func (sb *aclStateBuilder) Build(records []*ACLRecord) (state *ACLState, err err
return state, err return state, err
} }
func (sb *aclStateBuilder) Append(state *ACLState, records []*ACLRecord) (err error) {
for _, rec := range records {
err = state.applyRecord(rec)
if err != nil {
return
}
}
return
}

View File

@ -29,6 +29,7 @@ type ACLList interface {
Records() []*ACLRecord Records() []*ACLRecord
ACLState() *ACLState ACLState() *ACLState
IsAfter(first string, second string) (bool, error) IsAfter(first string, second string) (bool, error)
AddRawRecords(ctx context.Context, rec []*aclrecordproto.RawACLRecordWithId) (err error)
Head() *ACLRecord Head() *ACLRecord
Get(id string) (*ACLRecord, error) Get(id string) (*ACLRecord, error)
Iterate(iterFunc IterFunc) Iterate(iterFunc IterFunc)
@ -42,9 +43,11 @@ type aclList struct {
indexes map[string]int indexes map[string]int
id string id string
builder *aclStateBuilder stateBuilder *aclStateBuilder
aclState *ACLState recordBuilder ACLRecordBuilder
keychain *common.Keychain aclState *ACLState
keychain *common.Keychain
storage storage.ListStorage
sync.RWMutex sync.RWMutex
} }
@ -120,13 +123,15 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder
} }
list = &aclList{ list = &aclList{
root: aclRecRoot.Model.(*aclrecordproto.ACLRoot), root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
records: records, records: records,
indexes: indexes, indexes: indexes,
builder: stateBuilder, stateBuilder: stateBuilder,
aclState: state, recordBuilder: recBuilder,
id: id, aclState: state,
RWMutex: sync.RWMutex{}, storage: storage,
id: id,
RWMutex: sync.RWMutex{},
} }
return return
} }
@ -143,6 +148,40 @@ func (a *aclList) Root() *aclrecordproto.ACLRoot {
return a.root return a.root
} }
func (a *aclList) AddRawRecords(ctx context.Context, records []*aclrecordproto.RawACLRecordWithId) (err error) {
if len(records) == 0 {
return
}
// converting and verifying
var aclRecords []*ACLRecord
for _, rec := range records {
var record *ACLRecord
record, err = a.recordBuilder.ConvertFromRaw(rec)
if err != nil {
return
}
aclRecords = append(aclRecords, record)
}
// trying to append them to state
err = a.stateBuilder.Append(a.aclState, aclRecords)
if err != nil {
return
}
// saving to storage
for _, rec := range records {
err = a.storage.AddRawRecord(ctx, rec)
if err != nil {
return
}
}
// setting new head
err = a.storage.SetHead(records[len(records)-1].Id)
return
}
func (a *aclList) ACLState() *ACLState { func (a *aclList) ACLState() *ACLState {
return a.aclState return a.aclState
} }

View File

@ -5,6 +5,7 @@
package mock_list package mock_list
import ( import (
context "context"
reflect "reflect" reflect "reflect"
aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto" aclrecordproto "github.com/anytypeio/go-anytype-infrastructure-experiments/common/pkg/acl/aclrecordproto"
@ -49,6 +50,20 @@ func (mr *MockACLListMockRecorder) ACLState() *gomock.Call {
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ACLState", reflect.TypeOf((*MockACLList)(nil).ACLState)) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ACLState", reflect.TypeOf((*MockACLList)(nil).ACLState))
} }
// AddRawRecords mocks base method.
func (m *MockACLList) AddRawRecords(arg0 context.Context, arg1 []*aclrecordproto.RawACLRecordWithId) error {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "AddRawRecords", arg0, arg1)
ret0, _ := ret[0].(error)
return ret0
}
// AddRawRecords indicates an expected call of AddRawRecords.
func (mr *MockACLListMockRecorder) AddRawRecords(arg0, arg1 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "AddRawRecords", reflect.TypeOf((*MockACLList)(nil).AddRawRecords), arg0, arg1)
}
// Close mocks base method. // Close mocks base method.
func (m *MockACLList) Close() error { func (m *MockACLList) Close() error {
m.ctrl.T.Helper() m.ctrl.T.Helper()