cmd/dex: add logging config and serve logger for different modules.
This commit is contained in:
parent
79c51f2983
commit
2e22a948cf
@ -8,6 +8,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/connector/github"
|
"github.com/coreos/dex/connector/github"
|
||||||
"github.com/coreos/dex/connector/ldap"
|
"github.com/coreos/dex/connector/ldap"
|
||||||
@ -29,6 +30,7 @@ type Config struct {
|
|||||||
OAuth2 OAuth2 `json:"oauth2"`
|
OAuth2 OAuth2 `json:"oauth2"`
|
||||||
GRPC GRPC `json:"grpc"`
|
GRPC GRPC `json:"grpc"`
|
||||||
Expiry Expiry `json:"expiry"`
|
Expiry Expiry `json:"expiry"`
|
||||||
|
Logger Logger `json:"logger"`
|
||||||
|
|
||||||
Frontend server.WebConfig `json:"frontend"`
|
Frontend server.WebConfig `json:"frontend"`
|
||||||
|
|
||||||
@ -119,7 +121,7 @@ type Storage struct {
|
|||||||
|
|
||||||
// StorageConfig is a configuration that can create a storage.
|
// StorageConfig is a configuration that can create a storage.
|
||||||
type StorageConfig interface {
|
type StorageConfig interface {
|
||||||
Open() (storage.Storage, error)
|
Open(logrus.FieldLogger) (storage.Storage, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var storages = map[string]func() StorageConfig{
|
var storages = map[string]func() StorageConfig{
|
||||||
@ -170,7 +172,7 @@ type Connector struct {
|
|||||||
|
|
||||||
// ConnectorConfig is a configuration that can open a connector.
|
// ConnectorConfig is a configuration that can open a connector.
|
||||||
type ConnectorConfig interface {
|
type ConnectorConfig interface {
|
||||||
Open() (connector.Connector, error)
|
Open(logrus.FieldLogger) (connector.Connector, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var connectors = map[string]func() ConnectorConfig{
|
var connectors = map[string]func() ConnectorConfig{
|
||||||
@ -223,3 +225,12 @@ type Expiry struct {
|
|||||||
// IdTokens defines the duration of time for which the IdTokens will be valid.
|
// IdTokens defines the duration of time for which the IdTokens will be valid.
|
||||||
IDTokens string `json:"idTokens"`
|
IDTokens string `json:"idTokens"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Logger holds configuration required to customize logging for dex.
|
||||||
|
type Logger struct {
|
||||||
|
// Level sets logging level severity.
|
||||||
|
Level string `json:"level"`
|
||||||
|
|
||||||
|
// Format specifies the format to be used for logging.
|
||||||
|
Format string `json:"format"`
|
||||||
|
}
|
||||||
|
@ -59,6 +59,10 @@ staticPasswords:
|
|||||||
expiry:
|
expiry:
|
||||||
signingKeys: "6h"
|
signingKeys: "6h"
|
||||||
idTokens: "24h"
|
idTokens: "24h"
|
||||||
|
|
||||||
|
logger:
|
||||||
|
level: "debug"
|
||||||
|
format: "json"
|
||||||
`)
|
`)
|
||||||
|
|
||||||
want := Config{
|
want := Config{
|
||||||
@ -120,6 +124,10 @@ expiry:
|
|||||||
SigningKeys: "6h",
|
SigningKeys: "6h",
|
||||||
IDTokens: "24h",
|
IDTokens: "24h",
|
||||||
},
|
},
|
||||||
|
Logger: Logger{
|
||||||
|
Level: "debug",
|
||||||
|
Format: "json",
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
var c Config
|
var c Config
|
||||||
|
@ -9,8 +9,11 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net"
|
"net"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -111,6 +114,8 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
logger, _ := newLogger(c.Logger.Level, c.Logger.Format)
|
||||||
|
|
||||||
connectors := make([]server.Connector, len(c.Connectors))
|
connectors := make([]server.Connector, len(c.Connectors))
|
||||||
for i, conn := range c.Connectors {
|
for i, conn := range c.Connectors {
|
||||||
if conn.ID == "" {
|
if conn.ID == "" {
|
||||||
@ -119,7 +124,8 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||||||
if conn.Config == nil {
|
if conn.Config == nil {
|
||||||
return fmt.Errorf("no config field for connector %q", conn.ID)
|
return fmt.Errorf("no config field for connector %q", conn.ID)
|
||||||
}
|
}
|
||||||
c, err := conn.Config.Open()
|
connectorLogger := logger.WithField("connector", conn.Name)
|
||||||
|
c, err := conn.Config.Open(connectorLogger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("open %s: %v", conn.ID, err)
|
return fmt.Errorf("open %s: %v", conn.ID, err)
|
||||||
}
|
}
|
||||||
@ -130,7 +136,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
s, err := c.Storage.Config.Open()
|
s, err := c.Storage.Config.Open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("initializing storage: %v", err)
|
return fmt.Errorf("initializing storage: %v", err)
|
||||||
}
|
}
|
||||||
@ -153,6 +159,7 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||||||
Storage: s,
|
Storage: s,
|
||||||
Web: c.Frontend,
|
Web: c.Frontend,
|
||||||
EnablePasswordDB: c.EnablePasswordDB,
|
EnablePasswordDB: c.EnablePasswordDB,
|
||||||
|
Logger: logger,
|
||||||
}
|
}
|
||||||
if c.Expiry.SigningKeys != "" {
|
if c.Expiry.SigningKeys != "" {
|
||||||
signingKeys, err := time.ParseDuration(c.Expiry.SigningKeys)
|
signingKeys, err := time.ParseDuration(c.Expiry.SigningKeys)
|
||||||
@ -203,3 +210,33 @@ func serve(cmd *cobra.Command, args []string) error {
|
|||||||
|
|
||||||
return <-errc
|
return <-errc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func newLogger(level string, format string) (logrus.FieldLogger, error) {
|
||||||
|
var logLevel logrus.Level
|
||||||
|
switch strings.ToLower(level) {
|
||||||
|
case "debug":
|
||||||
|
logLevel = logrus.DebugLevel
|
||||||
|
case "", "info":
|
||||||
|
logLevel = logrus.InfoLevel
|
||||||
|
case "error":
|
||||||
|
logLevel = logrus.ErrorLevel
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported logLevel: %s", level)
|
||||||
|
}
|
||||||
|
|
||||||
|
var formatter logrus.Formatter
|
||||||
|
switch strings.ToLower(format) {
|
||||||
|
case "", "text":
|
||||||
|
formatter = &logrus.TextFormatter{DisableColors: true}
|
||||||
|
case "json":
|
||||||
|
formatter = &logrus.JSONFormatter{}
|
||||||
|
default:
|
||||||
|
return nil, fmt.Errorf("unsupported logger format: %s", format)
|
||||||
|
}
|
||||||
|
|
||||||
|
return &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: formatter,
|
||||||
|
Level: logLevel,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/github"
|
"golang.org/x/oauth2/github"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -31,12 +32,13 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open returns a strategy for logging in through GitHub.
|
// Open returns a strategy for logging in through GitHub.
|
||||||
func (c *Config) Open() (connector.Connector, error) {
|
func (c *Config) Open(logger logrus.FieldLogger) (connector.Connector, error) {
|
||||||
return &githubConnector{
|
return &githubConnector{
|
||||||
redirectURI: c.RedirectURI,
|
redirectURI: c.RedirectURI,
|
||||||
org: c.Org,
|
org: c.Org,
|
||||||
clientID: c.ClientID,
|
clientID: c.ClientID,
|
||||||
clientSecret: c.ClientSecret,
|
clientSecret: c.ClientSecret,
|
||||||
|
logger: logger,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -55,6 +57,7 @@ type githubConnector struct {
|
|||||||
org string
|
org string
|
||||||
clientID string
|
clientID string
|
||||||
clientSecret string
|
clientSecret string
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *githubConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
|
func (c *githubConnector) oauth2Config(scopes connector.Scopes) *oauth2.Config {
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"gopkg.in/ldap.v2"
|
"gopkg.in/ldap.v2"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -135,8 +136,8 @@ func parseScope(s string) (int, bool) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open returns an authentication strategy using LDAP.
|
// Open returns an authentication strategy using LDAP.
|
||||||
func (c *Config) Open() (connector.Connector, error) {
|
func (c *Config) Open(logger logrus.FieldLogger) (connector.Connector, error) {
|
||||||
conn, err := c.OpenConnector()
|
conn, err := c.OpenConnector(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -149,7 +150,7 @@ type refreshData struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// OpenConnector is the same as Open but returns a type with all implemented connector interfaces.
|
// OpenConnector is the same as Open but returns a type with all implemented connector interfaces.
|
||||||
func (c *Config) OpenConnector() (interface {
|
func (c *Config) OpenConnector(logger logrus.FieldLogger) (interface {
|
||||||
connector.Connector
|
connector.Connector
|
||||||
connector.PasswordConnector
|
connector.PasswordConnector
|
||||||
connector.RefreshConnector
|
connector.RefreshConnector
|
||||||
@ -206,7 +207,7 @@ func (c *Config) OpenConnector() (interface {
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("userSearch.Scope unknown value %q", c.GroupSearch.Scope)
|
return nil, fmt.Errorf("userSearch.Scope unknown value %q", c.GroupSearch.Scope)
|
||||||
}
|
}
|
||||||
return &ldapConnector{*c, userSearchScope, groupSearchScope, tlsConfig}, nil
|
return &ldapConnector{*c, userSearchScope, groupSearchScope, tlsConfig, logger}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ldapConnector struct {
|
type ldapConnector struct {
|
||||||
@ -216,6 +217,8 @@ type ldapConnector struct {
|
|||||||
groupSearchScope int
|
groupSearchScope int
|
||||||
|
|
||||||
tlsConfig *tls.Config
|
tlsConfig *tls.Config
|
||||||
|
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -9,12 +9,13 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
)
|
)
|
||||||
|
|
||||||
// NewCallbackConnector 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.
|
// the same (fake) identity.
|
||||||
func NewCallbackConnector() connector.Connector {
|
func NewCallbackConnector(logger logrus.FieldLogger) connector.Connector {
|
||||||
return &Callback{
|
return &Callback{
|
||||||
Identity: connector.Identity{
|
Identity: connector.Identity{
|
||||||
UserID: "0-385-28089-0",
|
UserID: "0-385-28089-0",
|
||||||
@ -24,6 +25,7 @@ func NewCallbackConnector() connector.Connector {
|
|||||||
Groups: []string{"authors"},
|
Groups: []string{"authors"},
|
||||||
ConnectorData: connectorData,
|
ConnectorData: connectorData,
|
||||||
},
|
},
|
||||||
|
Logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -37,6 +39,7 @@ var (
|
|||||||
type Callback struct {
|
type Callback struct {
|
||||||
// The returned identity.
|
// The returned identity.
|
||||||
Identity connector.Identity
|
Identity connector.Identity
|
||||||
|
Logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginURL returns the URL to redirect the user to login with.
|
// LoginURL returns the URL to redirect the user to login with.
|
||||||
@ -67,8 +70,8 @@ func (m *Callback) Refresh(ctx context.Context, s connector.Scopes, identity con
|
|||||||
type CallbackConfig struct{}
|
type CallbackConfig struct{}
|
||||||
|
|
||||||
// Open returns an authentication strategy which requires no user interaction.
|
// Open returns an authentication strategy which requires no user interaction.
|
||||||
func (c *CallbackConfig) Open() (connector.Connector, error) {
|
func (c *CallbackConfig) Open(logger logrus.FieldLogger) (connector.Connector, error) {
|
||||||
return NewCallbackConnector(), nil
|
return NewCallbackConnector(logger), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// PasswordConfig holds the configuration for a mock connector which prompts for the supplied
|
// PasswordConfig holds the configuration for a mock connector which prompts for the supplied
|
||||||
@ -79,19 +82,20 @@ type PasswordConfig struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open returns an authentication strategy which prompts for a predefined username and password.
|
// Open returns an authentication strategy which prompts for a predefined username and password.
|
||||||
func (c *PasswordConfig) Open() (connector.Connector, error) {
|
func (c *PasswordConfig) Open(logger logrus.FieldLogger) (connector.Connector, error) {
|
||||||
if c.Username == "" {
|
if c.Username == "" {
|
||||||
return nil, errors.New("no username supplied")
|
return nil, errors.New("no username supplied")
|
||||||
}
|
}
|
||||||
if c.Password == "" {
|
if c.Password == "" {
|
||||||
return nil, errors.New("no password supplied")
|
return nil, errors.New("no password supplied")
|
||||||
}
|
}
|
||||||
return &passwordConnector{c.Username, c.Password}, nil
|
return &passwordConnector{c.Username, c.Password, logger}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type passwordConnector struct {
|
type passwordConnector struct {
|
||||||
username string
|
username string
|
||||||
password string
|
password string
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p passwordConnector) Close() error { return nil }
|
func (p passwordConnector) Close() error { return nil }
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/go-oidc"
|
"github.com/coreos/go-oidc"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
@ -25,7 +26,7 @@ type Config struct {
|
|||||||
|
|
||||||
// Open returns a connector which can be used to login users through an upstream
|
// Open returns a connector which can be used to login users through an upstream
|
||||||
// OpenID Connect provider.
|
// OpenID Connect provider.
|
||||||
func (c *Config) Open() (conn connector.Connector, err error) {
|
func (c *Config) Open(logger logrus.FieldLogger) (conn connector.Connector, err error) {
|
||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
|
|
||||||
provider, err := oidc.NewProvider(ctx, c.Issuer)
|
provider, err := oidc.NewProvider(ctx, c.Issuer)
|
||||||
@ -55,6 +56,7 @@ func (c *Config) Open() (conn connector.Connector, err error) {
|
|||||||
oidc.VerifyExpiry(),
|
oidc.VerifyExpiry(),
|
||||||
oidc.VerifyAudience(clientID),
|
oidc.VerifyAudience(clientID),
|
||||||
),
|
),
|
||||||
|
logger: logger,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -68,6 +70,7 @@ type oidcConnector struct {
|
|||||||
verifier *oidc.IDTokenVerifier
|
verifier *oidc.IDTokenVerifier
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *oidcConnector) Close() error {
|
func (c *oidcConnector) Close() error {
|
||||||
|
@ -2,15 +2,23 @@ package server
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/api"
|
"github.com/coreos/dex/api"
|
||||||
"github.com/coreos/dex/storage/memory"
|
"github.com/coreos/dex/storage/memory"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Attempts to create, update and delete a test Password
|
// Attempts to create, update and delete a test Password
|
||||||
func TestPassword(t *testing.T) {
|
func TestPassword(t *testing.T) {
|
||||||
s := memory.New()
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
s := memory.New(logger)
|
||||||
serv := NewAPI(s)
|
serv := NewAPI(s)
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
|
@ -13,6 +13,7 @@ import (
|
|||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/gorilla/mux"
|
"github.com/gorilla/mux"
|
||||||
|
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
@ -57,6 +58,8 @@ type Config struct {
|
|||||||
EnablePasswordDB bool
|
EnablePasswordDB bool
|
||||||
|
|
||||||
Web WebConfig
|
Web WebConfig
|
||||||
|
|
||||||
|
Logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// WebConfig holds the server's frontend templates and asset configuration.
|
// WebConfig holds the server's frontend templates and asset configuration.
|
||||||
@ -112,6 +115,8 @@ type Server struct {
|
|||||||
now func() time.Time
|
now func() time.Time
|
||||||
|
|
||||||
idTokensValidFor time.Duration
|
idTokensValidFor time.Duration
|
||||||
|
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewServer constructs a server from the provided config.
|
// NewServer constructs a server from the provided config.
|
||||||
@ -182,6 +187,7 @@ func newServer(ctx context.Context, c Config, rotationStrategy rotationStrategy)
|
|||||||
skipApproval: c.SkipApprovalScreen,
|
skipApproval: c.SkipApprovalScreen,
|
||||||
now: now,
|
now: now,
|
||||||
templates: tmpls,
|
templates: tmpls,
|
||||||
|
logger: c.Logger,
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, conn := range c.Connectors {
|
for _, conn := range c.Connectors {
|
||||||
|
@ -20,6 +20,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
oidc "github.com/coreos/go-oidc"
|
oidc "github.com/coreos/go-oidc"
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
@ -72,19 +73,26 @@ FDWV28nTP9sqbtsmU8Tem2jzMvZ7C/Q0AuDoKELFUpux8shm8wfIhyaPnXUGZoAZ
|
|||||||
Np4vUwMSYV5mopESLWOg3loBxKyLGFtgGKVCjGiQvy6zISQ4fQo=
|
Np4vUwMSYV5mopESLWOg3loBxKyLGFtgGKVCjGiQvy6zISQ4fQo=
|
||||||
-----END RSA PRIVATE KEY-----`)
|
-----END RSA PRIVATE KEY-----`)
|
||||||
|
|
||||||
|
var logger = &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) {
|
func newTestServer(ctx context.Context, t *testing.T, updateConfig func(c *Config)) (*httptest.Server, *Server) {
|
||||||
var server *Server
|
var server *Server
|
||||||
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
s := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
server.ServeHTTP(w, r)
|
server.ServeHTTP(w, r)
|
||||||
}))
|
}))
|
||||||
|
|
||||||
config := Config{
|
config := Config{
|
||||||
Issuer: s.URL,
|
Issuer: s.URL,
|
||||||
Storage: memory.New(),
|
Storage: memory.New(logger),
|
||||||
Connectors: []Connector{
|
Connectors: []Connector{
|
||||||
{
|
{
|
||||||
ID: "mock",
|
ID: "mock",
|
||||||
DisplayName: "Mock",
|
DisplayName: "Mock",
|
||||||
Connector: mock.NewCallbackConnector(),
|
Connector: mock.NewCallbackConnector(logger),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Web: WebConfig{
|
Web: WebConfig{
|
||||||
@ -367,12 +375,17 @@ func TestOAuth2CodeFlow(t *testing.T) {
|
|||||||
ctx, cancel := context.WithCancel(context.Background())
|
ctx, cancel := context.WithCancel(context.Background())
|
||||||
defer cancel()
|
defer cancel()
|
||||||
|
|
||||||
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
httpServer, s := newTestServer(ctx, t, func(c *Config) {
|
httpServer, s := newTestServer(ctx, t, func(c *Config) {
|
||||||
c.Issuer = c.Issuer + "/non-root-path"
|
c.Issuer = c.Issuer + "/non-root-path"
|
||||||
c.Now = now
|
c.Now = now
|
||||||
c.IDTokensValidFor = idTokensValidFor
|
c.IDTokensValidFor = idTokensValidFor
|
||||||
// Create a new mock callback connector for each test case.
|
// Create a new mock callback connector for each test case.
|
||||||
conn = mock.NewCallbackConnector().(*mock.Callback)
|
conn = mock.NewCallbackConnector(logger).(*mock.Callback)
|
||||||
c.Connectors = []Connector{
|
c.Connectors = []Connector{
|
||||||
{
|
{
|
||||||
ID: "mock",
|
ID: "mock",
|
||||||
@ -743,7 +756,7 @@ func TestCrossClientScopes(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestPasswordDB(t *testing.T) {
|
func TestPasswordDB(t *testing.T) {
|
||||||
s := memory.New()
|
s := memory.New(logger)
|
||||||
conn := newPasswordDB(s)
|
conn := newPasswordDB(s)
|
||||||
|
|
||||||
pw := "hi"
|
pw := "hi"
|
||||||
@ -840,7 +853,7 @@ func TestKeyCacher(t *testing.T) {
|
|||||||
tNow := time.Now()
|
tNow := time.Now()
|
||||||
now := func() time.Time { return tNow }
|
now := func() time.Time { return tNow }
|
||||||
|
|
||||||
s := memory.New()
|
s := memory.New(logger)
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
before func()
|
before func()
|
||||||
|
@ -21,6 +21,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/ghodss/yaml"
|
"github.com/ghodss/yaml"
|
||||||
"github.com/gtank/cryptopasta"
|
"github.com/gtank/cryptopasta"
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
@ -33,6 +34,7 @@ type client struct {
|
|||||||
client *http.Client
|
client *http.Client
|
||||||
baseURL string
|
baseURL string
|
||||||
namespace string
|
namespace string
|
||||||
|
logger logrus.FieldLogger
|
||||||
|
|
||||||
// Hash function to map IDs (which could span a large range) to Kubernetes names.
|
// Hash function to map IDs (which could span a large range) to Kubernetes names.
|
||||||
// While this is not currently upgradable, it could be in the future.
|
// While this is not currently upgradable, it could be in the future.
|
||||||
@ -230,7 +232,7 @@ func (c *client) put(resource, name string, v interface{}) error {
|
|||||||
return checkHTTPErr(resp, http.StatusOK)
|
return checkHTTPErr(resp, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string) (*client, error) {
|
func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string, logger logrus.FieldLogger) (*client, error) {
|
||||||
tlsConfig := cryptopasta.DefaultTLSConfig()
|
tlsConfig := cryptopasta.DefaultTLSConfig()
|
||||||
data := func(b string, file string) ([]byte, error) {
|
data := func(b string, file string) ([]byte, error) {
|
||||||
if b != "" {
|
if b != "" {
|
||||||
@ -303,6 +305,7 @@ func newClient(cluster k8sapi.Cluster, user k8sapi.AuthInfo, namespace string) (
|
|||||||
hash: func() hash.Hash { return fnv.New64() },
|
hash: func() hash.Hash { return fnv.New64() },
|
||||||
namespace: namespace,
|
namespace: namespace,
|
||||||
apiVersion: "oidc.coreos.com/v1",
|
apiVersion: "oidc.coreos.com/v1",
|
||||||
|
logger: logger,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
|
|
||||||
"golang.org/x/net/context"
|
"golang.org/x/net/context"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
"github.com/coreos/dex/storage/kubernetes/k8sapi"
|
"github.com/coreos/dex/storage/kubernetes/k8sapi"
|
||||||
)
|
)
|
||||||
@ -39,8 +40,8 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open returns a storage using Kubernetes third party resource.
|
// Open returns a storage using Kubernetes third party resource.
|
||||||
func (c *Config) Open() (storage.Storage, error) {
|
func (c *Config) Open(logger logrus.FieldLogger) (storage.Storage, error) {
|
||||||
cli, err := c.open()
|
cli, err := c.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -48,7 +49,7 @@ func (c *Config) Open() (storage.Storage, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// open returns a client with no garbage collection.
|
// open returns a client with no garbage collection.
|
||||||
func (c *Config) open() (*client, error) {
|
func (c *Config) open(logger logrus.FieldLogger) (*client, error) {
|
||||||
if c.InCluster && (c.KubeConfigFile != "") {
|
if c.InCluster && (c.KubeConfigFile != "") {
|
||||||
return nil, errors.New("cannot specify both 'inCluster' and 'kubeConfigFile'")
|
return nil, errors.New("cannot specify both 'inCluster' and 'kubeConfigFile'")
|
||||||
}
|
}
|
||||||
@ -71,7 +72,7 @@ func (c *Config) open() (*client, error) {
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cli, err := newClient(cluster, user, namespace)
|
cli, err := newClient(cluster, user, namespace, logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("create client: %v", err)
|
return nil, fmt.Errorf("create client: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
"github.com/coreos/dex/storage/conformance"
|
"github.com/coreos/dex/storage/conformance"
|
||||||
)
|
)
|
||||||
@ -22,7 +23,12 @@ func loadClient(t *testing.T) *client {
|
|||||||
if config.KubeConfigFile == "" {
|
if config.KubeConfigFile == "" {
|
||||||
t.Skipf("test environment variable %q not set, skipping", testKubeConfigEnv)
|
t.Skipf("test environment variable %q not set, skipping", testKubeConfigEnv)
|
||||||
}
|
}
|
||||||
s, err := config.open()
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
s, err := config.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -6,17 +6,19 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
// New returns an in memory storage.
|
// New returns an in memory storage.
|
||||||
func New() storage.Storage {
|
func New(logger logrus.FieldLogger) storage.Storage {
|
||||||
return &memStorage{
|
return &memStorage{
|
||||||
clients: make(map[string]storage.Client),
|
clients: make(map[string]storage.Client),
|
||||||
authCodes: make(map[string]storage.AuthCode),
|
authCodes: make(map[string]storage.AuthCode),
|
||||||
refreshTokens: make(map[string]storage.RefreshToken),
|
refreshTokens: make(map[string]storage.RefreshToken),
|
||||||
authReqs: make(map[string]storage.AuthRequest),
|
authReqs: make(map[string]storage.AuthRequest),
|
||||||
passwords: make(map[string]storage.Password),
|
passwords: make(map[string]storage.Password),
|
||||||
|
logger: logger,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -28,8 +30,8 @@ type Config struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open always returns a new in memory storage.
|
// Open always returns a new in memory storage.
|
||||||
func (c *Config) Open() (storage.Storage, error) {
|
func (c *Config) Open(logger logrus.FieldLogger) (storage.Storage, error) {
|
||||||
return New(), nil
|
return New(logger), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type memStorage struct {
|
type memStorage struct {
|
||||||
@ -42,6 +44,8 @@ type memStorage struct {
|
|||||||
passwords map[string]storage.Password
|
passwords map[string]storage.Password
|
||||||
|
|
||||||
keys storage.Keys
|
keys storage.Keys
|
||||||
|
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *memStorage) tx(f func()) {
|
func (s *memStorage) tx(f func()) {
|
||||||
|
@ -1,11 +1,23 @@
|
|||||||
package memory
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
|
"github.com/coreos/dex/storage"
|
||||||
"github.com/coreos/dex/storage/conformance"
|
"github.com/coreos/dex/storage/conformance"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStorage(t *testing.T) {
|
func TestStorage(t *testing.T) {
|
||||||
conformance.RunTests(t, New)
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
newStorage := func() storage.Storage {
|
||||||
|
return New(logger)
|
||||||
|
}
|
||||||
|
conformance.RunTests(t, newStorage)
|
||||||
}
|
}
|
||||||
|
@ -1,14 +1,21 @@
|
|||||||
package memory
|
package memory
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestStaticClients(t *testing.T) {
|
func TestStaticClients(t *testing.T) {
|
||||||
s := New()
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
s := New(logger)
|
||||||
|
|
||||||
c1 := storage.Client{ID: "foo", Secret: "foo_secret"}
|
c1 := storage.Client{ID: "foo", Secret: "foo_secret"}
|
||||||
c2 := storage.Client{ID: "bar", Secret: "bar_secret"}
|
c2 := storage.Client{ID: "bar", Secret: "bar_secret"}
|
||||||
|
@ -6,6 +6,7 @@ import (
|
|||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -16,15 +17,15 @@ type SQLite3 struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open creates a new storage implementation backed by SQLite3
|
// Open creates a new storage implementation backed by SQLite3
|
||||||
func (s *SQLite3) Open() (storage.Storage, error) {
|
func (s *SQLite3) Open(logger logrus.FieldLogger) (storage.Storage, error) {
|
||||||
conn, err := s.open()
|
conn, err := s.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *SQLite3) open() (*conn, error) {
|
func (s *SQLite3) open(logger logrus.FieldLogger) (*conn, error) {
|
||||||
db, err := sql.Open("sqlite3", s.File)
|
db, err := sql.Open("sqlite3", s.File)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -34,7 +35,7 @@ func (s *SQLite3) open() (*conn, error) {
|
|||||||
// doesn't support this, so limit the number of connections to 1.
|
// doesn't support this, so limit the number of connections to 1.
|
||||||
db.SetMaxOpenConns(1)
|
db.SetMaxOpenConns(1)
|
||||||
}
|
}
|
||||||
c := &conn{db, flavorSQLite3}
|
c := &conn{db, flavorSQLite3, logger}
|
||||||
if _, err := c.migrate(); err != nil {
|
if _, err := c.migrate(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to perform migrations: %v", err)
|
return nil, fmt.Errorf("failed to perform migrations: %v", err)
|
||||||
}
|
}
|
||||||
@ -70,15 +71,15 @@ type Postgres struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Open creates a new storage implementation backed by Postgres.
|
// Open creates a new storage implementation backed by Postgres.
|
||||||
func (p *Postgres) Open() (storage.Storage, error) {
|
func (p *Postgres) Open(logger logrus.FieldLogger) (storage.Storage, error) {
|
||||||
conn, err := p.open()
|
conn, err := p.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return conn, nil
|
return conn, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *Postgres) open() (*conn, error) {
|
func (p *Postgres) open(logger logrus.FieldLogger) (*conn, error) {
|
||||||
v := url.Values{}
|
v := url.Values{}
|
||||||
set := func(key, val string) {
|
set := func(key, val string) {
|
||||||
if val != "" {
|
if val != "" {
|
||||||
@ -113,7 +114,7 @@ func (p *Postgres) open() (*conn, error) {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
c := &conn{db, flavorPostgres}
|
c := &conn{db, flavorPostgres, logger}
|
||||||
if _, err := c.migrate(); err != nil {
|
if _, err := c.migrate(); err != nil {
|
||||||
return nil, fmt.Errorf("failed to perform migrations: %v", err)
|
return nil, fmt.Errorf("failed to perform migrations: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/coreos/dex/storage"
|
"github.com/coreos/dex/storage"
|
||||||
"github.com/coreos/dex/storage/conformance"
|
"github.com/coreos/dex/storage/conformance"
|
||||||
)
|
)
|
||||||
@ -41,13 +42,19 @@ func cleanDB(c *conn) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var logger = &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
func TestSQLite3(t *testing.T) {
|
func TestSQLite3(t *testing.T) {
|
||||||
newStorage := func() storage.Storage {
|
newStorage := func() storage.Storage {
|
||||||
// NOTE(ericchiang): In memory means we only get one connection at a time. If we
|
// NOTE(ericchiang): In memory means we only get one connection at a time. If we
|
||||||
// ever write tests that require using multiple connections, for instance to test
|
// ever write tests that require using multiple connections, for instance to test
|
||||||
// transactions, we need to move to a file based system.
|
// transactions, we need to move to a file based system.
|
||||||
s := &SQLite3{":memory:"}
|
s := &SQLite3{":memory:"}
|
||||||
conn, err := s.open()
|
conn, err := s.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Fprintln(os.Stdout, err)
|
fmt.Fprintln(os.Stdout, err)
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
@ -92,7 +99,7 @@ func TestPostgres(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
newStorage := func() storage.Storage {
|
newStorage := func() storage.Storage {
|
||||||
conn, err := p.open()
|
conn, err := p.open(logger)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fatal(err)
|
fatal(err)
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,10 @@ package sql
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestMigrate(t *testing.T) {
|
func TestMigrate(t *testing.T) {
|
||||||
@ -12,7 +15,13 @@ func TestMigrate(t *testing.T) {
|
|||||||
}
|
}
|
||||||
defer db.Close()
|
defer db.Close()
|
||||||
|
|
||||||
c := &conn{db, flavorSQLite3}
|
logger := &logrus.Logger{
|
||||||
|
Out: os.Stderr,
|
||||||
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
||||||
|
Level: logrus.DebugLevel,
|
||||||
|
}
|
||||||
|
|
||||||
|
c := &conn{db, flavorSQLite3, logger}
|
||||||
for _, want := range []int{len(migrations), 0} {
|
for _, want := range []int{len(migrations), 0} {
|
||||||
got, err := c.migrate()
|
got, err := c.migrate()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"database/sql"
|
"database/sql"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
|
||||||
|
"github.com/Sirupsen/logrus"
|
||||||
"github.com/cockroachdb/cockroach-go/crdb"
|
"github.com/cockroachdb/cockroach-go/crdb"
|
||||||
|
|
||||||
// import third party drivers
|
// import third party drivers
|
||||||
@ -110,6 +111,7 @@ func (f flavor) translate(query string) string {
|
|||||||
type conn struct {
|
type conn struct {
|
||||||
db *sql.DB
|
db *sql.DB
|
||||||
flavor flavor
|
flavor flavor
|
||||||
|
logger logrus.FieldLogger
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *conn) Close() error {
|
func (c *conn) Close() error {
|
||||||
|
Reference in New Issue
Block a user