Skip to content

Commit

Permalink
msp/mgmt: move MSPPrincipalGetter to policy
Browse files Browse the repository at this point in the history
Signed-off-by: Matthew Sykes <sykesmat@us.ibm.com>
  • Loading branch information
sykesm authored and Jason Yellick committed Mar 15, 2021
1 parent bfa7dcf commit 1dbd6e9
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 71 deletions.
31 changes: 15 additions & 16 deletions core/aclmgmt/defaultaclprovider.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,6 @@ import (
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/core/aclmgmt/resources"
"github.com/hyperledger/fabric/core/policy"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/protoutil"
)

Expand Down Expand Up @@ -48,27 +47,27 @@ func newDefaultACLProvider(policyChecker policy.PolicyChecker) defaultACLProvide
}

//-------------- _lifecycle --------------
d.pResourcePolicyMap[resources.Lifecycle_InstallChaincode] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincode] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_GetInstalledChaincodePackage] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincodes] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_ApproveChaincodeDefinitionForMyOrg] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryApprovedChaincodeDefinition] = mgmt.Admins
d.pResourcePolicyMap[resources.Lifecycle_InstallChaincode] = policy.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincode] = policy.Admins
d.pResourcePolicyMap[resources.Lifecycle_GetInstalledChaincodePackage] = policy.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincodes] = policy.Admins
d.pResourcePolicyMap[resources.Lifecycle_ApproveChaincodeDefinitionForMyOrg] = policy.Admins
d.pResourcePolicyMap[resources.Lifecycle_QueryApprovedChaincodeDefinition] = policy.Admins

d.cResourcePolicyMap[resources.Lifecycle_CommitChaincodeDefinition] = CHANNELWRITERS
d.cResourcePolicyMap[resources.Lifecycle_QueryChaincodeDefinition] = CHANNELWRITERS
d.cResourcePolicyMap[resources.Lifecycle_QueryChaincodeDefinitions] = CHANNELWRITERS
d.cResourcePolicyMap[resources.Lifecycle_CheckCommitReadiness] = CHANNELWRITERS

//-------------- snapshot ---------------
d.pResourcePolicyMap[resources.Snapshot_submitrequest] = mgmt.Admins
d.pResourcePolicyMap[resources.Snapshot_cancelrequest] = mgmt.Admins
d.pResourcePolicyMap[resources.Snapshot_listpending] = mgmt.Admins
d.pResourcePolicyMap[resources.Snapshot_submitrequest] = policy.Admins
d.pResourcePolicyMap[resources.Snapshot_cancelrequest] = policy.Admins
d.pResourcePolicyMap[resources.Snapshot_listpending] = policy.Admins

//-------------- LSCC --------------
//p resources (implemented by the chaincode currently)
d.pResourcePolicyMap[resources.Lscc_Install] = mgmt.Admins
d.pResourcePolicyMap[resources.Lscc_GetInstalledChaincodes] = mgmt.Admins
d.pResourcePolicyMap[resources.Lscc_Install] = policy.Admins
d.pResourcePolicyMap[resources.Lscc_GetInstalledChaincodes] = policy.Admins

// c resources
d.cResourcePolicyMap[resources.Lscc_Deploy] = "" // ACL check covered by PROPOSAL
Expand All @@ -91,10 +90,10 @@ func newDefaultACLProvider(policyChecker policy.PolicyChecker) defaultACLProvide

//--------------- CSCC resources -----------
//p resources (implemented by the chaincode currently)
d.pResourcePolicyMap[resources.Cscc_JoinChain] = mgmt.Admins
d.pResourcePolicyMap[resources.Cscc_JoinChainBySnapshot] = mgmt.Admins
d.pResourcePolicyMap[resources.Cscc_JoinBySnapshotStatus] = mgmt.Admins
d.pResourcePolicyMap[resources.Cscc_GetChannels] = mgmt.Members
d.pResourcePolicyMap[resources.Cscc_JoinChain] = policy.Admins
d.pResourcePolicyMap[resources.Cscc_JoinChainBySnapshot] = policy.Admins
d.pResourcePolicyMap[resources.Cscc_JoinBySnapshotStatus] = policy.Admins
d.pResourcePolicyMap[resources.Cscc_GetChannels] = policy.Members

