github.com/Unheilbar/quorum@v1.0.0/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/qlight"
    10  	"github.com/ethereum/go-ethereum/plugin/security"
    11  	"google.golang.org/grpc/codes"
    12  	"google.golang.org/grpc/status"
    13  )
    14  
    15  // a template that returns the hello world plugin instance
    16  type HelloWorldPluginTemplate struct {
    17  	*basePlugin
    18  }
    19  
    20  func (p *HelloWorldPluginTemplate) Get() (helloworld.PluginHelloWorld, error) {
    21  	return &helloworld.ReloadablePluginHelloWorld{
    22  		DeferFunc: func() (helloworld.PluginHelloWorld, error) {
    23  			raw, err := p.dispense(helloworld.ConnectorName)
    24  			if err != nil {
    25  				return nil, err
    26  			}
    27  			return raw.(helloworld.PluginHelloWorld), nil
    28  		},
    29  	}, nil
    30  }
    31  
    32  type SecurityPluginTemplate struct {
    33  	*basePlugin
    34  }
    35  
    36  // TLSConfigurationSource returns an implementation of security.TLSConfigurationSource which could be nil
    37  // in case the plugin doesn't implement the corresponding service. In order to verify that, it attempts
    38  // to make a call and inspect the error.
    39  func (sp *SecurityPluginTemplate) TLSConfigurationSource() (security.TLSConfigurationSource, error) {
    40  	raw, err := sp.dispense(security.TLSConfigurationConnectorName)
    41  	if err != nil {
    42  		return nil, err
    43  	}
    44  	tlsConfigurationSource := raw.(security.TLSConfigurationSource)
    45  	// try to invoke the method to test if the plugin actually implements the service
    46  	_, err = tlsConfigurationSource.Get(context.Background())
    47  	rpcStatus, ok := status.FromError(err)
    48  	if ok && rpcStatus.Code() == codes.Unimplemented {
    49  		log.Info("Security: Plugin doesn't implement TLSConfigurationSource service", "err", err)
    50  		return nil, nil
    51  	}
    52  	return tlsConfigurationSource, nil
    53  }
    54  
    55  // AuthenticationManager returns an implementation of security.AuthenticationManager which could be
    56  // a deferred implemenation or a disabled implementation.
    57  //
    58  // The deferred implementation delegates to the actual implemenation (which is the plugin client).
    59  //
    60  // The disabled implementation allows no authentication verification.
    61  func (sp *SecurityPluginTemplate) AuthenticationManager() (security.AuthenticationManager, error) {
    62  	deferFunc := func() (security.AuthenticationManager, error) {
    63  		raw, err := sp.dispense(security.AuthenticationConnectorName)
    64  		if err != nil {
    65  			return nil, err
    66  		}
    67  		return raw.(security.AuthenticationManager), nil
    68  	}
    69  	if am, err := deferFunc(); err != nil {
    70  		return nil, err
    71  	} else {
    72  		// try to invoke the method to test if the plugin actually implements the service
    73  		_, err = am.Authenticate(context.Background(), "")
    74  		rpcStatus, ok := status.FromError(err)
    75  		if ok && rpcStatus.Code() == codes.Unimplemented {
    76  			log.Info("Security: Plugin doesn't implement AuthenticationManager service", "err", err)
    77  			return security.NewDisabledAuthenticationManager(), nil
    78  		}
    79  	}
    80  	return security.NewDeferredAuthenticationManager(deferFunc), nil
    81  }
    82  
    83  type ReloadableAccountServiceFactory struct {
    84  	*basePlugin
    85  }
    86  
    87  func (f *ReloadableAccountServiceFactory) Create() (account.Service, error) {
    88  	am := &account.ReloadableService{
    89  		DispenseFunc: func() (account.Service, error) {
    90  			raw, err := f.dispense(account.ConnectorName)
    91  			if err != nil {
    92  				return nil, err
    93  			}
    94  			return raw.(account.Service), nil
    95  		},
    96  	}
    97  
    98  	return am, nil
    99  }
   100  
   101  type QLightTokenManagerPluginTemplate struct {
   102  	*basePlugin
   103  }
   104  
   105  func (p *QLightTokenManagerPluginTemplate) Get() (qlight.PluginTokenManager, error) {
   106  	return &qlight.ReloadablePluginTokenManager{
   107  		DeferFunc: func() (qlight.PluginTokenManager, error) {
   108  			raw, err := p.dispense(qlight.ConnectorName)
   109  			if err != nil {
   110  				return nil, err
   111  			}
   112  			return raw.(qlight.PluginTokenManager), nil
   113  		},
   114  	}, nil
   115  }
   116  
   117  func (p *QLightTokenManagerPluginTemplate) ManagedPlugin() managedPlugin {
   118  	return p
   119  }
   120  
   121  type QLightTokenManagerPluginTemplateInterface interface {
   122  	Get() (qlight.PluginTokenManager, error)
   123  	Start() (err error)
   124  	Stop() (err error)
   125  	ManagedPlugin() managedPlugin
   126  }
   127  
   128  //go:generate mockgen -source=plugin_templates.go -destination plugin_templates_mockery.go -package plugin
   129  var _ QLightTokenManagerPluginTemplateInterface = &QLightTokenManagerPluginTemplate{}
   130  var _ QLightTokenManagerPluginTemplateInterface = &MockQLightTokenManagerPluginTemplateInterface{}