forked from mystiq/dex
Merge pull request #457 from bobbyrullo/client_manager_tweaks
Various client api tweaks
This commit is contained in:
commit
546463adcc
16 changed files with 260 additions and 570 deletions
|
@ -2,7 +2,6 @@ package manager
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"fmt"
|
|
||||||
|
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
@ -64,35 +63,6 @@ func NewClientManager(clientRepo client.ClientRepo, txnFactory repo.TransactionF
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientManagerFromClients(clientRepo client.ClientRepo, txnFactory repo.TransactionFactory, clients []client.Client, options ManagerOptions) (*ClientManager, error) {
|
|
||||||
clientManager := NewClientManager(clientRepo, txnFactory, options)
|
|
||||||
tx, err := clientManager.begin()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
for _, c := range clients {
|
|
||||||
if c.Credentials.Secret == "" {
|
|
||||||
return nil, fmt.Errorf("client %q has no secret", c.Credentials.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
cli, err := clientManager.generateClientCredentials(c)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = clientRepo.New(tx, cli)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if err := tx.Commit(); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return clientManager, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (m *ClientManager) New(cli client.Client) (*oidc.ClientCredentials, error) {
|
func (m *ClientManager) New(cli client.Client) (*oidc.ClientCredentials, error) {
|
||||||
tx, err := m.begin()
|
tx, err := m.begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -100,15 +70,15 @@ func (m *ClientManager) New(cli client.Client) (*oidc.ClientCredentials, error)
|
||||||
}
|
}
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
c, err := m.generateClientCredentials(cli)
|
err = m.addClientCredentials(&cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
creds := c.Credentials
|
creds := cli.Credentials
|
||||||
|
|
||||||
// Save Client
|
// Save Client
|
||||||
_, err = m.clientRepo.New(tx, c)
|
_, err = m.clientRepo.New(tx, cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -189,25 +159,25 @@ func (m *ClientManager) Authenticate(creds oidc.ClientCredentials) (bool, error)
|
||||||
return ok, nil
|
return ok, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *ClientManager) generateClientCredentials(cli client.Client) (client.Client, error) {
|
func (m *ClientManager) addClientCredentials(cli *client.Client) error {
|
||||||
// Generate Client ID
|
// Generate Client ID
|
||||||
if len(cli.Metadata.RedirectURIs) < 1 {
|
if len(cli.Metadata.RedirectURIs) < 1 {
|
||||||
return cli, errors.New("no client redirect url given")
|
return errors.New("no client redirect url given")
|
||||||
}
|
}
|
||||||
clientID, err := m.clientIDGenerator(cli.Metadata.RedirectURIs[0].Host)
|
clientID, err := m.clientIDGenerator(cli.Metadata.RedirectURIs[0].Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli, err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// Generate Secret
|
// Generate Secret
|
||||||
secret, err := m.secretGenerator()
|
secret, err := m.secretGenerator()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return cli, err
|
return err
|
||||||
}
|
}
|
||||||
clientSecret := base64.URLEncoding.EncodeToString(secret)
|
clientSecret := base64.URLEncoding.EncodeToString(secret)
|
||||||
cli.Credentials = oidc.ClientCredentials{
|
cli.Credentials = oidc.ClientCredentials{
|
||||||
ID: clientID,
|
ID: clientID,
|
||||||
Secret: clientSecret,
|
Secret: clientSecret,
|
||||||
}
|
}
|
||||||
return cli, nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -44,11 +44,14 @@ func makeTestFixtures() *testFixtures {
|
||||||
secGen := func() ([]byte, error) {
|
secGen := func() ([]byte, error) {
|
||||||
return []byte("secret"), nil
|
return []byte("secret"), nil
|
||||||
}
|
}
|
||||||
f.clientRepo = db.NewClientRepo(dbMap)
|
|
||||||
clientManager, err := NewClientManagerFromClients(f.clientRepo, db.TransactionFactory(dbMap), clients, ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
var err error
|
||||||
|
f.clientRepo, err = db.NewClientRepoFromClients(dbMap, clients)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to create client manager: " + err.Error())
|
panic("Failed to create client manager: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientManager := NewClientManager(f.clientRepo, db.TransactionFactory(dbMap), ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
||||||
f.mgr = clientManager
|
f.mgr = clientManager
|
||||||
return f
|
return f
|
||||||
}
|
}
|
||||||
|
|
12
db/client.go
12
db/client.go
|
@ -199,6 +199,18 @@ func (r *clientRepo) All(tx repo.Transaction) ([]client.Client, error) {
|
||||||
return cs, nil
|
return cs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewClientRepoFromClients(dbm *gorp.DbMap, cs []client.Client) (client.ClientRepo, error) {
|
||||||
|
repo := NewClientRepo(dbm).(*clientRepo)
|
||||||
|
for _, c := range cs {
|
||||||
|
cm, err := newClientModel(c)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
err = repo.executor(nil).Insert(cm)
|
||||||
|
}
|
||||||
|
return repo, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (r *clientRepo) get(tx repo.Transaction, clientID string) (client.Client, error) {
|
func (r *clientRepo) get(tx repo.Transaction, clientID string) (client.Client, error) {
|
||||||
cm, err := r.getModel(tx, clientID)
|
cm, err := r.getModel(tx, clientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
46
functional/config/config_sample_test.go
Normal file
46
functional/config/config_sample_test.go
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
package config
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
|
"github.com/coreos/dex/client/manager"
|
||||||
|
"github.com/coreos/dex/db"
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
clientsFile = "../../static/fixtures/clients.json.sample"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TestClientSample makes sure that the clients.json.sample file is valid and can be loaded properly.
|
||||||
|
func TestClientSample(t *testing.T) {
|
||||||
|
f, err := os.Open(clientsFile)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("could not open file %q: %v", clientsFile, err)
|
||||||
|
}
|
||||||
|
defer f.Close()
|
||||||
|
|
||||||
|
clients, err := client.ClientsFromReader(f)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Error loading Clients: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
memDB := db.NewMemDB()
|
||||||
|
repo := db.NewClientRepo(memDB)
|
||||||
|
for _, c := range clients {
|
||||||
|
repo.New(nil, c)
|
||||||
|
}
|
||||||
|
mgr := manager.NewClientManager(repo, db.TransactionFactory(memDB), manager.ManagerOptions{})
|
||||||
|
|
||||||
|
for i, c := range clients {
|
||||||
|
ok, err := mgr.Authenticate(c.Credentials)
|
||||||
|
if !ok {
|
||||||
|
t.Errorf("case %d: couldn't authenticate", i)
|
||||||
|
}
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("case %d: error authenticating: %v", i, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -12,7 +12,6 @@ import (
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
|
|
||||||
"github.com/coreos/dex/client"
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/client/manager"
|
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
"github.com/coreos/dex/refresh"
|
"github.com/coreos/dex/refresh"
|
||||||
"github.com/coreos/dex/user"
|
"github.com/coreos/dex/user"
|
||||||
|
@ -28,9 +27,7 @@ func newRefreshRepo(t *testing.T, users []user.UserWithRemoteIdentities, clients
|
||||||
if _, err := db.NewUserRepoFromUsers(dbMap, users); err != nil {
|
if _, err := db.NewUserRepoFromUsers(dbMap, users); err != nil {
|
||||||
t.Fatalf("Unable to add users: %v", err)
|
t.Fatalf("Unable to add users: %v", err)
|
||||||
}
|
}
|
||||||
if _, err := manager.NewClientManagerFromClients(db.NewClientRepo(dbMap), db.TransactionFactory(dbMap), clients, manager.ManagerOptions{}); err != nil {
|
|
||||||
t.Fatalf("Unable to add clients: %v", err)
|
|
||||||
}
|
|
||||||
return db.NewRefreshTokenRepo(dbMap)
|
return db.NewRefreshTokenRepo(dbMap)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,6 +12,8 @@ import (
|
||||||
"github.com/go-gorp/gorp"
|
"github.com/go-gorp/gorp"
|
||||||
"github.com/jonboulle/clockwork"
|
"github.com/jonboulle/clockwork"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
|
clientmanager "github.com/coreos/dex/client/manager"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
"github.com/coreos/dex/user"
|
"github.com/coreos/dex/user"
|
||||||
|
@ -79,3 +81,19 @@ func makeUserObjects(users []user.UserWithRemoteIdentities, passwords []user.Pas
|
||||||
um.Clock = clock
|
um.Clock = clock
|
||||||
return dbMap, ur, pwr, um
|
return dbMap, ur, pwr, um
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func makeClientRepoAndManager(dbMap *gorp.DbMap, clients []client.Client) (client.ClientRepo, *clientmanager.ClientManager, error) {
|
||||||
|
clientIDGenerator := func(hostport string) (string, error) {
|
||||||
|
return hostport, nil
|
||||||
|
}
|
||||||
|
secGen := func() ([]byte, error) {
|
||||||
|
return []byte("secret"), nil
|
||||||
|
}
|
||||||
|
clientRepo, err := db.NewClientRepoFromClients(dbMap, clients)
|
||||||
|
if err != nil {
|
||||||
|
return nil, nil, err
|
||||||
|
}
|
||||||
|
clientManager := clientmanager.NewClientManager(clientRepo, db.TransactionFactory(dbMap), clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
||||||
|
return clientRepo, clientManager, nil
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -9,8 +9,12 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/go-oidc/jose"
|
||||||
|
"github.com/coreos/go-oidc/key"
|
||||||
|
"github.com/coreos/go-oidc/oauth2"
|
||||||
|
"github.com/coreos/go-oidc/oidc"
|
||||||
|
|
||||||
"github.com/coreos/dex/client"
|
"github.com/coreos/dex/client"
|
||||||
clientmanager "github.com/coreos/dex/client/manager"
|
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
phttp "github.com/coreos/dex/pkg/http"
|
phttp "github.com/coreos/dex/pkg/http"
|
||||||
|
@ -18,10 +22,6 @@ import (
|
||||||
"github.com/coreos/dex/server"
|
"github.com/coreos/dex/server"
|
||||||
"github.com/coreos/dex/session/manager"
|
"github.com/coreos/dex/session/manager"
|
||||||
"github.com/coreos/dex/user"
|
"github.com/coreos/dex/user"
|
||||||
"github.com/coreos/go-oidc/jose"
|
|
||||||
"github.com/coreos/go-oidc/key"
|
|
||||||
"github.com/coreos/go-oidc/oauth2"
|
|
||||||
"github.com/coreos/go-oidc/oidc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockServer(cis []client.Client) (*server.Server, error) {
|
func mockServer(cis []client.Client) (*server.Server, error) {
|
||||||
|
@ -37,14 +37,7 @@ func mockServer(cis []client.Client) (*server.Server, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
clientRepo, clientManager, err := makeClientRepoAndManager(dbMap, cis)
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), cis, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -150,18 +143,12 @@ func TestHTTPExchangeTokenRefreshToken(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
dbMap := db.NewMemDB()
|
dbMap := db.NewMemDB()
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
clientRepo, clientManager, err := makeClientRepoAndManager(dbMap, []client.Client{ci})
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), []client.Client{ci}, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: " + err.Error())
|
t.Fatalf("Failed to create client identity manager: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
passwordInfoRepo, err := db.NewPasswordInfoRepoFromPasswordInfos(db.NewMemDB(), []user.PasswordInfo{passwordInfo})
|
passwordInfoRepo, err := db.NewPasswordInfoRepoFromPasswordInfos(db.NewMemDB(), []user.PasswordInfo{passwordInfo})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create password info repo: %v", err)
|
t.Fatalf("Failed to create password info repo: %v", err)
|
||||||
|
|
|
@ -18,7 +18,6 @@ import (
|
||||||
"google.golang.org/api/googleapi"
|
"google.golang.org/api/googleapi"
|
||||||
|
|
||||||
"github.com/coreos/dex/client"
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/client/manager"
|
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
schema "github.com/coreos/dex/schema/workerschema"
|
schema "github.com/coreos/dex/schema/workerschema"
|
||||||
"github.com/coreos/dex/server"
|
"github.com/coreos/dex/server"
|
||||||
|
@ -126,14 +125,8 @@ func makeUserAPITestFixtures() *userAPITestFixtures {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
_, clientManager, err := makeClientRepoAndManager(dbMap, clients)
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte(testClientSecret), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
|
||||||
clientManager, err := manager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), clients, manager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to create client identity manager: " + err.Error())
|
panic("Failed to create client identity manager: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -188,7 +188,7 @@ func TestList(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
// empty repo
|
// empty repo
|
||||||
{
|
{
|
||||||
cs: nil,
|
cs: []client.Client{},
|
||||||
want: nil,
|
want: nil,
|
||||||
},
|
},
|
||||||
// single client
|
// single client
|
||||||
|
@ -244,20 +244,14 @@ func TestList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
dbm := db.NewMemDB()
|
f, err := makeTestFixturesWithOptions(testFixtureOptions{
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
clients: tt.cs,
|
||||||
return hostport, nil
|
})
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := manager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), tt.cs, manager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
continue
|
|
||||||
}
|
}
|
||||||
res := &clientResource{manager: clientManager}
|
|
||||||
|
res := &clientResource{manager: f.clientManager}
|
||||||
|
|
||||||
r, err := http.NewRequest("GET", "http://example.com/clients", nil)
|
r, err := http.NewRequest("GET", "http://example.com/clients", nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -116,10 +116,9 @@ func (cfg *SingleServerConfig) Configure(srv *Server) error {
|
||||||
return fmt.Errorf("unable to read clients from file %s: %v", cfg.ClientsFile, err)
|
return fmt.Errorf("unable to read clients from file %s: %v", cfg.ClientsFile, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
clientRepo, err := db.NewClientRepoFromClients(dbMap, clients)
|
||||||
|
if err != nil {
|
||||||
for _, c := range clients {
|
return err
|
||||||
clientRepo.New(nil, c)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
f, err := os.Open(cfg.ConnectorsFile)
|
f, err := os.Open(cfg.ConnectorsFile)
|
||||||
|
@ -158,7 +157,7 @@ func (cfg *SingleServerConfig) Configure(srv *Server) error {
|
||||||
|
|
||||||
txnFactory := db.TransactionFactory(dbMap)
|
txnFactory := db.TransactionFactory(dbMap)
|
||||||
userManager := usermanager.NewUserManager(userRepo, pwiRepo, cfgRepo, txnFactory, usermanager.ManagerOptions{})
|
userManager := usermanager.NewUserManager(userRepo, pwiRepo, cfgRepo, txnFactory, usermanager.ManagerOptions{})
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), clients, clientmanager.ManagerOptions{})
|
clientManager := clientmanager.NewClientManager(clientRepo, db.TransactionFactory(dbMap), clientmanager.ManagerOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("Failed to create client identity manager: %v", err)
|
return fmt.Errorf("Failed to create client identity manager: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,10 +17,7 @@ import (
|
||||||
"github.com/jonboulle/clockwork"
|
"github.com/jonboulle/clockwork"
|
||||||
|
|
||||||
"github.com/coreos/dex/client"
|
"github.com/coreos/dex/client"
|
||||||
clientmanager "github.com/coreos/dex/client/manager"
|
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/db"
|
|
||||||
"github.com/coreos/dex/session/manager"
|
|
||||||
"github.com/coreos/go-oidc/jose"
|
"github.com/coreos/go-oidc/jose"
|
||||||
"github.com/coreos/go-oidc/oauth2"
|
"github.com/coreos/go-oidc/oauth2"
|
||||||
"github.com/coreos/go-oidc/oidc"
|
"github.com/coreos/go-oidc/oidc"
|
||||||
|
@ -76,38 +73,6 @@ func TestHandleAuthFuncResponsesSingleRedirectURL(t *testing.T) {
|
||||||
idpcs := []connector.Connector{
|
idpcs := []connector.Connector{
|
||||||
&fakeConnector{loginURL: "http://fake.example.com"},
|
&fakeConnector{loginURL: "http://fake.example.com"},
|
||||||
}
|
}
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clients := []client.Client{
|
|
||||||
client.Client{
|
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: "client.example.com",
|
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
url.URL{Scheme: "http", Host: "client.example.com", Path: "/callback"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
|
||||||
}
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
query url.Values
|
query url.Values
|
||||||
|
@ -118,7 +83,7 @@ func TestHandleAuthFuncResponsesSingleRedirectURL(t *testing.T) {
|
||||||
{
|
{
|
||||||
query: url.Values{
|
query: url.Values{
|
||||||
"response_type": []string{"code"},
|
"response_type": []string{"code"},
|
||||||
"client_id": []string{"client.example.com"},
|
"client_id": []string{testClientID},
|
||||||
"connector_id": []string{"fake"},
|
"connector_id": []string{"fake"},
|
||||||
"scope": []string{"openid"},
|
"scope": []string{"openid"},
|
||||||
},
|
},
|
||||||
|
@ -210,7 +175,12 @@ func TestHandleAuthFuncResponsesSingleRedirectURL(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
hdlr := handleAuthFunc(srv, idpcs, nil, true)
|
f, err := makeTestFixtures()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
hdlr := handleAuthFunc(f.srv, idpcs, nil, true)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
u := fmt.Sprintf("http://server.example.com?%s", tt.query.Encode())
|
u := fmt.Sprintf("http://server.example.com?%s", tt.query.Encode())
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
req, err := http.NewRequest("GET", u, nil)
|
||||||
|
@ -237,7 +207,6 @@ func TestHandleAuthFuncResponsesMultipleRedirectURLs(t *testing.T) {
|
||||||
&fakeConnector{loginURL: "http://fake.example.com"},
|
&fakeConnector{loginURL: "http://fake.example.com"},
|
||||||
}
|
}
|
||||||
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clients := []client.Client{
|
clients := []client.Client{
|
||||||
client.Client{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
|
@ -252,23 +221,11 @@ func TestHandleAuthFuncResponsesMultipleRedirectURLs(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
f, err := makeTestFixturesWithOptions(testFixtureOptions{
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
clients: clients,
|
||||||
return hostport, nil
|
})
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
}
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -327,7 +284,7 @@ func TestHandleAuthFuncResponsesMultipleRedirectURLs(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
hdlr := handleAuthFunc(srv, idpcs, nil, true)
|
hdlr := handleAuthFunc(f.srv, idpcs, nil, true)
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
u := fmt.Sprintf("http://server.example.com?%s", tt.query.Encode())
|
u := fmt.Sprintf("http://server.example.com?%s", tt.query.Encode())
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
req, err := http.NewRequest("GET", u, nil)
|
||||||
|
|
|
@ -10,7 +10,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/dex/client"
|
"github.com/coreos/dex/client"
|
||||||
clientmanager "github.com/coreos/dex/client/manager"
|
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
"github.com/coreos/dex/refresh/refreshtest"
|
"github.com/coreos/dex/refresh/refreshtest"
|
||||||
"github.com/coreos/dex/session/manager"
|
"github.com/coreos/dex/session/manager"
|
||||||
|
@ -22,7 +21,6 @@ import (
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
)
|
)
|
||||||
|
|
||||||
var clientTestSecret = base64.URLEncoding.EncodeToString([]byte("secret"))
|
|
||||||
var validRedirURL = url.URL{
|
var validRedirURL = url.URL{
|
||||||
Scheme: "http",
|
Scheme: "http",
|
||||||
Host: "client.example.com",
|
Host: "client.example.com",
|
||||||
|
@ -185,110 +183,42 @@ func TestServerNewSession(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerLogin(t *testing.T) {
|
func TestServerLogin(t *testing.T) {
|
||||||
ci := client.Client{
|
f, err := makeTestFixtures()
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
url.URL{
|
|
||||||
Scheme: "http",
|
|
||||||
Host: "client.example.com",
|
|
||||||
Path: "/callback",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), []client.Client{ci}, clientmanager.ManagerOptions{})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
km := &StaticKeyManager{
|
sm := f.sessionManager
|
||||||
signer: &StaticSigner{sig: []byte("beer"), err: nil},
|
sessionID, err := sm.NewSession("IDPC-1", testClientID, "bogus", testRedirectURL, "", false, []string{"openid"})
|
||||||
}
|
|
||||||
|
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
ident := oidc.Identity{ID: testUserRemoteID1, Name: "elroy", Email: testUserEmail1}
|
||||||
sm.GenerateCode = staticGenerateCodeFunc("fakecode")
|
|
||||||
sessionID, err := sm.NewSession("test_connector_id", ci.Credentials.ID, "bogus", ci.Metadata.RedirectURIs[0], "", false, []string{"openid"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
ident := oidc.Identity{ID: "YYY", Name: "elroy", Email: "elroy@example.com"}
|
|
||||||
key, err := sm.NewSessionKey(sessionID)
|
key, err := sm.NewSessionKey(sessionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
redirectURL, err := srv.Login(ident, key)
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
redirectURL, err := f.srv.Login(ident, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected err from Server.Login: %v", err)
|
t.Fatalf("Unexpected err from Server.Login: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
wantRedirectURL := "http://client.example.com/callback?code=fakecode&state=bogus"
|
wantRedirectURL := "http://client.example.com/callback?code=code-3&state=bogus"
|
||||||
if wantRedirectURL != redirectURL {
|
if wantRedirectURL != redirectURL {
|
||||||
t.Fatalf("Unexpected redirectURL: want=%q, got=%q", wantRedirectURL, redirectURL)
|
t.Fatalf("Unexpected redirectURL: want=%q, got=%q", wantRedirectURL, redirectURL)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
||||||
clients := []client.Client{
|
f, err := makeTestFixtures()
|
||||||
client.Client{
|
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID, Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
validRedirURL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
}
|
|
||||||
km := &StaticKeyManager{
|
|
||||||
signer: &StaticSigner{sig: nil, err: errors.New("fail")},
|
|
||||||
}
|
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ident := oidc.Identity{ID: "YYY", Name: "elroy", Email: "elroy@example.com"}
|
ident := oidc.Identity{ID: testUserRemoteID1, Name: "elroy", Email: testUserEmail1}
|
||||||
code, err := srv.Login(ident, testClientID)
|
code, err := f.srv.Login(ident, testClientID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Expected non-nil error")
|
t.Fatalf("Expected non-nil error")
|
||||||
}
|
}
|
||||||
|
@ -299,47 +229,12 @@ func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerLoginDisabledUser(t *testing.T) {
|
func TestServerLoginDisabledUser(t *testing.T) {
|
||||||
ci := client.Client{
|
f, err := makeTestFixtures()
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
validRedirURL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
clients := []client.Client{ci}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
}
|
|
||||||
km := &StaticKeyManager{
|
|
||||||
signer: &StaticSigner{sig: []byte("beer"), err: nil},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
err = f.userRepo.Create(nil, user.User{
|
||||||
sm.GenerateCode = staticGenerateCodeFunc("fakecode")
|
|
||||||
sessionID, err := sm.NewSession("test_connector_id", ci.Credentials.ID, "bogus", ci.Metadata.RedirectURIs[0], "", false, []string{"openid"})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = userRepo.Create(nil, user.User{
|
|
||||||
ID: "disabled-1",
|
ID: "disabled-1",
|
||||||
Email: "disabled@example.com",
|
Email: "disabled@example.com",
|
||||||
Disabled: true,
|
Disabled: true,
|
||||||
|
@ -348,79 +243,29 @@ func TestServerLoginDisabledUser(t *testing.T) {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
err = userRepo.AddRemoteIdentity(nil, "disabled-1", user.RemoteIdentity{
|
err = f.userRepo.AddRemoteIdentity(nil, "disabled-1", user.RemoteIdentity{
|
||||||
ConnectorID: "test_connector_id",
|
ConnectorID: "test_connector_id",
|
||||||
ID: "disabled-connector-id",
|
ID: "disabled-connector-id",
|
||||||
})
|
})
|
||||||
|
|
||||||
srv := &Server{
|
sessionID, err := f.sessionManager.NewSession("test_connector_id", testClientID, "bogus", testRedirectURL, "", false, []string{"openid"})
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
ident := oidc.Identity{ID: "disabled-connector-id", Name: "elroy", Email: "elroy@example.com"}
|
|
||||||
key, err := sm.NewSessionKey(sessionID)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = srv.Login(ident, key)
|
ident := oidc.Identity{ID: "disabled-connector-id", Name: "elroy", Email: "elroy@example.com"}
|
||||||
|
key, err := f.sessionManager.NewSessionKey(sessionID)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = f.srv.Login(ident, key)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Errorf("disabled user was allowed to log in")
|
t.Errorf("disabled user was allowed to log in")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerCodeToken(t *testing.T) {
|
func TestServerCodeToken(t *testing.T) {
|
||||||
ci := client.Client{
|
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
validRedirURL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
clients := []client.Client{ci}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
|
||||||
}
|
|
||||||
km := &StaticKeyManager{
|
|
||||||
signer: &StaticSigner{sig: []byte("beer"), err: nil},
|
|
||||||
}
|
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
|
||||||
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshTokenRepo := refreshtest.NewTestRefreshTokenRepo()
|
|
||||||
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
RefreshTokenRepo: refreshTokenRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
scope []string
|
scope []string
|
||||||
refreshToken string
|
refreshToken string
|
||||||
|
@ -440,7 +285,14 @@ func TestServerCodeToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
sessionID, err := sm.NewSession("bogus_idpc", ci.Credentials.ID, "bogus", url.URL{}, "", false, tt.scope)
|
f, err := makeTestFixtures()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
|
}
|
||||||
|
f.srv.RefreshTokenRepo = refreshtest.NewTestRefreshTokenRepo()
|
||||||
|
|
||||||
|
sm := f.sessionManager
|
||||||
|
sessionID, err := sm.NewSession("bogus_idpc", testClientID, "bogus", url.URL{}, "", false, tt.scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
@ -449,7 +301,7 @@ func TestServerCodeToken(t *testing.T) {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err = sm.AttachUser(sessionID, "testid-1")
|
_, err = sm.AttachUser(sessionID, testUserID1)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
@ -459,7 +311,11 @@ func TestServerCodeToken(t *testing.T) {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt, token, err := srv.CodeToken(ci.Credentials, key)
|
jwt, token, err := f.srv.CodeToken(
|
||||||
|
oidc.ClientCredentials{
|
||||||
|
ID: testClientID,
|
||||||
|
Secret: clientTestSecret,
|
||||||
|
}, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
@ -473,45 +329,13 @@ func TestServerCodeToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerTokenUnrecognizedKey(t *testing.T) {
|
func TestServerTokenUnrecognizedKey(t *testing.T) {
|
||||||
ci := client.Client{
|
f, err := makeTestFixtures()
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
validRedirURL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
clients := []client.Client{ci}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
}
|
}
|
||||||
km := &StaticKeyManager{
|
sm := f.sessionManager
|
||||||
signer: &StaticSigner{sig: []byte("beer"), err: nil},
|
|
||||||
}
|
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
|
||||||
|
|
||||||
srv := &Server{
|
sessionID, err := sm.NewSession("connector_id", testClientID, "bogus", url.URL{}, "", false, []string{"openid", "offline_access"})
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
}
|
|
||||||
|
|
||||||
sessionID, err := sm.NewSession("connector_id", ci.Credentials.ID, "bogus", url.URL{}, "", false, []string{"openid", "offline_access"})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -521,7 +345,7 @@ func TestServerTokenUnrecognizedKey(t *testing.T) {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt, token, err := srv.CodeToken(ci.Credentials, "foo")
|
jwt, token, err := f.srv.CodeToken(testClientCredentials, "foo")
|
||||||
if err == nil {
|
if err == nil {
|
||||||
t.Fatalf("Expected non-nil error")
|
t.Fatalf("Expected non-nil error")
|
||||||
}
|
}
|
||||||
|
@ -534,12 +358,8 @@ func TestServerTokenUnrecognizedKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerTokenFail(t *testing.T) {
|
func TestServerTokenFail(t *testing.T) {
|
||||||
issuerURL := url.URL{Scheme: "http", Host: "server.example.com"}
|
|
||||||
keyFixture := "goodkey"
|
keyFixture := "goodkey"
|
||||||
ccFixture := oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
}
|
|
||||||
signerFixture := &StaticSigner{sig: []byte("beer"), err: nil}
|
signerFixture := &StaticSigner{sig: []byte("beer"), err: nil}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
|
@ -555,7 +375,7 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
// NOTE(ericchiang): This test assumes that the database ID of the first
|
// NOTE(ericchiang): This test assumes that the database ID of the first
|
||||||
// refresh token will be "1".
|
// refresh token will be "1".
|
||||||
signer: signerFixture,
|
signer: signerFixture,
|
||||||
argCC: ccFixture,
|
argCC: testClientCredentials,
|
||||||
argKey: keyFixture,
|
argKey: keyFixture,
|
||||||
scope: []string{"openid", "offline_access"},
|
scope: []string{"openid", "offline_access"},
|
||||||
refreshToken: fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
refreshToken: fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
|
@ -564,7 +384,7 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
// no 'offline_access' in 'scope', should get empty refresh token
|
// no 'offline_access' in 'scope', should get empty refresh token
|
||||||
{
|
{
|
||||||
signer: signerFixture,
|
signer: signerFixture,
|
||||||
argCC: ccFixture,
|
argCC: testClientCredentials,
|
||||||
argKey: keyFixture,
|
argKey: keyFixture,
|
||||||
scope: []string{"openid"},
|
scope: []string{"openid"},
|
||||||
},
|
},
|
||||||
|
@ -572,7 +392,7 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
// unrecognized key
|
// unrecognized key
|
||||||
{
|
{
|
||||||
signer: signerFixture,
|
signer: signerFixture,
|
||||||
argCC: ccFixture,
|
argCC: testClientCredentials,
|
||||||
argKey: "foo",
|
argKey: "foo",
|
||||||
err: oauth2.NewError(oauth2.ErrorInvalidGrant),
|
err: oauth2.NewError(oauth2.ErrorInvalidGrant),
|
||||||
scope: []string{"openid", "offline_access"},
|
scope: []string{"openid", "offline_access"},
|
||||||
|
@ -590,7 +410,7 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
// signing operation fails
|
// signing operation fails
|
||||||
{
|
{
|
||||||
signer: &StaticSigner{sig: nil, err: errors.New("fail")},
|
signer: &StaticSigner{sig: nil, err: errors.New("fail")},
|
||||||
argCC: ccFixture,
|
argCC: testClientCredentials,
|
||||||
argKey: keyFixture,
|
argKey: keyFixture,
|
||||||
err: oauth2.NewError(oauth2.ErrorServerError),
|
err: oauth2.NewError(oauth2.ErrorServerError),
|
||||||
scope: []string{"openid", "offline_access"},
|
scope: []string{"openid", "offline_access"},
|
||||||
|
@ -598,10 +418,19 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
sm := manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB()))
|
|
||||||
sm.GenerateCode = func() (string, error) { return keyFixture, nil }
|
|
||||||
|
|
||||||
sessionID, err := sm.NewSession("connector_id", ccFixture.ID, "bogus", url.URL{}, "", false, tt.scope)
|
f, err := makeTestFixtures()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
|
}
|
||||||
|
sm := f.sessionManager
|
||||||
|
sm.GenerateCode = func() (string, error) { return keyFixture, nil }
|
||||||
|
f.srv.RefreshTokenRepo = refreshtest.NewTestRefreshTokenRepo()
|
||||||
|
f.srv.KeyManager = &StaticKeyManager{
|
||||||
|
signer: tt.signer,
|
||||||
|
}
|
||||||
|
|
||||||
|
sessionID, err := sm.NewSession(testConnectorID1, testClientID, "bogus", url.URL{}, "", false, tt.scope)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -611,60 +440,17 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
t.Errorf("case %d: unexpected error: %v", i, err)
|
t.Errorf("case %d: unexpected error: %v", i, err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
km := &StaticKeyManager{
|
_, err = sm.AttachUser(sessionID, testUserID1)
|
||||||
signer: tt.signer,
|
|
||||||
}
|
|
||||||
|
|
||||||
clients := []client.Client{
|
|
||||||
client.Client{
|
|
||||||
Credentials: ccFixture,
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
validRedirURL,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
|
||||||
}
|
|
||||||
_, err = sm.AttachUser(sessionID, "testid-1")
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("case %d: unexpected error: %v", i, err)
|
t.Fatalf("case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshTokenRepo := refreshtest.NewTestRefreshTokenRepo()
|
|
||||||
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: issuerURL,
|
|
||||||
KeyManager: km,
|
|
||||||
SessionManager: sm,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
RefreshTokenRepo: refreshTokenRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = sm.NewSessionKey(sessionID)
|
_, err = sm.NewSessionKey(sessionID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
jwt, token, err := srv.CodeToken(tt.argCC, tt.argKey)
|
jwt, token, err := f.srv.CodeToken(tt.argCC, tt.argKey)
|
||||||
if token != tt.refreshToken {
|
if token != tt.refreshToken {
|
||||||
fmt.Printf("case %d: expect refresh token %q, got %q\n", i, tt.refreshToken, token)
|
fmt.Printf("case %d: expect refresh token %q, got %q\n", i, tt.refreshToken, token)
|
||||||
t.Fatalf("case %d: expect refresh token %q, got %q", i, tt.refreshToken, token)
|
t.Fatalf("case %d: expect refresh token %q, got %q", i, tt.refreshToken, token)
|
||||||
|
@ -683,18 +469,7 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerRefreshToken(t *testing.T) {
|
func TestServerRefreshToken(t *testing.T) {
|
||||||
issuerURL := url.URL{Scheme: "http", Host: "server.example.com"}
|
|
||||||
clientA := client.Client{
|
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: testClientID,
|
|
||||||
Secret: clientTestSecret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: []url.URL{
|
|
||||||
url.URL{Scheme: "https", Host: "client.example.com", Path: "one/two/three"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
clientB := client.Client{
|
clientB := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "example2.com",
|
ID: "example2.com",
|
||||||
|
@ -706,7 +481,6 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
signerFixture := &StaticSigner{sig: []byte("beer"), err: nil}
|
signerFixture := &StaticSigner{sig: []byte("beer"), err: nil}
|
||||||
|
|
||||||
// NOTE(ericchiang): These tests assume that the database ID of the first
|
// NOTE(ericchiang): These tests assume that the database ID of the first
|
||||||
|
@ -721,39 +495,39 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Everything is good.
|
// Everything is good.
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientA.Credentials,
|
testClientCredentials,
|
||||||
signerFixture,
|
signerFixture,
|
||||||
nil,
|
nil,
|
||||||
},
|
},
|
||||||
// Invalid refresh token(malformatted).
|
// Invalid refresh token(malformatted).
|
||||||
{
|
{
|
||||||
"invalid-token",
|
"invalid-token",
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientA.Credentials,
|
testClientCredentials,
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
||||||
},
|
},
|
||||||
// Invalid refresh token(invalid payload content).
|
// Invalid refresh token(invalid payload content).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-2"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-2"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientA.Credentials,
|
testClientCredentials,
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
||||||
},
|
},
|
||||||
// Invalid refresh token(invalid ID content).
|
// Invalid refresh token(invalid ID content).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("0/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("0/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientA.Credentials,
|
testClientCredentials,
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
oauth2.NewError(oauth2.ErrorInvalidRequest),
|
||||||
},
|
},
|
||||||
// Invalid client(client is not associated with the token).
|
// Invalid client(client is not associated with the token).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientB.Credentials,
|
clientB.Credentials,
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidClient),
|
oauth2.NewError(oauth2.ErrorInvalidClient),
|
||||||
|
@ -761,7 +535,7 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Invalid client(no client ID).
|
// Invalid client(no client ID).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
oidc.ClientCredentials{ID: "", Secret: "aaa"},
|
oidc.ClientCredentials{ID: "", Secret: "aaa"},
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidClient),
|
oauth2.NewError(oauth2.ErrorInvalidClient),
|
||||||
|
@ -769,7 +543,7 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Invalid client(no such client).
|
// Invalid client(no such client).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
oidc.ClientCredentials{ID: "AAA", Secret: "aaa"},
|
oidc.ClientCredentials{ID: "AAA", Secret: "aaa"},
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidClient),
|
oauth2.NewError(oauth2.ErrorInvalidClient),
|
||||||
|
@ -777,7 +551,7 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Invalid client(no secrets).
|
// Invalid client(no secrets).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
oidc.ClientCredentials{ID: testClientID},
|
oidc.ClientCredentials{ID: testClientID},
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidClient),
|
oauth2.NewError(oauth2.ErrorInvalidClient),
|
||||||
|
@ -785,7 +559,7 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Invalid client(invalid secret).
|
// Invalid client(invalid secret).
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
oidc.ClientCredentials{ID: "bad-id", Secret: "bad-secret"},
|
oidc.ClientCredentials{ID: "bad-id", Secret: "bad-secret"},
|
||||||
signerFixture,
|
signerFixture,
|
||||||
oauth2.NewError(oauth2.ErrorInvalidClient),
|
oauth2.NewError(oauth2.ErrorInvalidClient),
|
||||||
|
@ -793,8 +567,8 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
// Signing operation fails.
|
// Signing operation fails.
|
||||||
{
|
{
|
||||||
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))),
|
||||||
clientA.Credentials.ID,
|
testClientID,
|
||||||
clientA.Credentials,
|
testClientCredentials,
|
||||||
&StaticSigner{sig: nil, err: errors.New("fail")},
|
&StaticSigner{sig: nil, err: errors.New("fail")},
|
||||||
oauth2.NewError(oauth2.ErrorServerError),
|
oauth2.NewError(oauth2.ErrorServerError),
|
||||||
},
|
},
|
||||||
|
@ -804,45 +578,22 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
km := &StaticKeyManager{
|
km := &StaticKeyManager{
|
||||||
signer: tt.signer,
|
signer: tt.signer,
|
||||||
}
|
}
|
||||||
|
f, err := makeTestFixtures()
|
||||||
clients := []client.Client{
|
if err != nil {
|
||||||
clientA,
|
t.Fatalf("error making test fixtures: %v", err)
|
||||||
clientB,
|
}
|
||||||
|
f.srv.RefreshTokenRepo = refreshtest.NewTestRefreshTokenRepo()
|
||||||
|
f.srv.KeyManager = km
|
||||||
|
_, err = f.clientRepo.New(nil, clientB)
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("case %d: error creating other client: %v", i, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
if _, err := f.srv.RefreshTokenRepo.Create(testUserID1, tt.clientID); err != nil {
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
|
||||||
}
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
t.Fatalf("Unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
refreshTokenRepo := refreshtest.NewTestRefreshTokenRepo()
|
jwt, err := f.srv.RefreshToken(tt.creds, tt.token)
|
||||||
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: issuerURL,
|
|
||||||
KeyManager: km,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
RefreshTokenRepo: refreshTokenRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := refreshTokenRepo.Create("testid-1", tt.clientID); err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
jwt, err := srv.RefreshToken(tt.creds, tt.token)
|
|
||||||
if !reflect.DeepEqual(err, tt.err) {
|
if !reflect.DeepEqual(err, tt.err) {
|
||||||
t.Errorf("Case %d: expect: %v, got: %v", i, tt.err, err)
|
t.Errorf("Case %d: expect: %v, got: %v", i, tt.err, err)
|
||||||
}
|
}
|
||||||
|
@ -855,71 +606,9 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Case %d: unexpected error: %v", i, err)
|
t.Errorf("Case %d: unexpected error: %v", i, err)
|
||||||
}
|
}
|
||||||
if claims["iss"] != issuerURL.String() || claims["sub"] != "testid-1" || claims["aud"] != testClientID {
|
if claims["iss"] != testIssuerURL.String() || claims["sub"] != testUserID1 || claims["aud"] != testClientID {
|
||||||
t.Errorf("Case %d: invalid claims: %v", i, claims)
|
t.Errorf("Case %d: invalid claims: %v", i, claims)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that we should return error when user cannot be found after
|
|
||||||
// verifying the token.
|
|
||||||
km := &StaticKeyManager{
|
|
||||||
signer: signerFixture,
|
|
||||||
}
|
|
||||||
|
|
||||||
clients := []client.Client{
|
|
||||||
clientA,
|
|
||||||
clientB,
|
|
||||||
}
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
|
||||||
return hostport, nil
|
|
||||||
}
|
|
||||||
secGen := func() ([]byte, error) {
|
|
||||||
return []byte("secret"), nil
|
|
||||||
}
|
|
||||||
dbm := db.NewMemDB()
|
|
||||||
clientRepo := db.NewClientRepo(dbm)
|
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbm), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Failed to create client identity manager: %v", err)
|
|
||||||
}
|
|
||||||
userRepo, err := makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create a user that will be removed later.
|
|
||||||
if err := userRepo.Create(nil, user.User{
|
|
||||||
ID: "testid-2",
|
|
||||||
Email: "test-2@example.com",
|
|
||||||
}); err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
refreshTokenRepo := refreshtest.NewTestRefreshTokenRepo()
|
|
||||||
|
|
||||||
srv := &Server{
|
|
||||||
IssuerURL: issuerURL,
|
|
||||||
KeyManager: km,
|
|
||||||
ClientRepo: clientRepo,
|
|
||||||
ClientManager: clientManager,
|
|
||||||
UserRepo: userRepo,
|
|
||||||
RefreshTokenRepo: refreshTokenRepo,
|
|
||||||
}
|
|
||||||
|
|
||||||
if _, err := refreshTokenRepo.Create("testid-2", clientA.Credentials.ID); err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Recreate the user repo to remove the user we created.
|
|
||||||
userRepo, err = makeNewUserRepo()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
srv.UserRepo = userRepo
|
|
||||||
|
|
||||||
_, err = srv.RefreshToken(clientA.Credentials, fmt.Sprintf("1/%s", base64.URLEncoding.EncodeToString([]byte("refresh-1"))))
|
|
||||||
if !reflect.DeepEqual(err, oauth2.NewError(oauth2.ErrorServerError)) {
|
|
||||||
t.Errorf("Expect: %v, got: %v", oauth2.NewError(oauth2.ErrorServerError), err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,21 +26,33 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
testUserID1 = "ID-1"
|
||||||
|
testUserEmail1 = "Email-1@example.com"
|
||||||
|
testUserRemoteID1 = "RID-1"
|
||||||
|
|
||||||
testIssuerURL = url.URL{Scheme: "http", Host: "server.example.com"}
|
testIssuerURL = url.URL{Scheme: "http", Host: "server.example.com"}
|
||||||
testClientID = "client.example.com"
|
|
||||||
|
testClientID = "client.example.com"
|
||||||
|
clientTestSecret = base64.URLEncoding.EncodeToString([]byte("secret"))
|
||||||
|
testClientCredentials = oidc.ClientCredentials{
|
||||||
|
ID: testClientID,
|
||||||
|
Secret: clientTestSecret,
|
||||||
|
}
|
||||||
|
|
||||||
|
testConnectorID1 = "IDPC-1"
|
||||||
|
|
||||||
testRedirectURL = url.URL{Scheme: "http", Host: "client.example.com", Path: "/callback"}
|
testRedirectURL = url.URL{Scheme: "http", Host: "client.example.com", Path: "/callback"}
|
||||||
|
|
||||||
testUsers = []user.UserWithRemoteIdentities{
|
testUsers = []user.UserWithRemoteIdentities{
|
||||||
{
|
{
|
||||||
User: user.User{
|
User: user.User{
|
||||||
ID: "ID-1",
|
ID: testUserID1,
|
||||||
Email: "Email-1@example.com",
|
Email: testUserEmail1,
|
||||||
},
|
},
|
||||||
RemoteIdentities: []user.RemoteIdentity{
|
RemoteIdentities: []user.RemoteIdentity{
|
||||||
{
|
{
|
||||||
ConnectorID: "IDPC-1",
|
ConnectorID: testConnectorID1,
|
||||||
ID: "RID-1",
|
ID: testUserRemoteID1,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -83,6 +95,10 @@ type testFixtures struct {
|
||||||
clientManager *clientmanager.ClientManager
|
clientManager *clientmanager.ClientManager
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type testFixtureOptions struct {
|
||||||
|
clients []client.Client
|
||||||
|
}
|
||||||
|
|
||||||
func sequentialGenerateCodeFunc() sessionmanager.GenerateCodeFunc {
|
func sequentialGenerateCodeFunc() sessionmanager.GenerateCodeFunc {
|
||||||
x := 0
|
x := 0
|
||||||
return func() (string, error) {
|
return func() (string, error) {
|
||||||
|
@ -92,6 +108,10 @@ func sequentialGenerateCodeFunc() sessionmanager.GenerateCodeFunc {
|
||||||
}
|
}
|
||||||
|
|
||||||
func makeTestFixtures() (*testFixtures, error) {
|
func makeTestFixtures() (*testFixtures, error) {
|
||||||
|
return makeTestFixturesWithOptions(testFixtureOptions{})
|
||||||
|
}
|
||||||
|
|
||||||
|
func makeTestFixturesWithOptions(options testFixtureOptions) (*testFixtures, error) {
|
||||||
dbMap := db.NewMemDB()
|
dbMap := db.NewMemDB()
|
||||||
userRepo, err := db.NewUserRepoFromUsers(dbMap, testUsers)
|
userRepo, err := db.NewUserRepoFromUsers(dbMap, testUsers)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -138,18 +158,20 @@ func makeTestFixtures() (*testFixtures, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
clients := []client.Client{
|
var clients []client.Client
|
||||||
client.Client{
|
if options.clients == nil {
|
||||||
Credentials: oidc.ClientCredentials{
|
clients = []client.Client{
|
||||||
ID: testClientID,
|
client.Client{
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
Credentials: testClientCredentials,
|
||||||
},
|
Metadata: oidc.ClientMetadata{
|
||||||
Metadata: oidc.ClientMetadata{
|
RedirectURIs: []url.URL{
|
||||||
RedirectURIs: []url.URL{
|
testRedirectURL,
|
||||||
testRedirectURL,
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
}
|
||||||
|
} else {
|
||||||
|
clients = options.clients
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIDGenerator := func(hostport string) (string, error) {
|
clientIDGenerator := func(hostport string) (string, error) {
|
||||||
|
@ -158,11 +180,13 @@ func makeTestFixtures() (*testFixtures, error) {
|
||||||
secGen := func() ([]byte, error) {
|
secGen := func() ([]byte, error) {
|
||||||
return []byte("secret"), nil
|
return []byte("secret"), nil
|
||||||
}
|
}
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
clientRepo, err := db.NewClientRepoFromClients(dbMap, clients)
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), clients, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
clientManager := clientmanager.NewClientManager(clientRepo, db.TransactionFactory(dbMap), clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
||||||
|
|
||||||
km := key.NewPrivateKeyManager()
|
km := key.NewPrivateKeyManager()
|
||||||
err = km.Set(key.NewPrivateKeySet([]*key.PrivateKey{testPrivKey}, time.Now().Add(time.Minute)))
|
err = km.Set(key.NewPrivateKeySet([]*key.PrivateKey{testPrivKey}, time.Now().Add(time.Minute)))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
2
test
2
test
|
@ -18,7 +18,7 @@ if [ ! -d $GOPATH/pkg ]; then
|
||||||
echo "WARNING: No cached builds detected. Please run the ./build script to speed up future tests."
|
echo "WARNING: No cached builds detected. Please run the ./build script to speed up future tests."
|
||||||
fi
|
fi
|
||||||
|
|
||||||
TESTABLE="connector db integration pkg/crypto pkg/flag pkg/http pkg/time pkg/html functional/repo server session session/manager user user/api user/manager user/email email admin client client/manager"
|
TESTABLE="admin client client/manager connector db email functional/repo integration pkg/crypto pkg/flag pkg/http pkg/time pkg/html server session session/manager user user/api user/manager user/email"
|
||||||
FORMATTABLE="$TESTABLE cmd/dexctl cmd/dex-worker cmd/dex-overlord examples/app functional pkg/log"
|
FORMATTABLE="$TESTABLE cmd/dexctl cmd/dex-worker cmd/dex-overlord examples/app functional pkg/log"
|
||||||
|
|
||||||
# user has not provided PKG override
|
# user has not provided PKG override
|
||||||
|
|
|
@ -4,3 +4,4 @@ source ./env
|
||||||
|
|
||||||
go test $@ github.com/coreos/dex/functional
|
go test $@ github.com/coreos/dex/functional
|
||||||
go test $@ github.com/coreos/dex/functional/repo
|
go test $@ github.com/coreos/dex/functional/repo
|
||||||
|
go test $@ github.com/coreos/dex/functional/config
|
||||||
|
|
|
@ -176,11 +176,11 @@ func makeTestFixtures() (*UsersAPI, *testEmailer) {
|
||||||
secGen := func() ([]byte, error) {
|
secGen := func() ([]byte, error) {
|
||||||
return []byte("secret"), nil
|
return []byte("secret"), nil
|
||||||
}
|
}
|
||||||
clientRepo := db.NewClientRepo(dbMap)
|
clientRepo, err := db.NewClientRepoFromClients(dbMap, []client.Client{ci})
|
||||||
clientManager, err := clientmanager.NewClientManagerFromClients(clientRepo, db.TransactionFactory(dbMap), []client.Client{ci}, clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
panic("Failed to create client manager: " + err.Error())
|
panic("Failed to create client manager: " + err.Error())
|
||||||
}
|
}
|
||||||
|
clientManager := clientmanager.NewClientManager(clientRepo, db.TransactionFactory(dbMap), clientmanager.ManagerOptions{ClientIDGenerator: clientIDGenerator, SecretGenerator: secGen})
|
||||||
|
|
||||||
// Used in TestRevokeRefreshToken test.
|
// Used in TestRevokeRefreshToken test.
|
||||||
refreshTokens := []struct {
|
refreshTokens := []struct {
|
||||||
|
|
Loading…
Reference in a new issue