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{}