github.com/Consensys/quorum@v21.1.0+incompatible/plugin/plugin_templates.go (about)

     1  package plugin
     2  
     3  import (
     4  	"context"
     5  
     6  	"github.com/ethereum/go-ethereum/log"
     7  	"github.com/ethereum/go-ethereum/plugin/account"
     8  	"github.com/ethereum/go-ethereum/plugin/helloworld"
     9  	"github.com/ethereum/go-ethereum/plugin/security"
    10  	"google.golang.org/grpc/codes"
    11  	"google.golang.org/grpc/status"
    12  )
    13  
    14  // a template that returns the hello world plugin instance
    15  type HelloWorldPluginTemplate struct {
    16  	*basePlugin
    17  }
    18  
    19  func (p *HelloWorldPluginTemplate) Get() (helloworld.PluginHelloWorld, error) {
    20  	return &helloworld.ReloadablePluginHelloWorld{
    21  		DeferFunc: func() (helloworld.PluginHelloWorld, error) {
    22  			raw, err := p.dispense(helloworld.ConnectorName)
    23  			if err != nil {
    24  				return nil, err
    25  			}
    26  			return raw.(helloworld.PluginHelloWorld), nil
    27  		},
    28  	}, nil
    29  }
    30  
    31  type SecurityPluginTemplate struct {
    32  	*basePlugin
    33  }
    34  
    35  // TLSConfigurationSource returns an implementation of security.TLSConfigurationSource which could be nil
    36  // in case the plugin doesn't implement the corresponding service. In order to verify that, it attempts
    37  // to make a call and inspect the error.
    38  func (sp *SecurityPluginTemplate) TLSConfigurationSource() (security.TLSConfigurationSource, error) {
    39  	raw, err := sp.dispense(security.TLSConfigurationConnectorName)
    40  	if err != nil {
    41  		return nil, err
    42  	}
    43  	tlsConfigurationSource := raw.(security.TLSConfigurationSource)
    44  	// try to invoke the method to test if the plugin actually implements the service
    45  	_, err = tlsConfigurationSource.Get(context.Background())
    46  	rpcStatus, ok := status.FromError(err)
    47  	if ok && rpcStatus.Code() == codes.Unimplemented {
    48  		log.Info("Security: Plugin doesn't implement TLSConfigurationSource service", "err", err)
    49  		return nil, nil
    50  	}
    51  	return tlsConfigurationSource, nil
    52  }
    53  
    54  // AuthenticationManager returns an implementation of security.AuthenticationManager which could be
    55  // a deferred implemenation or a disabled implementation.
    56  //
    57  // The deferred implementation delegates to the actual implemenation (which is the plugin client).
    58  //
    59  // The disabled implementation allows no authentication verification.
    60  func (sp *SecurityPluginTemplate) AuthenticationManager() (security.AuthenticationManager, error) {
    61  	deferFunc := func() (security.AuthenticationManager, error) {
    62  		raw, err := sp.dispense(security.AuthenticationConnectorName)
    63  		if err != nil {
    64  			return nil, err
    65  		}
    66  		return raw.(security.AuthenticationManager), nil
    67  	}
    68  	if am, err := deferFunc(); err != nil {
    69  		return nil, err
    70  	} else {
    71  		// try to invoke the method to test if the plugin actually implements the service
    72  		_, err = am.Authenticate(context.Background(), "")
    73  		rpcStatus, ok := status.FromError(err)
    74  		if ok && rpcStatus.Code() == codes.Unimplemented {
    75  			log.Info("Security: Plugin doesn't implement AuthenticationManager service", "err", err)
    76  			return security.NewDisabledAuthenticationManager(), nil
    77  		}
    78  	}
    79  	return security.NewDeferredAuthenticationManager(deferFunc), nil
    80  }
    81  
    82  type ReloadableAccountServiceFactory struct {
    83  	*basePlugin
    84  }
    85  
    86  func (f *ReloadableAccountServiceFactory) Create() (account.Service, error) {
    87  	am := &account.ReloadableService{
    88  		DispenseFunc: func() (account.Service, error) {
    89  			raw, err := f.dispense(account.ConnectorName)
    90  			if err != nil {
    91  				return nil, err
    92  			}
    93  			return raw.(account.Service), nil
    94  		},
    95  	}
    96  
    97  	return am, nil
    98  }