*: Client Repo now deals with custom Client object
This is instead of oidc.ClientIdentity. This makes it easier to add new fields custom to dex to the client.
This commit is contained in:
parent
35cefb7da9
commit
95757e8779
22 changed files with 241 additions and 156 deletions
35
admin/api.go
35
admin/api.go
|
@ -116,25 +116,38 @@ func (a *AdminAPI) GetState() (adminschema.State, error) {
|
||||||
return state, nil
|
return state, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type ClientRegistrationRequest struct {
|
func (a *AdminAPI) CreateClient(req adminschema.ClientCreateRequest) (adminschema.ClientCreateResponse, error) {
|
||||||
IsAdmin bool `json:"isAdmin"`
|
cli, err := adminschema.MapSchemaClientToClient(*req.Client)
|
||||||
Client oidc.ClientMetadata `json:"client"`
|
if err != nil {
|
||||||
|
// TODO should be 400s
|
||||||
|
return adminschema.ClientCreateResponse{}, mapError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *AdminAPI) CreateClient(req ClientRegistrationRequest) (oidc.ClientRegistrationResponse, error) {
|
if err := cli.Metadata.Valid(); err != nil {
|
||||||
if err := req.Client.Valid(); err != nil {
|
// TODO make sure this is not 500
|
||||||
return oidc.ClientRegistrationResponse{}, mapError(err)
|
return adminschema.ClientCreateResponse{}, mapError(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// metadata is guarenteed to have at least one redirect_uri by earlier validation.
|
// metadata is guarenteed to have at least one redirect_uri by earlier validation.
|
||||||
id, err := oidc.GenClientID(req.Client.RedirectURIs[0].Host)
|
id, err := oidc.GenClientID(cli.Metadata.RedirectURIs[0].Host)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oidc.ClientRegistrationResponse{}, mapError(err)
|
return adminschema.ClientCreateResponse{}, mapError(err)
|
||||||
}
|
}
|
||||||
c, err := a.clientIdentityRepo.New(id, req.Client, req.IsAdmin)
|
|
||||||
|
cli.Credentials.ID = id
|
||||||
|
|
||||||
|
creds, err := a.clientIdentityRepo.New(cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return oidc.ClientRegistrationResponse{}, mapError(err)
|
return adminschema.ClientCreateResponse{}, mapError(err)
|
||||||
}
|
}
|
||||||
return oidc.ClientRegistrationResponse{ClientID: c.ID, ClientSecret: c.Secret, ClientMetadata: req.Client}, nil
|
|
||||||
|
req.Client.Id = creds.ID
|
||||||
|
req.Client.Secret = creds.Secret
|
||||||
|
return adminschema.ClientCreateResponse{
|
||||||
|
Client: req.Client,
|
||||||
|
}, nil
|
||||||
|
|
||||||
|
// github.com/coreos/dex/integrationoidc.ClientRegistrationResponse{ClientID: c.ID, ClientSecret: c.Secret, ClientMetadata: req.Client.Metadata}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mapError(e error) error {
|
func mapError(e error) error {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package client
|
package client
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
|
"io"
|
||||||
"net/url"
|
"net/url"
|
||||||
"reflect"
|
"reflect"
|
||||||
|
|
||||||
|
@ -15,7 +17,15 @@ var (
|
||||||
ErrorNotFound = errors.New("no data found")
|
ErrorNotFound = errors.New("no data found")
|
||||||
)
|
)
|
||||||
|
|
||||||
|
type Client struct {
|
||||||
|
Credentials oidc.ClientCredentials
|
||||||
|
Metadata oidc.ClientMetadata
|
||||||
|
Admin bool
|
||||||
|
}
|
||||||
|
|
||||||
type ClientIdentityRepo interface {
|
type ClientIdentityRepo interface {
|
||||||
|
Get(clientID string) (Client, error)
|
||||||
|
|
||||||
// Metadata returns one matching ClientMetadata if the given client
|
// Metadata returns one matching ClientMetadata if the given client
|
||||||
// exists, otherwise nil. The returned error will be non-nil only
|
// exists, otherwise nil. The returned error will be non-nil only
|
||||||
// if the repo was unable to determine client existence.
|
// if the repo was unable to determine client existence.
|
||||||
|
@ -28,12 +38,12 @@ type ClientIdentityRepo interface {
|
||||||
Authenticate(creds oidc.ClientCredentials) (bool, error)
|
Authenticate(creds oidc.ClientCredentials) (bool, error)
|
||||||
|
|
||||||
// All returns all registered Client Identities.
|
// All returns all registered Client Identities.
|
||||||
All() ([]oidc.ClientIdentity, error)
|
All() ([]Client, error)
|
||||||
|
|
||||||
// New registers a ClientIdentity with the repo for the given metadata.
|
// New registers a ClientIdentity with the repo for the given metadata.
|
||||||
// An unused ID must be provided. A corresponding secret will be returned
|
// An unused ID must be provided. A corresponding secret will be returned
|
||||||
// in a ClientCredentials struct along with the provided ID.
|
// in a ClientCredentials struct along with the provided ID.
|
||||||
New(id string, meta oidc.ClientMetadata, admin bool) (*oidc.ClientCredentials, error)
|
New(client Client) (*oidc.ClientCredentials, error)
|
||||||
|
|
||||||
SetDexAdmin(clientID string, isAdmin bool) error
|
SetDexAdmin(clientID string, isAdmin bool) error
|
||||||
|
|
||||||
|
@ -64,3 +74,36 @@ func ValidRedirectURL(rURL *url.URL, redirectURLs []url.URL) (url.URL, error) {
|
||||||
}
|
}
|
||||||
return url.URL{}, ErrorInvalidRedirectURL
|
return url.URL{}, ErrorInvalidRedirectURL
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ClientsFromReader(r io.Reader) ([]Client, error) {
|
||||||
|
var c []struct {
|
||||||
|
ID string `json:"id"`
|
||||||
|
Secret string `json:"secret"`
|
||||||
|
RedirectURLs []string `json:"redirectURLs"`
|
||||||
|
}
|
||||||
|
if err := json.NewDecoder(r).Decode(&c); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
clients := make([]Client, len(c))
|
||||||
|
for i, client := range c {
|
||||||
|
redirectURIs := make([]url.URL, len(client.RedirectURLs))
|
||||||
|
for j, u := range client.RedirectURLs {
|
||||||
|
uri, err := url.Parse(u)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
redirectURIs[j] = *uri
|
||||||
|
}
|
||||||
|
|
||||||
|
clients[i] = Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: client.ID,
|
||||||
|
Secret: client.Secret,
|
||||||
|
},
|
||||||
|
Metadata: oidc.ClientMetadata{
|
||||||
|
RedirectURIs: redirectURIs,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return clients, nil
|
||||||
|
}
|
||||||
|
|
70
db/client.go
70
db/client.go
|
@ -41,21 +41,29 @@ func init() {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func newClientIdentityModel(id string, secret []byte, meta *oidc.ClientMetadata) (*clientIdentityModel, error) {
|
func newClientIdentityModel(cli client.Client) (*clientIdentityModel, error) {
|
||||||
hashed, err := bcrypt.GenerateFromPassword(secret, bcryptHashCost)
|
secretBytes, err := base64.URLEncoding.DecodeString(cli.Credentials.Secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
bmeta, err := json.Marshal(meta)
|
hashed, err := bcrypt.GenerateFromPassword([]byte(
|
||||||
|
secretBytes),
|
||||||
|
bcryptHashCost)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
bmeta, err := json.Marshal(&cli.Metadata)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cim := clientIdentityModel{
|
cim := clientIdentityModel{
|
||||||
ID: id,
|
ID: cli.Credentials.ID,
|
||||||
Secret: hashed,
|
Secret: hashed,
|
||||||
Metadata: string(bmeta),
|
Metadata: string(bmeta),
|
||||||
|
DexAdmin: cli.Admin,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cim, nil
|
return &cim, nil
|
||||||
|
@ -68,12 +76,13 @@ type clientIdentityModel struct {
|
||||||
DexAdmin bool `db:"dex_admin"`
|
DexAdmin bool `db:"dex_admin"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *clientIdentityModel) ClientIdentity() (*oidc.ClientIdentity, error) {
|
func (m *clientIdentityModel) Client() (*client.Client, error) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: m.ID,
|
ID: m.ID,
|
||||||
Secret: string(m.Secret),
|
Secret: string(m.Secret),
|
||||||
},
|
},
|
||||||
|
Admin: m.DexAdmin,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := json.Unmarshal([]byte(m.Metadata), &ci.Metadata); err != nil {
|
if err := json.Unmarshal([]byte(m.Metadata), &ci.Metadata); err != nil {
|
||||||
|
@ -91,7 +100,7 @@ func newClientIdentityRepo(dbm *gorp.DbMap) *clientIdentityRepo {
|
||||||
return &clientIdentityRepo{db: &db{dbm}}
|
return &clientIdentityRepo{db: &db{dbm}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewClientIdentityRepoFromClients(dbm *gorp.DbMap, clients []oidc.ClientIdentity) (client.ClientIdentityRepo, error) {
|
func NewClientIdentityRepoFromClients(dbm *gorp.DbMap, clients []client.Client) (client.ClientIdentityRepo, error) {
|
||||||
repo := newClientIdentityRepo(dbm)
|
repo := newClientIdentityRepo(dbm)
|
||||||
tx, err := repo.begin()
|
tx, err := repo.begin()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -103,12 +112,7 @@ func NewClientIdentityRepoFromClients(dbm *gorp.DbMap, clients []oidc.ClientIden
|
||||||
if c.Credentials.Secret == "" {
|
if c.Credentials.Secret == "" {
|
||||||
return nil, fmt.Errorf("client %q has no secret", c.Credentials.ID)
|
return nil, fmt.Errorf("client %q has no secret", c.Credentials.ID)
|
||||||
}
|
}
|
||||||
dec, err := base64.URLEncoding.DecodeString(c.Credentials.Secret)
|
cm, err := newClientIdentityModel(c)
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("client secrets must be base64 decodable. See issue #337. Please consider replacing %q with %q",
|
|
||||||
c.Credentials.Secret, base64.URLEncoding.EncodeToString([]byte(c.Credentials.Secret)))
|
|
||||||
}
|
|
||||||
cm, err := newClientIdentityModel(c.Credentials.ID, dec, &c.Metadata)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -127,27 +131,37 @@ type clientIdentityRepo struct {
|
||||||
*db
|
*db
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *clientIdentityRepo) Metadata(clientID string) (*oidc.ClientMetadata, error) {
|
func (r *clientIdentityRepo) Get(clientID string) (client.Client, error) {
|
||||||
m, err := r.executor(nil).Get(clientIdentityModel{}, clientID)
|
m, err := r.executor(nil).Get(clientIdentityModel{}, clientID)
|
||||||
|
|
||||||
if err == sql.ErrNoRows || m == nil {
|
if err == sql.ErrNoRows || m == nil {
|
||||||
return nil, client.ErrorNotFound
|
return client.Client{}, client.ErrorNotFound
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return client.Client{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cim, ok := m.(*clientIdentityModel)
|
cim, ok := m.(*clientIdentityModel)
|
||||||
if !ok {
|
if !ok {
|
||||||
log.Errorf("expected clientIdentityModel but found %v", reflect.TypeOf(m))
|
log.Errorf("expected clientModel but found %v", reflect.TypeOf(m))
|
||||||
return nil, errors.New("unrecognized model")
|
return client.Client{}, errors.New("unrecognized model")
|
||||||
}
|
}
|
||||||
|
|
||||||
ci, err := cim.ClientIdentity()
|
ci, err := cim.Client()
|
||||||
|
if err != nil {
|
||||||
|
return client.Client{}, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return *ci, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *clientIdentityRepo) Metadata(clientID string) (*oidc.ClientMetadata, error) {
|
||||||
|
c, err := r.Get(clientID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
return &ci.Metadata, nil
|
return &c.Metadata, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *clientIdentityRepo) IsDexAdmin(clientID string) (bool, error) {
|
func (r *clientIdentityRepo) IsDexAdmin(clientID string) (bool, error) {
|
||||||
|
@ -238,17 +252,17 @@ func isAlreadyExistsErr(err error) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *clientIdentityRepo) New(id string, meta oidc.ClientMetadata, admin bool) (*oidc.ClientCredentials, error) {
|
func (r *clientIdentityRepo) New(cli client.Client) (*oidc.ClientCredentials, error) {
|
||||||
secret, err := pcrypto.RandBytes(maxSecretLength)
|
secret, err := pcrypto.RandBytes(maxSecretLength)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cim, err := newClientIdentityModel(id, secret, &meta)
|
cli.Credentials.Secret = base64.URLEncoding.EncodeToString(secret)
|
||||||
|
cim, err := newClientIdentityModel(cli)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
cim.DexAdmin = admin
|
|
||||||
|
|
||||||
if err := r.executor(nil).Insert(cim); err != nil {
|
if err := r.executor(nil).Insert(cim); err != nil {
|
||||||
if isAlreadyExistsErr(err) {
|
if isAlreadyExistsErr(err) {
|
||||||
|
@ -258,14 +272,14 @@ func (r *clientIdentityRepo) New(id string, meta oidc.ClientMetadata, admin bool
|
||||||
}
|
}
|
||||||
|
|
||||||
cc := oidc.ClientCredentials{
|
cc := oidc.ClientCredentials{
|
||||||
ID: id,
|
ID: cli.Credentials.ID,
|
||||||
Secret: base64.URLEncoding.EncodeToString(secret),
|
Secret: cli.Credentials.Secret,
|
||||||
}
|
}
|
||||||
|
|
||||||
return &cc, nil
|
return &cc, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *clientIdentityRepo) All() ([]oidc.ClientIdentity, error) {
|
func (r *clientIdentityRepo) All() ([]client.Client, error) {
|
||||||
qt := r.quote(clientIdentityTableName)
|
qt := r.quote(clientIdentityTableName)
|
||||||
q := fmt.Sprintf("SELECT * FROM %s", qt)
|
q := fmt.Sprintf("SELECT * FROM %s", qt)
|
||||||
objs, err := r.executor(nil).Select(&clientIdentityModel{}, q)
|
objs, err := r.executor(nil).Select(&clientIdentityModel{}, q)
|
||||||
|
@ -273,14 +287,14 @@ func (r *clientIdentityRepo) All() ([]oidc.ClientIdentity, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
cs := make([]oidc.ClientIdentity, len(objs))
|
cs := make([]client.Client, len(objs))
|
||||||
for i, obj := range objs {
|
for i, obj := range objs {
|
||||||
m, ok := obj.(*clientIdentityModel)
|
m, ok := obj.(*clientIdentityModel)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("unable to cast client identity to clientIdentityModel")
|
return nil, errors.New("unable to cast client identity to clientIdentityModel")
|
||||||
}
|
}
|
||||||
|
|
||||||
ci, err := m.ClientIdentity()
|
ci, err := m.Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,10 +11,10 @@ import (
|
||||||
"github.com/go-gorp/gorp"
|
"github.com/go-gorp/gorp"
|
||||||
"golang.org/x/crypto/bcrypt"
|
"golang.org/x/crypto/bcrypt"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/pkg/log"
|
"github.com/coreos/dex/pkg/log"
|
||||||
"github.com/coreos/dex/refresh"
|
"github.com/coreos/dex/refresh"
|
||||||
"github.com/coreos/dex/repo"
|
"github.com/coreos/dex/repo"
|
||||||
"github.com/coreos/go-oidc/oidc"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -186,7 +186,7 @@ func (r *refreshTokenRepo) RevokeTokensForClient(userID, clientID string) error
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *refreshTokenRepo) ClientsWithRefreshTokens(userID string) ([]oidc.ClientIdentity, error) {
|
func (r *refreshTokenRepo) ClientsWithRefreshTokens(userID string) ([]client.Client, error) {
|
||||||
q := `SELECT c.* FROM %s as c
|
q := `SELECT c.* FROM %s as c
|
||||||
INNER JOIN %s as r ON c.id = r.client_id WHERE r.user_id = $1;`
|
INNER JOIN %s as r ON c.id = r.client_id WHERE r.user_id = $1;`
|
||||||
q = fmt.Sprintf(q, r.quote(clientIdentityTableName), r.quote(refreshTokenTableName))
|
q = fmt.Sprintf(q, r.quote(clientIdentityTableName), r.quote(refreshTokenTableName))
|
||||||
|
@ -196,9 +196,9 @@ func (r *refreshTokenRepo) ClientsWithRefreshTokens(userID string) ([]oidc.Clien
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
c := make([]oidc.ClientIdentity, len(clients))
|
c := make([]client.Client, len(clients))
|
||||||
for i, client := range clients {
|
for i, client := range clients {
|
||||||
ident, err := client.ClientIdentity()
|
ident, err := client.Client()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -191,7 +191,12 @@ func TestDBClientIdentityRepoMetadata(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := r.New("foo", cm, false)
|
_, err := r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "foo",
|
||||||
|
},
|
||||||
|
Metadata: cm,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -227,7 +232,12 @@ func TestDBClientIdentityRepoNewDuplicate(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.New("foo", meta1, false); err != nil {
|
if _, err := r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "foo",
|
||||||
|
},
|
||||||
|
Metadata: meta1,
|
||||||
|
}); err != nil {
|
||||||
t.Fatalf("unexpected error: %v", err)
|
t.Fatalf("unexpected error: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -237,7 +247,12 @@ func TestDBClientIdentityRepoNewDuplicate(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := r.New("foo", meta2, false); err == nil {
|
if _, err := r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "foo",
|
||||||
|
},
|
||||||
|
Metadata: meta2,
|
||||||
|
}); err == nil {
|
||||||
t.Fatalf("expected non-nil error")
|
t.Fatalf("expected non-nil error")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -251,7 +266,12 @@ func TestDBClientIdentityRepoAuthenticate(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
cc, err := r.New("baz", cm, false)
|
cc, err := r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "baz",
|
||||||
|
},
|
||||||
|
Metadata: cm,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -299,7 +319,12 @@ func TestDBClientIdentityAll(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := r.New("foo", cm, false)
|
_, err := r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "foo",
|
||||||
|
},
|
||||||
|
Metadata: cm,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
@ -322,7 +347,12 @@ func TestDBClientIdentityAll(t *testing.T) {
|
||||||
url.URL{Scheme: "http", Host: "foo.com", Path: "/cb"},
|
url.URL{Scheme: "http", Host: "foo.com", Path: "/cb"},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
_, err = r.New("bar", cm, false)
|
_, err = r.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: "bar",
|
||||||
|
},
|
||||||
|
Metadata: cm,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf(err.Error())
|
t.Fatalf(err.Error())
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,8 +14,8 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
testClients = []oidc.ClientIdentity{
|
testClients = []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "client1",
|
ID: "client1",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret-1")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secret-1")),
|
||||||
|
@ -30,7 +30,7 @@ var (
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "client2",
|
ID: "client2",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret-2")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secret-2")),
|
||||||
|
|
|
@ -11,12 +11,13 @@ import (
|
||||||
"github.com/go-gorp/gorp"
|
"github.com/go-gorp/gorp"
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"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"
|
||||||
)
|
)
|
||||||
|
|
||||||
func newRefreshRepo(t *testing.T, users []user.UserWithRemoteIdentities, clients []oidc.ClientIdentity) refresh.RefreshTokenRepo {
|
func newRefreshRepo(t *testing.T, users []user.UserWithRemoteIdentities, clients []client.Client) refresh.RefreshTokenRepo {
|
||||||
var dbMap *gorp.DbMap
|
var dbMap *gorp.DbMap
|
||||||
if dsn := os.Getenv("DEX_TEST_DSN"); dsn == "" {
|
if dsn := os.Getenv("DEX_TEST_DSN"); dsn == "" {
|
||||||
dbMap = db.NewMemDB()
|
dbMap = db.NewMemDB()
|
||||||
|
@ -35,7 +36,7 @@ func newRefreshRepo(t *testing.T, users []user.UserWithRemoteIdentities, clients
|
||||||
func TestRefreshTokenRepo(t *testing.T) {
|
func TestRefreshTokenRepo(t *testing.T) {
|
||||||
clientID := "client1"
|
clientID := "client1"
|
||||||
userID := "user1"
|
userID := "user1"
|
||||||
clients := []oidc.ClientIdentity{
|
clients := []client.Client{
|
||||||
{
|
{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: clientID,
|
ID: clientID,
|
||||||
|
|
|
@ -276,21 +276,24 @@ func TestCreateClient(t *testing.T) {
|
||||||
for i, tt := range tests {
|
for i, tt := range tests {
|
||||||
err := func() error {
|
err := func() error {
|
||||||
f := makeAdminAPITestFixtures()
|
f := makeAdminAPITestFixtures()
|
||||||
req := &adminschema.ClientCreateRequestClient{}
|
req := &adminschema.ClientCreateRequest{
|
||||||
for _, redirectURI := range tt.client.RedirectURIs {
|
Client: &adminschema.Client{},
|
||||||
req.Redirect_uris = append(req.Redirect_uris, redirectURI.String())
|
|
||||||
}
|
}
|
||||||
resp, err := f.adClient.Client.Create(&adminschema.ClientCreateRequest{Client: req}).Do()
|
|
||||||
|
for _, redirectURI := range tt.client.RedirectURIs {
|
||||||
|
req.Client.RedirectURIs = append(req.Client.RedirectURIs, redirectURI.String())
|
||||||
|
}
|
||||||
|
resp, err := f.adClient.Client.Create(req).Do()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if tt.wantError {
|
if tt.wantError {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if resp.Client_id == "" {
|
if resp.Client.Id == "" {
|
||||||
return errors.New("no client id returned")
|
return errors.New("no client id returned")
|
||||||
}
|
}
|
||||||
if resp.Client_secret == "" {
|
if resp.Client.Secret == "" {
|
||||||
return errors.New("no client secret returned")
|
return errors.New("no client secret returned")
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -7,12 +7,13 @@ import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
schema "github.com/coreos/dex/schema/workerschema"
|
schema "github.com/coreos/dex/schema/workerschema"
|
||||||
"github.com/coreos/go-oidc/oidc"
|
"github.com/coreos/go-oidc/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestClientCreate(t *testing.T) {
|
func TestClientCreate(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "72de74a9",
|
ID: "72de74a9",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
||||||
|
@ -23,7 +24,7 @@ func TestClientCreate(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cis := []oidc.ClientIdentity{ci}
|
cis := []client.Client{ci}
|
||||||
|
|
||||||
srv, err := mockServer(cis)
|
srv, err := mockServer(cis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"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"
|
||||||
|
@ -22,7 +23,7 @@ import (
|
||||||
"github.com/coreos/go-oidc/oidc"
|
"github.com/coreos/go-oidc/oidc"
|
||||||
)
|
)
|
||||||
|
|
||||||
func mockServer(cis []oidc.ClientIdentity) (*server.Server, error) {
|
func mockServer(cis []client.Client) (*server.Server, error) {
|
||||||
dbMap := db.NewMemDB()
|
dbMap := db.NewMemDB()
|
||||||
k, err := key.GeneratePrivateKey()
|
k, err := key.GeneratePrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -50,7 +51,7 @@ func mockServer(cis []oidc.ClientIdentity) (*server.Server, error) {
|
||||||
return srv, nil
|
return srv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func mockClient(srv *server.Server, ci oidc.ClientIdentity) (*oidc.Client, error) {
|
func mockClient(srv *server.Server, ci client.Client) (*oidc.Client, error) {
|
||||||
hdlr := srv.HTTPHandler()
|
hdlr := srv.HTTPHandler()
|
||||||
sClient := &phttp.HandlerClient{Handler: hdlr}
|
sClient := &phttp.HandlerClient{Handler: hdlr}
|
||||||
|
|
||||||
|
@ -75,7 +76,7 @@ func mockClient(srv *server.Server, ci oidc.ClientIdentity) (*oidc.Client, error
|
||||||
return oidc.NewClient(ccfg)
|
return oidc.NewClient(ccfg)
|
||||||
}
|
}
|
||||||
|
|
||||||
func verifyUserClaims(claims jose.Claims, ci *oidc.ClientIdentity, user *user.User, issuerURL url.URL) error {
|
func verifyUserClaims(claims jose.Claims, ci *client.Client, user *user.User, issuerURL url.URL) error {
|
||||||
expectedSub, expectedName := ci.Credentials.ID, ci.Credentials.ID
|
expectedSub, expectedName := ci.Credentials.ID, ci.Credentials.ID
|
||||||
if user != nil {
|
if user != nil {
|
||||||
expectedSub, expectedName = user.ID, user.DisplayName
|
expectedSub, expectedName = user.ID, user.DisplayName
|
||||||
|
@ -116,7 +117,7 @@ func TestHTTPExchangeTokenRefreshToken(t *testing.T) {
|
||||||
ID: "local",
|
ID: "local",
|
||||||
}
|
}
|
||||||
|
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "72de74a9",
|
ID: "72de74a9",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
||||||
|
@ -124,7 +125,7 @@ func TestHTTPExchangeTokenRefreshToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
dbMap := db.NewMemDB()
|
dbMap := db.NewMemDB()
|
||||||
cir, err := db.NewClientIdentityRepoFromClients(dbMap, []oidc.ClientIdentity{ci})
|
cir, err := db.NewClientIdentityRepoFromClients(dbMap, []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: " + err.Error())
|
t.Fatalf("Failed to create client identity repo: " + err.Error())
|
||||||
}
|
}
|
||||||
|
@ -262,13 +263,13 @@ func TestHTTPExchangeTokenRefreshToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHTTPClientCredsToken(t *testing.T) {
|
func TestHTTPClientCredsToken(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "72de74a9",
|
ID: "72de74a9",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("XXX")),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
cis := []oidc.ClientIdentity{ci}
|
cis := []client.Client{ci}
|
||||||
|
|
||||||
srv, err := mockServer(cis)
|
srv, err := mockServer(cis)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -102,8 +102,8 @@ func makeUserAPITestFixtures() *userAPITestFixtures {
|
||||||
|
|
||||||
dbMap, _, _, um := makeUserObjects(userUsers, userPasswords)
|
dbMap, _, _, um := makeUserObjects(userUsers, userPasswords)
|
||||||
cir := func() client.ClientIdentityRepo {
|
cir := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(dbMap, []oidc.ClientIdentity{
|
repo, err := db.NewClientIdentityRepoFromClients(dbMap, []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: testClientID,
|
ID: testClientID,
|
||||||
Secret: testClientSecret,
|
Secret: testClientSecret,
|
||||||
|
@ -114,7 +114,7 @@ func makeUserAPITestFixtures() *userAPITestFixtures {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: userBadClientID,
|
ID: userBadClientID,
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
||||||
|
|
|
@ -4,7 +4,7 @@ import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/oidc"
|
"github.com/coreos/dex/client"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -54,5 +54,5 @@ type RefreshTokenRepo interface {
|
||||||
RevokeTokensForClient(userID, clientID string) error
|
RevokeTokensForClient(userID, clientID string) error
|
||||||
|
|
||||||
// ClientsWithRefreshTokens returns a list of all clients the user has an outstanding client with.
|
// ClientsWithRefreshTokens returns a list of all clients the user has an outstanding client with.
|
||||||
ClientsWithRefreshTokens(userID string) ([]oidc.ClientIdentity, error)
|
ClientsWithRefreshTokens(userID string) ([]client.Client, error)
|
||||||
}
|
}
|
||||||
|
|
|
@ -116,7 +116,7 @@ func (s *AdminServer) getState(w http.ResponseWriter, r *http.Request, ps httpro
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *AdminServer) createClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
func (s *AdminServer) createClient(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {
|
||||||
var req admin.ClientRegistrationRequest
|
var req = adminschema.ClientCreateRequest{}
|
||||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||||
writeInvalidRequest(w, "cannot parse JSON body")
|
writeInvalidRequest(w, "cannot parse JSON body")
|
||||||
return
|
return
|
||||||
|
|
|
@ -26,7 +26,7 @@ func TestClientToken(t *testing.T) {
|
||||||
now := time.Now()
|
now := time.Now()
|
||||||
tomorrow := now.Add(24 * time.Hour)
|
tomorrow := now.Add(24 * time.Hour)
|
||||||
validClientID := "valid-client"
|
validClientID := "valid-client"
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: validClientID,
|
ID: validClientID,
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secret")),
|
||||||
|
@ -37,7 +37,7 @@ func TestClientToken(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{ci})
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: %v", err)
|
t.Fatalf("Failed to create client identity repo: %v", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,9 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/pkg/log"
|
"github.com/coreos/dex/pkg/log"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/oauth2"
|
"github.com/coreos/go-oidc/oauth2"
|
||||||
"github.com/coreos/go-oidc/oidc"
|
"github.com/coreos/go-oidc/oidc"
|
||||||
)
|
)
|
||||||
|
@ -43,7 +45,12 @@ func (s *Server) handleClientRegistrationRequest(r *http.Request) (*oidc.ClientR
|
||||||
return nil, newAPIError(oauth2.ErrorServerError, "unable to save client metadata")
|
return nil, newAPIError(oauth2.ErrorServerError, "unable to save client metadata")
|
||||||
}
|
}
|
||||||
|
|
||||||
creds, err := s.ClientIdentityRepo.New(id, clientMetadata, false)
|
creds, err := s.ClientIdentityRepo.New(client.Client{
|
||||||
|
Credentials: oidc.ClientCredentials{
|
||||||
|
ID: id,
|
||||||
|
},
|
||||||
|
Metadata: clientMetadata,
|
||||||
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed to create new client identity: %v", err)
|
log.Errorf("Failed to create new client identity: %v", err)
|
||||||
return nil, newAPIError(oauth2.ErrorServerError, "unable to save client metadata")
|
return nil, newAPIError(oauth2.ErrorServerError, "unable to save client metadata")
|
||||||
|
|
|
@ -49,7 +49,7 @@ func (c *clientResource) list(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
scs := make([]*schema.Client, len(cs))
|
scs := make([]*schema.Client, len(cs))
|
||||||
for i, ci := range cs {
|
for i, ci := range cs {
|
||||||
sc := schema.MapClientIdentityToSchemaClient(ci)
|
sc := schema.MapClientToSchemaClient(ci)
|
||||||
scs[i] = &sc
|
scs[i] = &sc
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ func (c *clientResource) create(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
ci, err := schema.MapSchemaClientToClientIdentity(sc)
|
ci, err := schema.MapSchemaClientToClient(sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Debugf("Invalid request data: %v", err)
|
log.Debugf("Invalid request data: %v", err)
|
||||||
writeAPIError(w, http.StatusBadRequest, newAPIError(errorInvalidClientMetadata, "missing or invalid field: redirectURIs"))
|
writeAPIError(w, http.StatusBadRequest, newAPIError(errorInvalidClientMetadata, "missing or invalid field: redirectURIs"))
|
||||||
|
@ -96,7 +96,9 @@ func (c *clientResource) create(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
creds, err := c.repo.New(clientID, ci.Metadata, false)
|
ci.Credentials.ID = clientID
|
||||||
|
creds, err := c.repo.New(ci)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("Failed creating client: %v", err)
|
log.Errorf("Failed creating client: %v", err)
|
||||||
writeAPIError(w, http.StatusInternalServerError, newAPIError(errorServerError, "unable to create client"))
|
writeAPIError(w, http.StatusInternalServerError, newAPIError(errorServerError, "unable to create client"))
|
||||||
|
@ -104,7 +106,7 @@ func (c *clientResource) create(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
ci.Credentials = *creds
|
ci.Credentials = *creds
|
||||||
|
|
||||||
ssc := schema.MapClientIdentityToSchemaClientWithSecret(ci)
|
ssc := schema.MapClientToSchemaClientWithSecret(ci)
|
||||||
w.Header().Add("Location", phttp.NewResourceLocation(r.URL, ci.Credentials.ID))
|
w.Header().Add("Location", phttp.NewResourceLocation(r.URL, ci.Credentials.ID))
|
||||||
writeResponseWithBody(w, http.StatusCreated, ssc)
|
writeResponseWithBody(w, http.StatusCreated, ssc)
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"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/go-oidc/oidc"
|
"github.com/coreos/go-oidc/oidc"
|
||||||
|
@ -177,7 +178,7 @@ func TestList(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
cs []oidc.ClientIdentity
|
cs []client.Client
|
||||||
want []*schema.Client
|
want []*schema.Client
|
||||||
}{
|
}{
|
||||||
// empty repo
|
// empty repo
|
||||||
|
@ -187,8 +188,8 @@ func TestList(t *testing.T) {
|
||||||
},
|
},
|
||||||
// single client
|
// single client
|
||||||
{
|
{
|
||||||
cs: []oidc.ClientIdentity{
|
cs: []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{ID: "foo", Secret: b64Encode("bar")},
|
Credentials: oidc.ClientCredentials{ID: "foo", Secret: b64Encode("bar")},
|
||||||
Metadata: oidc.ClientMetadata{
|
Metadata: oidc.ClientMetadata{
|
||||||
RedirectURIs: []url.URL{
|
RedirectURIs: []url.URL{
|
||||||
|
@ -206,8 +207,8 @@ func TestList(t *testing.T) {
|
||||||
},
|
},
|
||||||
// multi client
|
// multi client
|
||||||
{
|
{
|
||||||
cs: []oidc.ClientIdentity{
|
cs: []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{ID: "foo", Secret: b64Encode("bar")},
|
Credentials: oidc.ClientCredentials{ID: "foo", Secret: b64Encode("bar")},
|
||||||
Metadata: oidc.ClientMetadata{
|
Metadata: oidc.ClientMetadata{
|
||||||
RedirectURIs: []url.URL{
|
RedirectURIs: []url.URL{
|
||||||
|
@ -215,7 +216,7 @@ func TestList(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{ID: "biz", Secret: b64Encode("bang")},
|
Credentials: oidc.ClientCredentials{ID: "biz", Secret: b64Encode("bang")},
|
||||||
Metadata: oidc.ClientMetadata{
|
Metadata: oidc.ClientMetadata{
|
||||||
RedirectURIs: []url.URL{
|
RedirectURIs: []url.URL{
|
||||||
|
|
|
@ -13,10 +13,10 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/go-oidc/key"
|
"github.com/coreos/go-oidc/key"
|
||||||
"github.com/coreos/go-oidc/oidc"
|
|
||||||
"github.com/coreos/pkg/health"
|
"github.com/coreos/pkg/health"
|
||||||
"github.com/go-gorp/gorp"
|
"github.com/go-gorp/gorp"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
"github.com/coreos/dex/email"
|
"github.com/coreos/dex/email"
|
||||||
|
@ -214,47 +214,14 @@ func loadUsersFromReader(r io.Reader) (users []user.UserWithRemoteIdentities, pw
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// loadClients parses the clients.json file and returns the clients to be created.
|
// loadClients parses the clients.json file and returns a list of clients.
|
||||||
func loadClients(filepath string) ([]oidc.ClientIdentity, error) {
|
func loadClients(filepath string) ([]client.Client, error) {
|
||||||
f, err := os.Open(filepath)
|
f, err := os.Open(filepath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
defer f.Close()
|
defer f.Close()
|
||||||
return loadClientsFromReader(f)
|
return client.ClientsFromReader(f)
|
||||||
}
|
|
||||||
|
|
||||||
func loadClientsFromReader(r io.Reader) ([]oidc.ClientIdentity, error) {
|
|
||||||
var c []struct {
|
|
||||||
ID string `json:"id"`
|
|
||||||
Secret string `json:"secret"`
|
|
||||||
RedirectURLs []string `json:"redirectURLs"`
|
|
||||||
}
|
|
||||||
if err := json.NewDecoder(r).Decode(&c); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
clients := make([]oidc.ClientIdentity, len(c))
|
|
||||||
for i, client := range c {
|
|
||||||
redirectURIs := make([]url.URL, len(client.RedirectURLs))
|
|
||||||
for j, u := range client.RedirectURLs {
|
|
||||||
uri, err := url.Parse(u)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
redirectURIs[j] = *uri
|
|
||||||
}
|
|
||||||
|
|
||||||
clients[i] = oidc.ClientIdentity{
|
|
||||||
Credentials: oidc.ClientCredentials{
|
|
||||||
ID: client.ID,
|
|
||||||
Secret: client.Secret,
|
|
||||||
},
|
|
||||||
Metadata: oidc.ClientMetadata{
|
|
||||||
RedirectURIs: redirectURIs,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return clients, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (cfg *MultiServerConfig) Configure(srv *Server) error {
|
func (cfg *MultiServerConfig) Configure(srv *Server) error {
|
||||||
|
|
|
@ -79,8 +79,8 @@ func TestHandleAuthFuncResponsesSingleRedirectURL(t *testing.T) {
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
||||||
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
||||||
ClientIdentityRepo: func() client.ClientIdentityRepo {
|
ClientIdentityRepo: func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
||||||
|
@ -231,8 +231,8 @@ func TestHandleAuthFuncResponsesMultipleRedirectURLs(t *testing.T) {
|
||||||
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
IssuerURL: url.URL{Scheme: "http", Host: "server.example.com"},
|
||||||
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
SessionManager: manager.NewSessionManager(db.NewSessionRepo(db.NewMemDB()), db.NewSessionKeyRepo(db.NewMemDB())),
|
||||||
ClientIdentityRepo: func() client.ClientIdentityRepo {
|
ClientIdentityRepo: func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
||||||
|
|
|
@ -130,7 +130,7 @@ func TestServerNewSession(t *testing.T) {
|
||||||
|
|
||||||
state := "pants"
|
state := "pants"
|
||||||
nonce := "oncenay"
|
nonce := "oncenay"
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: "secrete",
|
Secret: "secrete",
|
||||||
|
@ -179,7 +179,7 @@ func TestServerNewSession(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerLogin(t *testing.T) {
|
func TestServerLogin(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: clientTestSecret,
|
Secret: clientTestSecret,
|
||||||
|
@ -195,7 +195,7 @@ func TestServerLogin(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ciRepo := func() client.ClientIdentityRepo {
|
ciRepo := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{ci})
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: %v", err)
|
t.Fatalf("Failed to create client identity repo: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -245,8 +245,8 @@ func TestServerLogin(t *testing.T) {
|
||||||
|
|
||||||
func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
||||||
ciRepo := func() client.ClientIdentityRepo {
|
ciRepo := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX", Secret: clientTestSecret,
|
ID: "XXX", Secret: clientTestSecret,
|
||||||
},
|
},
|
||||||
|
@ -281,7 +281,7 @@ func TestServerLoginUnrecognizedSessionKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerLoginDisabledUser(t *testing.T) {
|
func TestServerLoginDisabledUser(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: clientTestSecret,
|
Secret: clientTestSecret,
|
||||||
|
@ -297,7 +297,7 @@ func TestServerLoginDisabledUser(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ciRepo := func() client.ClientIdentityRepo {
|
ciRepo := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{ci})
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: %v", err)
|
t.Fatalf("Failed to create client identity repo: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -355,14 +355,14 @@ func TestServerLoginDisabledUser(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerCodeToken(t *testing.T) {
|
func TestServerCodeToken(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: clientTestSecret,
|
Secret: clientTestSecret,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ciRepo := func() client.ClientIdentityRepo {
|
ciRepo := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{ci})
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: %v", err)
|
t.Fatalf("Failed to create client identity repo: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -441,14 +441,14 @@ func TestServerCodeToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestServerTokenUnrecognizedKey(t *testing.T) {
|
func TestServerTokenUnrecognizedKey(t *testing.T) {
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: clientTestSecret,
|
Secret: clientTestSecret,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
ciRepo := func() client.ClientIdentityRepo {
|
ciRepo := func() client.ClientIdentityRepo {
|
||||||
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{ci})
|
repo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{ci})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("Failed to create client identity repo: %v", err)
|
t.Fatalf("Failed to create client identity repo: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -569,8 +569,8 @@ func TestServerTokenFail(t *testing.T) {
|
||||||
km := &StaticKeyManager{
|
km := &StaticKeyManager{
|
||||||
signer: tt.signer,
|
signer: tt.signer,
|
||||||
}
|
}
|
||||||
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{Credentials: ccFixture},
|
client.Client{Credentials: ccFixture},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("case %d: failed to create client identity repo: %v", i, err)
|
t.Errorf("case %d: failed to create client identity repo: %v", i, err)
|
||||||
|
@ -731,9 +731,9 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
signer: tt.signer,
|
signer: tt.signer,
|
||||||
}
|
}
|
||||||
|
|
||||||
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{Credentials: credXXX},
|
client.Client{Credentials: credXXX},
|
||||||
oidc.ClientIdentity{Credentials: credYYY},
|
client.Client{Credentials: credYYY},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("case %d: failed to create client identity repo: %v", i, err)
|
t.Errorf("case %d: failed to create client identity repo: %v", i, err)
|
||||||
|
@ -784,9 +784,9 @@ func TestServerRefreshToken(t *testing.T) {
|
||||||
signer: signerFixture,
|
signer: signerFixture,
|
||||||
}
|
}
|
||||||
|
|
||||||
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
ciRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{Credentials: credXXX},
|
client.Client{Credentials: credXXX},
|
||||||
oidc.ClientIdentity{Credentials: credYYY},
|
client.Client{Credentials: credYYY},
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatalf("failed to create client identity repo: %v", err)
|
t.Fatalf("failed to create client identity repo: %v", err)
|
||||||
|
|
|
@ -136,8 +136,8 @@ func makeTestFixtures() (*testFixtures, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
clientIdentityRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []oidc.ClientIdentity{
|
clientIdentityRepo, err := db.NewClientIdentityRepoFromClients(db.NewMemDB(), []client.Client{
|
||||||
oidc.ClientIdentity{
|
client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"github.com/jonboulle/clockwork"
|
"github.com/jonboulle/clockwork"
|
||||||
"github.com/kylelemons/godebug/pretty"
|
"github.com/kylelemons/godebug/pretty"
|
||||||
|
|
||||||
|
"github.com/coreos/dex/client"
|
||||||
"github.com/coreos/dex/connector"
|
"github.com/coreos/dex/connector"
|
||||||
"github.com/coreos/dex/db"
|
"github.com/coreos/dex/db"
|
||||||
schema "github.com/coreos/dex/schema/workerschema"
|
schema "github.com/coreos/dex/schema/workerschema"
|
||||||
|
@ -155,7 +156,7 @@ func makeTestFixtures() (*UsersAPI, *testEmailer) {
|
||||||
|
|
||||||
mgr := manager.NewUserManager(ur, pwr, ccr, db.TransactionFactory(dbMap), manager.ManagerOptions{})
|
mgr := manager.NewUserManager(ur, pwr, ccr, db.TransactionFactory(dbMap), manager.ManagerOptions{})
|
||||||
mgr.Clock = clock
|
mgr.Clock = clock
|
||||||
ci := oidc.ClientIdentity{
|
ci := client.Client{
|
||||||
Credentials: oidc.ClientCredentials{
|
Credentials: oidc.ClientCredentials{
|
||||||
ID: "XXX",
|
ID: "XXX",
|
||||||
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
Secret: base64.URLEncoding.EncodeToString([]byte("secrete")),
|
||||||
|
@ -166,8 +167,9 @@ func makeTestFixtures() (*UsersAPI, *testEmailer) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
if _, err := db.NewClientIdentityRepoFromClients(dbMap, []oidc.ClientIdentity{ci}); err != nil {
|
|
||||||
panic("Failed to create client identity repo: " + err.Error())
|
if _, err := db.NewClientIdentityRepoFromClients(dbMap, []client.Client{ci}); err != nil {
|
||||||
|
panic("Failed to create client repo: " + err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Used in TestRevokeRefreshToken test.
|
// Used in TestRevokeRefreshToken test.
|
||||||
|
|
Reference in a new issue