diff --git a/providers/azure.go b/providers/azure.go index 2e8c57d85..da3293bd0 100644 --- a/providers/azure.go +++ b/providers/azure.go @@ -7,6 +7,7 @@ import ( "log" "net/http" "net/url" + "github.com/bitly/go-simplejson" ) type AzureProvider struct { @@ -65,7 +66,27 @@ func getAzureHeader(access_token string) http.Header { return header } +func getEmailFromJSON(json *simplejson.Json) (string, error) { + var email string + var err error + + email, err = json.Get("mail").String() + + if err != nil || email == "" { + otherMails, otherMailsErr := json.Get("otherMails").Array() + if len(otherMails) > 0{ + email = otherMails[0].(string) + } + err = otherMailsErr + } + + return email, err + } + func (p *AzureProvider) GetEmailAddress(s *SessionState) (string, error) { + var email string + var err error + if s.AccessToken == "" { return "", errors.New("missing access token") } @@ -78,9 +99,26 @@ func (p *AzureProvider) GetEmailAddress(s *SessionState) (string, error) { json, err := api.Request(req) if err != nil { - log.Printf("failed making request %s", err) return "", err } - return json.Get("mail").String() + email, err = getEmailFromJSON(json) + + if err == nil && email != "" { + return email, err + } + + email, err = json.Get("userPrincipalName").String() + + if err != nil { + log.Printf("failed making request %s", err) + return "", err + } + + if email == "" { + log.Printf("failed to get email address") + return "", err + } + + return email, err } diff --git a/providers/azure_test.go b/providers/azure_test.go index 1aa823ac7..0d0c5b36b 100644 --- a/providers/azure_test.go +++ b/providers/azure_test.go @@ -125,11 +125,76 @@ func TestAzureProviderGetEmailAddress(t *testing.T) { b := testAzureBackend(`{ "mail": "user@windows.net" }`) defer b.Close() - b_url, _ := url.Parse(b.URL) - p := testAzureProvider(b_url.Host) + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) session := &SessionState{AccessToken: "imaginary_access_token"} email, err := p.GetEmailAddress(session) assert.Equal(t, nil, err) assert.Equal(t, "user@windows.net", email) } + +func TestAzureProviderGetEmailAddressMailNull(t *testing.T) { + b := testAzureBackend(`{ "mail": null, "otherMails": ["user@windows.net", "altuser@windows.net"] }`) + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) + + session := &SessionState{AccessToken: "imaginary_access_token"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, nil, err) + assert.Equal(t, "user@windows.net", email) +} + +func TestAzureProviderGetEmailAddressGetUserPrincipalName(t *testing.T) { + b := testAzureBackend(`{ "mail": null, "otherMails": [], "userPrincipalName": "user@windows.net" }`) + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) + + session := &SessionState{AccessToken: "imaginary_access_token"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, nil, err) + assert.Equal(t, "user@windows.net", email) +} + +func TestAzureProviderGetEmailAddressFailToGetEmailAddress(t *testing.T) { + b := testAzureBackend(`{ "mail": null, "otherMails": [], "userPrincipalName": null }`) + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) + + session := &SessionState{AccessToken: "imaginary_access_token"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, "type assertion to string failed", err.Error()) + assert.Equal(t, "", email) +} + +func TestAzureProviderGetEmailAddressEmptyUserPrincipalName(t *testing.T) { + b := testAzureBackend(`{ "mail": null, "otherMails": [], "userPrincipalName": "" }`) + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) + + session := &SessionState{AccessToken: "imaginary_access_token"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, nil, err) + assert.Equal(t, "", email) +} + +func TestAzureProviderGetEmailAddressIncorrectOtherMails(t *testing.T) { + b := testAzureBackend(`{ "mail": null, "otherMails": "", "userPrincipalName": null }`) + defer b.Close() + + bURL, _ := url.Parse(b.URL) + p := testAzureProvider(bURL.Host) + + session := &SessionState{AccessToken: "imaginary_access_token"} + email, err := p.GetEmailAddress(session) + assert.Equal(t, "type assertion to string failed", err.Error()) + assert.Equal(t, "", email) +} \ No newline at end of file