Skip to content

Commit

Permalink
Set Correct policy while channel update (#114)
Browse files Browse the repository at this point in the history
* Set Correct policy while channel update

Signed-off-by: n0s09by <[email protected]>

* Moved the rolePolicy function into utils

Signed-off-by: n0s09by <[email protected]>

* Enhancement:Refractored reptitive code into method

Signed-off-by: n0s09by <[email protected]>

---------

Signed-off-by: n0s09by <[email protected]>
  • Loading branch information
nidhi-singh02 authored Dec 27, 2023
1 parent 10533b6 commit a3516ef
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 275 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import hlf.java.rest.client.model.AnchorPeerDTO;
import hlf.java.rest.client.model.NewOrgParamsDTO;
import hlf.java.rest.client.service.AddOrgToChannelWriteSetBuilder;
import hlf.java.rest.client.util.FabricChannelUtil;
import hlf.java.rest.client.util.FabricClientConstants;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -15,12 +16,6 @@
import org.hyperledger.fabric.protos.common.Configtx.ConfigGroup;
import org.hyperledger.fabric.protos.common.Configtx.ConfigPolicy;
import org.hyperledger.fabric.protos.common.Configtx.ConfigValue;
import org.hyperledger.fabric.protos.common.MspPrincipal.MSPPrincipal;
import org.hyperledger.fabric.protos.common.MspPrincipal.MSPRole;
import org.hyperledger.fabric.protos.common.Policies.Policy;
import org.hyperledger.fabric.protos.common.Policies.SignaturePolicy;
import org.hyperledger.fabric.protos.common.Policies.SignaturePolicy.NOutOf;
import org.hyperledger.fabric.protos.common.Policies.SignaturePolicyEnvelope;
import org.hyperledger.fabric.protos.msp.MspConfigPackage.FabricCryptoConfig;
import org.hyperledger.fabric.protos.msp.MspConfigPackage.FabricMSPConfig;
import org.hyperledger.fabric.protos.msp.MspConfigPackage.FabricNodeOUs;
Expand All @@ -44,25 +39,27 @@ public ConfigGroup buildWriteset(ConfigGroup readset, NewOrgParamsDTO organizati
// Get existing organizations in the channel and set with as objects and their
// version to prevent deletion or modification
// Omitting existing groups results in their deletion.
Map<String, ConfigGroup> organizations = new HashMap<>();
Map<String, ConfigGroup> existingOrganizations = new HashMap<>();
ConfigGroup applicationConfigGroup =
readset.getGroupsOrThrow(FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION);
applicationConfigGroup
.getGroupsMap()
.forEach(
(k, v) ->
organizations.put(
k, setEmptyGroup(retrieveGroupVersionFromReadset(applicationConfigGroup, k))));
existingOrganizations.put(
k,
setEmptyGroup(retrieveMSPGroupVersionFromReadset(applicationConfigGroup, k))));
// The "Application" group
ConfigGroup applicationGroup =
ConfigGroup.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.putAllPolicies(setApplicationPolicies(readset))
.putGroups(newOrgMspId, setNewOrgGroup(newOrgMspId))
.putAllGroups(organizations)
// putAllGroups excludes new organization
.putAllGroups(existingOrganizations)
// Application group version
.setVersion(
retrieveGroupVersionFromReadset(
retrieveMSPGroupVersionFromReadset(
readset, FabricClientConstants.CHANNEL_CONFIG_GROUP_APPLICATION)
+ 1) // will
// be
Expand All @@ -84,17 +81,17 @@ public ConfigGroup buildWriteset(ConfigGroup readset, NewOrgParamsDTO organizati
.build();
}

private long retrieveGroupVersionFromReadset(ConfigGroup readset, String groupName)
private long retrieveMSPGroupVersionFromReadset(ConfigGroup readset, String mspId)
throws ServiceException {
long versionLong = DEFAULT_VERSION;
try {
ConfigGroup group = readset.getGroupsOrThrow(groupName);
ConfigGroup group = readset.getGroupsOrThrow(mspId);
versionLong = group.getVersion();
} catch (IllegalArgumentException e) {
throw new ServiceException(
ErrorCode.NOT_FOUND,
"WriteBuilder version iteration error: ConfigGroup with name - \""
+ groupName
+ mspId
+ "\" - not found in Readset",
e);
}
Expand Down Expand Up @@ -150,8 +147,9 @@ private Map<String, ConfigPolicy> setApplicationPolicies(ConfigGroup readset) {
.setModPolicy("")
.setVersion(map.get(FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS))
.build();

Map<String, ConfigPolicy> applicationPoliciesMap = new HashMap<>();
// add Admins, Readers, Writers, Endorsement and LifeCycle Endorsement policies at the channel
// level
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS, adminPolicy);
applicationPoliciesMap.put(
Expand All @@ -177,118 +175,16 @@ private ConfigGroup setNewOrgGroup(String newOrgMspId) {

return ConfigGroup.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.putAllPolicies(setNewOrgPolicies(newOrgMspId))
.putAllPolicies(FabricChannelUtil.getDefaultRolePolicy(newOrgMspId))
.putAllValues(valueMap)
.setVersion(0)
.setVersion(0) // First time update, hence version is 0
.build();
}

private ConfigGroup setEmptyGroup(long version) {
return ConfigGroup.newBuilder().setModPolicy("").setVersion(version).build();
}

private Map<String, ConfigPolicy> setNewOrgPolicies(String newOrgName) {
Map<String, ConfigPolicy> applicationPoliciesMap = new HashMap<>();
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS,
setNewOrgPolicy(newOrgName, FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS));
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT,
setNewOrgPolicy(newOrgName, FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT));
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS,
setNewOrgPolicy(newOrgName, FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS));
applicationPoliciesMap.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS,
setNewOrgPolicy(newOrgName, FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS));

return applicationPoliciesMap;
}

