mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
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.
This commit is contained in:
parent
545be60138
commit
10fe101add
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
//***
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user