Bladeren bron

Generic Oauth Support for ADFS (#9242)

* check upn field if email address isn't present, support for adfs

* correctly set login to the user's email address if not specified by the oauth server

* break up GenericOAuth.UserInfo into helper functions
Dan Cech 8 jaren geleden
bovenliggende
commit
5bb22b836d
1 gewijzigde bestanden met toevoegingen van 68 en 29 verwijderingen
  1. 68 29
      pkg/social/generic_oauth.go

+ 68 - 29
pkg/social/generic_oauth.go

@@ -5,6 +5,7 @@ import (
 	"errors"
 	"fmt"
 	"net/http"
+	"net/mail"
 
 	"github.com/grafana/grafana/pkg/models"
 
@@ -165,15 +166,18 @@ func (s *GenericOAuth) FetchOrganizations(client *http.Client) ([]string, error)
 	return logins, nil
 }
 
+type UserInfoJson struct {
+	Name        string              `json:"name"`
+	DisplayName string              `json:"display_name"`
+	Login       string              `json:"login"`
+	Username    string              `json:"username"`
+	Email       string              `json:"email"`
+	Upn         string              `json:"upn"`
+	Attributes  map[string][]string `json:"attributes"`
+}
+
 func (s *GenericOAuth) UserInfo(client *http.Client) (*BasicUserInfo, error) {
-	var data struct {
-		Name        string              `json:"name"`
-		DisplayName string              `json:"display_name"`
-		Login       string              `json:"login"`
-		Username    string              `json:"username"`
-		Email       string              `json:"email"`
-		Attributes  map[string][]string `json:"attributes"`
-	}
+	var data UserInfoJson
 
 	response, err := HttpGet(client, s.apiUrl)
 	if err != nil {
@@ -185,33 +189,25 @@ func (s *GenericOAuth) UserInfo(client *http.Client) (*BasicUserInfo, error) {
 		return nil, fmt.Errorf("Error getting user info: %s", err)
 	}
 
-	userInfo := &BasicUserInfo{
-		Name:  data.Name,
-		Login: data.Login,
-		Email: data.Email,
-	}
-
-	if userInfo.Email == "" && data.Attributes["email:primary"] != nil {
-		userInfo.Email = data.Attributes["email:primary"][0]
-	}
-
-	if userInfo.Email == "" {
-		userInfo.Email, err = s.FetchPrivateEmail(client)
-		if err != nil {
-			return nil, err
-		}
+	name, err := s.extractName(data)
+	if err != nil {
+		return nil, err
 	}
 
-	if userInfo.Name == "" && data.DisplayName != "" {
-		userInfo.Name = data.DisplayName
+	email, err := s.extractEmail(data, client)
+	if err != nil {
+		return nil, err
 	}
 
-	if userInfo.Login == "" && data.Username != "" {
-		userInfo.Login = data.Username
+	login, err := s.extractLogin(data, email)
+	if err != nil {
+		return nil, err
 	}
 
-	if userInfo.Login == "" {
-		userInfo.Login = data.Email
+	userInfo := &BasicUserInfo{
+		Name:  name,
+		Login: login,
+		Email: email,
 	}
 
 	if !s.IsTeamMember(client) {
@@ -224,3 +220,46 @@ func (s *GenericOAuth) UserInfo(client *http.Client) (*BasicUserInfo, error) {
 
 	return userInfo, nil
 }
+
+func (s *GenericOAuth) extractEmail(data UserInfoJson, client *http.Client) (string, error) {
+	if data.Email != "" {
+		return data.Email, nil
+	}
+
+	if data.Attributes["email:primary"] != nil {
+		return data.Attributes["email:primary"][0], nil
+	}
+
+	if data.Upn != "" {
+		emailAddr, emailErr := mail.ParseAddress(data.Upn)
+		if emailErr == nil {
+			return emailAddr.Address, nil
+		}
+	}
+
+	return s.FetchPrivateEmail(client)
+}
+
+func (s *GenericOAuth) extractLogin(data UserInfoJson, email string) (string, error) {
+	if data.Login != "" {
+		return data.Login, nil
+	}
+
+	if data.Username != "" {
+		return data.Username, nil
+	}
+
+	return email, nil
+}
+
+func (s *GenericOAuth) extractName(data UserInfoJson) (string, error) {
+	if data.Name != "" {
+		return data.Name, nil
+	}
+
+	if data.DisplayName != "" {
+		return data.DisplayName, nil
+	}
+
+	return "", nil
+}