github.com/s7techlab/cckit@v0.10.5/gateway/opt.go (about)

     1  package gateway
     2  
     3  import (
     4  	"context"
     5  	"fmt"
     6  
     7  	"github.com/golang/protobuf/jsonpb"
     8  	"github.com/golang/protobuf/proto"
     9  	"github.com/hyperledger/fabric-protos-go/peer"
    10  	"github.com/hyperledger/fabric/msp"
    11  
    12  	"github.com/s7techlab/cckit/extensions/encryption"
    13  	"github.com/s7techlab/cckit/state/mapping"
    14  )
    15  
    16  type (
    17  	Opts struct {
    18  		Context []ContextOpt
    19  		Input   []InputOpt
    20  		Output  []OutputOpt
    21  		Event   []EventOpt
    22  	}
    23  
    24  	InstanceOpts struct {
    25  		Locator *ChaincodeLocator
    26  		Opts    Opts
    27  	}
    28  
    29  	Opt func(*Opts)
    30  
    31  	ContextOpt func(ctx context.Context) context.Context
    32  	InputOpt   func(input *ChaincodeInput) error
    33  	OutputOpt  func(action InvocationType, response *peer.Response) error
    34  	EventOpt   func(event *ChaincodeEvent) error
    35  )
    36  
    37  func WithDefaultSigner(defaultSigner msp.SigningIdentity) Opt {
    38  	return func(opts *Opts) {
    39  		opts.Context = append(opts.Context, func(ctx context.Context) context.Context {
    40  			return ContextWithDefaultSigner(ctx, defaultSigner)
    41  		})
    42  	}
    43  }
    44  
    45  func WithDefaultTransientMapValue(key string, value []byte) Opt {
    46  	return func(o *Opts) {
    47  		o.Input = append(o.Input, func(input *ChaincodeInput) error {
    48  			if input.Transient == nil {
    49  				input.Transient = make(map[string][]byte)
    50  			}
    51  			if _, exists := input.Transient[key]; !exists {
    52  				input.Transient[key] = value
    53  			}
    54  			return nil
    55  		})
    56  	}
    57  }
    58  
    59  func WithEncryption(encKey []byte) Opt {
    60  	return func(o *Opts) {
    61  		WithDefaultTransientMapValue(encryption.TransientMapKey, encKey)(o)
    62  		WithArgsEncryption(encKey)(o)
    63  		WithInvokePayloadDecryption(encKey)(o)
    64  		WithEventDecryption(encKey)(o)
    65  	}
    66  }
    67  
    68  func WithArgsEncryption(encKey []byte) Opt {
    69  	return func(o *Opts) {
    70  		o.Input = append(o.Input, func(ccInput *ChaincodeInput) (err error) {
    71  			ccInput.Args, err = encryption.EncryptArgsBytes(encKey, ccInput.Args)
    72  			return err
    73  		})
    74  	}
    75  }
    76  
    77  func WithInvokePayloadDecryption(encKey []byte) Opt {
    78  	return func(o *Opts) {
    79  		o.Output = append(o.Output, func(action InvocationType, r *peer.Response) (err error) {
    80  			if action != InvocationType_INVOCATION_TYPE_INVOKE {
    81  				return nil
    82  			}
    83  			r.Payload, err = encryption.Decrypt(encKey, r.Payload)
    84  			if err != nil {
    85  				return fmt.Errorf(`decrypt invoke payload: %w`, err)
    86  			}
    87  			return nil
    88  		})
    89  	}
    90  }
    91  
    92  func WithEventDecryption(encKey []byte) Opt {
    93  	return func(o *Opts) {
    94  		o.Event = append(o.Event, func(e *ChaincodeEvent) error {
    95  			de, err := encryption.DecryptEvent(encKey, e.Event)
    96  			if err != nil {
    97  				return err
    98  			}
    99  
   100  			e.Event = de
   101  			return nil
   102  		})
   103  	}
   104  }
   105  
   106  func WithEventResolver(resolver mapping.EventResolver) Opt {
   107  	return func(o *Opts) {
   108  		o.Event = append(o.Event, func(e *ChaincodeEvent) error {
   109  			eventPayload, err := resolver.Resolve(e.Event.EventName, e.Event.Payload)
   110  			if err != nil {
   111  				return err
   112  			}
   113  
   114  			bb, err := (&jsonpb.Marshaler{EmitDefaults: true, OrigName: true}).MarshalToString(eventPayload.(proto.Message))
   115  			if err != nil {
   116  				return err
   117  			}
   118  
   119  			e.Payload = &RawJson{Value: []byte(bb)}
   120  			return nil
   121  		})
   122  	}
   123  }