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  }