Skip to content

Commit

Permalink
Add testing of email challenge parsing
Browse files Browse the repository at this point in the history
Signed-off-by: Nathan Smith <nathan@chainguard.dev>
  • Loading branch information
Nathan Smith committed May 13, 2022
1 parent 76edd42 commit e26c017
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
64 changes: 60 additions & 4 deletions pkg/challenges/challenges_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,9 @@ import (
"errors"
"fmt"
"net/url"
"reflect"
"testing"
"unsafe"

"github.com/coreos/go-oidc/v3/oidc"
"github.com/google/go-cmp/cmp"
Expand Down Expand Up @@ -238,10 +240,8 @@ func TestEmbedChallengeResult(t *testing.T) {
t.Error(err)
}
return
} else {
if test.WantErr {
t.Error("expected error")
}
} else if test.WantErr {
t.Error("expected error")
}
for factName, fact := range test.WantFacts {
t.Run(factName, func(t *testing.T) {
Expand Down Expand Up @@ -490,6 +490,62 @@ func Test_isURISubjectAllowed(t *testing.T) {
}
}

// reflect hack because "claims" field is unexported by oidc IDToken
// https://github.com/coreos/go-oidc/pull/329
func updateIDToken(idToken *oidc.IDToken, fieldName string, data []byte) {
val := reflect.Indirect(reflect.ValueOf(idToken))
member := val.FieldByName(fieldName)
pointer := unsafe.Pointer(member.UnsafeAddr())
realPointer := (*[]byte)(pointer)
*realPointer = data
}

func TestEmail(t *testing.T) {
tests := map[string]struct {
InputClaims []byte
WantErr bool
}{
"Good": {
InputClaims: []byte(`{"email":"John.Doe@email.com", "email_verified":true}`),
WantErr: false,
},
"Email not verified": {
InputClaims: []byte(`{"email":"John.Doe@email.com", "email_verified":false}`),
WantErr: true,
},
"Email missing": {
InputClaims: []byte(`{"email_verified":true}`),
WantErr: true,
},
}

ctx := context.Background()
cfg := &config.FulcioConfig{
OIDCIssuers: map[string]config.OIDCIssuer{
"email.com": {IssuerURL: "email.com"},
},
}
ctx = config.With(ctx, cfg)

for name, test := range tests {
t.Run(name, func(t *testing.T) {
idToken := &oidc.IDToken{
Issuer: `email.com`,
}
updateIDToken(idToken, "claims", test.InputClaims)
_, err := email(ctx, idToken)
if err != nil {
if !test.WantErr {
t.Error(err)
}
return
} else if test.WantErr {
t.Error("expected error")
}
})
}
}

func Test_validateAllowedDomain(t *testing.T) {
tests := []struct {
name string
Expand Down
4 changes: 4 additions & 0 deletions pkg/oauthflow/oidc.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
package oauthflow

import (
"errors"
"fmt"

"github.com/PaesslerAG/jsonpath"
Expand All @@ -31,6 +32,9 @@ func EmailFromIDToken(token *oidc.IDToken) (string, bool, error) {
if err := token.Claims(&claims); err != nil {
return "", false, err
}
if claims.Email == "" {
return "", false, errors.New("token missing email claim")
}

return claims.Email, claims.Verified, nil
}
Expand Down
6 changes: 5 additions & 1 deletion pkg/oauthflow/oidc_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,13 +53,17 @@ func TestTokenWithClaims(t *testing.T) {
inputClaims: []byte(`{}`),
expectedEmail: "",
expectedVerified: false,
expectedErr: nil,
expectedErr: errors.New("token missing email claim"),
}, {
name: "token with non-verified claims set",
inputClaims: []byte(`{"email":"John.Doe@email.com"}`),
expectedEmail: "John.Doe@email.com",
expectedVerified: false,
expectedErr: nil,
}, {
name: "token missing email claim",
inputClaims: []byte(`{"email_verified": true}`),
expectedErr: errors.New("token missing email claim"),
}, {
name: "token with claims set",
inputClaims: []byte(`{"email":"John.Doe@email.com", "email_verified":true}`),
Expand Down

0 comments on commit e26c017

Please sign in to comment.