mirror of
https://github.com/grafana/grafana.git
synced 2024-12-28 18:01:40 -06:00
7ce7c9b64c
* Chore: Move SearchOrgs to org service * Fix lint * Fix lint 2
631 lines
17 KiB
Go
631 lines
17 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"errors"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/grafana/grafana/pkg/api/response"
|
|
"github.com/grafana/grafana/pkg/api/routing"
|
|
"github.com/grafana/grafana/pkg/models"
|
|
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
|
"github.com/grafana/grafana/pkg/services/auth"
|
|
"github.com/grafana/grafana/pkg/services/ldap"
|
|
"github.com/grafana/grafana/pkg/services/login/loginservice"
|
|
"github.com/grafana/grafana/pkg/services/login/logintest"
|
|
"github.com/grafana/grafana/pkg/services/multildap"
|
|
"github.com/grafana/grafana/pkg/services/org"
|
|
"github.com/grafana/grafana/pkg/services/org/orgtest"
|
|
"github.com/grafana/grafana/pkg/services/sqlstore/mockstore"
|
|
"github.com/grafana/grafana/pkg/services/user"
|
|
"github.com/grafana/grafana/pkg/services/user/usertest"
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
)
|
|
|
|
type LDAPMock struct {
|
|
Results []*models.ExternalUserInfo
|
|
}
|
|
|
|
var userSearchResult *models.ExternalUserInfo
|
|
var userSearchConfig ldap.ServerConfig
|
|
var userSearchError error
|
|
var pingResult []*multildap.ServerStatus
|
|
var pingError error
|
|
|
|
func (m *LDAPMock) Ping() ([]*multildap.ServerStatus, error) {
|
|
return pingResult, pingError
|
|
}
|
|
|
|
func (m *LDAPMock) Login(query *models.LoginUserQuery) (*models.ExternalUserInfo, error) {
|
|
return &models.ExternalUserInfo{}, nil
|
|
}
|
|
|
|
func (m *LDAPMock) Users(logins []string) ([]*models.ExternalUserInfo, error) {
|
|
s := []*models.ExternalUserInfo{}
|
|
return s, nil
|
|
}
|
|
|
|
func (m *LDAPMock) User(login string) (*models.ExternalUserInfo, ldap.ServerConfig, error) {
|
|
return userSearchResult, userSearchConfig, userSearchError
|
|
}
|
|
|
|
// ***
|
|
// GetUserFromLDAP tests
|
|
// ***
|
|
|
|
func getUserFromLDAPContext(t *testing.T, requestURL string, searchOrgRst []*org.OrgDTO) *scenarioContext {
|
|
t.Helper()
|
|
|
|
sc := setupScenarioContext(t, requestURL)
|
|
|
|
origLDAP := setting.LDAPEnabled
|
|
setting.LDAPEnabled = true
|
|
t.Cleanup(func() { setting.LDAPEnabled = origLDAP })
|
|
|
|
hs := &HTTPServer{Cfg: setting.NewCfg(), ldapGroups: ldap.ProvideGroupsService(), orgService: &orgtest.FakeOrgService{ExpectedOrgs: searchOrgRst}}
|
|
|
|
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
|
sc.context = c
|
|
return hs.GetUserFromLDAP(c)
|
|
})
|
|
|
|
sc.m.Get("/api/admin/ldap/:username", sc.defaultHandler)
|
|
|
|
sc.resp = httptest.NewRecorder()
|
|
req, _ := http.NewRequest(http.MethodGet, requestURL, nil)
|
|
sc.req = req
|
|
sc.exec()
|
|
|
|
return sc
|
|
}
|
|
|
|
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
|
|
|
|
sc := getUserFromLDAPContext(t, "/api/admin/ldap/user-that-does-not-exist", []*org.OrgDTO{})
|
|
|
|
require.Equal(t, sc.resp.Code, http.StatusNotFound)
|
|
assert.JSONEq(t, "{\"message\":\"No user was found in the LDAP server(s) with that username\"}", sc.resp.Body.String())
|
|
}
|
|
|
|
func TestGetUserFromLDAPAPIEndpoint_OrgNotfound(t *testing.T) {
|
|
isAdmin := true
|
|
userSearchResult = &models.ExternalUserInfo{
|
|
Name: "John Doe",
|
|
Email: "john.doe@example.com",
|
|
Login: "johndoe",
|
|
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org"},
|
|
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin, 2: org.RoleViewer},
|
|
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: org.RoleAdmin,
|
|
},
|
|
{
|
|
GroupDN: "cn=admins,ou=groups,dc=grafana,dc=org",
|
|
OrgId: 2,
|
|
OrgRole: org.RoleViewer,
|
|
},
|
|
},
|
|
}
|
|
|
|
mockOrgSearchResult := []*org.OrgDTO{
|
|
{ID: 1, Name: "Main Org."},
|
|
}
|
|
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
sc := getUserFromLDAPContext(t, "/api/admin/ldap/johndoe", mockOrgSearchResult)
|
|
|
|
require.Equal(t, http.StatusBadRequest, sc.resp.Code)
|
|
|
|
var res map[string]interface{}
|
|
err := json.Unmarshal(sc.resp.Body.Bytes(), &res)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "unable to find organization with ID '2'", res["error"])
|
|
assert.Equal(t, "An organization was not found - Please verify your LDAP configuration", res["message"])
|
|
}
|
|
|
|
func TestGetUserFromLDAPAPIEndpoint(t *testing.T) {
|
|
isAdmin := true
|
|
userSearchResult = &models.ExternalUserInfo{
|
|
Name: "John Doe",
|
|
Email: "john.doe@example.com",
|
|
Login: "johndoe",
|
|
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org", "another-group-not-matched"},
|
|
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin},
|
|
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: org.RoleAdmin,
|
|
},
|
|
{
|
|
GroupDN: "cn=admins2,ou=groups,dc=grafana,dc=org",
|
|
OrgId: 1,
|
|
OrgRole: org.RoleAdmin,
|
|
},
|
|
},
|
|
}
|
|
|
|
mockOrgSearchResult := []*org.OrgDTO{
|
|
{ID: 1, Name: "Main Org."},
|
|
}
|
|
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
sc := getUserFromLDAPContext(t, "/api/admin/ldap/johndoe", mockOrgSearchResult)
|
|
|
|
assert.Equal(t, sc.resp.Code, http.StatusOK)
|
|
|
|
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" },
|
|
{ "orgId": 0, "orgRole": "", "orgName": "", "groupDN": "another-group-not-matched" }
|
|
],
|
|
"teams": null
|
|
}
|
|
`
|
|
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
func TestGetUserFromLDAPAPIEndpoint_WithTeamHandler(t *testing.T) {
|
|
isAdmin := true
|
|
userSearchResult = &models.ExternalUserInfo{
|
|
Name: "John Doe",
|
|
Email: "john.doe@example.com",
|
|
Login: "johndoe",
|
|
Groups: []string{"cn=admins,ou=groups,dc=grafana,dc=org"},
|
|
OrgRoles: map[int64]org.RoleType{1: org.RoleAdmin},
|
|
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: org.RoleAdmin,
|
|
},
|
|
},
|
|
}
|
|
|
|
mockOrgSearchResult := []*org.OrgDTO{
|
|
{ID: 1, Name: "Main Org."},
|
|
}
|
|
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
sc := getUserFromLDAPContext(t, "/api/admin/ldap/johndoe", mockOrgSearchResult)
|
|
|
|
require.Equal(t, sc.resp.Code, http.StatusOK)
|
|
|
|
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": null
|
|
}
|
|
`
|
|
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
// ***
|
|
// GetLDAPStatus tests
|
|
// ***
|
|
|
|
func getLDAPStatusContext(t *testing.T) *scenarioContext {
|
|
t.Helper()
|
|
|
|
requestURL := "/api/admin/ldap/status"
|
|
sc := setupScenarioContext(t, requestURL)
|
|
|
|
ldap := setting.LDAPEnabled
|
|
setting.LDAPEnabled = true
|
|
t.Cleanup(func() { setting.LDAPEnabled = ldap })
|
|
|
|
hs := &HTTPServer{Cfg: setting.NewCfg()}
|
|
|
|
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
|
sc.context = c
|
|
return hs.GetLDAPStatus(c)
|
|
})
|
|
|
|
sc.m.Get("/api/admin/ldap/status", sc.defaultHandler)
|
|
|
|
sc.resp = httptest.NewRecorder()
|
|
req, _ := http.NewRequest(http.MethodGet, requestURL, nil)
|
|
sc.req = req
|
|
sc.exec()
|
|
|
|
return sc
|
|
}
|
|
|
|
func TestGetLDAPStatusAPIEndpoint(t *testing.T) {
|
|
pingResult = []*multildap.ServerStatus{
|
|
{Host: "10.0.0.3", Port: 361, Available: true, Error: nil},
|
|
{Host: "10.0.0.3", Port: 362, Available: true, Error: nil},
|
|
{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{}
|
|
}
|
|
|
|
sc := getLDAPStatusContext(t)
|
|
|
|
require.Equal(t, http.StatusOK, sc.resp.Code)
|
|
|
|
expected := `
|
|
[
|
|
{ "host": "10.0.0.3", "port": 361, "available": true, "error": "" },
|
|
{ "host": "10.0.0.3", "port": 362, "available": true, "error": "" },
|
|
{ "host": "10.0.0.5", "port": 361, "available": false, "error": "something is awfully wrong" }
|
|
]
|
|
`
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
// ***
|
|
// PostSyncUserWithLDAP tests
|
|
// ***
|
|
|
|
func postSyncUserWithLDAPContext(t *testing.T, requestURL string, preHook func(*testing.T, *scenarioContext), userService user.Service) *scenarioContext {
|
|
t.Helper()
|
|
|
|
sc := setupScenarioContext(t, requestURL)
|
|
sc.authInfoService = &logintest.AuthInfoServiceFake{}
|
|
|
|
ldap := setting.LDAPEnabled
|
|
t.Cleanup(func() {
|
|
setting.LDAPEnabled = ldap
|
|
})
|
|
setting.LDAPEnabled = true
|
|
|
|
hs := &HTTPServer{
|
|
Cfg: sc.cfg,
|
|
AuthTokenService: auth.NewFakeUserAuthTokenService(),
|
|
Login: loginservice.LoginServiceMock{},
|
|
authInfoService: sc.authInfoService,
|
|
userService: userService,
|
|
}
|
|
|
|
sc.defaultHandler = routing.Wrap(func(c *models.ReqContext) response.Response {
|
|
sc.context = c
|
|
return hs.PostSyncUserWithLDAP(c)
|
|
})
|
|
|
|
sc.m.Post("/api/admin/ldap/sync/:id", sc.defaultHandler)
|
|
|
|
sc.resp = httptest.NewRecorder()
|
|
req, err := http.NewRequest(http.MethodPost, requestURL, nil)
|
|
require.NoError(t, err)
|
|
|
|
preHook(t, sc)
|
|
|
|
sc.req = req
|
|
sc.exec()
|
|
|
|
return sc
|
|
}
|
|
|
|
func TestPostSyncUserWithLDAPAPIEndpoint_Success(t *testing.T) {
|
|
userServiceMock := usertest.NewUserServiceFake()
|
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
|
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
userSearchResult = &models.ExternalUserInfo{
|
|
Login: "ldap-daniel",
|
|
}
|
|
}, userServiceMock)
|
|
|
|
assert.Equal(t, http.StatusOK, sc.resp.Code)
|
|
|
|
expected := `
|
|
{
|
|
"message": "User synced successfully"
|
|
}
|
|
`
|
|
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotFound(t *testing.T) {
|
|
userServiceMock := usertest.NewUserServiceFake()
|
|
userServiceMock.ExpectedError = user.ErrUserNotFound
|
|
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
}, userServiceMock)
|
|
|
|
assert.Equal(t, http.StatusNotFound, sc.resp.Code)
|
|
|
|
expected := `
|
|
{
|
|
"message": "user not found"
|
|
}
|
|
`
|
|
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenGrafanaAdmin(t *testing.T) {
|
|
userServiceMock := usertest.NewUserServiceFake()
|
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
|
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
userSearchError = multildap.ErrDidNotFindUser
|
|
|
|
sc.cfg.AdminUser = "ldap-daniel"
|
|
}, userServiceMock)
|
|
assert.Equal(t, http.StatusBadRequest, sc.resp.Code)
|
|
|
|
var res map[string]interface{}
|
|
err := json.Unmarshal(sc.resp.Body.Bytes(), &res)
|
|
assert.NoError(t, err)
|
|
assert.Equal(t, "did not find a user", res["error"])
|
|
assert.Equal(t, "Refusing to sync grafana super admin \"ldap-daniel\" - it would be disabled", res["message"])
|
|
}
|
|
|
|
func TestPostSyncUserWithLDAPAPIEndpoint_WhenUserNotInLDAP(t *testing.T) {
|
|
userServiceMock := usertest.NewUserServiceFake()
|
|
userServiceMock.ExpectedUser = &user.User{Login: "ldap-daniel", ID: 34}
|
|
sc := postSyncUserWithLDAPContext(t, "/api/admin/ldap/sync/34", func(t *testing.T, sc *scenarioContext) {
|
|
sc.authInfoService.ExpectedExternalUser = &models.ExternalUserInfo{IsDisabled: true, UserId: 34}
|
|
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
|
|
return &ldap.Config{}, nil
|
|
}
|
|
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
userSearchResult = nil
|
|
userSearchError = multildap.ErrDidNotFindUser
|
|
}, userServiceMock)
|
|
|
|
assert.Equal(t, http.StatusBadRequest, sc.resp.Code)
|
|
|
|
expected := `
|
|
{
|
|
"message": "User not found in LDAP. Disabled the user without updating information"
|
|
}
|
|
`
|
|
|
|
assert.JSONEq(t, expected, sc.resp.Body.String())
|
|
}
|
|
|
|
// ***
|
|
// Access control tests for ldap endpoints
|
|
// ***
|
|
|
|
func TestLDAP_AccessControl(t *testing.T) {
|
|
tests := []accessControlTestCase{
|
|
{
|
|
url: "/api/admin/ldap/reload",
|
|
method: http.MethodPost,
|
|
desc: "ReloadLDAPCfg should return 200 for user with correct permissions",
|
|
expectedCode: http.StatusOK,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: accesscontrol.ActionLDAPConfigReload},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/reload",
|
|
method: http.MethodPost,
|
|
desc: "ReloadLDAPCfg should return 403 for user without required permissions",
|
|
expectedCode: http.StatusForbidden,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: "wrong"},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/status",
|
|
method: http.MethodGet,
|
|
desc: "GetLDAPStatus should return 200 for user without required permissions",
|
|
expectedCode: http.StatusOK,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: accesscontrol.ActionLDAPStatusRead},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/status",
|
|
method: http.MethodGet,
|
|
desc: "GetLDAPStatus should return 200 for user without required permissions",
|
|
expectedCode: http.StatusForbidden,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: "wrong"},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/test",
|
|
method: http.MethodGet,
|
|
desc: "GetUserFromLDAP should return 200 for user with required permissions",
|
|
expectedCode: http.StatusOK,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: accesscontrol.ActionLDAPUsersRead},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/test",
|
|
method: http.MethodGet,
|
|
desc: "GetUserFromLDAP should return 403 for user without required permissions",
|
|
expectedCode: http.StatusForbidden,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: "wrong"},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/sync/1",
|
|
method: http.MethodPost,
|
|
desc: "PostSyncUserWithLDAP should return 200 for user without required permissions",
|
|
expectedCode: http.StatusOK,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: accesscontrol.ActionLDAPUsersSync},
|
|
},
|
|
},
|
|
{
|
|
url: "/api/admin/ldap/sync/1",
|
|
method: http.MethodPost,
|
|
desc: "PostSyncUserWithLDAP should return 200 for user without required permissions",
|
|
expectedCode: http.StatusForbidden,
|
|
permissions: []accesscontrol.Permission{
|
|
{Action: "wrong"},
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, test := range tests {
|
|
t.Run(test.desc, func(t *testing.T) {
|
|
enabled := setting.LDAPEnabled
|
|
configFile := setting.LDAPConfigFile
|
|
|
|
t.Cleanup(func() {
|
|
setting.LDAPEnabled = enabled
|
|
setting.LDAPConfigFile = configFile
|
|
})
|
|
|
|
setting.LDAPEnabled = true
|
|
path, err := filepath.Abs("../../conf/ldap.toml")
|
|
assert.NoError(t, err)
|
|
setting.LDAPConfigFile = path
|
|
|
|
cfg := setting.NewCfg()
|
|
cfg.LDAPEnabled = true
|
|
sc, hs := setupAccessControlScenarioContext(t, cfg, test.url, test.permissions)
|
|
hs.SQLStore = &mockstore.SQLStoreMock{ExpectedUser: &user.User{}}
|
|
hs.userService = &usertest.FakeUserService{ExpectedUser: &user.User{}}
|
|
hs.authInfoService = &logintest.AuthInfoServiceFake{}
|
|
hs.Login = &loginservice.LoginServiceMock{}
|
|
hs.orgService = &orgtest.FakeOrgService{}
|
|
sc.resp = httptest.NewRecorder()
|
|
sc.req, err = http.NewRequest(test.method, test.url, nil)
|
|
assert.NoError(t, err)
|
|
|
|
// Add minimal setup to pass handler
|
|
userSearchResult = &models.ExternalUserInfo{}
|
|
userSearchError = nil
|
|
newLDAP = func(_ []*ldap.ServerConfig) multildap.IMultiLDAP {
|
|
return &LDAPMock{}
|
|
}
|
|
|
|
sc.exec()
|
|
assert.Equal(t, test.expectedCode, sc.resp.Code)
|
|
})
|
|
}
|
|
}
|