From 66b68d8765c0193ef50496d5aa6d2568f0990321 Mon Sep 17 00:00:00 2001 From: Atte Niemi <4998544+hur@users.noreply.github.com> Date: Fri, 16 Aug 2024 18:46:57 +0100 Subject: [PATCH 1/2] Fix Microsoft connector emailToLowercase for refresh token Fixes #3283 Signed-off-by: Atte Niemi <4998544+hur@users.noreply.github.com> --- connector/microsoft/microsoft.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/connector/microsoft/microsoft.go b/connector/microsoft/microsoft.go index 2fcf6a75..662ecce0 100644 --- a/connector/microsoft/microsoft.go +++ b/connector/microsoft/microsoft.go @@ -312,6 +312,10 @@ func (c *microsoftConnector) Refresh(ctx context.Context, s connector.Scopes, id return identity, fmt.Errorf("microsoft: get user: %v", err) } + if c.emailToLowercase { + user.Email = strings.ToLower(user.Email) + } + identity.Username = user.Name identity.Email = user.Email From 83a852a094e5056dfe07f15628c65b99ff4725ce Mon Sep 17 00:00:00 2001 From: Atte Niemi <4998544+hur@users.noreply.github.com> Date: Fri, 16 Aug 2024 20:15:39 +0100 Subject: [PATCH 2/2] add unit tests for validating emailToLowercase behavior Signed-off-by: Atte Niemi <4998544+hur@users.noreply.github.com> --- connector/microsoft/microsoft_test.go | 62 +++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) diff --git a/connector/microsoft/microsoft_test.go b/connector/microsoft/microsoft_test.go index 67be660f..a86f4263 100644 --- a/connector/microsoft/microsoft_test.go +++ b/connector/microsoft/microsoft_test.go @@ -1,6 +1,7 @@ package microsoft import ( + "context" "encoding/json" "fmt" "net/http" @@ -101,6 +102,67 @@ func TestUserIdentityFromGraphAPI(t *testing.T) { expectEquals(t, len(identity.Groups), 0) } +func TestHandleCallbackWithEmailToLowercase(t *testing.T) { + s := newTestServer(map[string]testResponse{ + "/v1.0/me?$select=id,displayName,userPrincipalName": { + data: user{ID: "S56767889", Name: "Jane Doe", Email: "Jane.Doe@example.com"}, + }, + "/" + tenant + "/oauth2/v2.0/token": dummyToken, + }) + defer s.Close() + + req, _ := http.NewRequest("GET", s.URL, nil) + + c := microsoftConnector{apiURL: s.URL, graphURL: s.URL, tenant: tenant, emailToLowercase: true} + identity, err := c.HandleCallback(connector.Scopes{Groups: false}, req) + expectNil(t, err) + expectEquals(t, identity.Username, "Jane Doe") + expectEquals(t, identity.UserID, "S56767889") + expectEquals(t, identity.PreferredUsername, "") + expectEquals(t, identity.Email, "jane.doe@example.com") + expectEquals(t, identity.EmailVerified, true) + expectEquals(t, len(identity.Groups), 0) +} + +func TestRefreshWithEmailToLowercase(t *testing.T) { + s := newTestServer(map[string]testResponse{ + "/v1.0/me?$select=id,displayName,userPrincipalName": { + data: user{ID: "S56767889", Name: "Jane Doe", Email: "Jane.Doe@example.com"}, + }, + "/" + tenant + "/oauth2/v2.0/token": {data: map[string]interface{}{ + "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9", + "refresh_token": "oRzxVjCnohYRHEYEhZshkmakKmoyVoTjfUGC", + "expires_in": "30", + }}, + }) + defer s.Close() + + req, err := http.NewRequest("GET", s.URL, nil) + expectNil(t, err) + + c := microsoftConnector{apiURL: s.URL, graphURL: s.URL, tenant: tenant, emailToLowercase: true} + + expectNil(t, err) + + identity, err := c.HandleCallback(connector.Scopes{Groups: false, OfflineAccess: true}, req) + expectNil(t, err) + expectEquals(t, identity.Username, "Jane Doe") + expectEquals(t, identity.UserID, "S56767889") + expectEquals(t, identity.PreferredUsername, "") + expectEquals(t, identity.Email, "jane.doe@example.com") + expectEquals(t, identity.EmailVerified, true) + expectEquals(t, len(identity.Groups), 0) + + identity, err = c.Refresh(context.Background(), connector.Scopes{Groups: false, OfflineAccess: true}, identity) + expectNil(t, err) + expectEquals(t, identity.Username, "Jane Doe") + expectEquals(t, identity.UserID, "S56767889") + expectEquals(t, identity.PreferredUsername, "") + expectEquals(t, identity.Email, "jane.doe@example.com") + expectEquals(t, identity.EmailVerified, true) + expectEquals(t, len(identity.Groups), 0) +} + func TestUserGroupsFromGraphAPI(t *testing.T) { s := newTestServer(map[string]testResponse{ "/v1.0/me?$select=id,displayName,userPrincipalName": {data: user{}},