diff --git a/connector/plugin/plugin.go b/connector/plugin/plugin.go new file mode 100644 index 0000000000..44a9e6bb25 --- /dev/null +++ b/connector/plugin/plugin.go @@ -0,0 +1,46 @@ +package plugin + +import ( + plug "plugin" + + "github.com/dexidp/dex/connector" + "github.com/sirupsen/logrus" +) + +// Config holds configuration for loading a plugin +// +// An example config: +// id: sample +// name: sample +// type: plugin +// config: +// plugin: sample.so +// config: +// name: sample +// options: limitless +type Config struct { + Plugin string + Config interface{} +} + +type pluginConfig interface { + Open(interface{}, string, logrus.FieldLogger) (connector.Connector, error) +} + +// Open returns a connector loaded as a plugin +func (c *Config) Open(id string, logger logrus.FieldLogger) (connector.Connector, error) { + plug, err := plug.Open(c.Plugin) + if err != nil { + return nil, err + } + symConnector, err := plug.Lookup("Open") + if err != nil { + return nil, err + } + var connector pluginConfig + connector, ok := symConnector.(pluginConfig) + if !ok { + return nil, err + } + return connector.Open(c.Config, id, logger) +} diff --git a/connector/sample-plugin/plugin.go b/connector/sample-plugin/plugin.go new file mode 100644 index 0000000000..ae2cc31b25 --- /dev/null +++ b/connector/sample-plugin/plugin.go @@ -0,0 +1,20 @@ +package main + +import ( + "github.com/dexidp/dex/connector" + "github.com/dexidp/dex/connector/mock" + "github.com/sirupsen/logrus" +) + +func main() {} + +type plugin struct{} + +// Open prints provided config and returns a mock CallbackConnector +func (plugin) Open(config interface{}, id string, logger logrus.FieldLogger) (connector.Connector, error) { + logger.Println("loading connector with configuration ", config) + return mock.NewCallbackConnector(logger), nil +} + +// Open exports the plugin for loading +var Open plugin diff --git a/server/server.go b/server/server.go index d96f562d24..15cdbff747 100644 --- a/server/server.go +++ b/server/server.go @@ -31,6 +31,7 @@ import ( "github.com/dexidp/dex/connector/microsoft" "github.com/dexidp/dex/connector/mock" "github.com/dexidp/dex/connector/oidc" + "github.com/dexidp/dex/connector/plugin" "github.com/dexidp/dex/connector/saml" "github.com/dexidp/dex/storage" ) @@ -429,6 +430,7 @@ type ConnectorConfig interface { // ConnectorsConfig variable provides an easy way to return a config struct // depending on the connector type. var ConnectorsConfig = map[string]func() ConnectorConfig{ + "plugin": func() ConnectorConfig { return new(plugin.Config) }, "mockCallback": func() ConnectorConfig { return new(mock.CallbackConfig) }, "mockPassword": func() ConnectorConfig { return new(mock.PasswordConfig) }, "ldap": func() ConnectorConfig { return new(ldap.Config) },