Files
grafana/pkg/login/auth_test.go

244 lines
8.0 KiB
Go
Raw Normal View History

2018-01-26 10:41:41 +01:00
package login
import (
"errors"
"testing"
. "github.com/smartystreets/goconvey/convey"
"github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/services/ldap"
2018-01-26 10:41:41 +01:00
)
func TestAuthenticateUser(t *testing.T) {
Convey("Authenticate user", t, func() {
authScenario("When a user authenticates without setting a password", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(nil, sc)
mockLoginUsingLDAP(false, nil, sc)
loginQuery := models.LoginUserQuery{
Username: "user",
Password: "",
}
err := authenticateUser(&loginQuery)
Convey("login should fail", func() {
So(sc.grafanaLoginWasCalled, ShouldBeFalse)
So(sc.ldapLoginWasCalled, ShouldBeFalse)
So(err, ShouldEqual, ErrPasswordEmpty)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "")
})
})
2018-01-26 10:41:41 +01:00
authScenario("When a user authenticates having too many login attempts", func(sc *authScenarioContext) {
mockLoginAttemptValidation(ErrTooManyLoginAttempts, sc)
mockLoginUsingGrafanaDB(nil, sc)
mockLoginUsingLDAP(true, nil, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, ErrTooManyLoginAttempts)
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeFalse)
So(sc.ldapLoginWasCalled, ShouldBeFalse)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When grafana user authenticate with valid credentials", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(nil, sc)
mockLoginUsingLDAP(true, ErrInvalidCredentials, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, nil)
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeFalse)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "grafana")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When grafana user authenticate and unexpected error occurs", func(sc *authScenarioContext) {
customErr := errors.New("custom")
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(customErr, sc)
mockLoginUsingLDAP(true, ErrInvalidCredentials, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, customErr)
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeFalse)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "grafana")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When a non-existing grafana user authenticate and ldap disabled", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(models.ErrUserNotFound, sc)
mockLoginUsingLDAP(false, nil, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, models.ErrUserNotFound)
2018-01-26 10:41:41 +01:00
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeTrue)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When a non-existing grafana user authenticate and invalid ldap credentials", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(models.ErrUserNotFound, sc)
mockLoginUsingLDAP(true, ldap.ErrInvalidCredentials, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, ErrInvalidCredentials)
2018-01-26 10:41:41 +01:00
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeTrue)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeTrue)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "ldap")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When a non-existing grafana user authenticate and valid ldap credentials", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(models.ErrUserNotFound, sc)
mockLoginUsingLDAP(true, nil, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldBeNil)
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeTrue)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "ldap")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When a non-existing grafana user authenticate and ldap returns unexpected error", func(sc *authScenarioContext) {
customErr := errors.New("custom")
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(models.ErrUserNotFound, sc)
mockLoginUsingLDAP(true, customErr, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, customErr)
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeTrue)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeFalse)
So(sc.loginUserQuery.AuthModule, ShouldEqual, "ldap")
2018-01-26 10:41:41 +01:00
})
})
authScenario("When grafana user authenticate with invalid credentials and invalid ldap credentials", func(sc *authScenarioContext) {
mockLoginAttemptValidation(nil, sc)
mockLoginUsingGrafanaDB(ErrInvalidCredentials, sc)
mockLoginUsingLDAP(true, ldap.ErrInvalidCredentials, sc)
2018-01-26 10:41:41 +01:00
mockSaveInvalidLoginAttempt(sc)
err := authenticateUser(sc.loginUserQuery)
2018-01-26 10:41:41 +01:00
Convey("it should result in", func() {
So(err, ShouldEqual, ErrInvalidCredentials)
2018-01-26 10:41:41 +01:00
So(sc.loginAttemptValidationWasCalled, ShouldBeTrue)
So(sc.grafanaLoginWasCalled, ShouldBeTrue)
So(sc.ldapLoginWasCalled, ShouldBeTrue)
So(sc.saveInvalidLoginAttemptWasCalled, ShouldBeTrue)
})
})
})
}
type authScenarioContext struct {
loginUserQuery *models.LoginUserQuery
2018-01-26 10:41:41 +01:00
grafanaLoginWasCalled bool
ldapLoginWasCalled bool
loginAttemptValidationWasCalled bool
saveInvalidLoginAttemptWasCalled bool
}
type authScenarioFunc func(sc *authScenarioContext)
func mockLoginUsingGrafanaDB(err error, sc *authScenarioContext) {
loginUsingGrafanaDB = func(query *models.LoginUserQuery) error {
2018-01-26 10:41:41 +01:00
sc.grafanaLoginWasCalled = true
return err
}
}
func mockLoginUsingLDAP(enabled bool, err error, sc *authScenarioContext) {
loginUsingLDAP = func(query *models.LoginUserQuery) (bool, error) {
2018-01-26 10:41:41 +01:00
sc.ldapLoginWasCalled = true
return enabled, err
}
}
func mockLoginAttemptValidation(err error, sc *authScenarioContext) {
validateLoginAttempts = func(*models.LoginUserQuery) error {
2018-01-26 10:41:41 +01:00
sc.loginAttemptValidationWasCalled = true
return err
}
}
func mockSaveInvalidLoginAttempt(sc *authScenarioContext) {
saveInvalidLoginAttempt = func(query *models.LoginUserQuery) error {
2018-01-26 10:41:41 +01:00
sc.saveInvalidLoginAttemptWasCalled = true
return nil
2018-01-26 10:41:41 +01:00
}
}
func authScenario(desc string, fn authScenarioFunc) {
Convey(desc, func() {
origLoginUsingGrafanaDB := loginUsingGrafanaDB
origLoginUsingLDAP := loginUsingLDAP
2018-01-26 10:41:41 +01:00
origValidateLoginAttempts := validateLoginAttempts
origSaveInvalidLoginAttempt := saveInvalidLoginAttempt
sc := &authScenarioContext{
loginUserQuery: &models.LoginUserQuery{
2018-01-26 10:41:41 +01:00
Username: "user",
Password: "pwd",
IpAddress: "192.168.1.1:56433",
},
}
defer func() {
loginUsingGrafanaDB = origLoginUsingGrafanaDB
loginUsingLDAP = origLoginUsingLDAP
2018-01-26 10:41:41 +01:00
validateLoginAttempts = origValidateLoginAttempts
saveInvalidLoginAttempt = origSaveInvalidLoginAttempt
}()
fn(sc)
})
}