@@ -4,7 +4,6 @@ import (
44 "context"
55 "encoding/base64"
66 "encoding/json"
7− "errors"
87 "fmt"
98 "net/http"
109 "net/http/httptest"
@@ -54,6 +53,7 @@ func newOIDCProvider(serverURL *url.URL) *OIDCProvider {
5453 Scope: "openid profile offline_access",
5554 EmailClaim: "email",
5655 GroupsClaim: "groups",
56+ UserClaim: "sub",
5757 Verifier: internaloidc.NewVerifier(oidc.NewVerifier(
5858 oidcIssuer,
5959 mockJWKS{},
@@ -142,333 +142,6 @@ func TestOIDCProviderRedeem_custom_userid(t *testing.T) {
142142 assert.Equal(t, defaultIDToken.Phone, session.Email)
143143}
144144
145−func TestOIDCProvider_EnrichSession(t *testing.T) {
146− testCases := map[string]struct {
147− ExistingSession *sessions.SessionState
148− EmailClaim string
149− GroupsClaim string
150− ProfileJSON map[string]interface{}
151− ExpectedError error
152− ExpectedSession *sessions.SessionState
153− }{
154− "Already Populated": {
155− ExistingSession: &sessions.SessionState{
156− User: "already",
157− Email: "already@populated.com",
158− Groups: []string{"already", "populated"},
159− IDToken: idToken,
160− AccessToken: accessToken,
161− RefreshToken: refreshToken,
162− },
163− EmailClaim: "email",
164− GroupsClaim: "groups",
165− ProfileJSON: map[string]interface{}{
166− "email": "new@thing.com",
167− "groups": []string{"new", "thing"},
168− },
169− ExpectedError: nil,
170− ExpectedSession: &sessions.SessionState{
171− User: "already",
172− Email: "already@populated.com",
173− Groups: []string{"already", "populated"},
174− IDToken: idToken,
175− AccessToken: accessToken,
176− RefreshToken: refreshToken,
177− },
178− },
179− "Missing Email": {
180− ExistingSession: &sessions.SessionState{
181− User: "missing.email",
182− Groups: []string{"already", "populated"},
183− IDToken: idToken,
184− AccessToken: accessToken,
185− RefreshToken: refreshToken,
186− },
187− EmailClaim: "email",
188− GroupsClaim: "groups",
189− ProfileJSON: map[string]interface{}{
190− "email": "found@email.com",
191− "groups": []string{"new", "thing"},
192− },
193− ExpectedError: nil,
194− ExpectedSession: &sessions.SessionState{
195− User: "missing.email",
196− Email: "found@email.com",
197− Groups: []string{"already", "populated"},
198− IDToken: idToken,
199− AccessToken: accessToken,
200− RefreshToken: refreshToken,
201− },
202− },
203−
204− "Missing Email Only in Profile URL": {
205− ExistingSession: &sessions.SessionState{
206− User: "missing.email",
207− IDToken: idToken,
208− AccessToken: accessToken,
209− RefreshToken: refreshToken,
210− },
211− EmailClaim: "email",
212− GroupsClaim: "groups",
213− ProfileJSON: map[string]interface{}{
214− "email": "found@email.com",
215− },
216− ExpectedError: nil,
217− ExpectedSession: &sessions.SessionState{
218− User: "missing.email",
219− Email: "found@email.com",
220− IDToken: idToken,
221− AccessToken: accessToken,
222− RefreshToken: refreshToken,
223− },
224− },
225− "Missing Email with Custom Claim": {
226− ExistingSession: &sessions.SessionState{
227− User: "missing.email",
228− Groups: []string{"already", "populated"},
229− IDToken: idToken,
230− AccessToken: accessToken,
231− RefreshToken: refreshToken,
232− },
233− EmailClaim: "weird",
234− GroupsClaim: "groups",
235− ProfileJSON: map[string]interface{}{
236− "weird": "weird@claim.com",
237− "groups": []string{"new", "thing"},
238− },
239− ExpectedError: nil,
240− ExpectedSession: &sessions.SessionState{
241− User: "missing.email",
242− Email: "weird@claim.com",
243− Groups: []string{"already", "populated"},
244− IDToken: idToken,
245− AccessToken: accessToken,
246− RefreshToken: refreshToken,
247− },
248− },
249− "Missing Email not in Profile URL": {
250− ExistingSession: &sessions.SessionState{
251− User: "missing.email",
252− Groups: []string{"already", "populated"},
253− IDToken: idToken,
254− AccessToken: accessToken,
255− RefreshToken: refreshToken,
256− },
257− EmailClaim: "email",
258− GroupsClaim: "groups",
259− ProfileJSON: map[string]interface{}{
260− "groups": []string{"new", "thing"},
261− },
262− ExpectedError: errors.New("neither the id_token nor the profileURL set an email"),
263− ExpectedSession: &sessions.SessionState{
264− User: "missing.email",
265− Groups: []string{"already", "populated"},
266− IDToken: idToken,
267− AccessToken: accessToken,
268− RefreshToken: refreshToken,
269− },
270− },
271− "Missing Groups": {
272− ExistingSession: &sessions.SessionState{
273− User: "already",
274− Email: "already@populated.com",
275− Groups: nil,
276− IDToken: idToken,
277− AccessToken: accessToken,
278− RefreshToken: refreshToken,
279− },
280− EmailClaim: "email",
281− GroupsClaim: "groups",
282− ProfileJSON: map[string]interface{}{
283− "email": "new@thing.com",
284− "groups": []string{"new", "thing"},
285− },
286− ExpectedError: nil,
287− ExpectedSession: &sessions.SessionState{
288− User: "already",
289− Email: "already@populated.com",
290− Groups: []string{"new", "thing"},
291− IDToken: idToken,
292− AccessToken: accessToken,
293− RefreshToken: refreshToken,
294− },
295− },
296− "Missing Groups with Complex Groups in Profile URL": {
297− ExistingSession: &sessions.SessionState{
298− User: "already",
299− Email: "already@populated.com",
300− Groups: nil,
301− IDToken: idToken,
302− AccessToken: accessToken,
303− RefreshToken: refreshToken,
304− },
305− EmailClaim: "email",
306− GroupsClaim: "groups",
307− ProfileJSON: map[string]interface{}{
308− "email": "new@thing.com",
309− "groups": []map[string]interface{}{
310− {
311− "groupId": "Admin Group Id",
312− "roles": []string{"Admin"},
313− },
314− },
315− },
316− ExpectedError: nil,
317− ExpectedSession: &sessions.SessionState{
318− User: "already",
319− Email: "already@populated.com",
320− Groups: []string{"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}"},
321− IDToken: idToken,
322− AccessToken: accessToken,
323− RefreshToken: refreshToken,
324− },
325− },
326− "Missing Groups with Singleton Complex Group in Profile URL": {
327− ExistingSession: &sessions.SessionState{
328− User: "already",
329− Email: "already@populated.com",
330− Groups: nil,
331− IDToken: idToken,
332− AccessToken: accessToken,
333− RefreshToken: refreshToken,
334− },
335− EmailClaim: "email",
336− GroupsClaim: "groups",
337− ProfileJSON: map[string]interface{}{
338− "email": "new@thing.com",
339− "groups": map[string]interface{}{
340− "groupId": "Admin Group Id",
341− "roles": []string{"Admin"},
342− },
343− },
344− ExpectedError: nil,
345− ExpectedSession: &sessions.SessionState{
346− User: "already",
347− Email: "already@populated.com",
348− Groups: []string{"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}"},
349− IDToken: idToken,
350− AccessToken: accessToken,
351− RefreshToken: refreshToken,
352− },
353− },
354− "Empty Groups Claims": {
355− ExistingSession: &sessions.SessionState{
356− User: "already",
357− Email: "already@populated.com",
358− Groups: []string{},
359− IDToken: idToken,
360− AccessToken: accessToken,
361− RefreshToken: refreshToken,
362− },
363− EmailClaim: "email",
364− GroupsClaim: "groups",
365− ProfileJSON: map[string]interface{}{
366− "email": "new@thing.com",
367− "groups": []string{"new", "thing"},
368− },
369− ExpectedError: nil,
370− ExpectedSession: &sessions.SessionState{
371− User: "already",
372− Email: "already@populated.com",
373− Groups: []string{},
374− IDToken: idToken,
375− AccessToken: accessToken,
376− RefreshToken: refreshToken,
377− },
378− },
379− "Missing Groups with Custom Claim": {
380− ExistingSession: &sessions.SessionState{
381− User: "already",
382− Email: "already@populated.com",
383− Groups: nil,
384− IDToken: idToken,
385− AccessToken: accessToken,
386− RefreshToken: refreshToken,
387− },
388− EmailClaim: "email",
389− GroupsClaim: "roles",
390− ProfileJSON: map[string]interface{}{
391− "email": "new@thing.com",
392− "roles": []string{"new", "thing", "roles"},
393− },
394− ExpectedError: nil,
395− ExpectedSession: &sessions.SessionState{
396− User: "already",
397− Email: "already@populated.com",
398− Groups: []string{"new", "thing", "roles"},
399− IDToken: idToken,
400− AccessToken: accessToken,
401− RefreshToken: refreshToken,
402− },
403− },
404− "Missing Groups String Profile URL Response": {
405− ExistingSession: &sessions.SessionState{
406− User: "already",
407− Email: "already@populated.com",
408− Groups: nil,
409− IDToken: idToken,
410− AccessToken: accessToken,
411− RefreshToken: refreshToken,
412− },
413− EmailClaim: "email",
414− GroupsClaim: "groups",
415− ProfileJSON: map[string]interface{}{
416− "email": "new@thing.com",
417− "groups": "singleton",
418− },
419− ExpectedError: nil,
420− ExpectedSession: &sessions.SessionState{
421− User: "already",
422− Email: "already@populated.com",
423− Groups: []string{"singleton"},
424− IDToken: idToken,
425− AccessToken: accessToken,
426− RefreshToken: refreshToken,
427− },
428− },
429− "Missing Groups in both Claims and Profile URL": {
430− ExistingSession: &sessions.SessionState{
431− User: "already",
432− Email: "already@populated.com",
433− IDToken: idToken,
434− AccessToken: accessToken,
435− RefreshToken: refreshToken,
436− },
437− EmailClaim: "email",
438− GroupsClaim: "groups",
439− ProfileJSON: map[string]interface{}{
440− "email": "new@thing.com",
441− },
442− ExpectedError: nil,
443− ExpectedSession: &sessions.SessionState{
444− User: "already",
445− Email: "already@populated.com",
446− IDToken: idToken,
447− AccessToken: accessToken,
448− RefreshToken: refreshToken,
449− },
450− },
451− }
452− for testName, tc := range testCases {
453− t.Run(testName, func(t *testing.T) {
454− jsonResp, err := json.Marshal(tc.ProfileJSON)
455− assert.NoError(t, err)
456−
457− server, provider := newTestOIDCSetup(jsonResp)
458− provider.ProfileURL, err = url.Parse(server.URL)
459− assert.NoError(t, err)
460−
461− provider.EmailClaim = tc.EmailClaim
462− provider.GroupsClaim = tc.GroupsClaim
463− defer server.Close()
464−
465− err = provider.EnrichSession(context.Background(), tc.ExistingSession)
466− assert.Equal(t, tc.ExpectedError, err)
467− assert.Equal(t, *tc.ExpectedSession, *tc.ExistingSession)
468− })
469− }
470−}
471−
472145func TestOIDCProviderRefreshSessionIfNeededWithoutIdToken(t *testing.T) {
473146
474147 idToken, _ := newSignedTestIDToken(defaultIDToken)
@@ -565,11 +238,15 @@ func TestOIDCProviderCreateSessionFromToken(t *testing.T) {
565238 ExpectedGroups: []string{"test:c", "test:d"},
566239 },
567240 "Complex Groups Claim": {
568− IDToken: complexGroupsIDToken,
569− GroupsClaim: "groups",
570− ExpectedUser: "123456789",
571− ExpectedEmail: "complex@claims.com",
572− ExpectedGroups: []string{"{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}"},
241+ IDToken: complexGroupsIDToken,
242+ GroupsClaim: "groups",
243+ ExpectedUser: "123456789",
244+ ExpectedEmail: "complex@claims.com",
245+ ExpectedGroups: []string{
246+ "{\"groupId\":\"Admin Group Id\",\"roles\":[\"Admin\"]}",
247+ "12345",
248+ "Just::A::String",
249+ },
573250 },
574251 }
575252 for testName, tc := range testCases {