Skip to content

Commit 38e0d49

Browse files
committed
unit tests
Signed-off-by: Angelo De Caro <angelo.decaro@gmail.com>
1 parent 49dea13 commit 38e0d49

File tree

4 files changed

+395
-3
lines changed

4 files changed

+395
-3
lines changed

token/core/common/validator_auditing.go

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,32 @@ func AuditingSignaturesValidate[P driver.PublicParameters, T any, TA driver.Tran
1717
if len(ctx.TokenRequest.AuditorSignatures) != 0 {
1818
return errors.New("auditor signatures are not empty")
1919
}
20+
return nil
2021
}
2122

23+
auditors := ctx.PP.Auditors()
2224
for _, auditorSignature := range ctx.TokenRequest.AuditorSignatures {
2325
auditor := auditorSignature.Identity
26+
// check that issuer of this issue action is authorized
27+
found := false
28+
for _, target := range auditors {
29+
if auditor.Equal(target) {
30+
found = true
31+
break
32+
}
33+
}
34+
if !found {
35+
return errors.Errorf("auditor [%s] is not in auditors", auditor)
36+
}
37+
2438
verifier, err := ctx.Deserializer.GetAuditorVerifier(auditor)
2539
if err != nil {
26-
return errors.Errorf("failed to deserialize auditor's public key")
40+
return errors.Wrapf(err, "failed to deserialize auditor's public key")
2741
}
2842
_, err = ctx.SignatureProvider.HasBeenSignedBy(auditor, verifier)
2943
if err != nil {
30-
return errors.Errorf("failed to verify auditor's signature")
44+
return errors.Wrap(err, "failed to verify auditor's signature")
3145
}
3246
}
3347
return nil
34-
3548
}
Lines changed: 193 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,193 @@
1+
/*
2+
Copyright IBM Corp. All Rights Reserved.
3+
4+
SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
package common
8+
9+
import (
10+
"testing"
11+
12+
"github.com/hyperledger-labs/fabric-smart-client/pkg/utils/errors"
13+
"github.com/hyperledger-labs/fabric-smart-client/platform/common/services/identity"
14+
"github.com/hyperledger-labs/fabric-token-sdk/token/driver"
15+
"github.com/hyperledger-labs/fabric-token-sdk/token/driver/mock"
16+
"github.com/stretchr/testify/assert"
17+
)
18+
19+
type (
20+
TestContext = Context[driver.PublicParameters, any, driver.TransferAction, driver.IssueAction, driver.Deserializer]
21+
TestCheck = func() bool
22+
)
23+
24+
func TestAuditingSignaturesValidate(t *testing.T) {
25+
tests := []struct {
26+
name string
27+
err bool
28+
errMsg string
29+
context func() (*TestContext, TestCheck)
30+
}{
31+
{
32+
name: "No auditors but token requests with auditor signatures",
33+
err: true,
34+
errMsg: "auditor signatures are not empty",
35+
context: func() (*TestContext, TestCheck) {
36+
pp := &mock.PublicParameters{}
37+
pp.AuditorsReturns(nil)
38+
return &TestContext{
39+
PP: pp,
40+
TokenRequest: &driver.TokenRequest{
41+
AuditorSignatures: []*driver.AuditorSignature{
42+
{
43+
Identity: driver.Identity("auditor"),
44+
Signature: []byte("auditor's signature"),
45+
},
46+
},
47+
},
48+
}, nil
49+
},
50+
},
51+
{
52+
name: "No auditors and no token requests with auditor signatures",
53+
err: false,
54+
context: func() (*TestContext, TestCheck) {
55+
pp := &mock.PublicParameters{}
56+
pp.AuditorsReturns(nil)
57+
return &TestContext{
58+
PP: pp,
59+
TokenRequest: &driver.TokenRequest{},
60+
}, nil
61+
},
62+
},
63+
{
64+
name: "it is not an auditor",
65+
err: true,
66+
errMsg: "auditor [LERVQYVKJM22xRRnp0G1rmcuYpOTY4x0mWJ5V21ZQ5I=] is not in auditors",
67+
context: func() (*TestContext, TestCheck) {
68+
pp := &mock.PublicParameters{}
69+
pp.AuditorsReturns([]identity.Identity{driver.Identity("auditor1")})
70+
return &TestContext{
71+
PP: pp,
72+
TokenRequest: &driver.TokenRequest{
73+
AuditorSignatures: []*driver.AuditorSignature{
74+
{
75+
Identity: driver.Identity("auditor2"),
76+
Signature: []byte("auditor 2's signature"),
77+
},
78+
},
79+
},
80+
}, nil
81+
},
82+
},
83+
{
84+
name: "it is an auditor but I cannot deserialize it",
85+
err: true,
86+
errMsg: "failed to deserialize auditor's public key: auditor deserialize fail",
87+
context: func() (*TestContext, TestCheck) {
88+
pp := &mock.PublicParameters{}
89+
pp.AuditorsReturns([]identity.Identity{driver.Identity("auditor")})
90+
91+
des := &mock.Deserializer{}
92+
des.GetAuditorVerifierReturns(nil, errors.Errorf("auditor deserialize fail"))
93+
return &TestContext{
94+
PP: pp,
95+
TokenRequest: &driver.TokenRequest{
96+
AuditorSignatures: []*driver.AuditorSignature{
97+
{
98+
Identity: driver.Identity("auditor"),
99+
Signature: []byte("auditor's signature"),
100+
},
101+
},
102+
},
103+
Deserializer: des,
104+
}, nil
105+
},
106+
},
107+
{
108+
name: "it is an auditor but I cannot verify its signature",
109+
err: true,
110+
errMsg: "failed to verify auditor's signature: signature is not valid",
111+
context: func() (*TestContext, TestCheck) {
112+
auditor := driver.Identity("auditor")
113+
pp := &mock.PublicParameters{}
114+
pp.AuditorsReturns([]identity.Identity{auditor})
115+
ver := &mock.Verifier{}
116+
ver.VerifyReturns(errors.New("signature is not valid"))
117+
des := &mock.Deserializer{}
118+
des.GetAuditorVerifierReturns(ver, nil)
119+
sp := &mock.SignatureProvider{}
120+
sp.HasBeenSignedByReturns(nil, errors.New("signature is not valid"))
121+
return &TestContext{
122+
PP: pp,
123+
TokenRequest: &driver.TokenRequest{
124+
AuditorSignatures: []*driver.AuditorSignature{
125+
{
126+
Identity: auditor,
127+
Signature: []byte("auditor's signature"),
128+
},
129+
},
130+
},
131+
Deserializer: des,
132+
SignatureProvider: sp,
133+
}, func() bool {
134+
id, ver2 := sp.HasBeenSignedByArgsForCall(0)
135+
if ver2 != ver {
136+
return false
137+
}
138+
return auditor.Equal(id)
139+
}
140+
},
141+
},
142+
{
143+
name: "it is an auditor and the signature is valid",
144+
err: false,
145+
context: func() (*TestContext, TestCheck) {
146+
auditor := driver.Identity("auditor")
147+
pp := &mock.PublicParameters{}
148+
pp.AuditorsReturns([]identity.Identity{auditor})
149+
ver := &mock.Verifier{}
150+
ver.VerifyReturns(errors.New("signature is not valid"))
151+
des := &mock.Deserializer{}
152+
des.GetAuditorVerifierReturns(ver, nil)
153+
sp := &mock.SignatureProvider{}
154+
sp.HasBeenSignedByReturns(nil, nil)
155+
return &TestContext{
156+
PP: pp,
157+
TokenRequest: &driver.TokenRequest{
158+
AuditorSignatures: []*driver.AuditorSignature{
159+
{
160+
Identity: auditor,
161+
Signature: []byte("auditor's signature"),
162+
},
163+
},
164+
},
165+
Deserializer: des,
166+
SignatureProvider: sp,
167+
}, func() bool {
168+
id, ver2 := sp.HasBeenSignedByArgsForCall(0)
169+
if ver2 != ver {
170+
return false
171+
}
172+
return auditor.Equal(id)
173+
}
174+
},
175+
},
176+
}
177+
178+
for _, tt := range tests {
179+
t.Run(tt.name, func(t *testing.T) {
180+
ctx, check := tt.context()
181+
err := AuditingSignaturesValidate(ctx)
182+
if tt.err {
183+
assert.Error(t, err)
184+
assert.EqualError(t, err, tt.errMsg)
185+
} else {
186+
assert.NoError(t, err)
187+
}
188+
if check != nil {
189+
assert.True(t, check())
190+
}
191+
})
192+
}
193+
}

0 commit comments

Comments
 (0)