github.com/yacovm/fabric@v2.0.0-alpha.0.20191128145320-c5d4087dc723+incompatible/common/policies/policy_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package policies
     8  
     9  import (
    10  	"fmt"
    11  	"reflect"
    12  	"strconv"
    13  	"testing"
    14  
    15  	"github.com/golang/protobuf/proto"
    16  	cb "github.com/hyperledger/fabric-protos-go/common"
    17  	"github.com/hyperledger/fabric-protos-go/msp"
    18  	"github.com/hyperledger/fabric/common/policies/mocks"
    19  	mspi "github.com/hyperledger/fabric/msp"
    20  	"github.com/hyperledger/fabric/protoutil"
    21  	"github.com/pkg/errors"
    22  	"github.com/stretchr/testify/assert"
    23  )
    24  
    25  //go:generate counterfeiter -o mocks/identity_deserializer.go --fake-name IdentityDeserializer . identityDeserializer
    26  type identityDeserializer interface {
    27  	mspi.IdentityDeserializer
    28  }
    29  
    30  //go:generate counterfeiter -o mocks/identity.go --fake-name Identity . identity
    31  type identity interface {
    32  	mspi.Identity
    33  }
    34  
    35  type mockProvider struct{}
    36  
    37  func (mpp mockProvider) NewPolicy(data []byte) (Policy, proto.Message, error) {
    38  	return nil, nil, nil
    39  }
    40  
    41  const mockType = int32(0)
    42  
    43  func defaultProviders() map[int32]Provider {
    44  	providers := make(map[int32]Provider)
    45  	providers[mockType] = &mockProvider{}
    46  	return providers
    47  }
    48  
    49  func TestUnnestedManager(t *testing.T) {
    50  	config := &cb.ConfigGroup{
    51  		Policies: map[string]*cb.ConfigPolicy{
    52  			"1": {Policy: &cb.Policy{Type: mockType}},
    53  			"2": {Policy: &cb.Policy{Type: mockType}},
    54  			"3": {Policy: &cb.Policy{Type: mockType}},
    55  		},
    56  	}
    57  
    58  	m, err := NewManagerImpl("test", defaultProviders(), config)
    59  	assert.NoError(t, err)
    60  	assert.NotNil(t, m)
    61  
    62  	_, ok := m.Manager([]string{"subGroup"})
    63  	assert.False(t, ok, "Should not have found a subgroup manager")
    64  
    65  	r, ok := m.Manager([]string{})
    66  	assert.True(t, ok, "Should have found the root manager")
    67  	assert.Equal(t, m, r)
    68  
    69  	assert.Len(t, m.Policies, len(config.Policies))
    70  
    71  	for policyName := range config.Policies {
    72  		_, ok := m.GetPolicy(policyName)
    73  		assert.True(t, ok, "Should have found policy %s", policyName)
    74  	}
    75  }
    76  
    77  func TestNestedManager(t *testing.T) {
    78  	config := &cb.ConfigGroup{
    79  		Policies: map[string]*cb.ConfigPolicy{
    80  			"n0a": {Policy: &cb.Policy{Type: mockType}},
    81  			"n0b": {Policy: &cb.Policy{Type: mockType}},
    82  			"n0c": {Policy: &cb.Policy{Type: mockType}},
    83  		},
    84  		Groups: map[string]*cb.ConfigGroup{
    85  			"nest1": {
    86  				Policies: map[string]*cb.ConfigPolicy{
    87  					"n1a": {Policy: &cb.Policy{Type: mockType}},
    88  					"n1b": {Policy: &cb.Policy{Type: mockType}},
    89  					"n1c": {Policy: &cb.Policy{Type: mockType}},
    90  				},
    91  				Groups: map[string]*cb.ConfigGroup{
    92  					"nest2a": {
    93  						Policies: map[string]*cb.ConfigPolicy{
    94  							"n2a_1": {Policy: &cb.Policy{Type: mockType}},
    95  							"n2a_2": {Policy: &cb.Policy{Type: mockType}},
    96  							"n2a_3": {Policy: &cb.Policy{Type: mockType}},
    97  						},
    98  					},
    99  					"nest2b": {
   100  						Policies: map[string]*cb.ConfigPolicy{
   101  							"n2b_1": {Policy: &cb.Policy{Type: mockType}},
   102  							"n2b_2": {Policy: &cb.Policy{Type: mockType}},
   103  							"n2b_3": {Policy: &cb.Policy{Type: mockType}},
   104  						},
   105  					},
   106  				},
   107  			},
   108  		},
   109  	}
   110  
   111  	m, err := NewManagerImpl("nest0", defaultProviders(), config)
   112  	assert.NoError(t, err)
   113  	assert.NotNil(t, m)
   114  
   115  	r, ok := m.Manager([]string{})
   116  	assert.True(t, ok, "Should have found the root manager")
   117  	assert.Equal(t, m, r)
   118  
   119  	n1, ok := m.Manager([]string{"nest1"})
   120  	assert.True(t, ok)
   121  	n2a, ok := m.Manager([]string{"nest1", "nest2a"})
   122  	assert.True(t, ok)
   123  	n2b, ok := m.Manager([]string{"nest1", "nest2b"})
   124  	assert.True(t, ok)
   125  
   126  	n2as, ok := n1.Manager([]string{"nest2a"})
   127  	assert.True(t, ok)
   128  	assert.Equal(t, n2a, n2as)
   129  	n2bs, ok := n1.Manager([]string{"nest2b"})
   130  	assert.True(t, ok)
   131  	assert.Equal(t, n2b, n2bs)
   132  
   133  	absPrefix := PathSeparator + "nest0" + PathSeparator
   134  	for policyName := range config.Policies {
   135  		_, ok := m.GetPolicy(policyName)
   136  		assert.True(t, ok, "Should have found policy %s", policyName)
   137  
   138  		absName := absPrefix + policyName
   139  		_, ok = m.GetPolicy(absName)
   140  		assert.True(t, ok, "Should have found absolute policy %s", absName)
   141  	}
   142  
   143  	for policyName := range config.Groups["nest1"].Policies {
   144  		_, ok := n1.GetPolicy(policyName)
   145  		assert.True(t, ok, "Should have found policy %s", policyName)
   146  
   147  		relPathFromBase := "nest1" + PathSeparator + policyName
   148  		_, ok = m.GetPolicy(relPathFromBase)
   149  		assert.True(t, ok, "Should have found policy %s", policyName)
   150  
   151  		for i, abs := range []Manager{n1, m} {
   152  			absName := absPrefix + relPathFromBase
   153  			_, ok = abs.GetPolicy(absName)
   154  			assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
   155  		}
   156  	}
   157  
   158  	for policyName := range config.Groups["nest1"].Groups["nest2a"].Policies {
   159  		_, ok := n2a.GetPolicy(policyName)
   160  		assert.True(t, ok, "Should have found policy %s", policyName)
   161  
   162  		relPathFromN1 := "nest2a" + PathSeparator + policyName
   163  		_, ok = n1.GetPolicy(relPathFromN1)
   164  		assert.True(t, ok, "Should have found policy %s", policyName)
   165  
   166  		relPathFromBase := "nest1" + PathSeparator + relPathFromN1
   167  		_, ok = m.GetPolicy(relPathFromBase)
   168  		assert.True(t, ok, "Should have found policy %s", policyName)
   169  
   170  		for i, abs := range []Manager{n2a, n1, m} {
   171  			absName := absPrefix + relPathFromBase
   172  			_, ok = abs.GetPolicy(absName)
   173  			assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
   174  		}
   175  	}
   176  
   177  	for policyName := range config.Groups["nest1"].Groups["nest2b"].Policies {
   178  		_, ok := n2b.GetPolicy(policyName)
   179  		assert.True(t, ok, "Should have found policy %s", policyName)
   180  
   181  		relPathFromN1 := "nest2b" + PathSeparator + policyName
   182  		_, ok = n1.GetPolicy(relPathFromN1)
   183  		assert.True(t, ok, "Should have found policy %s", policyName)
   184  
   185  		relPathFromBase := "nest1" + PathSeparator + relPathFromN1
   186  		_, ok = m.GetPolicy(relPathFromBase)
   187  		assert.True(t, ok, "Should have found policy %s", policyName)
   188  
   189  		for i, abs := range []Manager{n2b, n1, m} {
   190  			absName := absPrefix + relPathFromBase
   191  			_, ok = abs.GetPolicy(absName)
   192  			assert.True(t, ok, "Should have found absolutely policy for manager %d", i)
   193  		}
   194  	}
   195  }
   196  
   197  func TestPrincipalUniqueSet(t *testing.T) {
   198  	var principalSet PrincipalSet
   199  	addPrincipal := func(i int) {
   200  		principalSet = append(principalSet, &msp.MSPPrincipal{
   201  			PrincipalClassification: msp.MSPPrincipal_Classification(i),
   202  			Principal:               []byte(fmt.Sprintf("%d", i)),
   203  		})
   204  	}
   205  
   206  	addPrincipal(1)
   207  	addPrincipal(2)
   208  	addPrincipal(2)
   209  	addPrincipal(3)
   210  	addPrincipal(3)
   211  	addPrincipal(3)
   212  
   213  	for principal, plurality := range principalSet.UniqueSet() {
   214  		assert.Equal(t, int(principal.PrincipalClassification), plurality)
   215  		assert.Equal(t, fmt.Sprintf("%d", plurality), string(principal.Principal))
   216  	}
   217  
   218  	v := reflect.Indirect(reflect.ValueOf(msp.MSPPrincipal{}))
   219  	// Ensure msp.MSPPrincipal has only 2 fields.
   220  	// This is essential for 'UniqueSet' to work properly
   221  	// XXX This is a rather brittle check and brittle way to fix the test
   222  	// There seems to be an assumption that the number of fields in the proto
   223  	// struct matches the number of fields in the proto message
   224  	assert.Equal(t, 5, v.NumField())
   225  }
   226  
   227  func TestPrincipalSetContainingOnly(t *testing.T) {
   228  	var principalSets PrincipalSets
   229  	var principalSet PrincipalSet
   230  	for j := 0; j < 3; j++ {
   231  		for i := 0; i < 10; i++ {
   232  			principalSet = append(principalSet, &msp.MSPPrincipal{
   233  				PrincipalClassification: msp.MSPPrincipal_IDENTITY,
   234  				Principal:               []byte(fmt.Sprintf("%d", j*10+i)),
   235  			})
   236  		}
   237  		principalSets = append(principalSets, principalSet)
   238  		principalSet = nil
   239  	}
   240  
   241  	between20And30 := func(principal *msp.MSPPrincipal) bool {
   242  		n, _ := strconv.ParseInt(string(principal.Principal), 10, 32)
   243  		return n >= 20 && n <= 29
   244  	}
   245  
   246  	principalSets = principalSets.ContainingOnly(between20And30)
   247  
   248  	assert.Len(t, principalSets, 1)
   249  	assert.True(t, principalSets[0].ContainingOnly(between20And30))
   250  }
   251  
   252  func TestSignatureSetToValidIdentities(t *testing.T) {
   253  	sd := []*protoutil.SignedData{
   254  		{
   255  			Data:      []byte("data1"),
   256  			Identity:  []byte("identity1"),
   257  			Signature: []byte("signature1"),
   258  		},
   259  		{
   260  			Data:      []byte("data1"),
   261  			Identity:  []byte("identity1"),
   262  			Signature: []byte("signature1"),
   263  		},
   264  	}
   265  
   266  	fIDDs := &mocks.IdentityDeserializer{}
   267  	fID := &mocks.Identity{}
   268  	fID.VerifyReturns(nil)
   269  	fID.GetIdentifierReturns(&mspi.IdentityIdentifier{
   270  		Id:    "id",
   271  		Mspid: "mspid",
   272  	})
   273  	fIDDs.DeserializeIdentityReturns(fID, nil)
   274  
   275  	ids := SignatureSetToValidIdentities(sd, fIDDs)
   276  	assert.Len(t, ids, 1)
   277  	assert.NotNil(t, ids[0].GetIdentifier())
   278  	assert.Equal(t, "id", ids[0].GetIdentifier().Id)
   279  	assert.Equal(t, "mspid", ids[0].GetIdentifier().Mspid)
   280  	data, sig := fID.VerifyArgsForCall(0)
   281  	assert.Equal(t, []byte("data1"), data)
   282  	assert.Equal(t, []byte("signature1"), sig)
   283  	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
   284  	assert.Equal(t, []byte("identity1"), sidBytes)
   285  }
   286  
   287  func TestSignatureSetToValidIdentitiesDeserialiseErr(t *testing.T) {
   288  	sd := []*protoutil.SignedData{
   289  		{
   290  			Data:      []byte("data1"),
   291  			Identity:  []byte("identity1"),
   292  			Signature: []byte("signature1"),
   293  		},
   294  	}
   295  
   296  	fIDDs := &mocks.IdentityDeserializer{}
   297  	fIDDs.DeserializeIdentityReturns(nil, errors.New("bad identity"))
   298  
   299  	ids := SignatureSetToValidIdentities(sd, fIDDs)
   300  	assert.Len(t, ids, 0)
   301  	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
   302  	assert.Equal(t, []byte("identity1"), sidBytes)
   303  }
   304  
   305  func TestSignatureSetToValidIdentitiesVerifyErr(t *testing.T) {
   306  	sd := []*protoutil.SignedData{
   307  		{
   308  			Data:      []byte("data1"),
   309  			Identity:  []byte("identity1"),
   310  			Signature: []byte("signature1"),
   311  		},
   312  	}
   313  
   314  	fIDDs := &mocks.IdentityDeserializer{}
   315  	fID := &mocks.Identity{}
   316  	fID.VerifyReturns(errors.New("bad signature"))
   317  	fID.GetIdentifierReturns(&mspi.IdentityIdentifier{
   318  		Id:    "id",
   319  		Mspid: "mspid",
   320  	})
   321  	fIDDs.DeserializeIdentityReturns(fID, nil)
   322  
   323  	ids := SignatureSetToValidIdentities(sd, fIDDs)
   324  	assert.Len(t, ids, 0)
   325  	data, sig := fID.VerifyArgsForCall(0)
   326  	assert.Equal(t, []byte("data1"), data)
   327  	assert.Equal(t, []byte("signature1"), sig)
   328  	sidBytes := fIDDs.DeserializeIdentityArgsForCall(0)
   329  	assert.Equal(t, []byte("identity1"), sidBytes)
   330  }