2016-08-25 20:00:53 +00:00
|
|
|
// Package mock implements connectors which help test various server components.
|
2016-07-25 20:00:28 +00:00
|
|
|
package mock
|
|
|
|
|
|
|
|
import (
|
2017-03-08 18:33:19 +00:00
|
|
|
"context"
|
2016-08-03 04:14:24 +00:00
|
|
|
"errors"
|
2016-07-25 20:00:28 +00:00
|
|
|
"fmt"
|
|
|
|
"net/http"
|
|
|
|
"net/url"
|
|
|
|
|
2018-09-03 06:44:44 +00:00
|
|
|
"github.com/dexidp/dex/connector"
|
2019-02-22 12:19:23 +00:00
|
|
|
"github.com/dexidp/dex/pkg/log"
|
2016-07-25 20:00:28 +00:00
|
|
|
)
|
|
|
|
|
2016-08-25 20:00:53 +00:00
|
|
|
// NewCallbackConnector returns a mock connector which requires no user interaction. It always returns
|
2016-07-25 20:00:28 +00:00
|
|
|
// the same (fake) identity.
|
2019-02-22 12:19:23 +00:00
|
|
|
func NewCallbackConnector(logger log.Logger) connector.Connector {
|
2016-11-21 20:16:36 +00:00
|
|
|
return &Callback{
|
|
|
|
Identity: connector.Identity{
|
|
|
|
UserID: "0-385-28089-0",
|
|
|
|
Username: "Kilgore Trout",
|
|
|
|
Email: "kilgore@kilgore.trout",
|
|
|
|
EmailVerified: true,
|
|
|
|
Groups: []string{"authors"},
|
|
|
|
ConnectorData: connectorData,
|
|
|
|
},
|
2016-11-22 23:35:46 +00:00
|
|
|
Logger: logger,
|
2016-11-21 20:16:36 +00:00
|
|
|
}
|
2016-07-25 20:00:28 +00:00
|
|
|
}
|
|
|
|
|
2016-08-03 04:14:24 +00:00
|
|
|
var (
|
2016-11-21 20:16:36 +00:00
|
|
|
_ connector.CallbackConnector = &Callback{}
|
2016-08-25 20:00:53 +00:00
|
|
|
|
|
|
|
_ connector.PasswordConnector = passwordConnector{}
|
2018-02-07 18:00:07 +00:00
|
|
|
_ connector.RefreshConnector = passwordConnector{}
|
2016-08-03 04:14:24 +00:00
|
|
|
)
|
|
|
|
|
2016-11-21 20:16:36 +00:00
|
|
|
// Callback is a connector that requires no user interaction and always returns the same identity.
|
|
|
|
type Callback struct {
|
|
|
|
// The returned identity.
|
|
|
|
Identity connector.Identity
|
2019-02-22 12:19:23 +00:00
|
|
|
Logger log.Logger
|
2016-11-21 20:16:36 +00:00
|
|
|
}
|
2016-07-25 20:00:28 +00:00
|
|
|
|
2016-11-21 20:16:36 +00:00
|
|
|
// LoginURL returns the URL to redirect the user to login with.
|
|
|
|
func (m *Callback) LoginURL(s connector.Scopes, callbackURL, state string) (string, error) {
|
2016-07-25 20:00:28 +00:00
|
|
|
u, err := url.Parse(callbackURL)
|
|
|
|
if err != nil {
|
|
|
|
return "", fmt.Errorf("failed to parse callbackURL %q: %v", callbackURL, err)
|
|
|
|
}
|
|
|
|
v := u.Query()
|
|
|
|
v.Set("state", state)
|
|
|
|
u.RawQuery = v.Encode()
|
|
|
|
return u.String(), nil
|
|
|
|
}
|
|
|
|
|
2016-08-03 04:14:24 +00:00
|
|
|
var connectorData = []byte("foobar")
|
|
|
|
|
2016-11-21 20:16:36 +00:00
|
|
|
// HandleCallback parses the request and returns the user's identity
|
|
|
|
func (m *Callback) HandleCallback(s connector.Scopes, r *http.Request) (connector.Identity, error) {
|
|
|
|
return m.Identity, nil
|
|
|
|
}
|
2016-11-18 21:40:41 +00:00
|
|
|
|
2016-11-21 20:16:36 +00:00
|
|
|
// Refresh updates the identity during a refresh token request.
|
|
|
|
func (m *Callback) Refresh(ctx context.Context, s connector.Scopes, identity connector.Identity) (connector.Identity, error) {
|
|
|
|
return m.Identity, nil
|
2016-07-25 20:00:28 +00:00
|
|
|
}
|
|
|
|
|
2016-08-25 20:00:53 +00:00
|
|
|
// CallbackConfig holds the configuration parameters for a connector which requires no interaction.
|
|
|
|
type CallbackConfig struct{}
|
2016-07-25 20:00:28 +00:00
|
|
|
|
|
|
|
// Open returns an authentication strategy which requires no user interaction.
|
2019-02-22 12:19:23 +00:00
|
|
|
func (c *CallbackConfig) Open(id string, logger log.Logger) (connector.Connector, error) {
|
2016-11-22 23:35:46 +00:00
|
|
|
return NewCallbackConnector(logger), nil
|
2016-08-25 20:00:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// PasswordConfig holds the configuration for a mock connector which prompts for the supplied
|
|
|
|
// username and password.
|
|
|
|
type PasswordConfig struct {
|
2016-11-03 21:32:23 +00:00
|
|
|
Username string `json:"username"`
|
|
|
|
Password string `json:"password"`
|
2016-08-25 20:00:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Open returns an authentication strategy which prompts for a predefined username and password.
|
2019-02-22 12:19:23 +00:00
|
|
|
func (c *PasswordConfig) Open(id string, logger log.Logger) (connector.Connector, error) {
|
2016-08-25 20:00:53 +00:00
|
|
|
if c.Username == "" {
|
|
|
|
return nil, errors.New("no username supplied")
|
|
|
|
}
|
|
|
|
if c.Password == "" {
|
|
|
|
return nil, errors.New("no password supplied")
|
|
|
|
}
|
2016-11-22 23:35:46 +00:00
|
|
|
return &passwordConnector{c.Username, c.Password, logger}, nil
|
2016-08-25 20:00:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type passwordConnector struct {
|
|
|
|
username string
|
|
|
|
password string
|
2019-02-22 12:19:23 +00:00
|
|
|
logger log.Logger
|
2016-08-25 20:00:53 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (p passwordConnector) Close() error { return nil }
|
|
|
|
|
2016-11-18 21:40:41 +00:00
|
|
|
func (p passwordConnector) Login(ctx context.Context, s connector.Scopes, username, password string) (identity connector.Identity, validPassword bool, err error) {
|
2016-08-25 20:00:53 +00:00
|
|
|
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
|
2016-07-25 20:00:28 +00:00
|
|
|
}
|
2017-11-07 09:28:21 +00:00
|
|
|
|
|
|
|
func (p passwordConnector) Prompt() string { return "" }
|
2018-02-07 18:00:07 +00:00
|
|
|
|
|
|
|
func (p passwordConnector) Refresh(_ context.Context, _ connector.Scopes, identity connector.Identity) (connector.Identity, error) {
|
|
|
|
return identity, nil
|
|
|
|
}
|