github.com/kaituanwang/hyperledger@v2.0.1+incompatible/discovery/support/acl/support_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package acl_test 8 9 import ( 10 "testing" 11 12 "github.com/hyperledger/fabric/common/channelconfig" 13 "github.com/hyperledger/fabric/common/policies" 14 "github.com/hyperledger/fabric/discovery/support/acl" 15 "github.com/hyperledger/fabric/discovery/support/mocks" 16 gmocks "github.com/hyperledger/fabric/internal/peer/gossip/mocks" 17 "github.com/hyperledger/fabric/protoutil" 18 "github.com/pkg/errors" 19 "github.com/stretchr/testify/assert" 20 ) 21 22 func TestGetChannelConfigFunc(t *testing.T) { 23 r := &mocks.Resources{} 24 f := func(cid string) channelconfig.Resources { 25 return r 26 } 27 assert.Equal(t, r, acl.ChannelConfigGetterFunc(f).GetChannelConfig("mychannel")) 28 } 29 30 func TestConfigSequenceEmptyChannelName(t *testing.T) { 31 // If the channel name is empty, there is no config sequence, 32 // and we return 0 33 sup := acl.NewDiscoverySupport(nil, nil, nil) 34 assert.Equal(t, uint64(0), sup.ConfigSequence("")) 35 } 36 37 func TestConfigSequence(t *testing.T) { 38 tests := []struct { 39 name string 40 resourcesFound bool 41 validatorFound bool 42 sequence uint64 43 shouldPanic bool 44 }{ 45 { 46 name: "resources not found", 47 shouldPanic: true, 48 }, 49 { 50 name: "validator not found", 51 resourcesFound: true, 52 shouldPanic: true, 53 }, 54 { 55 name: "both resources and validator are found", 56 resourcesFound: true, 57 validatorFound: true, 58 sequence: 100, 59 }, 60 } 61 62 for _, test := range tests { 63 test := test 64 t.Run(test.name, func(t *testing.T) { 65 chConfig := &mocks.ChannelConfigGetter{} 66 r := &mocks.Resources{} 67 v := &mocks.ConfigtxValidator{} 68 if test.resourcesFound { 69 chConfig.GetChannelConfigReturns(r) 70 } 71 if test.validatorFound { 72 r.ConfigtxValidatorReturns(v) 73 } 74 v.SequenceReturns(test.sequence) 75 76 sup := acl.NewDiscoverySupport(&mocks.Verifier{}, &mocks.Evaluator{}, chConfig) 77 if test.shouldPanic { 78 assert.Panics(t, func() { 79 sup.ConfigSequence("mychannel") 80 }) 81 return 82 } 83 assert.Equal(t, test.sequence, sup.ConfigSequence("mychannel")) 84 }) 85 } 86 } 87 88 func TestEligibleForService(t *testing.T) { 89 v := &mocks.Verifier{} 90 e := &mocks.Evaluator{} 91 v.VerifyByChannelReturnsOnCall(0, errors.New("verification failed")) 92 v.VerifyByChannelReturnsOnCall(1, nil) 93 e.EvaluateSignedDataReturnsOnCall(0, errors.New("verification failed for local msp")) 94 e.EvaluateSignedDataReturnsOnCall(1, nil) 95 chConfig := &mocks.ChannelConfigGetter{} 96 sup := acl.NewDiscoverySupport(v, e, chConfig) 97 err := sup.EligibleForService("mychannel", protoutil.SignedData{}) 98 assert.Equal(t, "verification failed", err.Error()) 99 err = sup.EligibleForService("mychannel", protoutil.SignedData{}) 100 assert.NoError(t, err) 101 err = sup.EligibleForService("", protoutil.SignedData{}) 102 assert.Equal(t, "verification failed for local msp", err.Error()) 103 err = sup.EligibleForService("", protoutil.SignedData{}) 104 assert.NoError(t, err) 105 } 106 107 func TestSatisfiesPrincipal(t *testing.T) { 108 var ( 109 chConfig = &mocks.ChannelConfigGetter{} 110 resources = &mocks.Resources{} 111 mgr = &mocks.MSPManager{} 112 idThatDoesNotSatisfyPrincipal = &mocks.Identity{} 113 idThatSatisfiesPrincipal = &mocks.Identity{} 114 ) 115 116 tests := []struct { 117 testDescription string 118 before func() 119 expectedErr string 120 }{ 121 { 122 testDescription: "Channel does not exist", 123 before: func() { 124 chConfig.GetChannelConfigReturns(nil) 125 }, 126 expectedErr: "channel mychannel doesn't exist", 127 }, 128 { 129 testDescription: "MSP manager not available", 130 before: func() { 131 chConfig.GetChannelConfigReturns(resources) 132 resources.MSPManagerReturns(nil) 133 }, 134 expectedErr: "could not find MSP manager for channel mychannel", 135 }, 136 { 137 testDescription: "Identity cannot be deserialized", 138 before: func() { 139 resources.MSPManagerReturns(mgr) 140 mgr.DeserializeIdentityReturns(nil, errors.New("not a valid identity")) 141 }, 142 expectedErr: "failed deserializing identity: not a valid identity", 143 }, 144 { 145 testDescription: "Identity does not satisfy principal", 146 before: func() { 147 idThatDoesNotSatisfyPrincipal.SatisfiesPrincipalReturns(errors.New("does not satisfy principal")) 148 mgr.DeserializeIdentityReturns(idThatDoesNotSatisfyPrincipal, nil) 149 }, 150 expectedErr: "does not satisfy principal", 151 }, 152 { 153 testDescription: "All is fine, identity is eligible", 154 before: func() { 155 idThatSatisfiesPrincipal.SatisfiesPrincipalReturns(nil) 156 mgr.DeserializeIdentityReturns(idThatSatisfiesPrincipal, nil) 157 }, 158 expectedErr: "", 159 }, 160 } 161 162 sup := acl.NewDiscoverySupport(&mocks.Verifier{}, &mocks.Evaluator{}, chConfig) 163 for _, test := range tests { 164 test := test 165 t.Run(test.testDescription, func(t *testing.T) { 166 test.before() 167 err := sup.SatisfiesPrincipal("mychannel", nil, nil) 168 if test.expectedErr != "" { 169 assert.Equal(t, test.expectedErr, err.Error()) 170 } else { 171 assert.NoError(t, err) 172 } 173 }) 174 175 } 176 } 177 178 func TestChannelVerifier(t *testing.T) { 179 polMgr := &gmocks.ChannelPolicyManagerGetterWithManager{ 180 Managers: map[string]policies.Manager{ 181 "mychannel": &gmocks.ChannelPolicyManager{ 182 Policy: &gmocks.Policy{ 183 Deserializer: &gmocks.IdentityDeserializer{ 184 Identity: []byte("Bob"), Msg: []byte("msg"), 185 }, 186 }, 187 }, 188 }, 189 } 190 191 verifier := &acl.ChannelVerifier{ 192 Policy: "some policy string", 193 ChannelPolicyManagerGetter: polMgr, 194 } 195 196 t.Run("Valid channel, identity, signature", func(t *testing.T) { 197 err := verifier.VerifyByChannel("mychannel", &protoutil.SignedData{ 198 Data: []byte("msg"), 199 Identity: []byte("Bob"), 200 Signature: []byte("msg"), 201 }) 202 assert.NoError(t, err) 203 }) 204 205 t.Run("Invalid channel", func(t *testing.T) { 206 err := verifier.VerifyByChannel("notmychannel", &protoutil.SignedData{ 207 Data: []byte("msg"), 208 Identity: []byte("Bob"), 209 Signature: []byte("msg"), 210 }) 211 assert.Error(t, err) 212 assert.Contains(t, err.Error(), "policy manager for channel notmychannel doesn't exist") 213 }) 214 215 t.Run("Writers policy cannot be retrieved", func(t *testing.T) { 216 polMgr.Managers["mychannel"].(*gmocks.ChannelPolicyManager).Policy = nil 217 err := verifier.VerifyByChannel("mychannel", &protoutil.SignedData{ 218 Data: []byte("msg"), 219 Identity: []byte("Bob"), 220 Signature: []byte("msg"), 221 }) 222 assert.Error(t, err) 223 assert.Contains(t, err.Error(), "failed obtaining channel application writers policy") 224 }) 225 226 }