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