Add raw record to list
This commit is contained in:
parent
5f6e51c15a
commit
2946c050b9
@ -11,6 +11,7 @@ import (
|
||||
|
||||
type ACLRecordBuilder interface {
|
||||
ConvertFromRaw(rawIdRecord *aclrecordproto.RawACLRecordWithId) (rec *ACLRecord, err error)
|
||||
BuildUserJoin(acceptPrivKeyBytes []byte, encSymKeyBytes []byte, state *ACLState) (rec *aclrecordproto.RawACLRecord, err error)
|
||||
}
|
||||
|
||||
type aclRecordBuilder struct {
|
||||
|
||||
@ -30,6 +30,7 @@ var ErrInsufficientPermissions = errors.New("insufficient permissions")
|
||||
var ErrNoReadKey = errors.New("acl state doesn't have a read key")
|
||||
var ErrInvalidSignature = errors.New("signature is invalid")
|
||||
var ErrIncorrectRoot = errors.New("incorrect root")
|
||||
var ErrIncorrectRecordSequence = errors.New("incorrect prev id of a record")
|
||||
|
||||
type UserPermissionPair struct {
|
||||
Identity string
|
||||
@ -48,6 +49,7 @@ type ACLState struct {
|
||||
|
||||
identity string
|
||||
permissionsAtRecord map[string][]UserPermissionPair
|
||||
lastRecordId string
|
||||
|
||||
keychain *common.Keychain
|
||||
}
|
||||
@ -114,15 +116,28 @@ func (st *ACLState) PermissionsAtRecord(id string, identity string) (UserPermiss
|
||||
}
|
||||
|
||||
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 {
|
||||
root, ok := record.Model.(*aclrecordproto.ACLRoot)
|
||||
if !ok {
|
||||
return ErrIncorrectRoot
|
||||
}
|
||||
err = st.applyRoot(root)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
st.permissionsAtRecord[record.Id] = []UserPermissionPair{
|
||||
{Identity: string(root.Identity), Permission: aclrecordproto.ACLUserPermissions_Admin},
|
||||
}
|
||||
return st.applyRoot(root)
|
||||
return
|
||||
}
|
||||
aclData := &aclrecordproto.ACLData{}
|
||||
|
||||
@ -152,7 +167,7 @@ func (st *ACLState) applyRecord(record *ACLRecord) (err error) {
|
||||
}
|
||||
|
||||
st.permissionsAtRecord[record.Id] = permissions
|
||||
return nil
|
||||
return
|
||||
}
|
||||
|
||||
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,
|
||||
}
|
||||
st.userStates[string(root.Identity)] = userState
|
||||
st.totalReadKeys++
|
||||
return
|
||||
}
|
||||
|
||||
@ -203,7 +219,6 @@ func (st *ACLState) saveReadKeyFromRoot(root *aclrecordproto.ACLRoot) (err error
|
||||
}
|
||||
st.currentReadKeyHash = root.CurrentReadKeyHash
|
||||
st.userReadKeys[root.CurrentReadKeyHash] = readKey
|
||||
st.totalReadKeys++
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
@ -45,3 +45,13 @@ func (sb *aclStateBuilder) Build(records []*ACLRecord) (state *ACLState, err 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
|
||||
}
|
||||
|
||||
@ -29,6 +29,7 @@ type ACLList interface {
|
||||
Records() []*ACLRecord
|
||||
ACLState() *ACLState
|
||||
IsAfter(first string, second string) (bool, error)
|
||||
AddRawRecords(ctx context.Context, rec []*aclrecordproto.RawACLRecordWithId) (err error)
|
||||
Head() *ACLRecord
|
||||
Get(id string) (*ACLRecord, error)
|
||||
Iterate(iterFunc IterFunc)
|
||||
@ -42,9 +43,11 @@ type aclList struct {
|
||||
indexes map[string]int
|
||||
id string
|
||||
|
||||
builder *aclStateBuilder
|
||||
aclState *ACLState
|
||||
keychain *common.Keychain
|
||||
stateBuilder *aclStateBuilder
|
||||
recordBuilder ACLRecordBuilder
|
||||
aclState *ACLState
|
||||
keychain *common.Keychain
|
||||
storage storage.ListStorage
|
||||
|
||||
sync.RWMutex
|
||||
}
|
||||
@ -120,13 +123,15 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder
|
||||
}
|
||||
|
||||
list = &aclList{
|
||||
root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
|
||||
records: records,
|
||||
indexes: indexes,
|
||||
builder: stateBuilder,
|
||||
aclState: state,
|
||||
id: id,
|
||||
RWMutex: sync.RWMutex{},
|
||||
root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
|
||||
records: records,
|
||||
indexes: indexes,
|
||||
stateBuilder: stateBuilder,
|
||||
recordBuilder: recBuilder,
|
||||
aclState: state,
|
||||
storage: storage,
|
||||
id: id,
|
||||
RWMutex: sync.RWMutex{},
|
||||
}
|
||||
return
|
||||
}
|
||||
@ -143,6 +148,40 @@ func (a *aclList) Root() *aclrecordproto.ACLRoot {
|
||||
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 {
|
||||
return a.aclState
|
||||
}
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
package mock_list
|
||||
|
||||
import (
|
||||
context "context"
|
||||
reflect "reflect"
|
||||
|
||||
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))
|
||||
}
|
||||
|
||||
// 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.
|
||||
func (m *MockACLList) Close() error {
|
||||
m.ctrl.T.Helper()
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user