mirror of https://github.com/dexidp/dex.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
125 lines
3.9 KiB
125 lines
3.9 KiB
// Package mock implements connectors which help test various server components. |
|
package mock |
|
|
|
import ( |
|
"context" |
|
"errors" |
|
"fmt" |
|
"log/slog" |
|
"net/http" |
|
"net/url" |
|
|
|
"github.com/dexidp/dex/connector" |
|
) |
|
|
|
// NewCallbackConnector returns a mock connector which requires no user interaction. It always returns |
|
// the same (fake) identity. |
|
func NewCallbackConnector(logger *slog.Logger) connector.Connector { |
|
return &Callback{ |
|
Identity: connector.Identity{ |
|
UserID: "0-385-28089-0", |
|
Username: "Kilgore Trout", |
|
Email: "kilgore@kilgore.trout", |
|
EmailVerified: true, |
|
Groups: []string{"authors"}, |
|
ConnectorData: connectorData, |
|
}, |
|
Logger: logger, |
|
} |
|
} |
|
|
|
var ( |
|
_ connector.CallbackConnector = &Callback{} |
|
|
|
_ connector.PasswordConnector = passwordConnector{} |
|
_ connector.RefreshConnector = passwordConnector{} |
|
) |
|
|
|
// Callback is a connector that requires no user interaction and always returns the same identity. |
|
type Callback struct { |
|
// The returned identity. |
|
Identity connector.Identity |
|
Logger *slog.Logger |
|
} |
|
|
|
// LoginURL returns the URL to redirect the user to login with. |
|
func (m *Callback) LoginURL(s connector.Scopes, callbackURL, state string) (string, []byte, error) { |
|
u, err := url.Parse(callbackURL) |
|
if err != nil { |
|
return "", nil, 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, nil |
|
} |
|
|
|
var connectorData = []byte("foobar") |
|
|
|
// HandleCallback parses the request and returns the user's identity |
|
func (m *Callback) HandleCallback(s connector.Scopes, connData []byte, r *http.Request) (connector.Identity, error) { |
|
return m.Identity, nil |
|
} |
|
|
|
// 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 |
|
} |
|
|
|
func (m *Callback) TokenIdentity(ctx context.Context, subjectTokenType, subjectToken string) (connector.Identity, error) { |
|
return m.Identity, nil |
|
} |
|
|
|
// 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 *CallbackConfig) Open(id string, logger *slog.Logger) (connector.Connector, error) { |
|
logger = logger.With(slog.Group("connector", "type", "callback", "id", id)) |
|
return NewCallbackConnector(logger), nil |
|
} |
|
|
|
// PasswordConfig holds the configuration for a mock connector which prompts for the supplied |
|
// username and password. |
|
type PasswordConfig struct { |
|
Username string `json:"username"` |
|
Password string `json:"password"` |
|
} |
|
|
|
// Open returns an authentication strategy which prompts for a predefined username and password. |
|
func (c *PasswordConfig) Open(id string, logger *slog.Logger) (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, logger}, nil |
|
} |
|
|
|
type passwordConnector struct { |
|
username string |
|
password string |
|
logger *slog.Logger |
|
} |
|
|
|
func (p passwordConnector) Close() error { return nil } |
|
|
|
func (p passwordConnector) Login(ctx context.Context, s connector.Scopes, 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, |
|
ConnectorData: []byte(`{"test": "true"}`), |
|
}, true, nil |
|
} |
|
return identity, false, nil |
|
} |
|
|
|
func (p passwordConnector) Prompt() string { return "" } |
|
|
|
func (p passwordConnector) Refresh(_ context.Context, _ connector.Scopes, identity connector.Identity) (connector.Identity, error) { |
|
return identity, nil |
|
}
|
|
|