This repository has been archived on 2022-08-17. You can view files and clone it, but cannot push or open issues or pull requests.
dex/cmd/dex/config_test.go

380 lines
8.2 KiB
Go

package main
import (
"os"
"testing"
"github.com/ghodss/yaml"
"github.com/kylelemons/godebug/pretty"
"github.com/dexidp/dex/connector/mock"
"github.com/dexidp/dex/connector/oidc"
"github.com/dexidp/dex/server"
"github.com/dexidp/dex/storage"
"github.com/dexidp/dex/storage/sql"
)
var _ = yaml.YAMLToJSON
const testHashStaticPasswordEnv = "DEX_FOO_USER_PASSWORD"
func TestValidConfiguration(t *testing.T) {
configuration := Config{
Issuer: "http://127.0.0.1:5556/dex",
Storage: Storage{
Type: "sqlite3",
Config: &sql.SQLite3{
File: "examples/dex.db",
},
},
Web: Web{
HTTP: "127.0.0.1:5556",
},
StaticConnectors: []Connector{
{
Type: "mockCallback",
ID: "mock",
Name: "Example",
Config: &mock.CallbackConfig{},
},
},
}
if err := configuration.Validate(); err != nil {
t.Fatalf("this configuration should have been valid: %v", err)
}
}
func TestInvalidConfiguration(t *testing.T) {
configuration := Config{}
err := configuration.Validate()
if err == nil {
t.Fatal("this configuration should be invalid")
}
got := err.Error()
wanted := `invalid Config:
- no issuer specified in config file
- no storage supplied in config file
- must supply a HTTP/HTTPS address to listen on`
if got != wanted {
t.Fatalf("Expected error message to be %q, got %q", wanted, got)
}
}
func TestUnmarshalConfig(t *testing.T) {
rawConfig := []byte(`
issuer: http://127.0.0.1:5556/dex
storage:
type: postgres
config:
host: 10.0.0.1
port: 65432
maxOpenConns: 5
maxIdleConns: 3
connMaxLifetime: 30
connectionTimeout: 3
web:
http: 127.0.0.1:5556
frontend:
dir: ./web
extra:
foo: bar
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
oauth2:
alwaysShowLoginScreen: true
connectors:
- type: mockCallback
id: mock
name: Example
- type: oidc
id: google
name: Google
config:
issuer: https://accounts.google.com
clientID: foo
clientSecret: bar
redirectURI: http://127.0.0.1:5556/dex/callback/google
enablePasswordDB: true
staticPasswords:
- email: "admin@example.com"
# bcrypt hash of the string "password"
hash: "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
- email: "foo@example.com"
# base64'd value of the same bcrypt hash above. We want to be able to parse both of these
hash: "JDJhJDEwJDMzRU1UMGNWWVZsUHk2V0FNQ0xzY2VMWWpXaHVIcGJ6NXl1Wnh1L0dBRmowM0o5THl0anV5"
username: "foo"
userID: "41331323-6f44-45e6-b3b9-2c4b60c02be5"
expiry:
signingKeys: "7h"
idTokens: "25h"
authRequests: "25h"
deviceRequests: "10m"
logger:
level: "debug"
format: "json"
`)
want := Config{
Issuer: "http://127.0.0.1:5556/dex",
Storage: Storage{
Type: "postgres",
Config: &sql.Postgres{
NetworkDB: sql.NetworkDB{
Host: "10.0.0.1",
Port: 65432,
MaxOpenConns: 5,
MaxIdleConns: 3,
ConnMaxLifetime: 30,
ConnectionTimeout: 3,
},
},
},
Web: Web{
HTTP: "127.0.0.1:5556",
},
Frontend: server.WebConfig{
Dir: "./web",
Extra: map[string]string{
"foo": "bar",
},
},
StaticClients: []storage.Client{
{
ID: "example-app",
Secret: "ZXhhbXBsZS1hcHAtc2VjcmV0",
Name: "Example App",
RedirectURIs: []string{
"http://127.0.0.1:5555/callback",
},
},
},
OAuth2: OAuth2{
AlwaysShowLoginScreen: true,
},
StaticConnectors: []Connector{
{
Type: "mockCallback",
ID: "mock",
Name: "Example",
Config: &mock.CallbackConfig{},
},
{
Type: "oidc",
ID: "google",
Name: "Google",
Config: &oidc.Config{
Issuer: "https://accounts.google.com",
ClientID: "foo",
ClientSecret: "bar",
RedirectURI: "http://127.0.0.1:5556/dex/callback/google",
},
},
},
EnablePasswordDB: true,
StaticPasswords: []password{
{
Email: "admin@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "admin",
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
},
{
Email: "foo@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "foo",
UserID: "41331323-6f44-45e6-b3b9-2c4b60c02be5",
},
},
Expiry: Expiry{
SigningKeys: "7h",
IDTokens: "25h",
AuthRequests: "25h",
DeviceRequests: "10m",
},
Logger: Logger{
Level: "debug",
Format: "json",
},
}
var c Config
if err := yaml.Unmarshal(rawConfig, &c); err != nil {
t.Fatalf("failed to decode config: %v", err)
}
if diff := pretty.Compare(c, want); diff != "" {
t.Errorf("got!=want: %s", diff)
}
}
func TestUnmarshalConfigWithEnv(t *testing.T) {
staticPasswordEnv := os.Getenv(testHashStaticPasswordEnv)
if staticPasswordEnv == "" {
t.Skipf("test environment variable %q not set, skipping", testHashStaticPasswordEnv)
}
rawConfig := []byte(`
issuer: http://127.0.0.1:5556/dex
storage:
type: postgres
config:
host: 10.0.0.1
port: 65432
maxOpenConns: 5
maxIdleConns: 3
connMaxLifetime: 30
connectionTimeout: 3
web:
http: 127.0.0.1:5556
frontend:
dir: ./web
extra:
foo: bar
staticClients:
- id: example-app
redirectURIs:
- 'http://127.0.0.1:5555/callback'
name: 'Example App'
secret: ZXhhbXBsZS1hcHAtc2VjcmV0
oauth2:
alwaysShowLoginScreen: true
connectors:
- type: mockCallback
id: mock
name: Example
- type: oidc
id: google
name: Google
config:
issuer: https://accounts.google.com
clientID: foo
clientSecret: bar
redirectURI: http://127.0.0.1:5556/dex/callback/google
enablePasswordDB: true
staticPasswords:
- email: "admin@example.com"
# bcrypt hash of the string "password"
hash: "$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"
username: "admin"
userID: "08a8684b-db88-4b73-90a9-3cd1661f5466"
- email: "foo@example.com"
hashFromEnv: "DEX_FOO_USER_PASSWORD"
username: "foo"
userID: "41331323-6f44-45e6-b3b9-2c4b60c02be5"
expiry:
signingKeys: "7h"
idTokens: "25h"
authRequests: "25h"
logger:
level: "debug"
format: "json"
`)
want := Config{
Issuer: "http://127.0.0.1:5556/dex",
Storage: Storage{
Type: "postgres",
Config: &sql.Postgres{
NetworkDB: sql.NetworkDB{
Host: "10.0.0.1",
Port: 65432,
MaxOpenConns: 5,
MaxIdleConns: 3,
ConnMaxLifetime: 30,
ConnectionTimeout: 3,
},
},
},
Web: Web{
HTTP: "127.0.0.1:5556",
},
Frontend: server.WebConfig{
Dir: "./web",
Extra: map[string]string{
"foo": "bar",
},
},
StaticClients: []storage.Client{
{
ID: "example-app",
Secret: "ZXhhbXBsZS1hcHAtc2VjcmV0",
Name: "Example App",
RedirectURIs: []string{
"http://127.0.0.1:5555/callback",
},
},
},
OAuth2: OAuth2{
AlwaysShowLoginScreen: true,
},
StaticConnectors: []Connector{
{
Type: "mockCallback",
ID: "mock",
Name: "Example",
Config: &mock.CallbackConfig{},
},
{
Type: "oidc",
ID: "google",
Name: "Google",
Config: &oidc.Config{
Issuer: "https://accounts.google.com",
ClientID: "foo",
ClientSecret: "bar",
RedirectURI: "http://127.0.0.1:5556/dex/callback/google",
},
},
},
EnablePasswordDB: true,
StaticPasswords: []password{
{
Email: "admin@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "admin",
UserID: "08a8684b-db88-4b73-90a9-3cd1661f5466",
},
{
Email: "foo@example.com",
Hash: []byte("$2a$10$33EMT0cVYVlPy6WAMCLsceLYjWhuHpbz5yuZxu/GAFj03J9Lytjuy"),
Username: "foo",
UserID: "41331323-6f44-45e6-b3b9-2c4b60c02be5",
},
},
Expiry: Expiry{
SigningKeys: "7h",
IDTokens: "25h",
AuthRequests: "25h",
},
Logger: Logger{
Level: "debug",
Format: "json",
},
}
var c Config
if err := yaml.Unmarshal(rawConfig, &c); err != nil {
t.Fatalf("failed to decode config: %v", err)
}
if diff := pretty.Compare(c, want); diff != "" {
t.Errorf("got!=want: %s", diff)
}
}