LDAP: Move LDAP globals to Config (#63255)
* structure dtos and private methods * add basic LDAP service * use LDAP service in ldap debug API * lower non fatal error * remove unused globals * wip * remove final globals * fix tests to use cfg enabled * restructure errors * remove logger from globals * use ldap service in authn * use ldap service in context handler * fix failed tests * fix ldap middleware provides * fix provides in auth_test.go
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/grafana/grafana/pkg/services/ldap"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
)
|
||||
|
||||
// swagger:parameters getUserFromLDAP
|
||||
type GetLDAPUserParams struct {
|
||||
// in:path
|
||||
// required:true
|
||||
UserName string `json:"user_name"`
|
||||
}
|
||||
|
||||
// swagger:parameters postSyncUserWithLDAP
|
||||
type SyncLDAPUserParams struct {
|
||||
// in:path
|
||||
// required:true
|
||||
UserID int64 `json:"user_id"`
|
||||
}
|
||||
|
||||
// LDAPAttribute is a serializer for user attributes mapped from LDAP. Is meant to display both the serialized value and the LDAP key we received it from.
|
||||
type LDAPAttribute struct {
|
||||
ConfigAttributeValue string `json:"cfgAttrValue"`
|
||||
LDAPAttributeValue string `json:"ldapValue"`
|
||||
}
|
||||
|
||||
// RoleDTO is a serializer for mapped roles from LDAP
|
||||
type LDAPRoleDTO struct {
|
||||
OrgId int64 `json:"orgId"`
|
||||
OrgName string `json:"orgName"`
|
||||
OrgRole org.RoleType `json:"orgRole"`
|
||||
GroupDN string `json:"groupDN"`
|
||||
}
|
||||
|
||||
// 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 []LDAPRoleDTO `json:"roles"`
|
||||
Teams []ldap.TeamOrgGroupDTO `json:"teams"`
|
||||
}
|
||||
|
||||
// LDAPServerDTO is a serializer for LDAP server statuses
|
||||
type LDAPServerDTO struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Available bool `json:"available"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
package api
|
||||
|
||||
import "fmt"
|
||||
|
||||
type OrganizationNotFoundError struct {
|
||||
OrgID int64
|
||||
}
|
||||
|
||||
func (e *OrganizationNotFoundError) Error() string {
|
||||
return fmt.Sprintf("unable to find organization with ID '%d'", e.OrgID)
|
||||
}
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
contextmodel "github.com/grafana/grafana/pkg/services/contexthandler/model"
|
||||
"github.com/grafana/grafana/pkg/services/ldap"
|
||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||
"github.com/grafana/grafana/pkg/services/ldap/service"
|
||||
"github.com/grafana/grafana/pkg/services/login"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
"github.com/grafana/grafana/pkg/services/supportbundles"
|
||||
@@ -26,15 +27,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/web"
|
||||
)
|
||||
|
||||
var (
|
||||
getLDAPConfig = multildap.GetConfig
|
||||
newLDAP = multildap.New
|
||||
|
||||
errOrganizationNotFound = func(orgId int64) error {
|
||||
return fmt.Errorf("unable to find organization with ID '%d'", orgId)
|
||||
}
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
cfg *setting.Cfg
|
||||
userService user.Service
|
||||
@@ -44,11 +36,12 @@ type Service struct {
|
||||
orgService org.Service
|
||||
sessionService auth.UserTokenService
|
||||
log log.Logger
|
||||
ldapService service.LDAP
|
||||
}
|
||||
|
||||
func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessControl ac.AccessControl,
|
||||
userService user.Service, authInfoService login.AuthInfoService, ldapGroupsService ldap.Groups,
|
||||
loginService login.Service, orgService org.Service,
|
||||
loginService login.Service, orgService org.Service, ldapService service.LDAP,
|
||||
sessionService auth.UserTokenService, bundleRegistry supportbundles.Service) *Service {
|
||||
s := &Service{
|
||||
cfg: cfg,
|
||||
@@ -58,6 +51,7 @@ func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessContro
|
||||
loginService: loginService,
|
||||
orgService: orgService,
|
||||
sessionService: sessionService,
|
||||
ldapService: ldapService,
|
||||
log: log.New("ldap.api"),
|
||||
}
|
||||
|
||||
@@ -85,78 +79,6 @@ func ProvideService(cfg *setting.Cfg, router routing.RouteRegister, accessContro
|
||||
return s
|
||||
}
|
||||
|
||||
// LDAPAttribute is a serializer for user attributes mapped from LDAP. Is meant to display both the serialized value and the LDAP key we received it from.
|
||||
type LDAPAttribute struct {
|
||||
ConfigAttributeValue string `json:"cfgAttrValue"`
|
||||
LDAPAttributeValue string `json:"ldapValue"`
|
||||
}
|
||||
|
||||
// RoleDTO is a serializer for mapped roles from LDAP
|
||||
type LDAPRoleDTO struct {
|
||||
OrgId int64 `json:"orgId"`
|
||||
OrgName string `json:"orgName"`
|
||||
OrgRole org.RoleType `json:"orgRole"`
|
||||
GroupDN string `json:"groupDN"`
|
||||
}
|
||||
|
||||
// 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 []LDAPRoleDTO `json:"roles"`
|
||||
Teams []ldap.TeamOrgGroupDTO `json:"teams"`
|
||||
}
|
||||
|
||||
// LDAPServerDTO is a serializer for LDAP server statuses
|
||||
type LDAPServerDTO struct {
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Available bool `json:"available"`
|
||||
Error string `json:"error"`
|
||||
}
|
||||
|
||||
// FetchOrgs fetches the organization(s) information by executing a single query to the database. Then, populating the DTO with the information retrieved.
|
||||
func (user *LDAPUserDTO) FetchOrgs(ctx context.Context, orga org.Service) error {
|
||||
orgIds := []int64{}
|
||||
|
||||
for _, or := range user.OrgRoles {
|
||||
orgIds = append(orgIds, or.OrgId)
|
||||
}
|
||||
|
||||
q := &org.SearchOrgsQuery{}
|
||||
q.IDs = orgIds
|
||||
|
||||
result, err := orga.Search(ctx, q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
orgNamesById := map[int64]string{}
|
||||
for _, org := range result {
|
||||
orgNamesById[org.ID] = org.Name
|
||||
}
|
||||
|
||||
for i, orgDTO := range user.OrgRoles {
|
||||
if orgDTO.OrgId < 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
orgName := orgNamesById[orgDTO.OrgId]
|
||||
|
||||
if orgName != "" {
|
||||
user.OrgRoles[i].OrgName = orgName
|
||||
} else {
|
||||
return errOrganizationNotFound(orgDTO.OrgId)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// swagger:route POST /admin/ldap/reload admin_ldap reloadLDAPCfg
|
||||
//
|
||||
// Reloads the LDAP configuration.
|
||||
@@ -176,10 +98,10 @@ func (s *Service) ReloadLDAPCfg(c *contextmodel.ReqContext) response.Response {
|
||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||
}
|
||||
|
||||
err := ldap.ReloadConfig(s.cfg.LDAPConfigFilePath)
|
||||
if err != nil {
|
||||
if err := s.ldapService.ReloadConfig(); err != nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to reload LDAP config", err)
|
||||
}
|
||||
|
||||
return response.Success("LDAP config reloaded")
|
||||
}
|
||||
|
||||
@@ -202,18 +124,12 @@ func (s *Service) GetLDAPStatus(c *contextmodel.ReqContext) response.Response {
|
||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||
}
|
||||
|
||||
ldapConfig, err := getLDAPConfig(s.cfg)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration. Please verify the configuration and try again", err)
|
||||
}
|
||||
|
||||
ldap := newLDAP(ldapConfig.Servers)
|
||||
|
||||
if ldap == nil {
|
||||
ldapClient := s.ldapService.Client()
|
||||
if ldapClient == nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to find the LDAP server", nil)
|
||||
}
|
||||
|
||||
statuses, err := ldap.Ping()
|
||||
statuses, err := ldapClient.Ping()
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "Failed to connect to the LDAP server(s)", err)
|
||||
}
|
||||
@@ -255,9 +171,9 @@ func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Resp
|
||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||
}
|
||||
|
||||
ldapConfig, err := getLDAPConfig(s.cfg)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration. Please verify the configuration and try again", err)
|
||||
ldapClient := s.ldapService.Client()
|
||||
if ldapClient == nil {
|
||||
return response.Error(http.StatusInternalServerError, "Failed to find the LDAP server", nil)
|
||||
}
|
||||
|
||||
userId, err := strconv.ParseInt(web.Params(c.Req)[":id"], 10, 64)
|
||||
@@ -270,10 +186,10 @@ func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Resp
|
||||
usr, err := s.userService.GetByID(c.Req.Context(), &query)
|
||||
if err != nil { // validate the userId exists
|
||||
if errors.Is(err, user.ErrUserNotFound) {
|
||||
return response.Error(404, user.ErrUserNotFound.Error(), nil)
|
||||
return response.Error(http.StatusNotFound, user.ErrUserNotFound.Error(), nil)
|
||||
}
|
||||
|
||||
return response.Error(500, "Failed to get user", err)
|
||||
return response.Error(http.StatusInternalServerError, "Failed to get user", err)
|
||||
}
|
||||
|
||||
authModuleQuery := &login.GetAuthInfoQuery{UserId: usr.ID, AuthModule: login.LDAPAuthModule}
|
||||
@@ -285,8 +201,7 @@ func (s *Service) PostSyncUserWithLDAP(c *contextmodel.ReqContext) response.Resp
|
||||
return response.Error(500, "Failed to get user", err)
|
||||
}
|
||||
|
||||
ldapServer := newLDAP(ldapConfig.Servers)
|
||||
userInfo, _, err := ldapServer.User(usr.Login)
|
||||
userInfo, _, err := ldapClient.User(usr.Login)
|
||||
if err != nil {
|
||||
if errors.Is(err, multildap.ErrDidNotFindUser) { // User was not in the LDAP server - we need to take action:
|
||||
if s.cfg.AdminUser == usr.Login { // User is *the* Grafana Admin. We cannot disable it.
|
||||
@@ -351,20 +266,14 @@ func (s *Service) GetUserFromLDAP(c *contextmodel.ReqContext) response.Response
|
||||
return response.Error(http.StatusBadRequest, "LDAP is not enabled", nil)
|
||||
}
|
||||
|
||||
ldapConfig, err := getLDAPConfig(s.cfg)
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "Failed to obtain the LDAP configuration", err)
|
||||
}
|
||||
|
||||
multiLDAP := newLDAP(ldapConfig.Servers)
|
||||
ldapClient := s.ldapService.Client()
|
||||
|
||||
username := web.Params(c.Req)[":username"]
|
||||
|
||||
if len(username) == 0 {
|
||||
return response.Error(http.StatusBadRequest, "Validation error. You must specify an username", nil)
|
||||
}
|
||||
|
||||
user, serverConfig, err := multiLDAP.User(username)
|
||||
user, serverConfig, err := ldapClient.User(username)
|
||||
if user == nil || err != nil {
|
||||
return response.Error(http.StatusNotFound, "No user was found in the LDAP server(s) with that username", err)
|
||||
}
|
||||
@@ -409,7 +318,7 @@ func (s *Service) GetUserFromLDAP(c *contextmodel.ReqContext) response.Response
|
||||
}
|
||||
|
||||
s.log.Debug("mapping org roles", "orgsRoles", u.OrgRoles)
|
||||
if err := u.FetchOrgs(c.Req.Context(), s.orgService); err != nil {
|
||||
if err := u.fetchOrgs(c.Req.Context(), s.orgService); err != nil {
|
||||
return response.Error(http.StatusBadRequest, "An organization was not found - Please verify your LDAP configuration", err)
|
||||
}
|
||||
|
||||
@@ -435,16 +344,40 @@ func splitName(name string) (string, string) {
|
||||
}
|
||||
}
|
||||
|
||||
// swagger:parameters getUserFromLDAP
|
||||
type GetLDAPUserParams struct {
|
||||
// in:path
|
||||
// required:true
|
||||
UserName string `json:"user_name"`
|
||||
}
|
||||
// fetchOrgs fetches the organization(s) information by executing a single query to the database. Then, populating the DTO with the information retrieved.
|
||||
func (user *LDAPUserDTO) fetchOrgs(ctx context.Context, orga org.Service) error {
|
||||
orgIds := []int64{}
|
||||
|
||||
// swagger:parameters postSyncUserWithLDAP
|
||||
type SyncLDAPUserParams struct {
|
||||
// in:path
|
||||
// required:true
|
||||
UserID int64 `json:"user_id"`
|
||||
for _, or := range user.OrgRoles {
|
||||
orgIds = append(orgIds, or.OrgId)
|
||||
}
|
||||
|
||||
q := &org.SearchOrgsQuery{}
|
||||
q.IDs = orgIds
|
||||
|
||||
result, err := orga.Search(ctx, q)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
orgNamesById := map[int64]string{}
|
||||
for _, org := range result {
|
||||
orgNamesById[org.ID] = org.Name
|
||||
}
|
||||
|
||||
for i, orgDTO := range user.OrgRoles {
|
||||
if orgDTO.OrgId < 1 {
|
||||
continue
|
||||
}
|
||||
|
||||
orgName := orgNamesById[orgDTO.OrgId]
|
||||
|
||||
if orgName != "" {
|
||||
user.OrgRoles[i].OrgName = orgName
|
||||
} else {
|
||||
return &OrganizationNotFoundError{orgDTO.OrgId}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/services/auth/authtest"
|
||||
"github.com/grafana/grafana/pkg/services/ldap"
|
||||
"github.com/grafana/grafana/pkg/services/ldap/multildap"
|
||||
"github.com/grafana/grafana/pkg/services/ldap/service"
|
||||
"github.com/grafana/grafana/pkg/services/login"
|
||||
"github.com/grafana/grafana/pkg/services/login/logintest"
|
||||
"github.com/grafana/grafana/pkg/services/org"
|
||||
@@ -69,6 +70,7 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
||||
ldap.ProvideGroupsService(),
|
||||
&logintest.LoginServiceFake{},
|
||||
&orgtest.FakeOrgService{},
|
||||
service.NewLDAPFakeService(),
|
||||
authtest.NewFakeUserAuthTokenService(),
|
||||
supportbundlestest.NewFakeBundleService(),
|
||||
)
|
||||
@@ -83,20 +85,16 @@ func setupAPITest(t *testing.T, opts ...func(a *Service)) (*Service, *webtest.Se
|
||||
}
|
||||
|
||||
func TestGetUserFromLDAPAPIEndpoint_UserNotFound(t *testing.T) {
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{
|
||||
UserSearchResult: nil,
|
||||
}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.orgService = &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: []*org.OrgDTO{},
|
||||
}
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{
|
||||
UserSearchResult: nil,
|
||||
},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewGetRequest("/api/admin/ldap/user-that-does-not-exist")
|
||||
@@ -147,13 +145,6 @@ func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
||||
},
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
}
|
||||
}
|
||||
|
||||
mockOrgSearchResult := []*org.OrgDTO{
|
||||
{ID: 1, Name: "Main Org."},
|
||||
}
|
||||
@@ -162,12 +153,15 @@ func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
||||
a.orgService = &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: mockOrgSearchResult,
|
||||
}
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
req := server.NewGetRequest("/api/admin/ldap/johndoe")
|
||||
webtest.RequestWithSignedInUser(req, &user.SignedInUser{
|
||||
OrgID: 1,
|
||||
@@ -225,21 +219,17 @@ func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
|
||||
{ID: 1, Name: "Main Org."},
|
||||
}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.orgService = &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: mockOrgSearchResult,
|
||||
}
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewGetRequest("/api/admin/ldap/johndoe")
|
||||
@@ -314,21 +304,17 @@ func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
|
||||
{ID: 1, Name: "Main Org."},
|
||||
}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.orgService = &orgtest.FakeOrgService{
|
||||
ExpectedOrgs: mockOrgSearchResult,
|
||||
}
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{
|
||||
UserSearchResult: userSearchResult,
|
||||
UserSearchConfig: userSearchConfig,
|
||||
},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewGetRequest("/api/admin/ldap/johndoe")
|
||||
@@ -378,15 +364,11 @@ func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
|
||||
{Host: "10.0.0.5", Port: 361, Available: false, Error: errors.New("something is awfully wrong")},
|
||||
}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewGetRequest("/api/admin/ldap/status")
|
||||
@@ -418,18 +400,14 @@ func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
|
||||
userServiceMock := usertest.NewUserServiceFake()
|
||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{UserSearchResult: &login.ExternalUserInfo{
|
||||
Login: "ldap-daniel",
|
||||
}}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.userService = userServiceMock
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{UserSearchResult: &login.ExternalUserInfo{
|
||||
Login: "ldap-daniel",
|
||||
}},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewPostRequest("/api/admin/ldap/sync/34", nil)
|
||||
@@ -459,16 +437,12 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
|
||||
userServiceMock := usertest.NewUserServiceFake()
|
||||
userServiceMock.ExpectedError = user.ErrUserNotFound
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.userService = userServiceMock
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewPostRequest("/api/admin/ldap/sync/34", nil)
|
||||
@@ -498,17 +472,13 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
|
||||
userServiceMock := usertest.NewUserServiceFake()
|
||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.userService = userServiceMock
|
||||
a.cfg.AdminUser = "ldap-daniel"
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewPostRequest("/api/admin/ldap/sync/34", nil)
|
||||
@@ -536,17 +506,13 @@ func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
||||
userServiceMock := usertest.NewUserServiceFake()
|
||||
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser}
|
||||
}
|
||||
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.userService = userServiceMock
|
||||
a.authInfoService = &logintest.AuthInfoServiceFake{ExpectedExternalUser: &login.ExternalUserInfo{IsDisabled: true, UserId: 34}}
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{UserSearchError: multildap.ErrDidNotFindUser},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
|
||||
req := server.NewPostRequest("/api/admin/ldap/sync/34", nil)
|
||||
@@ -589,18 +555,6 @@ search_base_dns = ["dc=grafana,dc=org"]`)
|
||||
errF = f.Close()
|
||||
require.NoError(t, errF)
|
||||
|
||||
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
||||
return &ldap.Config{}, nil
|
||||
}
|
||||
|
||||
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
||||
return &LDAPMock{
|
||||
UserSearchResult: &login.ExternalUserInfo{
|
||||
Login: "ldap-daniel",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
type testCase struct {
|
||||
desc string
|
||||
method string
|
||||
@@ -688,6 +642,12 @@ search_base_dns = ["dc=grafana,dc=org"]`)
|
||||
_, server := setupAPITest(t, func(a *Service) {
|
||||
a.userService = &usertest.FakeUserService{ExpectedUser: &user.User{Login: "ldap-daniel", ID: 1}}
|
||||
a.cfg.LDAPConfigFilePath = ldapConfigFile
|
||||
a.ldapService = &service.LDAPFakeService{
|
||||
ExpectedClient: &LDAPMock{UserSearchResult: &login.ExternalUserInfo{
|
||||
Login: "ldap-daniel",
|
||||
}},
|
||||
ExpectedConfig: &ldap.Config{},
|
||||
}
|
||||
})
|
||||
// Add minimal setup to pass handler
|
||||
res, err := server.Send(
|
||||
|
||||
@@ -9,19 +9,17 @@ import (
|
||||
"github.com/BurntSushi/toml"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/supportbundles"
|
||||
"github.com/grafana/grafana/pkg/setting"
|
||||
)
|
||||
|
||||
func (s *Service) supportBundleCollector(context.Context) (*supportbundles.SupportItem, error) {
|
||||
bWriter := bytes.NewBuffer(nil)
|
||||
bWriter.WriteString("# LDAP information\n\n")
|
||||
|
||||
ldapConfig, err := getLDAPConfig(s.cfg)
|
||||
|
||||
ldapConfig := s.ldapService.Config()
|
||||
if ldapConfig != nil {
|
||||
bWriter.WriteString("## LDAP Status\n")
|
||||
|
||||
ldapClient := newLDAP(ldapConfig.Servers)
|
||||
ldapClient := s.ldapService.Client()
|
||||
|
||||
ldapStatus, err := ldapClient.Ping()
|
||||
if err != nil {
|
||||
@@ -66,7 +64,7 @@ func (s *Service) supportBundleCollector(context.Context) (*supportbundles.Suppo
|
||||
errM := toml.NewEncoder(bWriter).Encode(ldapConfig)
|
||||
if errM != nil {
|
||||
bWriter.WriteString(
|
||||
fmt.Sprintf("Unable to encode LDAP configuration \n Err: %s", err))
|
||||
fmt.Sprintf("Unable to encode LDAP configuration \n Err: %s", errM))
|
||||
}
|
||||
bWriter.WriteString("```\n\n")
|
||||
|
||||
@@ -77,9 +75,9 @@ func (s *Service) supportBundleCollector(context.Context) (*supportbundles.Suppo
|
||||
bWriter.WriteString(fmt.Sprintf("enabled = %v\n", s.cfg.LDAPEnabled))
|
||||
bWriter.WriteString(fmt.Sprintf("config_file = %s\n", s.cfg.LDAPConfigFilePath))
|
||||
bWriter.WriteString(fmt.Sprintf("allow_sign_up = %v\n", s.cfg.LDAPAllowSignup))
|
||||
bWriter.WriteString(fmt.Sprintf("sync_cron = %s\n", setting.LDAPSyncCron))
|
||||
bWriter.WriteString(fmt.Sprintf("active_sync_enabled = %v\n", setting.LDAPActiveSyncEnabled))
|
||||
bWriter.WriteString(fmt.Sprintf("skip_org_role_sync = %v\n", setting.LDAPSkipOrgRoleSync))
|
||||
bWriter.WriteString(fmt.Sprintf("sync_cron = %s\n", s.cfg.LDAPSyncCron))
|
||||
bWriter.WriteString(fmt.Sprintf("active_sync_enabled = %v\n", s.cfg.LDAPActiveSyncEnabled))
|
||||
bWriter.WriteString(fmt.Sprintf("skip_org_role_sync = %v\n", s.cfg.LDAPSkipOrgRoleSync))
|
||||
|
||||
bWriter.WriteString("```\n\n")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user