github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/aclmgmt/defaultaclprovider.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package aclmgmt
     8  
     9  import (
    10  	"fmt"
    11  
    12  	"github.com/hechain20/hechain/common/policies"
    13  	"github.com/hechain20/hechain/core/aclmgmt/resources"
    14  	"github.com/hechain20/hechain/core/policy"
    15  	"github.com/hechain20/hechain/protoutil"
    16  	"github.com/hyperledger/fabric-protos-go/common"
    17  	pb "github.com/hyperledger/fabric-protos-go/peer"
    18  )
    19  
    20  const (
    21  	CHANNELREADERS = policies.ChannelApplicationReaders
    22  	CHANNELWRITERS = policies.ChannelApplicationWriters
    23  )
    24  
    25  type defaultACLProvider interface {
    26  	ACLProvider
    27  	IsPtypePolicy(resName string) bool
    28  }
    29  
    30  // defaultACLProvider used if resource-based ACL Provider is not provided or
    31  // if it does not contain a policy for the named resource
    32  type defaultACLProviderImpl struct {
    33  	policyChecker policy.PolicyChecker
    34  
    35  	// peer wide policy (currently not used)
    36  	pResourcePolicyMap map[string]string
    37  
    38  	// channel specific policy
    39  	cResourcePolicyMap map[string]string
    40  }
    41  
    42  func newDefaultACLProvider(policyChecker policy.PolicyChecker) defaultACLProvider {
    43  	d := &defaultACLProviderImpl{
    44  		policyChecker:      policyChecker,
    45  		pResourcePolicyMap: map[string]string{},
    46  		cResourcePolicyMap: map[string]string{},
    47  	}
    48  
    49  	//-------------- _lifecycle --------------
    50  	d.pResourcePolicyMap[resources.Lifecycle_InstallChaincode] = policy.Admins
    51  	d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincode] = policy.Admins
    52  	d.pResourcePolicyMap[resources.Lifecycle_GetInstalledChaincodePackage] = policy.Admins
    53  	d.pResourcePolicyMap[resources.Lifecycle_QueryInstalledChaincodes] = policy.Admins
    54  	d.pResourcePolicyMap[resources.Lifecycle_ApproveChaincodeDefinitionForMyOrg] = policy.Admins
    55  	d.pResourcePolicyMap[resources.Lifecycle_QueryApprovedChaincodeDefinition] = policy.Admins
    56  
    57  	d.cResourcePolicyMap[resources.Lifecycle_CommitChaincodeDefinition] = CHANNELWRITERS
    58  	d.cResourcePolicyMap[resources.Lifecycle_QueryChaincodeDefinition] = CHANNELWRITERS
    59  	d.cResourcePolicyMap[resources.Lifecycle_QueryChaincodeDefinitions] = CHANNELWRITERS
    60  	d.cResourcePolicyMap[resources.Lifecycle_CheckCommitReadiness] = CHANNELWRITERS
    61  
    62  	//-------------- snapshot ---------------
    63  	d.pResourcePolicyMap[resources.Snapshot_submitrequest] = policy.Admins
    64  	d.pResourcePolicyMap[resources.Snapshot_cancelrequest] = policy.Admins
    65  	d.pResourcePolicyMap[resources.Snapshot_listpending] = policy.Admins
    66  
    67  	//-------------- LSCC --------------
    68  	//p resources (implemented by the chaincode currently)
    69  	d.pResourcePolicyMap[resources.Lscc_Install] = policy.Admins
    70  	d.pResourcePolicyMap[resources.Lscc_GetInstalledChaincodes] = policy.Admins
    71  
    72  	// c resources
    73  	d.cResourcePolicyMap[resources.Lscc_Deploy] = ""  // ACL check covered by PROPOSAL
    74  	d.cResourcePolicyMap[resources.Lscc_Upgrade] = "" // ACL check covered by PROPOSAL
    75  	d.cResourcePolicyMap[resources.Lscc_ChaincodeExists] = CHANNELREADERS
    76  	d.cResourcePolicyMap[resources.Lscc_GetDeploymentSpec] = CHANNELREADERS
    77  	d.cResourcePolicyMap[resources.Lscc_GetChaincodeData] = CHANNELREADERS
    78  	d.cResourcePolicyMap[resources.Lscc_GetInstantiatedChaincodes] = CHANNELREADERS
    79  	d.cResourcePolicyMap[resources.Lscc_GetCollectionsConfig] = CHANNELREADERS
    80  
    81  	//-------------- QSCC --------------
    82  	//p resources (none)
    83  
    84  	// c resources
    85  	d.cResourcePolicyMap[resources.Qscc_GetChainInfo] = CHANNELREADERS
    86  	d.cResourcePolicyMap[resources.Qscc_GetBlockByNumber] = CHANNELREADERS
    87  	d.cResourcePolicyMap[resources.Qscc_GetBlockByHash] = CHANNELREADERS
    88  	d.cResourcePolicyMap[resources.Qscc_GetTransactionByID] = CHANNELREADERS
    89  	d.cResourcePolicyMap[resources.Qscc_GetBlockByTxID] = CHANNELREADERS
    90  
    91  	//--------------- CSCC resources -----------
    92  	//p resources (implemented by the chaincode currently)
    93  	d.pResourcePolicyMap[resources.Cscc_JoinChain] = policy.Admins
    94  	d.pResourcePolicyMap[resources.Cscc_JoinChainBySnapshot] = policy.Admins
    95  	d.pResourcePolicyMap[resources.Cscc_JoinBySnapshotStatus] = policy.Admins
    96  	d.pResourcePolicyMap[resources.Cscc_GetChannels] = policy.Members
    97  
    98  	// c resources
    99  	d.cResourcePolicyMap[resources.Cscc_GetConfigBlock] = CHANNELREADERS
   100  	d.cResourcePolicyMap[resources.Cscc_GetChannelConfig] = CHANNELREADERS
   101  
   102  	//---------------- non-scc resources ------------
   103  	//Peer resources
   104  	d.cResourcePolicyMap[resources.Peer_Propose] = CHANNELWRITERS
   105  	d.cResourcePolicyMap[resources.Peer_ChaincodeToChaincode] = CHANNELWRITERS
   106  
   107  	// Event resources
   108  	d.cResourcePolicyMap[resources.Event_Block] = CHANNELREADERS
   109  	d.cResourcePolicyMap[resources.Event_FilteredBlock] = CHANNELREADERS
   110  
   111  	// Gateway resources
   112  	d.cResourcePolicyMap[resources.Gateway_CommitStatus] = CHANNELREADERS
   113  	d.cResourcePolicyMap[resources.Gateway_ChaincodeEvents] = CHANNELREADERS
   114  
   115  	return d
   116  }
   117  
   118  func (d *defaultACLProviderImpl) IsPtypePolicy(resName string) bool {
   119  	_, ok := d.pResourcePolicyMap[resName]
   120  	return ok
   121  }
   122  
   123  // CheckACL provides default (v 1.0) behavior by mapping resources to their ACL for a channel.
   124  func (d *defaultACLProviderImpl) CheckACL(resName string, channelID string, idinfo interface{}) error {
   125  	// the default behavior is to use p type if defined and use channeless policy checks
   126  	policy := d.pResourcePolicyMap[resName]
   127  	if policy != "" {
   128  		channelID = ""
   129  	} else {
   130  		policy = d.cResourcePolicyMap[resName]
   131  		if policy == "" {
   132  			aclLogger.Errorf("Unmapped policy for %s", resName)
   133  			return fmt.Errorf("Unmapped policy for %s", resName)
   134  		}
   135  	}
   136  	aclLogger.Debugw("Applying default access policy for resource", "channel", channelID, "policy", policy, "resource", resName)
   137  
   138  	switch typedData := idinfo.(type) {
   139  	case *pb.SignedProposal:
   140  		return d.policyChecker.CheckPolicy(channelID, policy, typedData)
   141  	case *common.Envelope:
   142  		sd, err := protoutil.EnvelopeAsSignedData(typedData)
   143  		if err != nil {
   144  			return err
   145  		}
   146  		return d.policyChecker.CheckPolicyBySignedData(channelID, policy, sd)
   147  	case *protoutil.SignedData:
   148  		return d.policyChecker.CheckPolicyBySignedData(channelID, policy, []*protoutil.SignedData{typedData})
   149  	case []*protoutil.SignedData:
   150  		return d.policyChecker.CheckPolicyBySignedData(channelID, policy, typedData)
   151  	default:
   152  		aclLogger.Errorf("Unmapped id on checkACL %s", resName)
   153  		return fmt.Errorf("Unknown id on checkACL %s", resName)
   154  	}
   155  }
   156  
   157  // CheckACL provides default behavior by mapping channelless resources to their ACL.
   158  func (d *defaultACLProviderImpl) CheckACLNoChannel(resName string, idinfo interface{}) error {
   159  	policy := d.pResourcePolicyMap[resName]
   160  	if policy == "" {
   161  		aclLogger.Errorf("Unmapped channelless policy for %s", resName)
   162  		return fmt.Errorf("Unmapped channelless policy for %s", resName)
   163  	}
   164  
   165  	switch typedData := idinfo.(type) {
   166  	case *pb.SignedProposal:
   167  		return d.policyChecker.CheckPolicyNoChannel(policy, typedData)
   168  	case *common.Envelope:
   169  		sd, err := protoutil.EnvelopeAsSignedData(typedData)
   170  		if err != nil {
   171  			return err
   172  		}
   173  		return d.policyChecker.CheckPolicyNoChannelBySignedData(policy, sd)
   174  	case []*protoutil.SignedData:
   175  		return d.policyChecker.CheckPolicyNoChannelBySignedData(policy, typedData)
   176  	default:
   177  		aclLogger.Errorf("Unmapped id on channelless checkACL %s", resName)
   178  		return fmt.Errorf("Unknown id on channelless checkACL %s", resName)
   179  	}
   180  }