github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/events/producer/handler.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 producer 18 19 import ( 20 "fmt" 21 "strconv" 22 23 "github.com/golang/protobuf/proto" 24 25 "github.com/hyperledger/fabric/common/util" 26 "github.com/hyperledger/fabric/msp/mgmt" 27 pb "github.com/hyperledger/fabric/protos/peer" 28 ) 29 30 type handler struct { 31 ChatStream pb.Events_ChatServer 32 interestedEvents map[string]*pb.Interest 33 RemoteAddr string 34 } 35 36 func newEventHandler(stream pb.Events_ChatServer) (*handler, error) { 37 h := &handler{ 38 ChatStream: stream, 39 interestedEvents: make(map[string]*pb.Interest), 40 RemoteAddr: util.ExtractRemoteAddress(stream.Context()), 41 } 42 logger.Debug("event handler created for", h.RemoteAddr) 43 return h, nil 44 } 45 46 // Stop stops this handler 47 func (h *handler) Stop() error { 48 h.deregisterAll() 49 h.interestedEvents = nil 50 logger.Debug("handler stopped for", h.RemoteAddr) 51 return nil 52 } 53 54 func getInterestKey(interest pb.Interest) string { 55 var key string 56 switch interest.EventType { 57 case pb.EventType_BLOCK: 58 key = "/" + strconv.Itoa(int(pb.EventType_BLOCK)) 59 case pb.EventType_REJECTION: 60 key = "/" + strconv.Itoa(int(pb.EventType_REJECTION)) 61 case pb.EventType_CHAINCODE: 62 key = "/" + strconv.Itoa(int(pb.EventType_CHAINCODE)) + "/" + interest.GetChaincodeRegInfo().ChaincodeId + "/" + interest.GetChaincodeRegInfo().EventName 63 default: 64 logger.Errorf("unsupported interest type: %s", interest.EventType) 65 } 66 67 return key 68 } 69 70 func (h *handler) register(iMsg []*pb.Interest) error { 71 // Could consider passing interest array to registerHandler 72 // and only lock once for entire array here 73 for _, v := range iMsg { 74 if err := registerHandler(v, h); err != nil { 75 logger.Errorf("could not register %s for %s: %s", v, h.RemoteAddr, err) 76 continue 77 } 78 h.interestedEvents[getInterestKey(*v)] = v 79 } 80 81 return nil 82 } 83 84 func (h *handler) deregister(iMsg []*pb.Interest) error { 85 for _, v := range iMsg { 86 if err := deRegisterHandler(v, h); err != nil { 87 logger.Errorf("could not deregister %s for %s: %s", v, h.RemoteAddr, err) 88 continue 89 } 90 delete(h.interestedEvents, getInterestKey(*v)) 91 } 92 return nil 93 } 94 95 func (h *handler) deregisterAll() { 96 for k, v := range h.interestedEvents { 97 if err := deRegisterHandler(v, h); err != nil { 98 logger.Errorf("could not deregister %s for %s: %s", v, h.RemoteAddr, err) 99 continue 100 } 101 delete(h.interestedEvents, k) 102 } 103 } 104 105 // HandleMessage handles the Openchain messages for the Peer. 106 func (h *handler) HandleMessage(msg *pb.SignedEvent) error { 107 evt, err := validateEventMessage(msg) 108 if err != nil { 109 return fmt.Errorf("event message must be properly signed by an identity from the same organization as the peer for %s: %s", h.RemoteAddr, err) 110 } 111 112 switch evt.Event.(type) { 113 case *pb.Event_Register: 114 eventsObj := evt.GetRegister() 115 if err := h.register(eventsObj.Events); err != nil { 116 return fmt.Errorf("could not register events for %s: %s", h.RemoteAddr, err) 117 } 118 case *pb.Event_Unregister: 119 eventsObj := evt.GetUnregister() 120 if err := h.deregister(eventsObj.Events); err != nil { 121 return fmt.Errorf("could not deregister events for %s: %s", h.RemoteAddr, err) 122 } 123 case nil: 124 default: 125 return fmt.Errorf("invalid event type received from %s: %T", h.RemoteAddr, evt.Event) 126 } 127 //TODO return supported events.. for now just return the received msg 128 if err := h.ChatStream.Send(evt); err != nil { 129 return fmt.Errorf("error sending response to %s: %s", h.RemoteAddr, err) 130 } 131 132 return nil 133 } 134 135 // SendMessage sends a message to the remote PEER through the stream 136 func (h *handler) SendMessage(msg *pb.Event) error { 137 logger.Debug("sending event to", h.RemoteAddr) 138 err := h.ChatStream.Send(msg) 139 if err != nil { 140 logger.Debugf("sending event failed for %s: %s", h.RemoteAddr, err) 141 return fmt.Errorf("error sending message through ChatStream: %s", err) 142 } 143 logger.Debug("event sent successfully to", h.RemoteAddr) 144 return nil 145 } 146 147 // Validates event messages by validating the Creator and verifying 148 // the signature. Returns the unmarshaled Event object 149 // Validation of the creator identity's validity is done by checking with local MSP to ensure the 150 // submitter is a member in the same organization as the peer 151 // 152 // TODO: ideally this should also check each channel's "Readers" policy to ensure the identity satisfies 153 // each channel's access control policy. This step is necessary because the registered listener is going 154 // to get read access to all channels by receiving Block events from all channels. 155 // However, this is not being done for v1.0 due to complexity concerns and the need to complex a stable, 156 // minimally viable release. Eventually events will be made channel-specific, at which point this method 157 // should be revisited 158 func validateEventMessage(signedEvt *pb.SignedEvent) (*pb.Event, error) { 159 logger.Debugf("ValidateEventMessage starts for signed event %p", signedEvt) 160 161 // messages from the client for registering and unregistering must be signed 162 // and accompanied by the signing certificate in the "Creator" field 163 evt := &pb.Event{} 164 err := proto.Unmarshal(signedEvt.EventBytes, evt) 165 if err != nil { 166 return nil, fmt.Errorf("error unmarshaling the event bytes in the SignedEvent: %s", err) 167 } 168 169 localMSP := mgmt.GetLocalMSP() 170 principalGetter := mgmt.NewLocalMSPPrincipalGetter() 171 172 // Load MSPPrincipal for policy 173 principal, err := principalGetter.Get(mgmt.Members) 174 if err != nil { 175 return nil, fmt.Errorf("failed getting local MSP principal [member]: %s", err) 176 } 177 178 id, err := localMSP.DeserializeIdentity(evt.Creator) 179 if err != nil { 180 return nil, fmt.Errorf("failed deserializing event creator: %s", err) 181 } 182 183 // Verify that event's creator satisfies the principal 184 err = id.SatisfiesPrincipal(principal) 185 if err != nil { 186 return nil, fmt.Errorf("failed verifying the creator satisfies local MSP's [member] principal: %s", err) 187 } 188 189 // Verify the signature 190 err = id.Verify(signedEvt.EventBytes, signedEvt.Signature) 191 if err != nil { 192 return nil, fmt.Errorf("failed verifying the event signature: %s", err) 193 } 194 195 return evt, nil 196 }