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 }