-
Notifications
You must be signed in to change notification settings - Fork 8.9k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[FAB-5583] create basic resource system chaincode
The RSCC has the basic function to read policy for a channel from the Join genesis block. It uses the default ACL provider used by the ACL management framework as a fall back for resources not defined in the channel policy. The channel read policy is currently just a stub waiting for the RSCC policy to be set in RSCC ledger state. As soon as that work is ready and integrated, RSCC will update its cache from the channel ledger. RSCC is currently "disabled" in core.yaml. Once enabled, CheckACL calls to aclmgmt will be routed to RSCC's CheckACL. Change-Id: I9f039fd5a068827f2b232a640f5949a5f0872b24 Signed-off-by: Srinivasan Muralidharan <muralisr@us.ibm.com>
- v3.0.0
- v3.0.0-rc1
- v3.0.0-preview
- v3.0.0-beta
- v2.5.10
- v2.5.9
- v2.5.8
- v2.5.7
- v2.5.6
- v2.5.5
- v2.5.4
- v2.5.3
- v2.5.2
- v2.5.1
- v2.5.0
- v2.5.0-beta2
- v2.5.0-beta
- v2.5.0-alpha3
- v2.5.0-alpha2
- v2.5.0-alpha1
- v2.4.9
- v2.4.8
- v2.4.7
- v2.4.6
- v2.4.5
- v2.4.4
- v2.4.3
- v2.4.2
- v2.4.1
- v2.4.0
- v2.4.0-beta
- v2.4.0-alpha
- v2.3.3
- v2.3.2
- v2.3.1
- v2.3.0
- v2.2.15
- v2.2.14
- v2.2.13
- v2.2.12
- v2.2.11
- v2.2.10
- v2.2.9
- v2.2.8
- v2.2.7
- v2.2.6
- v2.2.5
- v2.2.4
- v2.2.3
- v2.2.2
- v2.2.1
- v2.2.0
- v2.1.1
- v2.1.0
- v2.0.1
- v2.0.0
- v2.0.0-beta
- v2.0.0-alpha
- v1.4.12
- v1.4.11
- v1.4.10
- v1.4.9
- v1.4.8
- v1.4.7
- v1.4.6
- v1.4.5
- v1.4.4
- v1.4.3
- v1.4.2
- v1.4.1
- v1.4.1-rc1
- v1.4.0
- v1.4.0-rc2
- v1.4.0-rc1
- v1.3.0
- v1.3.0-rc1
- v1.2.1
- v1.2.0
- v1.2.0-rc1
- v1.1.1
- v1.1.0
- v1.1.0-rc1
- v1.1.0-preview
- v1.1.0-alpha
Srinivasan Muralidharan
committed
Aug 8, 2017
1 parent
c2c8e20
commit 8cd32bf
Showing
8 changed files
with
438 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
/* | ||
Copyright IBM Corp. All Rights Reserved. | ||
SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package rscc | ||
|
||
import ( | ||
"fmt" | ||
"sync" | ||
|
||
"github.com/golang/protobuf/proto" | ||
"github.com/hyperledger/fabric/common/flogging" | ||
"github.com/hyperledger/fabric/core/aclmgmt" | ||
"github.com/hyperledger/fabric/core/chaincode/shim" | ||
"github.com/hyperledger/fabric/protos/common" | ||
pb "github.com/hyperledger/fabric/protos/peer" | ||
) | ||
|
||
const ( | ||
//CHANNEL name | ||
CHANNEL = "channel" | ||
|
||
//POLICY for the channel | ||
POLICY = "policy" | ||
|
||
//Init Errors (for UT) | ||
|
||
//NOCHANNEL channel not found | ||
NOCHANNEL = "nochannel" | ||
|
||
//NOPOLICY policy not found for channel | ||
NOPOLICY = "nopolicy" | ||
|
||
//BADPOLICY bad policy | ||
BADPOLICY = "badpolicy" | ||
) | ||
|
||
//the basic policyProvider for the channel, consists of a | ||
//default and rscc policy providers | ||
type policyProvider struct { | ||
//maybe we should use a separate default policy provider | ||
//than the only from aclmgmt (which is 1.0 defaults) | ||
defaultProvider aclmgmt.ACLProvider | ||
|
||
rsccProvider rsccPolicyProvider | ||
} | ||
|
||
//Rscc SCC implementing resouce->Policy mapping for the fabric | ||
type Rscc struct { | ||
sync.RWMutex | ||
|
||
//the cache of RSCC policies for all the channels | ||
policyCache map[string]*policyProvider | ||
} | ||
|
||
var rsccLogger = flogging.MustGetLogger("rscc") | ||
|
||
//NewRscc get an initialzed new Rscc | ||
func NewRscc() *Rscc { | ||
return &Rscc{policyCache: make(map[string]*policyProvider)} | ||
} | ||
|
||
//--------- errors --------- | ||
|
||
//NoPolicyProviderInCache in cache for channel | ||
type NoPolicyProviderInCache string | ||
|
||
func (e NoPolicyProviderInCache) Error() string { | ||
return fmt.Sprintf("cannot find policy provider in cache for channel %s", string(e)) | ||
} | ||
|
||
//PolicyProviderNotFound for channel | ||
type PolicyProviderNotFound string | ||
|
||
func (e PolicyProviderNotFound) Error() string { | ||
return fmt.Sprintf("cannot find policy provider for channel %s", string(e)) | ||
} | ||
|
||
//-------- ACLProvider interface ------ | ||
|
||
//CheckACL rscc implements AClProvider's CheckACL interface. This is the key interface | ||
// . CheckACL works off the cache | ||
// . CheckACL uses two providers - the RSCC provider from channel config and default provider | ||
// that implements 1.0 functions | ||
// . If a resource in RSCC Provider it'll use the policy defined there. Otherwise it'll defer | ||
// to default provider | ||
func (rscc *Rscc) CheckACL(resName string, channelID string, idinfo interface{}) error { | ||
rsccLogger.Debugf("acl check(%s, %s)", resName, channelID) | ||
rscc.RLock() | ||
defer rscc.RUnlock() | ||
pp := rscc.policyCache[channelID] | ||
if pp == nil { | ||
return NoPolicyProviderInCache(channelID) | ||
} | ||
|
||
//found policyProvider | ||
if pp.rsccProvider != nil { | ||
//get the policy mapping if any | ||
if policyName := pp.rsccProvider.GetPolicyName(resName); policyName != "" { | ||
return pp.rsccProvider.CheckACL(policyName, idinfo) | ||
} | ||
} | ||
|
||
//try default provider | ||
if pp.defaultProvider != nil { | ||
return pp.defaultProvider.CheckACL(resName, channelID, idinfo) | ||
} | ||
|
||
return PolicyProviderNotFound(channelID) | ||
} | ||
|
||
//---------- misc functions --------- | ||
func (rscc *Rscc) putPolicyProvider(channel string, pp *policyProvider) { | ||
rscc.Lock() | ||
defer rscc.Unlock() | ||
rscc.policyCache[channel] = pp | ||
} | ||
|
||
func (rscc *Rscc) setPolicyProvider(channel string, defProv aclmgmt.ACLProvider, rsccProv rsccPolicyProvider) { | ||
pp := &policyProvider{defProv, rsccProv} | ||
rscc.putPolicyProvider(channel, pp) | ||
} | ||
|
||
//-------- CC interface ------------ | ||
|
||
// Init RSCC - Init is just used to initialize policy assuming it is found in the | ||
// channel ledger. Don't return error and get out. For example, we might still serve | ||
// Invokes to set policy | ||
func (rscc *Rscc) Init(stub shim.ChaincodeStubInterface) pb.Response { | ||
rsccLogger.Info("Init RSCC") | ||
|
||
b, err := stub.GetState(CHANNEL) | ||
if err != nil || len(b) == 0 { | ||
rsccLogger.Errorf("cannot find channel name") | ||
return shim.Success([]byte(NOCHANNEL)) | ||
} | ||
|
||
channel := string(b) | ||
|
||
defProv := aclmgmt.NewDefaultACLProvider() | ||
|
||
b, err = stub.GetState(POLICY) | ||
if err != nil || len(b) == 0 { | ||
//we do not have policy, create just defaults | ||
rscc.setPolicyProvider(channel, defProv, nil) | ||
rsccLogger.Errorf("cannot find policy for channel %s", channel) | ||
return shim.Success([]byte(NOPOLICY)) | ||
} | ||
|
||
//TODO this is a place holder.. will change based on what is stored in | ||
//ledger | ||
cg := &common.ConfigGroup{} | ||
err = proto.Unmarshal(b, cg) | ||
if err != nil { | ||
rscc.setPolicyProvider(channel, defProv, nil) | ||
rsccLogger.Errorf("cannot unmarshal policy for channel %s", channel) | ||
return shim.Success([]byte(BADPOLICY)) | ||
} | ||
|
||
rsccpp, err := newRsccPolicyProvider(cg) | ||
if err != nil { | ||
rsccLogger.Errorf("cannot create policy provider for channel %s", channel) | ||
} | ||
|
||
rscc.setPolicyProvider(channel, defProv, rsccpp) | ||
|
||
return shim.Success(nil) | ||
} | ||
|
||
//Invoke - update policies | ||
func (rscc *Rscc) Invoke(stub shim.ChaincodeStubInterface) pb.Response { | ||
return shim.Error("--TBD---") | ||
} |
Oops, something went wrong.