The open and composable observability and data visualization platform. Visualize metrics, logs, and traces from multiple sources like Prometheus, Loki, Elasticsearch, InfluxDB, Postgres and many more.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 
grafana/pkg/login/ldap_login_test.go

182 lines
3.7 KiB

package login
import (
"errors"
"testing"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
"github.com/grafana/grafana/pkg/services/multildap"
"github.com/grafana/grafana/pkg/setting"
. "github.com/smartystreets/goconvey/convey"
)
var errTest = errors.New("test error")
func TestLDAPLogin(t *testing.T) {
Convey("Login using ldap", t, func() {
Convey("Given ldap enabled and no server configured", func() {
setting.LDAPEnabled = true
LDAPLoginScenario("When login", func(sc *LDAPLoginScenarioContext) {
sc.withLoginResult(false)
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
config := &ldap.Config{
Servers: []*ldap.ServerConfig{},
}
return config, nil
}
enabled, err := loginUsingLDAP(sc.loginUserQuery)
Convey("it should return true", func() {
So(enabled, ShouldBeTrue)
})
Convey("it should return no LDAP servers error", func() {
So(err, ShouldEqual, errTest)
})
Convey("it should not call ldap login", func() {
So(sc.LDAPAuthenticatorMock.loginCalled, ShouldBeTrue)
})
})
})
Convey("Given ldap disabled", func() {
setting.LDAPEnabled = false
LDAPLoginScenario("When login", func(sc *LDAPLoginScenarioContext) {
sc.withLoginResult(false)
enabled, err := loginUsingLDAP(&models.LoginUserQuery{
Username: "user",
Password: "pwd",
})
Convey("it should return false", func() {
So(enabled, ShouldBeFalse)
})
Convey("it should not return error", func() {
So(err, ShouldBeNil)
})
Convey("it should not call ldap login", func() {
So(sc.LDAPAuthenticatorMock.loginCalled, ShouldBeFalse)
})
})
})
})
}
type mockAuth struct {
validLogin bool
loginCalled bool
pingCalled bool
}
func (auth *mockAuth) Ping() ([]*multildap.ServerStatus, error) {
auth.pingCalled = true
return nil, nil
}
func (auth *mockAuth) Login(query *models.LoginUserQuery) (
*models.ExternalUserInfo,
error,
) {
auth.loginCalled = true
if !auth.validLogin {
return nil, errTest
}
return nil, nil
}
func (auth *mockAuth) Users(logins []string) (
[]*models.ExternalUserInfo,
error,
) {
return nil, nil
}
func (auth *mockAuth) User(login string) (
*models.ExternalUserInfo,
ldap.ServerConfig,
error,
) {
return nil, ldap.ServerConfig{}, nil
}
func (auth *mockAuth) Add(dn string, values map[string][]string) error {
return nil
}
func (auth *mockAuth) Remove(dn string) error {
return nil
}
func mockLDAPAuthenticator(valid bool) *mockAuth {
mock := &mockAuth{
validLogin: valid,
}
newLDAP = func(servers []*ldap.ServerConfig) multildap.IMultiLDAP {
return mock
}
return mock
}
type LDAPLoginScenarioContext struct {
loginUserQuery *models.LoginUserQuery
LDAPAuthenticatorMock *mockAuth
}
type LDAPLoginScenarioFunc func(c *LDAPLoginScenarioContext)
func LDAPLoginScenario(desc string, fn LDAPLoginScenarioFunc) {
Convey(desc, func() {
mock := &mockAuth{}
sc := &LDAPLoginScenarioContext{
loginUserQuery: &models.LoginUserQuery{
Username: "user",
Password: "pwd",
IpAddress: "192.168.1.1:56433",
},
LDAPAuthenticatorMock: mock,
}
origNewLDAP := newLDAP
origGetLDAPConfig := getLDAPConfig
defer func() {
newLDAP = origNewLDAP
getLDAPConfig = origGetLDAPConfig
}()
getLDAPConfig = func(*setting.Cfg) (*ldap.Config, error) {
config := &ldap.Config{
Servers: []*ldap.ServerConfig{
{
Host: "",
},
},
}
return config, nil
}
newLDAP = func(server []*ldap.ServerConfig) multildap.IMultiLDAP {
return mock
}
fn(sc)
})
}
func (sc *LDAPLoginScenarioContext) withLoginResult(valid bool) {
sc.LDAPAuthenticatorMock = mockLDAPAuthenticator(valid)
}