github.com/argoproj/argo-cd/v3@v3.2.1/util/jwt/jwt_test.go (about) 1 package jwt 2 3 import ( 4 "testing" 5 "time" 6 7 "github.com/golang-jwt/jwt/v5" 8 "github.com/stretchr/testify/assert" 9 "github.com/stretchr/testify/require" 10 ) 11 12 func TestGetSingleStringScope(t *testing.T) { 13 claims := jwt.MapClaims{"groups": "my-org:my-team"} 14 groups := GetScopeValues(claims, []string{"groups"}) 15 assert.Contains(t, groups, "my-org:my-team") 16 } 17 18 func TestGetMultipleListScopes(t *testing.T) { 19 claims := jwt.MapClaims{"groups1": []string{"my-org:my-team1"}, "groups2": []string{"my-org:my-team2"}} 20 groups := GetScopeValues(claims, []string{"groups1", "groups2"}) 21 assert.Contains(t, groups, "my-org:my-team1") 22 assert.Contains(t, groups, "my-org:my-team2") 23 } 24 25 func TestClaims(t *testing.T) { 26 assert.Nil(t, Claims(nil)) 27 assert.NotNil(t, Claims(jwt.MapClaims{})) 28 } 29 30 func TestIsMember(t *testing.T) { 31 assert.False(t, IsMember(jwt.MapClaims{}, nil, []string{"groups"})) 32 assert.False(t, IsMember(jwt.MapClaims{"groups": []string{""}}, []string{"my-group"}, []string{"groups"})) 33 assert.False(t, IsMember(jwt.MapClaims{"groups": []string{"my-group"}}, []string{""}, []string{"groups"})) 34 assert.True(t, IsMember(jwt.MapClaims{"groups": []string{"my-group"}}, []string{"my-group"}, []string{"groups"})) 35 } 36 37 func TestGetGroups(t *testing.T) { 38 assert.Empty(t, GetGroups(jwt.MapClaims{}, []string{"groups"})) 39 assert.Equal(t, []string{"foo"}, GetGroups(jwt.MapClaims{"groups": []string{"foo"}}, []string{"groups"})) 40 } 41 42 func TestIssuedAtTime_Int64(t *testing.T) { 43 // Tuesday, 1 December 2020 14:00:00 44 claims := jwt.MapClaims{"iat": int64(1606831200)} 45 issuedAt, err := IssuedAtTime(claims) 46 require.NoError(t, err) 47 str := issuedAt.UTC().Format("Mon Jan _2 15:04:05 2006") 48 assert.Equal(t, "Tue Dec 1 14:00:00 2020", str) 49 } 50 51 func TestIssuedAtTime_Error_NoInt(t *testing.T) { 52 claims := jwt.MapClaims{"iat": 1606831200} 53 _, err := IssuedAtTime(claims) 54 assert.Error(t, err) 55 } 56 57 func TestIssuedAtTime_Error_Missing(t *testing.T) { 58 claims := jwt.MapClaims{} 59 iat, err := IssuedAtTime(claims) 60 require.Error(t, err) 61 assert.Equal(t, time.Unix(0, 0), iat) 62 } 63 64 func TestIsValid(t *testing.T) { 65 assert.True(t, IsValid("foo.bar.foo")) 66 assert.True(t, IsValid("foo.bar.foo.bar")) 67 assert.False(t, IsValid("foo.bar")) 68 assert.False(t, IsValid("foo")) 69 assert.False(t, IsValid("")) 70 } 71 72 func TestGetUserIdentifier(t *testing.T) { 73 tests := []struct { 74 name string 75 claims jwt.MapClaims 76 want string 77 }{ 78 { 79 name: "when both dex and sub defined - prefer dex user_id", 80 claims: jwt.MapClaims{ 81 "sub": "ignored:login", 82 "federated_claims": map[string]any{ 83 "user_id": "dex-user", 84 }, 85 }, 86 want: "dex-user", 87 }, 88 { 89 name: "when both dex and sub defined but dex user_id empty - fallback to sub", 90 claims: jwt.MapClaims{ 91 "sub": "test:apiKey", 92 "federated_claims": map[string]any{ 93 "user_id": "", 94 }, 95 }, 96 want: "test:apiKey", 97 }, 98 { 99 name: "when only sub is defined (no dex) - use sub", 100 claims: jwt.MapClaims{ 101 "sub": "admin:login", 102 }, 103 want: "admin:login", 104 }, 105 { 106 name: "when neither dex nor sub defined - return empty", 107 claims: jwt.MapClaims{}, 108 want: "", 109 }, 110 { 111 name: "nil claims", 112 claims: nil, 113 want: "", 114 }, 115 { 116 name: "invalid subject", 117 claims: jwt.MapClaims{ 118 "sub": nil, 119 }, 120 want: "", 121 }, 122 { 123 name: "invalid federated_claims", 124 claims: jwt.MapClaims{ 125 "sub": "test:apiKey", 126 "federated_claims": "invalid", 127 }, 128 want: "test:apiKey", 129 }, 130 } 131 132 for _, tt := range tests { 133 t.Run(tt.name, func(t *testing.T) { 134 got := GetUserIdentifier(tt.claims) 135 assert.Equal(t, tt.want, got) 136 }) 137 } 138 }