Skip to content

Commit 14f6ff3

Browse files
authored
Merge pull request #1073 from kaleido-io/node-patch
V1.0.x fix: Allow update of node using parent org identity
2 parents a28c2b3 + ccbeeb7 commit 14f6ff3

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

internal/definitions/definition_handler_identity_claim.go

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -36,21 +36,24 @@ func (dh *definitionHandlers) handleIdentityClaimBroadcast(ctx context.Context,
3636

3737
}
3838

39+
func (dh *definitionHandlers) getExpectedSigner(identity *fftypes.Identity, parent *fftypes.Identity) *fftypes.Identity {
40+
switch {
41+
case identity.Type == fftypes.IdentityTypeNode && parent != nil:
42+
// In the special case of a node, the parent signs it directly
43+
return parent
44+
default:
45+
return identity
46+
}
47+
}
48+
3949
func (dh *definitionHandlers) verifyClaimSignature(ctx context.Context, msg *fftypes.Message, identity *fftypes.Identity, parent *fftypes.Identity) (valid bool) {
4050

4151
author := msg.Header.Author
4252
if author == "" {
4353
return false
4454
}
4555

46-
var expectedSigner *fftypes.Identity
47-
switch {
48-
case identity.Type == fftypes.IdentityTypeNode:
49-
// In the special case of a node, the parent signs it directly
50-
expectedSigner = parent
51-
default:
52-
expectedSigner = identity
53-
}
56+
expectedSigner := dh.getExpectedSigner(identity, parent)
5457

5558
valid = author == expectedSigner.DID ||
5659
(expectedSigner.Type == fftypes.IdentityTypeOrg && author == fmt.Sprintf("%s%s", fftypes.FireFlyOrgDIDPrefix, expectedSigner.ID))

internal/definitions/definition_handler_identity_update.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,17 @@ func (dh *definitionHandlers) handleIdentityUpdateBroadcast(ctx context.Context,
4848
return HandlerResult{Action: ActionReject}, nil
4949
}
5050

51+
parent, retryable, err := dh.identity.VerifyIdentityChain(ctx, identity)
52+
if err != nil && retryable {
53+
return HandlerResult{Action: ActionRetry}, err
54+
} else if err != nil {
55+
log.L(ctx).Infof("Unable to process identity update (parked) %s: %s", msg.Header.ID, err)
56+
return HandlerResult{Action: ActionWait}, nil
57+
}
58+
5159
// Check the author matches
52-
if identity.DID != msg.Header.Author {
60+
expectedSigner := dh.getExpectedSigner(identity, parent)
61+
if expectedSigner.DID != msg.Header.Author {
5362
log.L(ctx).Warnf("Invalid identity update message %s - wrong author: %s", msg.Header.ID, msg.Header.Author)
5463
return HandlerResult{Action: ActionReject}, nil
5564
}

internal/definitions/definition_handler_identity_update_test.go

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ func TestHandleDefinitionIdentityUpdateOk(t *testing.T) {
7474

7575
mim := dh.identity.(*identitymanagermocks.Manager)
7676
mim.On("CachedIdentityLookupByID", ctx, org1.ID).Return(org1, nil)
77+
mim.On("VerifyIdentityChain", ctx, mock.Anything).Return(nil, false, nil)
7778

7879
mdi := dh.database.(*databasemocks.Plugin)
7980
mdi.On("UpsertIdentity", ctx, mock.MatchedBy(func(identity *fftypes.Identity) bool {
@@ -105,6 +106,7 @@ func TestHandleDefinitionIdentityUpdateUpsertFail(t *testing.T) {
105106

106107
mim := dh.identity.(*identitymanagermocks.Manager)
107108
mim.On("CachedIdentityLookupByID", ctx, org1.ID).Return(org1, nil)
109+
mim.On("VerifyIdentityChain", ctx, mock.Anything).Return(nil, false, nil)
108110

109111
mdi := dh.database.(*databasemocks.Plugin)
110112
mdi.On("UpsertIdentity", ctx, mock.Anything, database.UpsertOptimizationExisting).Return(fmt.Errorf("pop"))
@@ -127,6 +129,7 @@ func TestHandleDefinitionIdentityInvalidIdentity(t *testing.T) {
127129

128130
mim := dh.identity.(*identitymanagermocks.Manager)
129131
mim.On("CachedIdentityLookupByID", ctx, org1.ID).Return(org1, nil)
132+
mim.On("VerifyIdentityChain", ctx, mock.Anything).Return(nil, false, nil)
130133

131134
action, err := dh.HandleDefinitionBroadcast(ctx, bs, updateMsg, fftypes.DataArray{updateData}, fftypes.NewUUID())
132135
assert.Equal(t, HandlerResult{Action: ActionReject}, action)
@@ -136,6 +139,44 @@ func TestHandleDefinitionIdentityInvalidIdentity(t *testing.T) {
136139
bs.assertNoFinalizers()
137140
}
138141

142+
func TestHandleDefinitionVerifyFail(t *testing.T) {
143+
dh, bs := newTestDefinitionHandlers(t)
144+
ctx := context.Background()
145+
146+
org1, updateMsg, updateData, _ := testIdentityUpdate(t)
147+
updateMsg.Header.Author = "wrong"
148+
149+
mim := dh.identity.(*identitymanagermocks.Manager)
150+
mim.On("CachedIdentityLookupByID", ctx, org1.ID).Return(org1, nil)
151+
mim.On("VerifyIdentityChain", ctx, mock.Anything).Return(nil, true, fmt.Errorf("pop"))
152+
153+
action, err := dh.HandleDefinitionBroadcast(ctx, bs, updateMsg, fftypes.DataArray{updateData}, fftypes.NewUUID())
154+
assert.Equal(t, HandlerResult{Action: ActionRetry}, action)
155+
assert.Regexp(t, "pop", err)
156+
157+
mim.AssertExpectations(t)
158+
bs.assertNoFinalizers()
159+
}
160+
161+
func TestHandleDefinitionVerifyWait(t *testing.T) {
162+
dh, bs := newTestDefinitionHandlers(t)
163+
ctx := context.Background()
164+
165+
org1, updateMsg, updateData, _ := testIdentityUpdate(t)
166+
updateMsg.Header.Author = "wrong"
167+
168+
mim := dh.identity.(*identitymanagermocks.Manager)
169+
mim.On("CachedIdentityLookupByID", ctx, org1.ID).Return(org1, nil)
170+
mim.On("VerifyIdentityChain", ctx, mock.Anything).Return(nil, false, fmt.Errorf("pop"))
171+
172+
action, err := dh.HandleDefinitionBroadcast(ctx, bs, updateMsg, fftypes.DataArray{updateData}, fftypes.NewUUID())
173+
assert.Equal(t, HandlerResult{Action: ActionWait}, action)
174+
assert.NoError(t, err)
175+
176+
mim.AssertExpectations(t)
177+
bs.assertNoFinalizers()
178+
}
179+
139180
func TestHandleDefinitionIdentityNotFound(t *testing.T) {
140181
dh, bs := newTestDefinitionHandlers(t)
141182
ctx := context.Background()

0 commit comments

Comments
 (0)