This Gist contains a few tests for the JOSE bug fix.
The following line will run the tests.
$ go test main_test.go -v
| package main | |
| import ( | |
| "testing" | |
| "github.com/SermoDigital/jose/crypto" | |
| "github.com/SermoDigital/jose/jws" | |
| "github.com/SermoDigital/jose/jwt" | |
| ) | |
| func TestMultipleAudienceBug_AfterMarshal(t *testing.T) { | |
| // Create JWS claims | |
| claims := jws.Claims{} | |
| claims.SetAudience("example.com", "api.example.com") | |
| token := jws.NewJWT(claims, crypto.SigningMethodHS256) | |
| serializedToken, _ := token.Serialize([]byte("abcdef")) | |
| // Unmarshal JSON | |
| newToken, _ := jws.ParseJWT(serializedToken) | |
| c := newToken.Claims() | |
| // Get Audience | |
| aud, ok := c.Audience() | |
| if !ok { | |
| // Fails | |
| t.Fail() | |
| } | |
| t.Logf("aud Value: %s", aud) | |
| t.Logf("aud Type : %T", aud) | |
| } | |
| func TestMultipleAudienceFix_AfterMarshal(t *testing.T) { | |
| // Create JWS claims | |
| claims := jws.Claims{} | |
| claims.SetAudience("example.com", "api.example.com") | |
| token := jws.NewJWT(claims, crypto.SigningMethodHS256) | |
| serializedToken, _ := token.Serialize([]byte("abcdef")) | |
| // Unmarshal JSON | |
| newToken, _ := jws.ParseJWT(serializedToken) | |
| c := newToken.Claims() | |
| // Get Audience | |
| aud, ok := Audience(c, t) | |
| if !ok { | |
| // Fails | |
| t.Fail() | |
| } | |
| t.Logf("aud len(): %d", len(aud)) | |
| t.Logf("aud Value: %s", aud) | |
| t.Logf("aud Type : %T", aud) | |
| } | |
| func TestSingleAudienceFix_AfterMarshal(t *testing.T) { | |
| // Create JWS claims | |
| claims := jws.Claims{} | |
| claims.SetAudience("example.com") | |
| token := jws.NewJWT(claims, crypto.SigningMethodHS256) | |
| serializedToken, _ := token.Serialize([]byte("abcdef")) | |
| // Unmarshal JSON | |
| newToken, _ := jws.ParseJWT(serializedToken) | |
| c := newToken.Claims() | |
| // Get Audience | |
| aud, ok := Audience(c, t) | |
| if !ok { | |
| // Fails | |
| t.Fail() | |
| } | |
| t.Logf("aud len(): %d", len(aud)) | |
| t.Logf("aud Value: %s", aud) | |
| t.Logf("aud Type : %T", aud) | |
| } | |
| // Audience retrieves claim "aud" per its type in | |
| // https://tools.ietf.org/html/rfc7519#section-4.1.3 | |
| func Audience(c jwt.Claims, tester *testing.T) ([]string, bool) { | |
| switch t := c.Get("aud").(type) { | |
| case string: | |
| return []string{t}, true | |
| case []string: | |
| return t, true | |
| case []interface{}: | |
| return stringify(t...) | |
| case interface{}: | |
| return stringify(t) | |
| } | |
| return nil, false | |
| } | |
| // stringify has not changed any from the JOSE implementation | |
| func stringify(a ...interface{}) ([]string, bool) { | |
| if len(a) == 0 { | |
| return nil, false | |
| } | |
| s := make([]string, len(a)) | |
| for i := range a { | |
| str, ok := a[i].(string) | |
| if !ok { | |
| return nil, false | |
| } | |
| s[i] = str | |
| } | |
| return s, true | |
| } |