private ConfigPolicy setNewOrgPolicy(String newOrgName, String policyTarget) {
return ConfigPolicy.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.setPolicy(setTypeOnePolicy(newOrgName, policyTarget))
.setVersion(0)
.build();
}

private Policy setTypeOnePolicy(String orgName, String policyTarget) {
ArrayList<MSPPrincipal> identitiesList = new ArrayList<>();

MSPRole mspRoleAdmin =
MSPRole.newBuilder().setRole(MSPRole.MSPRoleType.ADMIN).setMspIdentifier(orgName).build();
MSPPrincipal mspPrincipalAdmin =
MSPPrincipal.newBuilder()
.setPrincipal(mspRoleAdmin.toByteString())
.setPrincipalClassification(MSPPrincipal.Classification.ROLE)
.build();
MSPRole mspRolePeer =
MSPRole.newBuilder().setRole(MSPRole.MSPRoleType.PEER).setMspIdentifier(orgName).build();
MSPPrincipal mspPrincipalPeer =
MSPPrincipal.newBuilder()
.setPrincipal(mspRolePeer.toByteString())
.setPrincipalClassification(MSPPrincipal.Classification.ROLE)
.build();
MSPRole mspRoleClient =
MSPRole.newBuilder().setRole(MSPRole.MSPRoleType.CLIENT).setMspIdentifier(orgName).build();
MSPPrincipal mspPrincipalClient =
MSPPrincipal.newBuilder()
.setPrincipal(mspRoleClient.toByteString())
.setPrincipalClassification(MSPPrincipal.Classification.ROLE)
.build();

// "SignaturePolicy" is repeated internally despite being the same class, but
// with
// different internal components used
SignaturePolicy rules = null;
NOutOf nOutOf = null;

switch (policyTarget) {
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS:
identitiesList.add(mspPrincipalAdmin);
rules = SignaturePolicy.newBuilder().setSignedBy(0).build();
nOutOf = NOutOf.newBuilder().setN(1).addRules(rules).build();
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT:
identitiesList.add(mspPrincipalPeer);
rules = SignaturePolicy.newBuilder().setSignedBy(0).build();
nOutOf = NOutOf.newBuilder().setN(1).addRules(rules).build();
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS:
identitiesList.add(mspPrincipalAdmin);
identitiesList.add(mspPrincipalPeer);
identitiesList.add(mspPrincipalClient);
rules = SignaturePolicy.newBuilder().setSignedBy(0).setSignedBy(1).setSignedBy(2).build();
nOutOf = NOutOf.newBuilder().setN(3).addRules(rules).build();
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS:
identitiesList.add(mspPrincipalAdmin);
identitiesList.add(mspPrincipalClient);
rules = SignaturePolicy.newBuilder().setSignedBy(0).setSignedBy(1).build();
nOutOf = NOutOf.newBuilder().setN(2).addRules(rules).build();
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_LIFECYCLE_ENDORSEMENT:
// Fill later based on requirements
break;
default:
throw new ServiceException(
ErrorCode.NOT_FOUND,
"Error building readset. Policy Type: \"" + policyTarget + "\" not found.");
}
SignaturePolicy rule = SignaturePolicy.newBuilder().setNOutOf(nOutOf).build();

// For type 1 policy
SignaturePolicyEnvelope spe =
SignaturePolicyEnvelope.newBuilder()
.setVersion(0)
.addAllIdentities(identitiesList)
.setRule(rule)
.build();

return Policy.newBuilder().setType(1).setValue(spe.toByteString()).build();
}

