Merge pull request #1290 from smallstep/herman/email-domain-ssh-sign-error

Add email address to error message returned for OIDC validation
This commit is contained in:
Herman Slatman 2023-02-23 21:13:54 +01:00 committed by GitHub
commit 176cf30a6f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 27 deletions

View file

@ -230,7 +230,7 @@ func (o *OIDC) ValidatePayload(p openIDPayload) error {
} }
} }
if !found { if !found {
return errs.Unauthorized("validatePayload: failed to validate oidc token payload: email is not allowed") return errs.Unauthorized("validatePayload: failed to validate oidc token payload: email %q is not allowed", p.Email)
} }
} }

View file

@ -13,6 +13,7 @@ import (
"testing" "testing"
"time" "time"
"github.com/stretchr/testify/require"
"go.step.sm/crypto/jose" "go.step.sm/crypto/jose"
"github.com/smallstep/assert" "github.com/smallstep/assert"
@ -221,39 +222,37 @@ func TestOIDC_authorizeToken(t *testing.T) {
args args args args
code int code int
wantIssuer string wantIssuer string
wantErr bool expErr error
}{ }{
{"ok1", p1, args{t1}, http.StatusOK, issuer, false}, {"ok1", p1, args{t1}, http.StatusOK, issuer, nil},
{"ok tenantid", p2, args{t2}, http.StatusOK, tenantIssuer, false}, {"ok tenantid", p2, args{t2}, http.StatusOK, tenantIssuer, nil},
{"ok admin", p3, args{t3}, http.StatusOK, issuer, false}, {"ok admin", p3, args{t3}, http.StatusOK, issuer, nil},
{"ok domain", p3, args{t4}, http.StatusOK, issuer, false}, {"ok domain", p3, args{t4}, http.StatusOK, issuer, nil},
{"ok no email", p3, args{t5}, http.StatusOK, issuer, false}, {"ok no email", p3, args{t5}, http.StatusOK, issuer, nil},
{"fail-domain", p3, args{failDomain}, http.StatusUnauthorized, "", true}, {"fail-domain", p3, args{failDomain}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken: validatePayload: failed to validate oidc token payload: email "name@example.com" is not allowed`)},
{"fail-key", p1, args{failKey}, http.StatusUnauthorized, "", true}, {"fail-key", p1, args{failKey}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken; cannot validate oidc token`)},
{"fail-token", p1, args{failTok}, http.StatusUnauthorized, "", true}, {"fail-token", p1, args{failTok}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken; error parsing oidc token: invalid character '~' looking for beginning of value`)},
{"fail-claims", p1, args{failClaims}, http.StatusUnauthorized, "", true}, {"fail-claims", p1, args{failClaims}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken; error parsing oidc token claims: invalid character '~' looking for beginning of value`)},
{"fail-issuer", p1, args{failIss}, http.StatusUnauthorized, "", true}, {"fail-issuer", p1, args{failIss}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken: validatePayload: failed to validate oidc token payload: square/go-jose/jwt: validation failed, invalid issuer claim (iss)`)},
{"fail-audience", p1, args{failAud}, http.StatusUnauthorized, "", true}, {"fail-audience", p1, args{failAud}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken: validatePayload: failed to validate oidc token payload: square/go-jose/jwt: validation failed, invalid audience claim (aud)`)},
{"fail-signature", p1, args{failSig}, http.StatusUnauthorized, "", true}, {"fail-signature", p1, args{failSig}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken; cannot validate oidc token`)},
{"fail-expired", p1, args{failExp}, http.StatusUnauthorized, "", true}, {"fail-expired", p1, args{failExp}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken: validatePayload: failed to validate oidc token payload: square/go-jose/jwt: validation failed, token is expired (exp)`)},
{"fail-not-before", p1, args{failNbf}, http.StatusUnauthorized, "", true}, {"fail-not-before", p1, args{failNbf}, http.StatusUnauthorized, "", errors.New(`oidc.AuthorizeToken: validatePayload: failed to validate oidc token payload: square/go-jose/jwt: validation failed, token not valid yet (nbf)`)},
} }
for _, tt := range tests { for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) { t.Run(tt.name, func(t *testing.T) {
got, err := tt.prov.authorizeToken(tt.args.token) got, err := tt.prov.authorizeToken(tt.args.token)
if (err != nil) != tt.wantErr { if tt.expErr != nil {
fmt.Println(tt) require.Error(t, err)
t.Errorf("OIDC.Authorize() error = %v, wantErr %v", err, tt.wantErr) require.EqualError(t, err, tt.expErr.Error())
return
}
if err != nil {
var sc render.StatusCodedError var sc render.StatusCodedError
assert.Fatal(t, errors.As(err, &sc), "error does not implement StatusCodedError interface") require.ErrorAs(t, err, &sc, "error does not implement StatusCodedError interface")
assert.Equals(t, sc.StatusCode(), tt.code) require.Equal(t, tt.code, sc.StatusCode())
assert.Nil(t, got) require.Nil(t, got)
} else { } else {
assert.NotNil(t, got) require.NotNil(t, got)
assert.Equals(t, got.Issuer, tt.wantIssuer) require.Equal(t, tt.wantIssuer, got.Issuer)
} }
}) })
} }