Add raw record to list
This commit is contained in:
parent
5f6e51c15a
commit
2946c050b9
@ -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 {
|
||||||
|
|||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
}
|
||||||
|
|||||||
@ -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
|
||||||
|
recordBuilder ACLRecordBuilder
|
||||||
aclState *ACLState
|
aclState *ACLState
|
||||||
keychain *common.Keychain
|
keychain *common.Keychain
|
||||||
|
storage storage.ListStorage
|
||||||
|
|
||||||
sync.RWMutex
|
sync.RWMutex
|
||||||
}
|
}
|
||||||
@ -123,8 +126,10 @@ func build(id string, stateBuilder *aclStateBuilder, recBuilder ACLRecordBuilder
|
|||||||
root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
|
root: aclRecRoot.Model.(*aclrecordproto.ACLRoot),
|
||||||
records: records,
|
records: records,
|
||||||
indexes: indexes,
|
indexes: indexes,
|
||||||
builder: stateBuilder,
|
stateBuilder: stateBuilder,
|
||||||
|
recordBuilder: recBuilder,
|
||||||
aclState: state,
|
aclState: state,
|
||||||
|
storage: storage,
|
||||||
id: id,
|
id: id,
|
||||||
RWMutex: sync.RWMutex{},
|
RWMutex: sync.RWMutex{},
|
||||||
}
|
}
|
||||||
@ -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
|
||||||
}
|
}
|
||||||
|
|||||||
@ -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()
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user