private ConfigValue setNewOrgMspValue(String newOrgMspId) {
return ConfigValue.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import hlf.java.rest.client.model.ClientResponseModel;
import hlf.java.rest.client.service.ChannelService;
import hlf.java.rest.client.service.HFClientWrapper;
import hlf.java.rest.client.util.FabricChannelUtil;
import hlf.java.rest.client.util.FabricClientConstants;
import java.util.ArrayList;
import java.util.HashMap;
Expand All @@ -25,7 +26,6 @@
import org.hyperledger.fabric.protos.common.Common;
import org.hyperledger.fabric.protos.common.Configtx;
import org.hyperledger.fabric.protos.common.Configuration;
import org.hyperledger.fabric.protos.common.MspPrincipal;
import org.hyperledger.fabric.protos.common.Policies;
import org.hyperledger.fabric.protos.msp.MspConfigPackage;
import org.hyperledger.fabric.sdk.Channel;
Expand Down Expand Up @@ -366,163 +366,12 @@ private Configtx.ConfigGroup getMSPConfigGroup(hlf.java.rest.client.model.Peer p
.setVersion(EMPTY_VERSION)
.putAllGroups(new HashMap<>())
.setModPolicy(EMPTY_MOD_POLICY)
.putAllPolicies(getDefaultRolePolicy(peer.getMspid())) // Organization's role policies
.putAllPolicies(
FabricChannelUtil.getDefaultRolePolicy(peer.getMspid())) // Organization's role policies
.putAllValues(valueMap)
.build();
}

// The method returns a default policy for each organization
// that maps the roles. The policy type is signature. Roles
// are identified by their signatures, as those signatures
// represent the certificate.
private HashMap<String, Configtx.ConfigPolicy> getDefaultRolePolicy(String orgMSPId) {
HashMap<String, Configtx.ConfigPolicy> defaultOrgRolePolicy = new HashMap<>();
// add Admins, Readers, Writers and Endorsement policies
defaultOrgRolePolicy.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS,
getDefaultRoleConfigPolicyForMSP(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS, orgMSPId));
defaultOrgRolePolicy.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS,
getDefaultRoleConfigPolicyForMSP(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS, orgMSPId));
defaultOrgRolePolicy.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS,
getDefaultRoleConfigPolicyForMSP(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS, orgMSPId));
defaultOrgRolePolicy.put(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT,
getDefaultRoleConfigPolicyForMSP(
FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT, orgMSPId));
return defaultOrgRolePolicy;
}

// getRolesFor returns the SignaturePolicy that has MSP
// with the logical conditions.
// For example, it is possible to design OR(msp1.member, msp2.client)
// this evaluates to
// identities: {
// ... msp1
// ... msp2
// }
// n out of {
// n: 1
// rules: {
// SignaturePolicy{index: 0}
// SignaturePolicy{index: 1}
// }
// }
private List<MspPrincipal.MSPPrincipal> getRolesFor(String policyFor, String orgMSPId) {
List<MspPrincipal.MSPPrincipal> mspPrincipals = new ArrayList<>();
MspPrincipal.MSPRole mspRole;
MspPrincipal.MSPPrincipal mspPrincipal;
switch (policyFor) {
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ADMINS:
mspRole =
MspPrincipal.MSPRole.newBuilder()
.setMspIdentifier(orgMSPId)
.setRole(MspPrincipal.MSPRole.MSPRoleType.ADMIN)
.build();
mspPrincipal =
MspPrincipal.MSPPrincipal.newBuilder()
.setPrincipal(mspRole.toByteString())
.setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE)
.build();
mspPrincipals.add(mspPrincipal);
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_WRITERS:
// any member who is an admin can write
mspRole =
MspPrincipal.MSPRole.newBuilder()
.setMspIdentifier(orgMSPId)
.setRole(MspPrincipal.MSPRole.MSPRoleType.ADMIN)
.build();
mspPrincipal =
MspPrincipal.MSPPrincipal.newBuilder()
.setPrincipal(mspRole.toByteString())
.setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE)
.build();
mspPrincipals.add(mspPrincipal);
// any client can also write
mspRole =
MspPrincipal.MSPRole.newBuilder()
.setMspIdentifier(orgMSPId)
.setRole(MspPrincipal.MSPRole.MSPRoleType.CLIENT)
.build();
mspPrincipal =
MspPrincipal.MSPPrincipal.newBuilder()
.setPrincipal(mspRole.toByteString())
.setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE)
.build();
mspPrincipals.add(mspPrincipal);
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_ENDORSEMENT:
// any member who is peer can only endorse
mspRole =
MspPrincipal.MSPRole.newBuilder()
.setMspIdentifier(orgMSPId)
.setRole(MspPrincipal.MSPRole.MSPRoleType.PEER)
.build();
mspPrincipal =
MspPrincipal.MSPPrincipal.newBuilder()
.setPrincipal(mspRole.toByteString())
.setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE)
.build();
mspPrincipals.add(mspPrincipal);
break;
case FabricClientConstants.CHANNEL_CONFIG_POLICY_TYPE_READERS:
// any member can read
mspRole =
MspPrincipal.MSPRole.newBuilder()
.setMspIdentifier(orgMSPId)
.setRole(MspPrincipal.MSPRole.MSPRoleType.MEMBER)
.build();
mspPrincipal =
MspPrincipal.MSPPrincipal.newBuilder()
.setPrincipal(mspRole.toByteString())
.setPrincipalClassification(MspPrincipal.MSPPrincipal.Classification.ROLE)
.build();
mspPrincipals.add(mspPrincipal);
break;
}
return mspPrincipals;
}

// The method returns a ConfigPolicy of type signature for the
// passed organization's MSP ID.
private Configtx.ConfigPolicy getDefaultRoleConfigPolicyForMSP(
String policyFor, String orgMSPId) {
List<MspPrincipal.MSPPrincipal> mspPrincipals = getRolesFor(policyFor, orgMSPId);
// loop through each entry and apply the n out of policy
// that is always get at least one signature.
// get the signature policy
// set rules
// create those roles
Policies.SignaturePolicyEnvelope.Builder signaturePolicyEnvelopeBuilder =
Policies.SignaturePolicyEnvelope.newBuilder();
Policies.SignaturePolicy.Builder signaturePolicyBuilder = Policies.SignaturePolicy.newBuilder();
Policies.SignaturePolicy.NOutOf.Builder signatureNOutOfBuilder =
Policies.SignaturePolicy.NOutOf.newBuilder().setN(1); // expect just one signature always
for (int idx = 0; idx < mspPrincipals.size(); idx++) {
signaturePolicyEnvelopeBuilder.setIdentities(idx, mspPrincipals.get(idx));
signatureNOutOfBuilder.setRules(
idx, Policies.SignaturePolicy.newBuilder().setSignedBy(idx).build());
}
signaturePolicyBuilder.setNOutOf(signatureNOutOfBuilder.build());
signaturePolicyEnvelopeBuilder.setRule(signaturePolicyBuilder.build());
// get the policy
Policies.Policy policy =
Policies.Policy.newBuilder()
.setType(Policies.Policy.PolicyType.SIGNATURE_VALUE)
.setValue(signaturePolicyEnvelopeBuilder.build().toByteString())
.build();
// create config policy and return
return Configtx.ConfigPolicy.newBuilder()
.setPolicy(policy)
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
.build();
}

private Configtx.ConfigValue getOrgMspValue(hlf.java.rest.client.model.Peer peer) {
return Configtx.ConfigValue.newBuilder()
.setModPolicy(FabricClientConstants.CHANNEL_CONFIG_MOD_POLICY_ADMINS)
Expand Down Expand Up @@ -653,8 +502,7 @@ private Policies.Policy getImplicitMetaPolicy(String subPolicyName, int rule) {
* @param modPolicy
* @return
*/
private Configtx.ConfigPolicy getConfigPolicy(
String subPolicyName, int rule, String modPolicy) {
private Configtx.ConfigPolicy getConfigPolicy(String subPolicyName, int rule, String modPolicy) {
return Configtx.ConfigPolicy.newBuilder()
.setPolicy(getImplicitMetaPolicy(subPolicyName, rule))
.setModPolicy(modPolicy)
Expand Down
Loading

0 comments on commit a3516ef

Please sign in to comment.