// c resources
d.cResourcePolicyMap[resources.Cscc_GetConfigBlock] = CHANNELREADERS
Expand Down
4 changes: 2 additions & 2 deletions core/aclmgmt/resourceprovider_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ import (
"github.com/hyperledger/fabric-protos-go/common"
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/core/aclmgmt/mocks"
"github.com/hyperledger/fabric/core/policy"
"github.com/hyperledger/fabric/internal/pkg/identity"
"github.com/hyperledger/fabric/msp/mgmt"
msptesttools "github.com/hyperledger/fabric/msp/mgmt/testtools"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -119,7 +119,7 @@ func TestCheckACLNoChannel(t *testing.T) {

// error paths
defAclProvider := &defaultACLProviderImpl{
pResourcePolicyMap: map[string]string{"aptype": mgmt.Admins},
pResourcePolicyMap: map[string]string{"aptype": policy.Admins},
}
rp = &resourceProvider{defaultProvider: defAclProvider}
err = rp.CheckACLNoChannel("nontype", struct{}{})
Expand Down
11 changes: 7 additions & 4 deletions core/policy/policy.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ import (
pb "github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/msp"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/protoutil"
)

Expand Down Expand Up @@ -42,12 +41,16 @@ type PolicyChecker interface {
type policyChecker struct {
channelPolicyManagerGetter policies.ChannelPolicyManagerGetter
localMSP msp.IdentityDeserializer
principalGetter mgmt.MSPPrincipalGetter
principalGetter MSPPrincipalGetter
}

// NewPolicyChecker creates a new instance of PolicyChecker
func NewPolicyChecker(channelPolicyManagerGetter policies.ChannelPolicyManagerGetter, localMSP msp.IdentityDeserializer, principalGetter mgmt.MSPPrincipalGetter) PolicyChecker {
return &policyChecker{channelPolicyManagerGetter, localMSP, principalGetter}
func NewPolicyChecker(channelPolicyManagerGetter policies.ChannelPolicyManagerGetter, localMSP msp.MSP) PolicyChecker {
return &policyChecker{
channelPolicyManagerGetter: channelPolicyManagerGetter,
localMSP: localMSP,
principalGetter: &localMSPPrincipalGetter{localMSP: localMSP},
}
}

// CheckPolicy checks that the passed signed proposal is valid with the respect to
Expand Down
33 changes: 16 additions & 17 deletions core/policy/policy_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import (
"github.com/hyperledger/fabric-protos-go/peer"
"github.com/hyperledger/fabric/common/policies"
"github.com/hyperledger/fabric/core/policy/mocks"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/hyperledger/fabric/protoutil"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -100,11 +99,11 @@ func TestPolicyCheckerInvalidArgs(t *testing.T) {
Identity: []byte("Alice"),
Msg: []byte("msg1"),
}
pc := NewPolicyChecker(
policyManagerGetter,
identityDeserializer,
&mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
)
pc := &policyChecker{
channelPolicyManagerGetter: policyManagerGetter,
localMSP: identityDeserializer,
principalGetter: &mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
}

// Check that (non-empty channel, empty policy) fails
err := pc.CheckPolicy("A", "", nil)
Expand Down Expand Up @@ -157,11 +156,11 @@ func TestPolicyChecker(t *testing.T) {
Identity: []byte("Alice"),
Msg: []byte("msg1"),
}
pc := NewPolicyChecker(
policyManagerGetter,
identityDeserializer,
&mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
)
pc := &policyChecker{
channelPolicyManagerGetter: policyManagerGetter,
localMSP: identityDeserializer,
principalGetter: &mocks.MockMSPPrincipalGetter{Principal: []byte("Alice")},
}

t.Run("CheckPolicy", func(t *testing.T) {
// Validate Alice signatures against channel A's readers
Expand All @@ -188,12 +187,12 @@ func TestPolicyChecker(t *testing.T) {

// Alice is a member of the local MSP, policy check must succeed
identityDeserializer.Msg = sProp.ProposalBytes
err := pc.CheckPolicyNoChannel(mgmt.Members, sProp)
err := pc.CheckPolicyNoChannel(Members, sProp)
require.NoError(t, err)

sProp, _ = protoutil.MockSignedEndorserProposalOrPanic("A", &peer.ChaincodeSpec{}, []byte("Bob"), []byte("msg2"))
// Bob is not a member of the local MSP, policy check must fail
err = pc.CheckPolicyNoChannel(mgmt.Members, sProp)
err = pc.CheckPolicyNoChannel(Members, sProp)
require.Error(t, err)
require.Contains(t, err.Error(), "Failed deserializing proposal creator during channelless check policy with policy [Members]: [Invalid Identity]")
})
Expand All @@ -207,7 +206,7 @@ func TestPolicyChecker(t *testing.T) {

// Alice is a member of the local MSP, policy check must succeed
identityDeserializer.Msg = signedData.Data
err := pc.CheckPolicyNoChannelBySignedData(mgmt.Admins, []*protoutil.SignedData{signedData})
err := pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{signedData})
require.NoError(t, err)

// CheckPolicyNoChannelBySignedData iterates each signed data and returns an error if any data is invalid
Expand All @@ -217,7 +216,7 @@ func TestPolicyChecker(t *testing.T) {
Data: []byte("msg2"),
Signature: []byte("msg2"),
}
err = pc.CheckPolicyNoChannelBySignedData(mgmt.Admins, []*protoutil.SignedData{signedData, signedData2})
err = pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{signedData, signedData2})
require.Error(t, err)
require.Contains(t, err.Error(), "failed deserializing signed data identity during channelless check policy with policy [Admins]: [Invalid Identity]")

Expand All @@ -226,9 +225,9 @@ func TestPolicyChecker(t *testing.T) {
require.EqualError(t, err, "invalid policy name during channelless check policy. Name must be different from nil.")

// signed data cannot be nil or empty
err = pc.CheckPolicyNoChannelBySignedData(mgmt.Admins, nil)
err = pc.CheckPolicyNoChannelBySignedData(Admins, nil)
require.EqualError(t, err, "no signed data during channelless check policy with policy [Admins]")
err = pc.CheckPolicyNoChannelBySignedData(mgmt.Admins, []*protoutil.SignedData{})
err = pc.CheckPolicyNoChannelBySignedData(Admins, []*protoutil.SignedData{})
require.EqualError(t, err, "no signed data during channelless check policy with policy [Admins]")
})
}
31 changes: 15 additions & 16 deletions msp/mgmt/principal.go → core/policy/principal.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,62 @@ See the License for the specific language governing permissions and
limitations under the License.
*/

package mgmt
package policy

import (
"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/bccsp"
protomsp "github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/msp"
"github.com/pkg/errors"
)

const (
// Admins is the label for the local MSP admins
Admins = "Admins"

// Members is the label for the local MSP members
Members = "Members"
)

type MSPPrincipalGetter interface {
// Get returns an MSP principal for the given role
Get(role string) (*msp.MSPPrincipal, error)
Get(role string) (*protomsp.MSPPrincipal, error)
}

func NewLocalMSPPrincipalGetter(cryptoProvider bccsp.BCCSP) MSPPrincipalGetter {
func NewLocalMSPPrincipalGetter(localMSP msp.MSP) MSPPrincipalGetter {
return &localMSPPrincipalGetter{
cryptoProvider: cryptoProvider,
localMSP: localMSP,
}
}

type localMSPPrincipalGetter struct {
cryptoProvider bccsp.BCCSP
localMSP msp.MSP
}

func (m *localMSPPrincipalGetter) Get(role string) (*msp.MSPPrincipal, error) {
mspid, err := GetLocalMSP(m.cryptoProvider).GetIdentifier()
func (m *localMSPPrincipalGetter) Get(role string) (*protomsp.MSPPrincipal, error) {
mspid, err := m.localMSP.GetIdentifier()
if err != nil {
return nil, errors.WithMessage(err, "could not extract local msp identifier")
}

switch role {
case Admins:
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_ADMIN, MspIdentifier: mspid})
principalBytes, err := proto.Marshal(&protomsp.MSPRole{Role: protomsp.MSPRole_ADMIN, MspIdentifier: mspid})
if err != nil {
return nil, errors.Wrap(err, "marshalling failed")
}

return &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
return &protomsp.MSPPrincipal{
PrincipalClassification: protomsp.MSPPrincipal_ROLE,
Principal: principalBytes,
}, nil
case Members:
principalBytes, err := proto.Marshal(&msp.MSPRole{Role: msp.MSPRole_MEMBER, MspIdentifier: mspid})
principalBytes, err := proto.Marshal(&protomsp.MSPRole{Role: protomsp.MSPRole_MEMBER, MspIdentifier: mspid})
if err != nil {
return nil, errors.Wrap(err, "marshalling failed")
}

return &msp.MSPPrincipal{
PrincipalClassification: msp.MSPPrincipal_ROLE,
return &protomsp.MSPPrincipal{
PrincipalClassification: protomsp.MSPPrincipal_ROLE,
Principal: principalBytes,
}, nil
default:
Expand Down
21 changes: 6 additions & 15 deletions msp/mgmt/principal_test.go → core/policy/principal_test.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,35 @@
/*
Copyright IBM Corp. 2017 All Rights Reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
SPDX-License-Identifier: Apache-2.0
*/

package mgmt
package policy

import (
"testing"

"github.com/golang/protobuf/proto"
"github.com/hyperledger/fabric-protos-go/msp"
"github.com/hyperledger/fabric/bccsp/sw"
"github.com/hyperledger/fabric/msp/mgmt"
"github.com/stretchr/testify/require"
)

func TestNewLocalMSPPrincipalGetter(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)
require.NotNil(t, NewLocalMSPPrincipalGetter(cryptoProvider))
require.NotNil(t, NewLocalMSPPrincipalGetter(mgmt.GetLocalMSP(cryptoProvider)))
}

func TestLocalMSPPrincipalGetter_Get(t *testing.T) {
cryptoProvider, err := sw.NewDefaultSecurityLevelWithKeystore(sw.NewDummyKeyStore())
require.NoError(t, err)

localMSP := GetLocalMSP(cryptoProvider)
localMSP := mgmt.GetLocalMSP(cryptoProvider)
localMSPID, err := localMSP.GetIdentifier()
require.NoError(t, err)
g := NewLocalMSPPrincipalGetter(cryptoProvider)
g := NewLocalMSPPrincipalGetter(localMSP)

_, err = g.Get("")
require.Error(t, err)
Expand Down
1 change: 0 additions & 1 deletion internal/peer/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -326,7 +326,6 @@ func serve(args []string) error {
policyChecker := policy.NewPolicyChecker(
policies.PolicyManagerGetterFunc(peerInstance.GetPolicyManager),
mgmt.GetLocalMSP(factory.GetDefault()),
mgmt.NewLocalMSPPrincipalGetter(factory.GetDefault()),
)

// startup aclmgmt with default ACL providers (resource based and default 1.0 policies based).
Expand Down

0 comments on commit 1dbd6e9

Please sign in to comment.