2016-10-04 07:26:04 +00:00
|
|
|
package server
|
2016-10-27 23:28:11 +00:00
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
2016-11-22 23:35:46 +00:00
|
|
|
"os"
|
2016-10-27 23:28:11 +00:00
|
|
|
"testing"
|
2017-02-14 22:40:20 +00:00
|
|
|
"time"
|
2016-10-27 23:28:11 +00:00
|
|
|
|
2016-11-22 23:35:46 +00:00
|
|
|
"github.com/Sirupsen/logrus"
|
2016-10-27 23:28:11 +00:00
|
|
|
"github.com/coreos/dex/api"
|
2017-02-14 22:40:20 +00:00
|
|
|
"github.com/coreos/dex/server/internal"
|
|
|
|
"github.com/coreos/dex/storage"
|
2016-10-27 23:28:11 +00:00
|
|
|
"github.com/coreos/dex/storage/memory"
|
|
|
|
)
|
|
|
|
|
|
|
|
// Attempts to create, update and delete a test Password
|
|
|
|
func TestPassword(t *testing.T) {
|
2016-11-22 23:35:46 +00:00
|
|
|
logger := &logrus.Logger{
|
|
|
|
Out: os.Stderr,
|
|
|
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
|
|
|
Level: logrus.DebugLevel,
|
|
|
|
}
|
|
|
|
|
|
|
|
s := memory.New(logger)
|
2016-12-12 22:54:01 +00:00
|
|
|
serv := NewAPI(s, logger)
|
2016-10-27 23:28:11 +00:00
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
p := api.Password{
|
|
|
|
Email: "test@example.com",
|
|
|
|
// bcrypt hash of the value "test1" with cost 10
|
|
|
|
Hash: []byte("$2a$10$XVMN/Fid.Ks4CXgzo8fpR.iU1khOMsP5g9xQeXuBm1wXjRX8pjUtO"),
|
|
|
|
Username: "test",
|
|
|
|
UserId: "test123",
|
|
|
|
}
|
|
|
|
|
|
|
|
createReq := api.CreatePasswordReq{
|
|
|
|
Password: &p,
|
|
|
|
}
|
|
|
|
|
2017-02-21 23:00:22 +00:00
|
|
|
if resp, err := serv.CreatePassword(ctx, &createReq); err != nil || resp.AlreadyExists {
|
|
|
|
if resp.AlreadyExists {
|
|
|
|
t.Fatalf("Unable to create password since %s already exists", createReq.Password.Email)
|
|
|
|
}
|
2016-10-27 23:28:11 +00:00
|
|
|
t.Fatalf("Unable to create password: %v", err)
|
|
|
|
}
|
|
|
|
|
2017-02-21 23:00:22 +00:00
|
|
|
// Attempt to create a password that already exists.
|
|
|
|
if resp, _ := serv.CreatePassword(ctx, &createReq); !resp.AlreadyExists {
|
|
|
|
t.Fatalf("Created password %s twice", createReq.Password.Email)
|
|
|
|
}
|
|
|
|
|
2016-10-27 23:28:11 +00:00
|
|
|
updateReq := api.UpdatePasswordReq{
|
|
|
|
Email: "test@example.com",
|
|
|
|
NewUsername: "test1",
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := serv.UpdatePassword(ctx, &updateReq); err != nil {
|
|
|
|
t.Fatalf("Unable to update password: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
pass, err := s.GetPassword(updateReq.Email)
|
|
|
|
if err != nil {
|
|
|
|
t.Fatalf("Unable to retrieve password: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if pass.Username != updateReq.NewUsername {
|
|
|
|
t.Fatalf("UpdatePassword failed. Expected username %s retrieved %s", updateReq.NewUsername, pass.Username)
|
|
|
|
}
|
|
|
|
|
|
|
|
deleteReq := api.DeletePasswordReq{
|
|
|
|
Email: "test@example.com",
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := serv.DeletePassword(ctx, &deleteReq); err != nil {
|
|
|
|
t.Fatalf("Unable to delete password: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2017-02-14 22:40:20 +00:00
|
|
|
|
|
|
|
// Attempts to list and revoke an exisiting refresh token.
|
|
|
|
func TestRefreshToken(t *testing.T) {
|
|
|
|
logger := &logrus.Logger{
|
|
|
|
Out: os.Stderr,
|
|
|
|
Formatter: &logrus.TextFormatter{DisableColors: true},
|
|
|
|
Level: logrus.DebugLevel,
|
|
|
|
}
|
|
|
|
|
|
|
|
s := memory.New(logger)
|
|
|
|
serv := NewAPI(s, logger)
|
|
|
|
|
|
|
|
ctx := context.Background()
|
|
|
|
|
|
|
|
// Creating a storage with an existing refresh token and offline session for the user.
|
|
|
|
id := storage.NewID()
|
|
|
|
r := storage.RefreshToken{
|
|
|
|
ID: id,
|
|
|
|
Token: "bar",
|
|
|
|
Nonce: "foo",
|
|
|
|
ClientID: "client_id",
|
|
|
|
ConnectorID: "client_secret",
|
|
|
|
Scopes: []string{"openid", "email", "profile"},
|
|
|
|
CreatedAt: time.Now().UTC().Round(time.Millisecond),
|
|
|
|
LastUsed: time.Now().UTC().Round(time.Millisecond),
|
|
|
|
Claims: storage.Claims{
|
|
|
|
UserID: "1",
|
|
|
|
Username: "jane",
|
|
|
|
Email: "jane.doe@example.com",
|
|
|
|
EmailVerified: true,
|
|
|
|
Groups: []string{"a", "b"},
|
|
|
|
},
|
|
|
|
ConnectorData: []byte(`{"some":"data"}`),
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := s.CreateRefresh(r); err != nil {
|
|
|
|
t.Fatalf("create refresh token: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
tokenRef := storage.RefreshTokenRef{
|
|
|
|
ID: r.ID,
|
|
|
|
ClientID: r.ClientID,
|
|
|
|
CreatedAt: r.CreatedAt,
|
|
|
|
LastUsed: r.LastUsed,
|
|
|
|
}
|
|
|
|
|
|
|
|
session := storage.OfflineSessions{
|
|
|
|
UserID: r.Claims.UserID,
|
|
|
|
ConnID: r.ConnectorID,
|
|
|
|
Refresh: make(map[string]*storage.RefreshTokenRef),
|
|
|
|
}
|
|
|
|
session.Refresh[tokenRef.ClientID] = &tokenRef
|
|
|
|
|
|
|
|
if err := s.CreateOfflineSessions(session); err != nil {
|
|
|
|
t.Fatalf("create offline session: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
subjectString, err := internal.Marshal(&internal.IDTokenSubject{
|
|
|
|
UserId: r.Claims.UserID,
|
|
|
|
ConnId: r.ConnectorID,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
t.Errorf("failed to marshal offline session ID: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
//Testing the api.
|
|
|
|
listReq := api.ListRefreshReq{
|
|
|
|
UserId: subjectString,
|
|
|
|
}
|
|
|
|
|
|
|
|
if _, err := serv.ListRefresh(ctx, &listReq); err != nil {
|
|
|
|
t.Fatalf("Unable to list refresh tokens for user: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
revokeReq := api.RevokeRefreshReq{
|
|
|
|
UserId: subjectString,
|
|
|
|
ClientId: r.ClientID,
|
|
|
|
}
|
|
|
|
|
|
|
|
resp, err := serv.RevokeRefresh(ctx, &revokeReq)
|
|
|
|
if err != nil || resp.NotFound {
|
|
|
|
t.Fatalf("Unable to revoke refresh tokens for user: %v", err)
|
|
|
|
}
|
|
|
|
|
|
|
|
if resp, _ := serv.ListRefresh(ctx, &listReq); len(resp.RefreshTokens) != 0 {
|
|
|
|
t.Fatalf("Refresh token returned inspite of revoking it.")
|
|
|
|
}
|
|
|
|
}
|