*: add a mock connector which takes a username and password for testing

Since we don't have a good strategy which takes a username and password
add a mock connector which implementes PasswordConnector so we can
develop the frontend screens.
This commit is contained in:
Eric Chiang 2016-08-25 13:00:53 -07:00
parent 144fa41a23
commit 68746fd795
3 changed files with 69 additions and 34 deletions

View file

@ -111,9 +111,15 @@ func (c *Connector) UnmarshalYAML(unmarshal func(interface{}) error) error {
var err error
switch c.Type {
case "mock":
case "mockCallback":
var config struct {
Config mock.Config `yaml:"config"`
Config mock.CallbackConfig `yaml:"config"`
}
err = unmarshal(&config)
c.Config = &config.Config
case "mockPassword":
var config struct {
Config mock.PasswordConfig `yaml:"config"`
}
err = unmarshal(&config)
c.Config = &config.Config

View file

@ -1,4 +1,4 @@
// Package mock implements a mock connector which requires no user interaction.
// Package mock implements connectors which help test various server components.
package mock
import (
@ -11,22 +11,24 @@ import (
"github.com/coreos/dex/connector"
)
// New returns a mock connector which requires no user interaction. It always returns
// NewCallbackConnector returns a mock connector which requires no user interaction. It always returns
// the same (fake) identity.
func New() connector.Connector {
return mockConnector{}
func NewCallbackConnector() connector.Connector {
return callbackConnector{}
}
var (
_ connector.CallbackConnector = mockConnector{}
_ connector.GroupsConnector = mockConnector{}
_ connector.CallbackConnector = callbackConnector{}
_ connector.GroupsConnector = callbackConnector{}
_ connector.PasswordConnector = passwordConnector{}
)
type mockConnector struct{}
type callbackConnector struct{}
func (m mockConnector) Close() error { return nil }
func (m callbackConnector) Close() error { return nil }
func (m mockConnector) LoginURL(callbackURL, state string) (string, error) {
func (m callbackConnector) LoginURL(callbackURL, state string) (string, error) {
u, err := url.Parse(callbackURL)
if err != nil {
return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err)
@ -39,7 +41,7 @@ func (m mockConnector) LoginURL(callbackURL, state string) (string, error) {
var connectorData = []byte("foobar")
func (m mockConnector) HandleCallback(r *http.Request) (connector.Identity, string, error) {
func (m callbackConnector) HandleCallback(r *http.Request) (connector.Identity, string, error) {
return connector.Identity{
UserID: "0-385-28089-0",
Username: "Kilgore Trout",
@ -49,17 +51,54 @@ func (m mockConnector) HandleCallback(r *http.Request) (connector.Identity, stri
}, r.URL.Query().Get("state"), nil
}
func (m mockConnector) Groups(identity connector.Identity) ([]string, error) {
func (m callbackConnector) Groups(identity connector.Identity) ([]string, error) {
if !bytes.Equal(identity.ConnectorData, connectorData) {
return nil, errors.New("connector data mismatch")
}
return []string{"authors"}, nil
}
// Config holds the configuration parameters for the mock connector.
type Config struct{}
// CallbackConfig holds the configuration parameters for a connector which requires no interaction.
type CallbackConfig struct{}
// Open returns an authentication strategy which requires no user interaction.
func (c *Config) Open() (connector.Connector, error) {
return New(), nil
func (c *CallbackConfig) Open() (connector.Connector, error) {
return NewCallbackConnector(), nil
}
// PasswordConfig holds the configuration for a mock connector which prompts for the supplied
// username and password.
type PasswordConfig struct {
Username string `yaml:"username"`
Password string `yaml:"password"`
}
// Open returns an authentication strategy which prompts for a predefined username and password.
func (c *PasswordConfig) Open() (connector.Connector, error) {
if c.Username == "" {
return nil, errors.New("no username supplied")
}
if c.Password == "" {
return nil, errors.New("no password supplied")
}
return &passwordConnector{c.Username, c.Password}, nil
}
type passwordConnector struct {
username string
password string
}
func (p passwordConnector) Close() error { return nil }
func (p passwordConnector) Login(username, password string) (identity connector.Identity, validPassword bool, err error) {
if username == p.username && password == p.password {
return connector.Identity{
UserID: "0-385-28089-0",
Username: "Kilgore Trout",
Email: "kilgore@kilgore.trout",
EmailVerified: true,
}, true, nil
}
return identity, false, nil
}

View file

@ -7,25 +7,15 @@ web:
http: 127.0.0.1:5556
connectors:
- type: mock
id: mock
- type: mockCallback
id: mock-callback
name: Mock
- type: github
id: github
name: GitHub
- type: mockPassword
id: mock-password
name: Password
config:
clientID: "$GITHUB_CLIENT_ID"
clientSecret: "$GITHUB_CLIENT_SECRET"
redirectURI: http://127.0.0.1:5556/callback/github
org: kubernetes
- type: oidc
id: google
name: Google Account
config:
issuer: https://accounts.google.com
clientID: "$GOOGLE_OAUTH2_CLIENT_ID"
clientSecret: "$GOOGLE_OAUTH2_CLIENT_SECRET"
redirectURI: http://127.0.0.1:5556/callback/google
username: "admin"
password: "PASSWORD"
staticClients:
- id: example-app