a418e1c4e7
adds a client manager to handle business logic, leaving the repo for basic crud operations. Also adds client to the test script
162 lines
4.2 KiB
Go
162 lines
4.2 KiB
Go
package server
|
|
|
|
import (
|
|
"bytes"
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/coreos/go-oidc/jose"
|
|
"github.com/coreos/go-oidc/key"
|
|
"github.com/coreos/go-oidc/oidc"
|
|
)
|
|
|
|
func TestHandleVerifyEmailResend(t *testing.T) {
|
|
now := time.Now()
|
|
tomorrow := now.Add(24 * time.Hour)
|
|
yesterday := now.Add(-24 * time.Hour)
|
|
|
|
privKey, err := key.GeneratePrivateKey()
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate private key, error=%v", err)
|
|
}
|
|
|
|
signer := privKey.Signer()
|
|
|
|
pubKey := *key.NewPublicKey(privKey.JWK())
|
|
keysFunc := func() ([]key.PublicKey, error) {
|
|
return []key.PublicKey{pubKey}, nil
|
|
}
|
|
|
|
makeToken := func(iss, sub, aud string, iat, exp time.Time) string {
|
|
claims := oidc.NewClaims(iss, sub, aud, iat, exp)
|
|
jwt, err := jose.NewSignedJWT(claims, signer)
|
|
if err != nil {
|
|
t.Fatalf("Failed to generate JWT, error=%v", err)
|
|
}
|
|
return jwt.Encode()
|
|
}
|
|
|
|
tests := []struct {
|
|
bearerJWT string
|
|
userJWT string
|
|
redirectURL url.URL
|
|
wantCode int
|
|
verifyEmailUserID string
|
|
}{
|
|
{
|
|
// The happy case
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"ID-1", testClientID, now, tomorrow),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusOK,
|
|
},
|
|
{
|
|
// Already verified
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"ID-1", testClientID, now, tomorrow),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusBadRequest,
|
|
verifyEmailUserID: "ID-1",
|
|
},
|
|
{
|
|
// Expired userJWT
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"ID-1", testClientID, now, yesterday),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusUnauthorized,
|
|
},
|
|
{
|
|
// Client ID is unknown
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
"fakeclientid", testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"ID-1", testClientID, now, tomorrow),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusBadRequest,
|
|
},
|
|
{
|
|
// No sub in user JWT
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"", testClientID, now, tomorrow),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusBadRequest,
|
|
},
|
|
{
|
|
// Unknown user
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"NonExistent", testClientID, now, tomorrow),
|
|
redirectURL: testRedirectURL,
|
|
wantCode: http.StatusBadRequest,
|
|
},
|
|
{
|
|
// No redirect URL
|
|
bearerJWT: makeToken(testIssuerURL.String(),
|
|
testClientID, testClientID, now, tomorrow),
|
|
userJWT: makeToken(testIssuerURL.String(),
|
|
"ID-1", testClientID, now, tomorrow),
|
|
redirectURL: url.URL{},
|
|
wantCode: http.StatusBadRequest,
|
|
},
|
|
}
|
|
|
|
for i, tt := range tests {
|
|
f, err := makeTestFixtures()
|
|
if tt.verifyEmailUserID != "" {
|
|
usr, _ := f.userRepo.Get(nil, tt.verifyEmailUserID)
|
|
usr.EmailVerified = true
|
|
f.userRepo.Update(nil, usr)
|
|
}
|
|
|
|
if err != nil {
|
|
t.Fatalf("case %d: could not make test fixtures: %v", i, err)
|
|
}
|
|
|
|
hdlr := handleVerifyEmailResendFunc(
|
|
testIssuerURL,
|
|
keysFunc,
|
|
f.srv.UserEmailer,
|
|
f.userRepo,
|
|
f.clientManager)
|
|
|
|
w := httptest.NewRecorder()
|
|
u := "http://example.com"
|
|
q := struct {
|
|
Token string `json:"token"`
|
|
RedirectURI string `json:"redirectURI"`
|
|
}{
|
|
Token: tt.userJWT,
|
|
RedirectURI: tt.redirectURL.String(),
|
|
}
|
|
qBytes, err := json.Marshal(&q)
|
|
if err != nil {
|
|
t.Errorf("case %d: unable to marshal JSON: %q", i, err)
|
|
}
|
|
|
|
req, err := http.NewRequest("POST", u, bytes.NewReader(qBytes))
|
|
req.Header.Set("Authorization", "Bearer "+tt.bearerJWT)
|
|
|
|
if err != nil {
|
|
t.Errorf("case %d: unable to form HTTP request: %v", i, err)
|
|
}
|
|
|
|
hdlr.ServeHTTP(w, req)
|
|
if tt.wantCode != w.Code {
|
|
t.Errorf("case %d: wantCode=%v, got=%v", i, tt.wantCode, w.Code)
|
|
t.Logf("case %d: response body was: %v", i, w.Body.String())
|
|
}
|
|
}
|
|
}
|