mirror of
https://github.com/anyproto/any-sync.git
synced 2025-06-11 10:18:08 +09:00
Merge pull request #172 from anyproto/GO-2966-multiple-changes-one-record
Go 2966 multiple changes one record
This commit is contained in:
commit
c095ff519c
12 changed files with 554 additions and 149 deletions
|
@ -27,6 +27,7 @@ type InviteSaveFunc func()
|
||||||
type AclSpaceClient interface {
|
type AclSpaceClient interface {
|
||||||
app.Component
|
app.Component
|
||||||
GenerateInvite() (list.InviteResult, error)
|
GenerateInvite() (list.InviteResult, error)
|
||||||
|
StopSharing(ctx context.Context, readKeyChange list.ReadKeyChangePayload) (err error)
|
||||||
AddRecord(ctx context.Context, consRec *consensusproto.RawRecord) error
|
AddRecord(ctx context.Context, consRec *consensusproto.RawRecord) error
|
||||||
RemoveAccounts(ctx context.Context, payload list.AccountRemovePayload) error
|
RemoveAccounts(ctx context.Context, payload list.AccountRemovePayload) error
|
||||||
AcceptRequest(ctx context.Context, payload list.RequestAcceptPayload) error
|
AcceptRequest(ctx context.Context, payload list.RequestAcceptPayload) error
|
||||||
|
@ -114,6 +115,39 @@ func (c *aclSpaceClient) RemoveAccounts(ctx context.Context, payload list.Accoun
|
||||||
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
|
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (c *aclSpaceClient) StopSharing(ctx context.Context, readKeyChange list.ReadKeyChangePayload) (err error) {
|
||||||
|
c.acl.Lock()
|
||||||
|
var (
|
||||||
|
identities []crypto.PubKey
|
||||||
|
recIds []string
|
||||||
|
)
|
||||||
|
for _, state := range c.acl.AclState().CurrentAccounts() {
|
||||||
|
if state.Permissions.NoPermissions() || state.Permissions.IsOwner() {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
identities = append(identities, state.PubKey)
|
||||||
|
}
|
||||||
|
recs, _ := c.acl.AclState().JoinRecords(false)
|
||||||
|
for _, rec := range recs {
|
||||||
|
recIds = append(recIds, rec.RecordId)
|
||||||
|
}
|
||||||
|
payload := list.BatchRequestPayload{
|
||||||
|
Removals: list.AccountRemovePayload{
|
||||||
|
Identities: identities,
|
||||||
|
Change: readKeyChange,
|
||||||
|
},
|
||||||
|
Declines: recIds,
|
||||||
|
InviteRevokes: c.acl.AclState().InviteIds(),
|
||||||
|
}
|
||||||
|
res, err := c.acl.RecordBuilder().BuildBatchRequest(payload)
|
||||||
|
if err != nil {
|
||||||
|
c.acl.Unlock()
|
||||||
|
return
|
||||||
|
}
|
||||||
|
c.acl.Unlock()
|
||||||
|
return c.sendRecordAndUpdate(ctx, c.spaceId, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (c *aclSpaceClient) DeclineRequest(ctx context.Context, identity crypto.PubKey) (err error) {
|
func (c *aclSpaceClient) DeclineRequest(ctx context.Context, identity crypto.PubKey) (err error) {
|
||||||
c.acl.Lock()
|
c.acl.Lock()
|
||||||
pendingReq, err := c.acl.AclState().JoinRecord(identity, false)
|
pendingReq, err := c.acl.AclState().JoinRecord(identity, false)
|
||||||
|
|
|
@ -55,6 +55,15 @@ type AccountAdd struct {
|
||||||
Metadata []byte
|
Metadata []byte
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type BatchRequestPayload struct {
|
||||||
|
Additions []AccountAdd
|
||||||
|
Changes []PermissionChangePayload
|
||||||
|
Removals AccountRemovePayload
|
||||||
|
Approvals []RequestAcceptPayload
|
||||||
|
Declines []string
|
||||||
|
InviteRevokes []string
|
||||||
|
}
|
||||||
|
|
||||||
type AccountRemovePayload struct {
|
type AccountRemovePayload struct {
|
||||||
Identities []crypto.PubKey
|
Identities []crypto.PubKey
|
||||||
Change ReadKeyChangePayload
|
Change ReadKeyChangePayload
|
||||||
|
@ -70,6 +79,7 @@ type AclRecordBuilder interface {
|
||||||
Unmarshall(rawRecord *consensusproto.RawRecord) (rec *AclRecord, err error)
|
Unmarshall(rawRecord *consensusproto.RawRecord) (rec *AclRecord, err error)
|
||||||
|
|
||||||
BuildRoot(content RootContent) (rec *consensusproto.RawRecordWithId, err error)
|
BuildRoot(content RootContent) (rec *consensusproto.RawRecordWithId, err error)
|
||||||
|
BuildBatchRequest(payload BatchRequestPayload) (rawRecord *consensusproto.RawRecord, err error)
|
||||||
BuildInvite() (res InviteResult, err error)
|
BuildInvite() (res InviteResult, err error)
|
||||||
BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error)
|
BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error)
|
||||||
BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error)
|
BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error)
|
||||||
|
@ -101,10 +111,59 @@ func NewAclRecordBuilder(id string, keyStorage crypto.KeyStorage, keys *accountd
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) BuildBatchRequest(payload BatchRequestPayload) (rawRec *consensusproto.RawRecord, err error) {
|
||||||
|
var aclContent []*aclrecordproto.AclContentValue
|
||||||
|
if len(payload.Additions) > 0 {
|
||||||
|
content, err := a.buildAccountsAdd(AccountsAddPayload{Additions: payload.Additions})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
if len(payload.Changes) > 0 {
|
||||||
|
content, err := a.buildPermissionChanges(PermissionChangesPayload{Changes: payload.Changes})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
for _, acc := range payload.Approvals {
|
||||||
|
content, err := a.buildRequestAccept(acc)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
for _, id := range payload.Declines {
|
||||||
|
content, err := a.buildRequestDecline(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
for _, id := range payload.InviteRevokes {
|
||||||
|
content, err := a.buildInviteRevoke(id)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
if len(payload.Removals.Identities) > 0 {
|
||||||
|
content, err := a.buildAccountRemove(payload.Removals)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
aclContent = append(aclContent, content)
|
||||||
|
}
|
||||||
|
return a.buildRecords(aclContent)
|
||||||
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValue) (rawRec *consensusproto.RawRecord, err error) {
|
||||||
aclData := &aclrecordproto.AclData{AclContent: []*aclrecordproto.AclContentValue{
|
return a.buildRecords([]*aclrecordproto.AclContentValue{aclContent})
|
||||||
aclContent,
|
}
|
||||||
}}
|
|
||||||
|
func (a *aclRecordBuilder) buildRecords(aclContent []*aclrecordproto.AclContentValue) (rawRec *consensusproto.RawRecord, err error) {
|
||||||
|
aclData := &aclrecordproto.AclData{AclContent: aclContent}
|
||||||
marshalledData, err := aclData.Marshal()
|
marshalledData, err := aclData.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
|
@ -135,6 +194,14 @@ func (a *aclRecordBuilder) buildRecord(aclContent *aclrecordproto.AclContentValu
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildPermissionChanges(payload PermissionChangesPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildPermissionChanges(payload PermissionChangesPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildPermissionChanges(payload)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildPermissionChanges(payload PermissionChangesPayload) (content *aclrecordproto.AclContentValue, err error) {
|
||||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||||
err = ErrInsufficientPermissions
|
err = ErrInsufficientPermissions
|
||||||
return
|
return
|
||||||
|
@ -158,13 +225,20 @@ func (a *aclRecordBuilder) BuildPermissionChanges(payload PermissionChangesPaylo
|
||||||
Permissions: aclrecordproto.AclUserPermissions(perm.Permissions),
|
Permissions: aclrecordproto.AclUserPermissions(perm.Permissions),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_PermissionChanges{
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_PermissionChanges{
|
||||||
&aclrecordproto.AclAccountPermissionChanges{changes},
|
&aclrecordproto.AclAccountPermissionChanges{changes},
|
||||||
}}
|
}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildAccountsAdd(payload AccountsAddPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildAccountsAdd(payload AccountsAddPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildAccountsAdd(payload)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildAccountsAdd(payload AccountsAddPayload) (value *aclrecordproto.AclContentValue, err error) {
|
||||||
var accs []*aclrecordproto.AclAccountAdd
|
var accs []*aclrecordproto.AclAccountAdd
|
||||||
for _, acc := range payload.Additions {
|
for _, acc := range payload.Additions {
|
||||||
if !a.state.Permissions(acc.Identity).NoPermissions() {
|
if !a.state.Permissions(acc.Identity).NoPermissions() {
|
||||||
|
@ -207,10 +281,9 @@ func (a *aclRecordBuilder) BuildAccountsAdd(payload AccountsAddPayload) (rawReco
|
||||||
EncryptedReadKey: enc,
|
EncryptedReadKey: enc,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountsAdd{
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountsAdd{
|
||||||
&aclrecordproto.AclAccountsAdd{accs},
|
&aclrecordproto.AclAccountsAdd{accs},
|
||||||
}}
|
}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
||||||
|
@ -238,6 +311,14 @@ func (a *aclRecordBuilder) BuildInvite() (res InviteResult, err error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildInviteRevoke(inviteRecordId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildInviteRevoke(inviteRecordId string) (value *aclrecordproto.AclContentValue, err error) {
|
||||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||||
err = ErrInsufficientPermissions
|
err = ErrInsufficientPermissions
|
||||||
return
|
return
|
||||||
|
@ -248,8 +329,7 @@ func (a *aclRecordBuilder) BuildInviteRevoke(inviteRecordId string) (rawRecord *
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
revokeRec := &aclrecordproto.AclAccountInviteRevoke{InviteRecordId: inviteRecordId}
|
revokeRec := &aclrecordproto.AclAccountInviteRevoke{InviteRecordId: inviteRecordId}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_InviteRevoke{InviteRevoke: revokeRec}}
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_InviteRevoke{InviteRevoke: revokeRec}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
@ -306,6 +386,14 @@ func (a *aclRecordBuilder) BuildRequestJoin(payload RequestJoinPayload) (rawReco
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildRequestAccept(payload)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildRequestAccept(payload RequestAcceptPayload) (value *aclrecordproto.AclContentValue, err error) {
|
||||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||||
err = ErrInsufficientPermissions
|
err = ErrInsufficientPermissions
|
||||||
return
|
return
|
||||||
|
@ -337,11 +425,18 @@ func (a *aclRecordBuilder) BuildRequestAccept(payload RequestAcceptPayload) (raw
|
||||||
EncryptedReadKey: enc,
|
EncryptedReadKey: enc,
|
||||||
Permissions: aclrecordproto.AclUserPermissions(payload.Permissions),
|
Permissions: aclrecordproto.AclUserPermissions(payload.Permissions),
|
||||||
}
|
}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestAccept{RequestAccept: acceptRec}}
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestAccept{RequestAccept: acceptRec}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildRequestDecline(requestRecordId)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildRequestDecline(requestRecordId string) (value *aclrecordproto.AclContentValue, err error) {
|
||||||
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
if !a.state.Permissions(a.state.pubKey).CanManageAccounts() {
|
||||||
err = ErrInsufficientPermissions
|
err = ErrInsufficientPermissions
|
||||||
return
|
return
|
||||||
|
@ -352,8 +447,7 @@ func (a *aclRecordBuilder) BuildRequestDecline(requestRecordId string) (rawRecor
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
declineRec := &aclrecordproto.AclAccountRequestDecline{RequestRecordId: requestRecordId}
|
declineRec := &aclrecordproto.AclAccountRequestDecline{RequestRecordId: requestRecordId}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestDecline{RequestDecline: declineRec}}
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_RequestDecline{RequestDecline: declineRec}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildRequestCancel(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildRequestCancel(requestRecordId string) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
@ -468,6 +562,14 @@ func (a *aclRecordBuilder) buildReadKeyChange(payload ReadKeyChangePayload, remo
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
content, err := a.buildAccountRemove(payload)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return a.buildRecord(content)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (a *aclRecordBuilder) buildAccountRemove(payload AccountRemovePayload) (value *aclrecordproto.AclContentValue, err error) {
|
||||||
deletedMap := map[string]struct{}{}
|
deletedMap := map[string]struct{}{}
|
||||||
for _, key := range payload.Identities {
|
for _, key := range payload.Identities {
|
||||||
permissions := a.state.Permissions(key)
|
permissions := a.state.Permissions(key)
|
||||||
|
@ -496,8 +598,7 @@ func (a *aclRecordBuilder) BuildAccountRemove(payload AccountRemovePayload) (raw
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
removeRec := &aclrecordproto.AclAccountRemove{ReadKeyChange: rkChange, Identities: marshalledIdentities}
|
removeRec := &aclrecordproto.AclAccountRemove{ReadKeyChange: rkChange, Identities: marshalledIdentities}
|
||||||
content := &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}}
|
return &aclrecordproto.AclContentValue{Value: &aclrecordproto.AclContentValue_AccountRemove{AccountRemove: removeRec}}, nil
|
||||||
return a.buildRecord(content)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *consensusproto.RawRecord, err error) {
|
func (a *aclRecordBuilder) BuildRequestRemove() (rawRecord *consensusproto.RawRecord, err error) {
|
||||||
|
|
|
@ -192,7 +192,15 @@ func (st *AclState) Invites() []crypto.PubKey {
|
||||||
return invites
|
return invites
|
||||||
}
|
}
|
||||||
|
|
||||||
func (st *AclState) applyRecord(record *AclRecord) (err error) {
|
func (st *AclState) InviteIds() []string {
|
||||||
|
var invites []string
|
||||||
|
for invId := range st.inviteKeys {
|
||||||
|
invites = append(invites, invId)
|
||||||
|
}
|
||||||
|
return invites
|
||||||
|
}
|
||||||
|
|
||||||
|
func (st *AclState) ApplyRecord(record *AclRecord) (err error) {
|
||||||
if st.lastRecordId != record.PrevId {
|
if st.lastRecordId != record.PrevId {
|
||||||
err = ErrIncorrectRecordSequence
|
err = ErrIncorrectRecordSequence
|
||||||
return
|
return
|
||||||
|
@ -296,6 +304,44 @@ func (st *AclState) applyChangeData(record *AclRecord) (err error) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (st *AclState) Copy() *AclState {
|
||||||
|
newSt := &AclState{
|
||||||
|
id: st.id,
|
||||||
|
key: st.key,
|
||||||
|
pubKey: st.key.GetPublic(),
|
||||||
|
keys: make(map[string]AclKeys),
|
||||||
|
accountStates: make(map[string]AccountState),
|
||||||
|
inviteKeys: make(map[string]crypto.PubKey),
|
||||||
|
requestRecords: make(map[string]RequestRecord),
|
||||||
|
pendingRequests: make(map[string]string),
|
||||||
|
keyStore: st.keyStore,
|
||||||
|
}
|
||||||
|
for k, v := range st.keys {
|
||||||
|
newSt.keys[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range st.accountStates {
|
||||||
|
var permChanges []PermissionChange
|
||||||
|
permChanges = append(permChanges, v.PermissionChanges...)
|
||||||
|
accState := v
|
||||||
|
accState.PermissionChanges = permChanges
|
||||||
|
newSt.accountStates[k] = accState
|
||||||
|
}
|
||||||
|
for k, v := range st.inviteKeys {
|
||||||
|
newSt.inviteKeys[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range st.requestRecords {
|
||||||
|
newSt.requestRecords[k] = v
|
||||||
|
}
|
||||||
|
for k, v := range st.pendingRequests {
|
||||||
|
newSt.pendingRequests[k] = v
|
||||||
|
}
|
||||||
|
newSt.readKeyChanges = append(newSt.readKeyChanges, st.readKeyChanges...)
|
||||||
|
newSt.list = st.list
|
||||||
|
newSt.lastRecordId = st.lastRecordId
|
||||||
|
newSt.contentValidator = newContentValidator(newSt.keyStore, newSt)
|
||||||
|
return newSt
|
||||||
|
}
|
||||||
|
|
||||||
func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, record *AclRecord) error {
|
func (st *AclState) applyChangeContent(ch *aclrecordproto.AclContentValue, record *AclRecord) error {
|
||||||
switch {
|
switch {
|
||||||
case ch.GetPermissionChange() != nil:
|
case ch.GetPermissionChange() != nil:
|
||||||
|
@ -522,16 +568,18 @@ func (st *AclState) unpackAllKeys(rk []byte) error {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
model := rec.Model.(*aclrecordproto.AclData)
|
model := rec.Model.(*aclrecordproto.AclData)
|
||||||
if len(model.GetAclContent()) != 1 {
|
content := model.GetAclContent()
|
||||||
return ErrIncorrectReadKey
|
|
||||||
}
|
|
||||||
ch := model.GetAclContent()[0]
|
|
||||||
var readKeyChange *aclrecordproto.AclReadKeyChange
|
var readKeyChange *aclrecordproto.AclReadKeyChange
|
||||||
switch {
|
for _, ch := range content {
|
||||||
case ch.GetReadKeyChange() != nil:
|
switch {
|
||||||
readKeyChange = ch.GetReadKeyChange()
|
case ch.GetReadKeyChange() != nil:
|
||||||
case ch.GetAccountRemove() != nil:
|
readKeyChange = ch.GetReadKeyChange()
|
||||||
readKeyChange = ch.GetAccountRemove().GetReadKeyChange()
|
case ch.GetAccountRemove() != nil:
|
||||||
|
readKeyChange = ch.GetAccountRemove().GetReadKeyChange()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if readKeyChange == nil {
|
||||||
|
return ErrIncorrectReadKey
|
||||||
}
|
}
|
||||||
oldReadKey, err := st.unmarshallDecryptReadKey(readKeyChange.EncryptedOldReadKey, iterReadKey.Decrypt)
|
oldReadKey, err := st.unmarshallDecryptReadKey(readKeyChange.EncryptedOldReadKey, iterReadKey.Decrypt)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -41,7 +41,7 @@ func (sb *aclStateBuilder) Build(records []*AclRecord, list *aclList) (state *Ac
|
||||||
}
|
}
|
||||||
state.list = list
|
state.list = list
|
||||||
for _, rec := range records[1:] {
|
for _, rec := range records[1:] {
|
||||||
err = state.applyRecord(rec)
|
err = state.ApplyRecord(rec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -52,7 +52,7 @@ func (sb *aclStateBuilder) Build(records []*AclRecord, list *aclList) (state *Ac
|
||||||
|
|
||||||
func (sb *aclStateBuilder) Append(state *AclState, records []*AclRecord) (err error) {
|
func (sb *aclStateBuilder) Append(state *AclState, records []*AclRecord) (err error) {
|
||||||
for _, rec := range records {
|
for _, rec := range records {
|
||||||
err = state.applyRecord(rec)
|
err = state.ApplyRecord(rec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,8 +47,164 @@ var (
|
||||||
errIncorrectParts = errors.New("incorrect parts")
|
errIncorrectParts = errors.New("incorrect parts")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func (a *AclTestExecutor) buildBatchRequest(args []string, acl AclList, getPerm func(perm string) AclPermissions, addRec func(rec *consensusproto.RawRecordWithId) error) (afterAll []func(), err error) {
|
||||||
|
// remove:a,b,c;add:d,rw,m1|e,r,m2;changes:f,rw|g,r;revoke:inv1id;decline:g,h;
|
||||||
|
batchPayload := BatchRequestPayload{}
|
||||||
|
for _, arg := range args {
|
||||||
|
parts := strings.Split(arg, ":")
|
||||||
|
if len(parts) != 2 {
|
||||||
|
return nil, errIncorrectParts
|
||||||
|
}
|
||||||
|
command := parts[0]
|
||||||
|
commandArgs := strings.Split(parts[1], "|")
|
||||||
|
switch command {
|
||||||
|
case "add":
|
||||||
|
var payloads []AccountAdd
|
||||||
|
for _, arg := range commandArgs {
|
||||||
|
argParts := strings.Split(arg, ",")
|
||||||
|
if len(argParts) != 3 {
|
||||||
|
return nil, errIncorrectParts
|
||||||
|
}
|
||||||
|
keys, err := accountdata.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
ownerAcl := a.actualAccounts[a.owner].Acl.(*aclList)
|
||||||
|
accountAcl, err := BuildAclListWithIdentity(keys, ownerAcl.storage, NoOpAcceptorVerifier{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
state := &TestAclState{
|
||||||
|
Keys: keys,
|
||||||
|
Acl: accountAcl,
|
||||||
|
}
|
||||||
|
account := argParts[0]
|
||||||
|
a.actualAccounts[account] = state
|
||||||
|
a.expectedAccounts[account] = &accountExpectedState{
|
||||||
|
perms: getPerm(argParts[1]),
|
||||||
|
status: StatusActive,
|
||||||
|
metadata: []byte(argParts[2]),
|
||||||
|
pseudoId: account,
|
||||||
|
}
|
||||||
|
payloads = append(payloads, AccountAdd{
|
||||||
|
Identity: keys.SignKey.GetPublic(),
|
||||||
|
Permissions: getPerm(argParts[1]),
|
||||||
|
Metadata: []byte(argParts[2]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
defer func() {
|
||||||
|
if err != nil {
|
||||||
|
for _, arg := range args {
|
||||||
|
argParts := strings.Split(arg, ",")
|
||||||
|
account := argParts[0]
|
||||||
|
delete(a.expectedAccounts, account)
|
||||||
|
delete(a.actualAccounts, account)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
batchPayload.Additions = payloads
|
||||||
|
case "remove":
|
||||||
|
identities := strings.Split(commandArgs[0], ",")
|
||||||
|
var pubKeys []crypto.PubKey
|
||||||
|
for _, id := range identities {
|
||||||
|
pk := a.actualAccounts[id].Keys.SignKey.GetPublic()
|
||||||
|
pubKeys = append(pubKeys, pk)
|
||||||
|
}
|
||||||
|
priv, _, err := crypto.GenerateRandomEd25519KeyPair()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
sym := crypto.NewAES()
|
||||||
|
payload := AccountRemovePayload{
|
||||||
|
Identities: pubKeys,
|
||||||
|
Change: ReadKeyChangePayload{
|
||||||
|
MetadataKey: priv,
|
||||||
|
ReadKey: sym,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
batchPayload.Removals = payload
|
||||||
|
afterAll = append(afterAll, func() {
|
||||||
|
for _, id := range identities {
|
||||||
|
a.expectedAccounts[id].status = StatusRemoved
|
||||||
|
a.expectedAccounts[id].perms = AclPermissionsNone
|
||||||
|
}
|
||||||
|
})
|
||||||
|
case "changes":
|
||||||
|
var payloads []PermissionChangePayload
|
||||||
|
for _, arg := range commandArgs {
|
||||||
|
argParts := strings.Split(arg, ",")
|
||||||
|
if len(argParts) != 2 {
|
||||||
|
return nil, errIncorrectParts
|
||||||
|
}
|
||||||
|
changed := a.actualAccounts[argParts[0]].Keys.SignKey.GetPublic()
|
||||||
|
perms := getPerm(argParts[1])
|
||||||
|
payloads = append(payloads, PermissionChangePayload{
|
||||||
|
Identity: changed,
|
||||||
|
Permissions: perms,
|
||||||
|
})
|
||||||
|
afterAll = append(afterAll, func() {
|
||||||
|
a.expectedAccounts[argParts[0]].perms = perms
|
||||||
|
})
|
||||||
|
}
|
||||||
|
batchPayload.Changes = payloads
|
||||||
|
case "revoke":
|
||||||
|
invite := a.invites[commandArgs[0]]
|
||||||
|
invId, err := acl.AclState().GetInviteIdByPrivKey(invite)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
batchPayload.InviteRevokes = append(batchPayload.InviteRevokes, invId)
|
||||||
|
case "decline":
|
||||||
|
id := commandArgs[0]
|
||||||
|
pk := a.actualAccounts[id].Keys.SignKey.GetPublic()
|
||||||
|
rec, err := acl.AclState().JoinRecord(pk, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
batchPayload.Declines = append(batchPayload.Declines, rec.RecordId)
|
||||||
|
afterAll = append(afterAll, func() {
|
||||||
|
a.expectedAccounts[id].status = StatusDeclined
|
||||||
|
})
|
||||||
|
case "approve":
|
||||||
|
recs, err := acl.AclState().JoinRecords(false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
argParts := strings.Split(commandArgs[0], ",")
|
||||||
|
if len(argParts) != 2 {
|
||||||
|
return nil, errIncorrectParts
|
||||||
|
}
|
||||||
|
approved := a.actualAccounts[argParts[0]].Keys.SignKey.GetPublic()
|
||||||
|
var recId string
|
||||||
|
for _, rec := range recs {
|
||||||
|
if rec.RequestIdentity.Equals(approved) {
|
||||||
|
recId = rec.RecordId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if recId == "" {
|
||||||
|
return nil, fmt.Errorf("no join records for approve")
|
||||||
|
}
|
||||||
|
perms := getPerm(argParts[1])
|
||||||
|
afterAll = append(afterAll, func() {
|
||||||
|
a.expectedAccounts[argParts[0]].status = StatusActive
|
||||||
|
a.expectedAccounts[argParts[0]].perms = perms
|
||||||
|
})
|
||||||
|
batchPayload.Approvals = append(batchPayload.Approvals, RequestAcceptPayload{
|
||||||
|
RequestRecordId: recId,
|
||||||
|
Permissions: perms,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
res, err := acl.RecordBuilder().BuildBatchRequest(batchPayload)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return afterAll, addRec(WrapAclRecord(res))
|
||||||
|
}
|
||||||
|
|
||||||
func (a *AclTestExecutor) Execute(cmd string) (err error) {
|
func (a *AclTestExecutor) Execute(cmd string) (err error) {
|
||||||
parts := strings.Split(cmd, ":")
|
parts := strings.Split(cmd, "::")
|
||||||
if len(parts) != 2 {
|
if len(parts) != 2 {
|
||||||
return errIncorrectParts
|
return errIncorrectParts
|
||||||
}
|
}
|
||||||
|
@ -181,6 +337,11 @@ func (a *AclTestExecutor) Execute(cmd string) (err error) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
case "batch":
|
||||||
|
afterAll, err = a.buildBatchRequest(args, acl, getPerm, addRec)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
case "approve":
|
case "approve":
|
||||||
recs, err := acl.AclState().JoinRecords(false)
|
recs, err := acl.AclState().JoinRecords(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -50,61 +50,67 @@ func TestAclExecutor(t *testing.T) {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
cmds := []cmdErr{
|
cmds := []cmdErr{
|
||||||
{"a.init:a", nil},
|
{"a.init::a", nil},
|
||||||
// creating an invite
|
// creating an invite
|
||||||
{"a.invite:invId", nil},
|
{"a.invite::invId", nil},
|
||||||
// cannot self join
|
// cannot self join
|
||||||
{"a.join:invId", ErrInsufficientPermissions},
|
{"a.join::invId", ErrInsufficientPermissions},
|
||||||
// now b can join
|
// now b can join
|
||||||
{"b.join:invId", nil},
|
{"b.join::invId", nil},
|
||||||
// a approves b, it can write now
|
// a approves b, it can write now
|
||||||
{"a.approve:b,r", nil},
|
{"a.approve::b,r", nil},
|
||||||
// c joins with the same invite
|
// c joins with the same invite
|
||||||
{"c.join:invId", nil},
|
{"c.join::invId", nil},
|
||||||
// a approves c
|
// a approves c
|
||||||
{"a.approve:c,r", nil},
|
{"a.approve::c,r", nil},
|
||||||
// a removes c
|
// a removes c
|
||||||
{"a.remove:c", nil},
|
{"a.remove::c", nil},
|
||||||
// e also joins as an admin
|
// e also joins as an admin
|
||||||
{"e.join:invId", nil},
|
{"e.join::invId", nil},
|
||||||
{"a.approve:e,adm", nil},
|
{"a.approve::e,adm", nil},
|
||||||
// now e can remove other users
|
// now e can remove other users
|
||||||
{"e.remove:b", nil},
|
{"e.remove::b", nil},
|
||||||
{"e.revoke:invId", nil},
|
{"e.revoke::invId", nil},
|
||||||
{"z.join:invId", ErrNoSuchInvite},
|
{"z.join::invId", ErrNoSuchInvite},
|
||||||
// e can't revoke the same id
|
// e can't revoke the same id
|
||||||
{"e.revoke:invId", ErrNoSuchRecord},
|
{"e.revoke::invId", ErrNoSuchRecord},
|
||||||
// e can't remove a, because a is the owner
|
// e can't remove a, because a is the owner
|
||||||
{"e.remove:a", ErrInsufficientPermissions},
|
{"e.remove::a", ErrInsufficientPermissions},
|
||||||
// e can add new users
|
// e can add new users
|
||||||
{"e.add:x,r,m1;y,adm,m2", nil},
|
{"e.add::x,r,m1;y,adm,m2", nil},
|
||||||
// now y can also change permission as an admin
|
// now y can also change permission as an admin
|
||||||
{"y.changes:x,rw", nil},
|
{"y.changes::x,rw", nil},
|
||||||
// e can generate another invite
|
// e can generate another invite
|
||||||
{"e.invite:inv1Id", nil},
|
{"e.invite::inv1Id", nil},
|
||||||
// b tries to join again
|
// b tries to join again
|
||||||
{"b.join:inv1Id", nil},
|
{"b.join::inv1Id", nil},
|
||||||
// e approves b
|
// e approves b
|
||||||
{"e.approve:b,rw", nil},
|
{"e.approve::b,rw", nil},
|
||||||
{"g.join:inv1Id", nil},
|
{"g.join::inv1Id", nil},
|
||||||
{"g.cancel:g", nil},
|
{"g.cancel::g", nil},
|
||||||
// e cannot approve cancelled request
|
// e cannot approve cancelled request
|
||||||
{"e.approve:g,rw", fmt.Errorf("no join records for approve")},
|
{"e.approve::g,rw", fmt.Errorf("no join records for approve")},
|
||||||
{"g.join:inv1Id", nil},
|
{"g.join::inv1Id", nil},
|
||||||
{"e.decline:g", nil},
|
{"e.decline::g", nil},
|
||||||
// g cannot cancel declined request
|
// g cannot cancel declined request
|
||||||
{"g.cancel:g", ErrNoSuchRecord},
|
{"g.cancel::g", ErrNoSuchRecord},
|
||||||
{"g.join:inv1Id", nil},
|
{"g.join::inv1Id", nil},
|
||||||
{"e.approve:g,r", nil},
|
{"e.approve::g,r", nil},
|
||||||
// g can request remove
|
// g can request remove
|
||||||
{"g.request_remove:g", nil},
|
{"g.request_remove::g", nil},
|
||||||
// g can cancel request to remove
|
// g can cancel request to remove
|
||||||
{"g.cancel:g", nil},
|
{"g.cancel::g", nil},
|
||||||
{"g.request_remove:g", nil},
|
{"g.request_remove::g", nil},
|
||||||
{"g.request_remove:g", ErrPendingRequest},
|
{"g.request_remove::g", ErrPendingRequest},
|
||||||
{"a.remove:g", nil},
|
{"a.remove::g", nil},
|
||||||
// g cannot cancel not existing request to remove
|
// g cannot cancel not existing request to remove
|
||||||
{"g.cancel:g", ErrNoSuchRecord},
|
{"g.cancel::g", ErrNoSuchRecord},
|
||||||
|
{"l.join::inv1Id", nil},
|
||||||
|
{"p.join::inv1Id", nil},
|
||||||
|
{"s.join::inv1Id", nil},
|
||||||
|
{"a.batch::remove:e,y;add:z,rw,mz|u,r,mu;revoke:inv1Id;approve:l,r;approve:p,adm;decline:s", nil},
|
||||||
|
{"p.remove::l", nil},
|
||||||
|
{"s.join::inv1Id", ErrNoSuchInvite},
|
||||||
}
|
}
|
||||||
for _, cmd := range cmds {
|
for _, cmd := range cmds {
|
||||||
err := a.Execute(cmd.cmd)
|
err := a.Execute(cmd.cmd)
|
||||||
|
|
|
@ -58,7 +58,7 @@ type AclList interface {
|
||||||
KeyStorage() crypto.KeyStorage
|
KeyStorage() crypto.KeyStorage
|
||||||
RecordBuilder() AclRecordBuilder
|
RecordBuilder() AclRecordBuilder
|
||||||
|
|
||||||
ValidateRawRecord(record *consensusproto.RawRecord) (err error)
|
ValidateRawRecord(rawRec *consensusproto.RawRecord, afterValid func(state *AclState) error) (err error)
|
||||||
AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error)
|
AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err error)
|
||||||
AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error)
|
AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) (err error)
|
||||||
|
|
||||||
|
@ -192,12 +192,17 @@ func (a *aclList) Records() []*AclRecord {
|
||||||
return a.records
|
return a.records
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord) (err error) {
|
func (a *aclList) ValidateRawRecord(rawRec *consensusproto.RawRecord, afterValid func(state *AclState) error) (err error) {
|
||||||
record, err := a.recordBuilder.Unmarshall(rawRec)
|
record, err := a.recordBuilder.Unmarshall(rawRec)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
return a.aclState.Validator().ValidateAclRecordContents(record)
|
stateCopy := a.aclState.Copy()
|
||||||
|
err = stateCopy.ApplyRecord(record)
|
||||||
|
if err != nil || afterValid == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return afterValid(stateCopy)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) error {
|
func (a *aclList) AddRawRecords(rawRecords []*consensusproto.RawRecordWithId) error {
|
||||||
|
@ -218,9 +223,11 @@ func (a *aclList) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err erro
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err = a.aclState.applyRecord(record); err != nil {
|
copyState := a.aclState.Copy()
|
||||||
|
if err = copyState.ApplyRecord(record); err != nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
a.setState(copyState)
|
||||||
a.records = append(a.records, record)
|
a.records = append(a.records, record)
|
||||||
a.indexes[record.Id] = len(a.records) - 1
|
a.indexes[record.Id] = len(a.records) - 1
|
||||||
if err = a.storage.AddRawRecord(context.Background(), rawRec); err != nil {
|
if err = a.storage.AddRawRecord(context.Background(), rawRec); err != nil {
|
||||||
|
@ -232,6 +239,11 @@ func (a *aclList) AddRawRecord(rawRec *consensusproto.RawRecordWithId) (err erro
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (a *aclList) setState(state *AclState) {
|
||||||
|
a.aclState = state
|
||||||
|
a.recordBuilder.(*aclRecordBuilder).state = state
|
||||||
|
}
|
||||||
|
|
||||||
func (a *aclList) Id() string {
|
func (a *aclList) Id() string {
|
||||||
return a.id
|
return a.id
|
||||||
}
|
}
|
||||||
|
|
|
@ -56,10 +56,14 @@ func (fx *aclFixture) addRec(t *testing.T, rec *consensusproto.RawRecordWithId)
|
||||||
|
|
||||||
func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
|
func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
|
||||||
var (
|
var (
|
||||||
ownerAcl = fx.ownerAcl
|
ownerAcl = fx.ownerAcl
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
accountAcl = fx.accountAcl
|
accountAcl = fx.accountAcl
|
||||||
accountState = fx.accountAcl.aclState
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
// building invite
|
// building invite
|
||||||
inv, err := ownerAcl.RecordBuilder().BuildInvite()
|
inv, err := ownerAcl.RecordBuilder().BuildInvite()
|
||||||
|
@ -83,7 +87,7 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
// validate
|
// validate
|
||||||
err = ownerAcl.ValidateRawRecord(requestAccept)
|
err = ownerAcl.ValidateRawRecord(requestAccept, nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
requestAcceptRec := WrapAclRecord(requestAccept)
|
requestAcceptRec := WrapAclRecord(requestAccept)
|
||||||
fx.addRec(t, requestAcceptRec)
|
fx.addRec(t, requestAcceptRec)
|
||||||
|
@ -95,10 +99,10 @@ func (fx *aclFixture) inviteAccount(t *testing.T, perms AclPermissions) {
|
||||||
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
||||||
}
|
}
|
||||||
|
|
||||||
permsAtJoinRec, err := ownerState.PermissionsAtRecord(requestJoinRec.Id, accountState.pubKey)
|
permsAtJoinRec, err := ownerState().PermissionsAtRecord(requestJoinRec.Id, accountState().pubKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.Equal(t, AclPermissionsNone, permsAtJoinRec)
|
require.Equal(t, AclPermissionsNone, permsAtJoinRec)
|
||||||
permsAtRec, err := ownerState.PermissionsAtRecord(requestAcceptRec.Id, accountState.pubKey)
|
permsAtRec, err := ownerState().PermissionsAtRecord(requestAcceptRec.Id, accountState().pubKey)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, permsAtRec == perms)
|
require.True(t, permsAtRec == perms)
|
||||||
require.Equal(t, ownerAcl.AclState().lastRecordId, requestAcceptRec.Id)
|
require.Equal(t, ownerAcl.AclState().lastRecordId, requestAcceptRec.Id)
|
||||||
|
@ -122,8 +126,14 @@ func TestAclList_InvitePipeline(t *testing.T) {
|
||||||
func TestAclList_InviteRevoke(t *testing.T) {
|
func TestAclList_InviteRevoke(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerAcl = fx.ownerAcl
|
||||||
accountState = fx.accountAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
|
accountAcl = fx.accountAcl
|
||||||
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
// building invite
|
// building invite
|
||||||
inv, err := fx.ownerAcl.RecordBuilder().BuildInvite()
|
inv, err := fx.ownerAcl.RecordBuilder().BuildInvite()
|
||||||
|
@ -132,25 +142,29 @@ func TestAclList_InviteRevoke(t *testing.T) {
|
||||||
fx.addRec(t, inviteRec)
|
fx.addRec(t, inviteRec)
|
||||||
|
|
||||||
// building invite revoke
|
// building invite revoke
|
||||||
inviteRevoke, err := fx.ownerAcl.RecordBuilder().BuildInviteRevoke(ownerState.lastRecordId)
|
inviteRevoke, err := fx.ownerAcl.RecordBuilder().BuildInviteRevoke(ownerState().lastRecordId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
inviteRevokeRec := WrapAclRecord(inviteRevoke)
|
inviteRevokeRec := WrapAclRecord(inviteRevoke)
|
||||||
fx.addRec(t, inviteRevokeRec)
|
fx.addRec(t, inviteRevokeRec)
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, ownerState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions())
|
require.True(t, ownerState().Permissions(accountState().pubKey).NoPermissions())
|
||||||
require.Empty(t, ownerState.inviteKeys)
|
require.Empty(t, ownerState().inviteKeys)
|
||||||
require.Empty(t, accountState.inviteKeys)
|
require.Empty(t, accountState().inviteKeys)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAclList_RequestDecline(t *testing.T) {
|
func TestAclList_RequestDecline(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerAcl = fx.ownerAcl
|
ownerAcl = fx.ownerAcl
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
accountAcl = fx.accountAcl
|
accountAcl = fx.accountAcl
|
||||||
accountState = fx.accountAcl.aclState
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
// building invite
|
// building invite
|
||||||
inv, err := ownerAcl.RecordBuilder().BuildInvite()
|
inv, err := ownerAcl.RecordBuilder().BuildInvite()
|
||||||
|
@ -167,23 +181,29 @@ func TestAclList_RequestDecline(t *testing.T) {
|
||||||
fx.addRec(t, requestJoinRec)
|
fx.addRec(t, requestJoinRec)
|
||||||
|
|
||||||
// building request decline
|
// building request decline
|
||||||
requestDecline, err := ownerAcl.RecordBuilder().BuildRequestDecline(ownerState.lastRecordId)
|
requestDecline, err := ownerAcl.RecordBuilder().BuildRequestDecline(ownerState().lastRecordId)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
requestDeclineRec := WrapAclRecord(requestDecline)
|
requestDeclineRec := WrapAclRecord(requestDecline)
|
||||||
fx.addRec(t, requestDeclineRec)
|
fx.addRec(t, requestDeclineRec)
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, ownerState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions())
|
require.True(t, ownerState().Permissions(accountState().pubKey).NoPermissions())
|
||||||
require.Empty(t, ownerState.pendingRequests)
|
require.Empty(t, ownerState().pendingRequests)
|
||||||
require.Empty(t, accountState.pendingRequests)
|
require.Empty(t, accountState().pendingRequests)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAclList_Remove(t *testing.T) {
|
func TestAclList_Remove(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerAcl = fx.ownerAcl
|
||||||
accountState = fx.accountAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
|
accountAcl = fx.accountAcl
|
||||||
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
|
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
|
||||||
|
|
||||||
|
@ -202,21 +222,21 @@ func TestAclList_Remove(t *testing.T) {
|
||||||
fx.addRec(t, removeRec)
|
fx.addRec(t, removeRec)
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, ownerState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, ownerState.Permissions(accountState.pubKey).NoPermissions())
|
require.True(t, ownerState().Permissions(accountState().pubKey).NoPermissions())
|
||||||
require.True(t, ownerState.keys[removeRec.Id].ReadKey.Equals(newReadKey))
|
require.True(t, ownerState().keys[removeRec.Id].ReadKey.Equals(newReadKey))
|
||||||
require.True(t, ownerState.keys[removeRec.Id].MetadataPrivKey.Equals(privKey))
|
require.True(t, ownerState().keys[removeRec.Id].MetadataPrivKey.Equals(privKey))
|
||||||
require.True(t, ownerState.keys[removeRec.Id].MetadataPubKey.Equals(pubKey))
|
require.True(t, ownerState().keys[removeRec.Id].MetadataPubKey.Equals(pubKey))
|
||||||
require.NotEmpty(t, ownerState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, ownerState().keys[fx.ownerAcl.Id()])
|
||||||
require.Equal(t, 0, len(ownerState.pendingRequests))
|
require.Equal(t, 0, len(ownerState().pendingRequests))
|
||||||
require.Equal(t, 0, len(accountState.pendingRequests))
|
require.Equal(t, 0, len(accountState().pendingRequests))
|
||||||
require.True(t, accountState.Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, accountState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, accountState.Permissions(accountState.pubKey).NoPermissions())
|
require.True(t, accountState().Permissions(accountState().pubKey).NoPermissions())
|
||||||
require.NotEmpty(t, accountState.keys[removeRec.Id])
|
require.NotEmpty(t, accountState().keys[removeRec.Id])
|
||||||
require.Nil(t, accountState.keys[removeRec.Id].MetadataPrivKey)
|
require.Nil(t, accountState().keys[removeRec.Id].MetadataPrivKey)
|
||||||
require.NotNil(t, accountState.keys[removeRec.Id].MetadataPubKey)
|
require.NotNil(t, accountState().keys[removeRec.Id].MetadataPubKey)
|
||||||
require.Nil(t, accountState.keys[removeRec.Id].ReadKey)
|
require.Nil(t, accountState().keys[removeRec.Id].ReadKey)
|
||||||
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, accountState().keys[fx.ownerAcl.Id()])
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAclList_FixAcceptPanic(t *testing.T) {
|
func TestAclList_FixAcceptPanic(t *testing.T) {
|
||||||
|
@ -256,8 +276,14 @@ func TestAclList_MetadataDecrypt(t *testing.T) {
|
||||||
func TestAclList_ReadKeyChange(t *testing.T) {
|
func TestAclList_ReadKeyChange(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerAcl = fx.ownerAcl
|
||||||
accountState = fx.accountAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
|
accountAcl = fx.accountAcl
|
||||||
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin))
|
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin))
|
||||||
|
|
||||||
|
@ -273,26 +299,32 @@ func TestAclList_ReadKeyChange(t *testing.T) {
|
||||||
fx.addRec(t, readKeyRec)
|
fx.addRec(t, readKeyRec)
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
require.True(t, ownerState.Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, ownerState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, ownerState.Permissions(accountState.pubKey).CanManageAccounts())
|
require.True(t, ownerState().Permissions(accountState().pubKey).CanManageAccounts())
|
||||||
require.True(t, ownerState.keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
|
require.True(t, ownerState().keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
|
||||||
require.True(t, ownerState.keys[readKeyRec.Id].MetadataPrivKey.Equals(privKey))
|
require.True(t, ownerState().keys[readKeyRec.Id].MetadataPrivKey.Equals(privKey))
|
||||||
require.True(t, ownerState.keys[readKeyRec.Id].MetadataPubKey.Equals(pubKey))
|
require.True(t, ownerState().keys[readKeyRec.Id].MetadataPubKey.Equals(pubKey))
|
||||||
require.True(t, accountState.keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
|
require.True(t, accountState().keys[readKeyRec.Id].ReadKey.Equals(newReadKey))
|
||||||
require.NotEmpty(t, ownerState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, ownerState().keys[fx.ownerAcl.Id()])
|
||||||
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, accountState().keys[fx.ownerAcl.Id()])
|
||||||
readKey, err := ownerState.CurrentReadKey()
|
readKey, err := ownerState().CurrentReadKey()
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
require.True(t, newReadKey.Equals(readKey))
|
require.True(t, newReadKey.Equals(readKey))
|
||||||
require.Equal(t, 0, len(ownerState.pendingRequests))
|
require.Equal(t, 0, len(ownerState().pendingRequests))
|
||||||
require.Equal(t, 0, len(accountState.pendingRequests))
|
require.Equal(t, 0, len(accountState().pendingRequests))
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestAclList_PermissionChange(t *testing.T) {
|
func TestAclList_PermissionChange(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerAcl = fx.ownerAcl
|
||||||
accountState = fx.accountAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
|
accountAcl = fx.accountAcl
|
||||||
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin))
|
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Admin))
|
||||||
|
|
||||||
|
@ -306,8 +338,8 @@ func TestAclList_PermissionChange(t *testing.T) {
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
for _, acl := range []*aclList{fx.ownerAcl, fx.accountAcl} {
|
for _, acl := range []*aclList{fx.ownerAcl, fx.accountAcl} {
|
||||||
require.True(t, acl.AclState().Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, acl.AclState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, acl.AclState().Permissions(accountState.pubKey).CanWrite())
|
require.True(t, acl.AclState().Permissions(accountState().pubKey).CanWrite())
|
||||||
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
||||||
require.NotEmpty(t, acl.AclState().keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, acl.AclState().keys[fx.ownerAcl.Id()])
|
||||||
}
|
}
|
||||||
|
@ -316,8 +348,14 @@ func TestAclList_PermissionChange(t *testing.T) {
|
||||||
func TestAclList_RequestRemove(t *testing.T) {
|
func TestAclList_RequestRemove(t *testing.T) {
|
||||||
fx := newFixture(t)
|
fx := newFixture(t)
|
||||||
var (
|
var (
|
||||||
ownerState = fx.ownerAcl.aclState
|
ownerAcl = fx.ownerAcl
|
||||||
accountState = fx.accountAcl.aclState
|
ownerState = func() *AclState {
|
||||||
|
return ownerAcl.aclState
|
||||||
|
}
|
||||||
|
accountAcl = fx.accountAcl
|
||||||
|
accountState = func() *AclState {
|
||||||
|
return accountAcl.aclState
|
||||||
|
}
|
||||||
)
|
)
|
||||||
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
|
fx.inviteAccount(t, AclPermissions(aclrecordproto.AclUserPermissions_Writer))
|
||||||
|
|
||||||
|
@ -328,7 +366,7 @@ func TestAclList_RequestRemove(t *testing.T) {
|
||||||
|
|
||||||
recs := fx.accountAcl.AclState().RemoveRecords()
|
recs := fx.accountAcl.AclState().RemoveRecords()
|
||||||
require.Len(t, recs, 1)
|
require.Len(t, recs, 1)
|
||||||
require.True(t, accountState.pubKey.Equals(recs[0].RequestIdentity))
|
require.True(t, accountState().pubKey.Equals(recs[0].RequestIdentity))
|
||||||
|
|
||||||
newReadKey := crypto.NewAES()
|
newReadKey := crypto.NewAES()
|
||||||
privKey, _, err := crypto.GenerateRandomEd25519KeyPair()
|
privKey, _, err := crypto.GenerateRandomEd25519KeyPair()
|
||||||
|
@ -346,14 +384,14 @@ func TestAclList_RequestRemove(t *testing.T) {
|
||||||
|
|
||||||
// checking acl state
|
// checking acl state
|
||||||
for _, acl := range []*aclList{fx.ownerAcl, fx.accountAcl} {
|
for _, acl := range []*aclList{fx.ownerAcl, fx.accountAcl} {
|
||||||
require.True(t, acl.AclState().Permissions(ownerState.pubKey).IsOwner())
|
require.True(t, acl.AclState().Permissions(ownerState().pubKey).IsOwner())
|
||||||
require.True(t, acl.AclState().Permissions(accountState.pubKey).NoPermissions())
|
require.True(t, acl.AclState().Permissions(accountState().pubKey).NoPermissions())
|
||||||
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
require.Equal(t, 0, len(acl.AclState().pendingRequests))
|
||||||
}
|
}
|
||||||
require.True(t, ownerState.keys[removeRec.Id].ReadKey.Equals(newReadKey))
|
require.True(t, ownerState().keys[removeRec.Id].ReadKey.Equals(newReadKey))
|
||||||
require.NotEmpty(t, ownerState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, ownerState().keys[fx.ownerAcl.Id()])
|
||||||
require.Nil(t, accountState.keys[removeRec.Id].MetadataPrivKey)
|
require.Nil(t, accountState().keys[removeRec.Id].MetadataPrivKey)
|
||||||
require.NotNil(t, accountState.keys[removeRec.Id].MetadataPubKey)
|
require.NotNil(t, accountState().keys[removeRec.Id].MetadataPubKey)
|
||||||
require.Nil(t, accountState.keys[removeRec.Id].ReadKey)
|
require.Nil(t, accountState().keys[removeRec.Id].ReadKey)
|
||||||
require.NotEmpty(t, accountState.keys[fx.ownerAcl.Id()])
|
require.NotEmpty(t, accountState().keys[fx.ownerAcl.Id()])
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// mockgen -destination mock_list/mock_list.go github.com/anyproto/any-sync/commonspace/object/acl/list AclList
|
// mockgen -destination mock_list/mock_list.go github.com/anyproto/any-sync/commonspace/object/acl/list AclList
|
||||||
//
|
//
|
||||||
|
|
||||||
// Package mock_list is a generated GoMock package.
|
// Package mock_list is a generated GoMock package.
|
||||||
package mock_list
|
package mock_list
|
||||||
|
|
||||||
|
@ -344,15 +343,15 @@ func (mr *MockAclListMockRecorder) Unlock() *gomock.Call {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRawRecord mocks base method.
|
// ValidateRawRecord mocks base method.
|
||||||
func (m *MockAclList) ValidateRawRecord(arg0 *consensusproto.RawRecord) error {
|
func (m *MockAclList) ValidateRawRecord(arg0 *consensusproto.RawRecord, arg1 func(*list.AclState) error) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ValidateRawRecord", arg0)
|
ret := m.ctrl.Call(m, "ValidateRawRecord", arg0, arg1)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRawRecord indicates an expected call of ValidateRawRecord.
|
// ValidateRawRecord indicates an expected call of ValidateRawRecord.
|
||||||
func (mr *MockAclListMockRecorder) ValidateRawRecord(arg0 any) *gomock.Call {
|
func (mr *MockAclListMockRecorder) ValidateRawRecord(arg0, arg1 any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateRawRecord", reflect.TypeOf((*MockAclList)(nil).ValidateRawRecord), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateRawRecord", reflect.TypeOf((*MockAclList)(nil).ValidateRawRecord), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,13 @@ type contentValidator struct {
|
||||||
aclState *AclState
|
aclState *AclState
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newContentValidator(keyStore crypto.KeyStorage, aclState *AclState) ContentValidator {
|
||||||
|
return &contentValidator{
|
||||||
|
keyStore: keyStore,
|
||||||
|
aclState: aclState,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (c *contentValidator) ValidatePermissionChanges(ch *aclrecordproto.AclAccountPermissionChanges, authorIdentity crypto.PubKey) (err error) {
|
func (c *contentValidator) ValidatePermissionChanges(ch *aclrecordproto.AclAccountPermissionChanges, authorIdentity crypto.PubKey) (err error) {
|
||||||
for _, ch := range ch.Changes {
|
for _, ch := range ch.Changes {
|
||||||
err := c.ValidatePermissionChange(ch, authorIdentity)
|
err := c.ValidatePermissionChange(ch, authorIdentity)
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
//
|
//
|
||||||
// mockgen -destination mock_syncacl/mock_syncacl.go github.com/anyproto/any-sync/commonspace/object/acl/syncacl SyncAcl,SyncClient,RequestFactory,AclSyncProtocol
|
// mockgen -destination mock_syncacl/mock_syncacl.go github.com/anyproto/any-sync/commonspace/object/acl/syncacl SyncAcl,SyncClient,RequestFactory,AclSyncProtocol
|
||||||
//
|
//
|
||||||
|
|
||||||
// Package mock_syncacl is a generated GoMock package.
|
// Package mock_syncacl is a generated GoMock package.
|
||||||
package mock_syncacl
|
package mock_syncacl
|
||||||
|
|
||||||
|
@ -456,17 +455,17 @@ func (mr *MockSyncAclMockRecorder) Unlock() *gomock.Call {
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRawRecord mocks base method.
|
// ValidateRawRecord mocks base method.
|
||||||
func (m *MockSyncAcl) ValidateRawRecord(arg0 *consensusproto.RawRecord) error {
|
func (m *MockSyncAcl) ValidateRawRecord(arg0 *consensusproto.RawRecord, arg1 func(*list.AclState) error) error {
|
||||||
m.ctrl.T.Helper()
|
m.ctrl.T.Helper()
|
||||||
ret := m.ctrl.Call(m, "ValidateRawRecord", arg0)
|
ret := m.ctrl.Call(m, "ValidateRawRecord", arg0, arg1)
|
||||||
ret0, _ := ret[0].(error)
|
ret0, _ := ret[0].(error)
|
||||||
return ret0
|
return ret0
|
||||||
}
|
}
|
||||||
|
|
||||||
// ValidateRawRecord indicates an expected call of ValidateRawRecord.
|
// ValidateRawRecord indicates an expected call of ValidateRawRecord.
|
||||||
func (mr *MockSyncAclMockRecorder) ValidateRawRecord(arg0 any) *gomock.Call {
|
func (mr *MockSyncAclMockRecorder) ValidateRawRecord(arg0, arg1 any) *gomock.Call {
|
||||||
mr.mock.ctrl.T.Helper()
|
mr.mock.ctrl.T.Helper()
|
||||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateRawRecord", reflect.TypeOf((*MockSyncAcl)(nil).ValidateRawRecord), arg0)
|
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ValidateRawRecord", reflect.TypeOf((*MockSyncAcl)(nil).ValidateRawRecord), arg0, arg1)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MockSyncClient is a mock of SyncClient interface.
|
// MockSyncClient is a mock of SyncClient interface.
|
||||||
|
|
|
@ -128,10 +128,10 @@ func TestObjectTree(t *testing.T) {
|
||||||
err error
|
err error
|
||||||
}
|
}
|
||||||
cmds := []cmdErr{
|
cmds := []cmdErr{
|
||||||
{"a.init:a", nil},
|
{"a.init::a", nil},
|
||||||
{"a.invite:invId", nil},
|
{"a.invite::invId", nil},
|
||||||
{"b.join:invId", nil},
|
{"b.join::invId", nil},
|
||||||
{"a.approve:b,r", nil},
|
{"a.approve::b,r", nil},
|
||||||
}
|
}
|
||||||
for _, cmd := range cmds {
|
for _, cmd := range cmds {
|
||||||
err := exec.Execute(cmd.cmd)
|
err := exec.Execute(cmd.cmd)
|
||||||
|
@ -161,7 +161,7 @@ func TestObjectTree(t *testing.T) {
|
||||||
bStore := aTree.Storage().(*treestorage.InMemoryTreeStorage).Copy()
|
bStore := aTree.Storage().(*treestorage.InMemoryTreeStorage).Copy()
|
||||||
bTree, err := BuildKeyFilterableObjectTree(bStore, bAccount.Acl)
|
bTree, err := BuildKeyFilterableObjectTree(bStore, bAccount.Acl)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
err = exec.Execute("a.remove:b")
|
err = exec.Execute("a.remove::b")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
res, err := aTree.AddContent(ctx, SignableChangeContent{
|
res, err := aTree.AddContent(ctx, SignableChangeContent{
|
||||||
Data: []byte("some"),
|
Data: []byte("some"),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue