github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/common/tools/configtxlator/sanitycheck/sanitycheck.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package sanitycheck 18 19 import ( 20 "fmt" 21 22 "github.com/hyperledger/fabric/common/configtx" 23 cb "github.com/hyperledger/fabric/protos/common" 24 mspprotos "github.com/hyperledger/fabric/protos/msp" 25 "github.com/hyperledger/fabric/protos/utils" 26 27 "github.com/golang/protobuf/proto" 28 ) 29 30 type Messages struct { 31 GeneralErrors []string `json:"general_errors"` 32 ElementWarnings []*ElementMessage `json:"element_errors"` 33 ElementErrors []*ElementMessage `json:"element_errors"` 34 } 35 36 type ElementMessage struct { 37 Path string `json:"path"` 38 Message string `json:"message"` 39 } 40 41 func Check(config *cb.Config) (*Messages, error) { 42 envConfig, err := utils.CreateSignedEnvelope(cb.HeaderType_CONFIG, "sanitycheck", nil, &cb.ConfigEnvelope{Config: config}, 0, 0) 43 if err != nil { 44 return nil, err 45 } 46 47 result := &Messages{} 48 49 cm, err := configtx.NewManagerImpl(envConfig, configtx.NewInitializer(), nil) 50 if err != nil { 51 result.GeneralErrors = []string{err.Error()} 52 return result, nil 53 } 54 55 // This should come from the MSP manager, but, for some reason 56 // the MSP manager is not intialized if there are no orgs, so, 57 // we collect this manually. 58 mspMap := make(map[string]struct{}) 59 60 if ac, ok := cm.ApplicationConfig(); ok { 61 for _, org := range ac.Organizations() { 62 mspMap[org.MSPID()] = struct{}{} 63 } 64 } 65 66 if oc, ok := cm.OrdererConfig(); ok { 67 for _, org := range oc.Organizations() { 68 mspMap[org.MSPID()] = struct{}{} 69 } 70 } 71 72 policyWarnings, policyErrors := checkPolicyPrincipals(config.ChannelGroup, "", mspMap) 73 74 result.ElementWarnings = policyWarnings 75 result.ElementErrors = policyErrors 76 77 return result, nil 78 } 79 80 func checkPolicyPrincipals(group *cb.ConfigGroup, basePath string, mspMap map[string]struct{}) (warnings []*ElementMessage, errors []*ElementMessage) { 81 for policyName, configPolicy := range group.Policies { 82 appendError := func(err string) { 83 errors = append(errors, &ElementMessage{ 84 Path: basePath + ".policies." + policyName, 85 Message: err, 86 }) 87 } 88 89 appendWarning := func(err string) { 90 warnings = append(errors, &ElementMessage{ 91 Path: basePath + ".policies." + policyName, 92 Message: err, 93 }) 94 } 95 96 if configPolicy.Policy == nil { 97 appendError(fmt.Sprintf("no policy value set for %s", policyName)) 98 continue 99 } 100 101 if configPolicy.Policy.Type != int32(cb.Policy_SIGNATURE) { 102 continue 103 } 104 spe := &cb.SignaturePolicyEnvelope{} 105 err := proto.Unmarshal(configPolicy.Policy.Value, spe) 106 if err != nil { 107 appendError(fmt.Sprintf("error unmarshaling policy value to SignaturePolicyEnvelope: %s", err)) 108 continue 109 } 110 111 for i, identity := range spe.Identities { 112 var mspID string 113 switch identity.PrincipalClassification { 114 case mspprotos.MSPPrincipal_ROLE: 115 role := &mspprotos.MSPRole{} 116 err = proto.Unmarshal(identity.Principal, role) 117 if err != nil { 118 appendError(fmt.Sprintf("value of identities array at index %d is of type ROLE, but could not be unmarshaled to msp.MSPRole: %s", i, err)) 119 continue 120 } 121 mspID = role.MspIdentifier 122 case mspprotos.MSPPrincipal_ORGANIZATION_UNIT: 123 ou := &mspprotos.OrganizationUnit{} 124 err = proto.Unmarshal(identity.Principal, ou) 125 if err != nil { 126 appendError(fmt.Sprintf("value of identities array at index %d is of type ORGANIZATION_UNIT, but could not be unmarshaled to msp.OrganizationUnit: %s", i, err)) 127 continue 128 } 129 mspID = ou.MspIdentifier 130 default: 131 continue 132 } 133 134 _, ok := mspMap[mspID] 135 if !ok { 136 appendWarning(fmt.Sprintf("identity principal at index %d refers to MSP ID '%s', which is not an MSP in the network", i, mspID)) 137 } 138 } 139 } 140 141 for subGroupName, subGroup := range group.Groups { 142 subWarnings, subErrors := checkPolicyPrincipals(subGroup, basePath+".groups."+subGroupName, mspMap) 143 warnings = append(warnings, subWarnings...) 144 errors = append(errors, subErrors...) 145 } 146 return 147 }