ソースを参照

LDAP: Fetch teams in debug view (#18951)

Adds the definition of `GetTeamsForLDAPGroupCommand` which handles the lookup of team information based on LDAP groupDNs.

This is an Enterprise only feature. To diferentiate,a response will contain the `team` key as `null` on OSS while on Enterprise the key will contain an empty array `[]` when no teams are found.
gotjosh 6 年 前
コミット
10fe101add
3 ファイル変更120 行追加18 行削除
  1. 25 17
      pkg/api/ldap_debug.go
  2. 84 1
      pkg/api/ldap_debug_test.go
  3. 11 0
      pkg/models/user_auth.go

+ 25 - 17
pkg/api/ldap_debug.go

@@ -5,6 +5,7 @@ import (
 	"net/http"
 
 	"github.com/grafana/grafana/pkg/bus"
+	"github.com/grafana/grafana/pkg/infra/log"
 	"github.com/grafana/grafana/pkg/models"
 	"github.com/grafana/grafana/pkg/services/ldap"
 	"github.com/grafana/grafana/pkg/services/multildap"
@@ -15,6 +16,8 @@ var (
 	getLDAPConfig = multildap.GetConfig
 	newLDAP       = multildap.New
 
+	logger = log.New("LDAP.debug")
+
 	errOrganizationNotFound = func(orgId int64) error {
 		return fmt.Errorf("Unable to find organization with ID '%d'", orgId)
 	}
@@ -34,23 +37,16 @@ type RoleDTO struct {
 	GroupDN string          `json:"groupDN"`
 }
 
-// TeamDTO is a serializer for mapped Teams from LDAP
-type TeamDTO struct {
-	GroupDN  string `json:"groupDN"`
-	TeamId   int64  `json:"teamId"`
-	TeamName string `json:"teamName"`
-}
-
 // LDAPUserDTO is a serializer for users mapped from LDAP
 type LDAPUserDTO struct {
-	Name           *LDAPAttribute `json:"name"`
-	Surname        *LDAPAttribute `json:"surname"`
-	Email          *LDAPAttribute `json:"email"`
-	Username       *LDAPAttribute `json:"login"`
-	IsGrafanaAdmin *bool          `json:"isGrafanaAdmin"`
-	IsDisabled     bool           `json:"isDisabled"`
-	OrgRoles       []RoleDTO      `json:"roles"`
-	Teams          []TeamDTO      `json:"teams"`
+	Name           *LDAPAttribute           `json:"name"`
+	Surname        *LDAPAttribute           `json:"surname"`
+	Email          *LDAPAttribute           `json:"email"`
+	Username       *LDAPAttribute           `json:"login"`
+	IsGrafanaAdmin *bool                    `json:"isGrafanaAdmin"`
+	IsDisabled     bool                     `json:"isDisabled"`
+	OrgRoles       []RoleDTO                `json:"roles"`
+	Teams          []models.TeamOrgGroupDTO `json:"teams"`
 }
 
 // FetchOrgs fetches the organization(s) information by executing a single query to the database. Then, populating the DTO with the information retrieved.
@@ -154,7 +150,7 @@ func (server *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
 	ldapConfig, err := getLDAPConfig()
 
 	if err != nil {
-		return Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration. Please ", err)
+		return Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration", err)
 	}
 
 	ldap := newLDAP(ldapConfig.Servers)
@@ -171,6 +167,8 @@ func (server *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
 		return Error(http.StatusNotFound, "No user was found on the LDAP server(s)", err)
 	}
 
+	logger.Debug("user found", "user", user)
+
 	name, surname := splitName(user.Name)
 
 	u := &LDAPUserDTO{
@@ -203,12 +201,22 @@ func (server *HTTPServer) GetUserFromLDAP(c *models.ReqContext) Response {
 
 	u.OrgRoles = orgRoles
 
+	logger.Debug("mapping org roles", "orgsRoles", u.OrgRoles)
 	err = u.FetchOrgs()
 
 	if err != nil {
-		return Error(http.StatusBadRequest, "Organization not found - Please verify your LDAP configuration", err)
+		return Error(http.StatusBadRequest, "An oganization was not found - Please verify your LDAP configuration", err)
 	}
 
+	cmd := &models.GetTeamsForLDAPGroupCommand{Groups: user.Groups}
+	err = bus.Dispatch(cmd)
+
+	if err != bus.ErrHandlerNotFound && err != nil {
+		return Error(http.StatusBadRequest, "Unable to find the teams for this user", err)
+	}
+
+	u.Teams = cmd.Result
+
 	return JSON(200, u)
 }
 

+ 84 - 1
pkg/api/ldap_debug_test.go

@@ -150,7 +150,7 @@ func TestGetUserFromLDAPApiEndpoint_OrgNotfound(t *testing.T) {
 	expected := `
 	{
 		"error": "Unable to find organization with ID '2'",
-		"message": "Organization not found - Please verify your LDAP configuration"
+		"message": "An oganization was not found - Please verify your LDAP configuration"
 	}
 	`
 	var expectedJSON interface{}
@@ -237,6 +237,89 @@ func TestGetUserFromLDAPApiEndpoint(t *testing.T) {
 	assert.Equal(t, expectedJSON, jsonResponse)
 }
 
+func TestGetUserFromLDAPApiEndpoint_WithTeamHandler(t *testing.T) {
+	isAdmin := true
+	userSearchResult = &models.ExternalUserInfo{
+		Name:           "John Doe",
+		Email:          "john.doe@example.com",
+		Login:          "johndoe",
+		OrgRoles:       map[int64]models.RoleType{1: models.ROLE_ADMIN},
+		IsGrafanaAdmin: &isAdmin,
+	}
+
+	userSearchConfig = ldap.ServerConfig{
+		Attr: ldap.AttributeMap{
+			Name:     "ldap-name",
+			Surname:  "ldap-surname",
+			Email:    "ldap-email",
+			Username: "ldap-username",
+		},
+		Groups: []*ldap.GroupToOrgRole{
+			{
+				GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
+				OrgID:   1,
+				OrgRole: models.ROLE_ADMIN,
+			},
+		},
+	}
+
+	mockOrgSearchResult := []*models.OrgDTO{
+		{Id: 1, Name: "Main Org."},
+	}
+
+	bus.AddHandler("test", func(query *models.SearchOrgsQuery) error {
+		query.Result = mockOrgSearchResult
+		return nil
+	})
+
+	bus.AddHandler("test", func(cmd *models.GetTeamsForLDAPGroupCommand) error {
+		cmd.Result = []models.TeamOrgGroupDTO{}
+		return nil
+	})
+
+	getLDAPConfig = func() (*ldap.Config, error) {
+		return &ldap.Config{}, nil
+	}
+
+	newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
+		return &LDAPMock{}
+	}
+
+	sc := getUserFromLDAPContext(t, "/api/admin/ldap/johndoe")
+
+	require.Equal(t, sc.resp.Code, http.StatusOK)
+
+	jsonResponse, err := getJSONbody(sc.resp)
+	assert.Nil(t, err)
+
+	expected := `
+		{
+		  "name": {
+				"cfgAttrValue": "ldap-name", "ldapValue": "John"
+			},
+			"surname": {
+				"cfgAttrValue": "ldap-surname", "ldapValue": "Doe"
+			},
+			"email": {
+				"cfgAttrValue": "ldap-email", "ldapValue": "john.doe@example.com"
+			},
+			"login": {
+				"cfgAttrValue": "ldap-username", "ldapValue": "johndoe"
+			},
+			"isGrafanaAdmin": true,
+			"isDisabled": false,
+			"roles": [
+				{ "orgId": 1, "orgRole": "Admin", "orgName": "Main Org.", "groupDN": "cn=admins,ou=groups,dc=grafana,dc=org" }
+			],
+			"teams": []
+		}
+	`
+	var expectedJSON interface{}
+	_ = json.Unmarshal([]byte(expected), &expectedJSON)
+
+	assert.Equal(t, expectedJSON, jsonResponse)
+}
+
 //***
 // GetLDAPStatus tests
 //***

+ 11 - 0
pkg/models/user_auth.go

@@ -100,6 +100,17 @@ type GetAuthInfoQuery struct {
 	Result *UserAuth
 }
 
+type TeamOrgGroupDTO struct {
+	TeamName string `json:"teamName"`
+	OrgName  string `json:"orgName"`
+	GroupDN  string `json:"groupDN"`
+}
+
+type GetTeamsForLDAPGroupCommand struct {
+	Groups []string
+	Result []TeamOrgGroupDTO
+}
+
 type SyncTeamsCommand struct {
 	ExternalUser *ExternalUserInfo
 	User         *User