grafana_login_test.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. package login
  2. import (
  3. "testing"
  4. . "github.com/smartystreets/goconvey/convey"
  5. "github.com/grafana/grafana/pkg/bus"
  6. m "github.com/grafana/grafana/pkg/models"
  7. )
  8. func TestGrafanaLogin(t *testing.T) {
  9. Convey("Login using Grafana DB", t, func() {
  10. grafanaLoginScenario("When login with non-existing user", func(sc *grafanaLoginScenarioContext) {
  11. sc.withNonExistingUser()
  12. err := loginUsingGrafanaDB(sc.loginUserQuery)
  13. Convey("it should result in user not found error", func() {
  14. So(err, ShouldEqual, m.ErrUserNotFound)
  15. })
  16. Convey("it should not call password validation", func() {
  17. So(sc.validatePasswordCalled, ShouldBeFalse)
  18. })
  19. Convey("it should not pupulate user object", func() {
  20. So(sc.loginUserQuery.User, ShouldBeNil)
  21. })
  22. })
  23. grafanaLoginScenario("When login with invalid credentials", func(sc *grafanaLoginScenarioContext) {
  24. sc.withInvalidPassword()
  25. err := loginUsingGrafanaDB(sc.loginUserQuery)
  26. Convey("it should result in invalid credentials error", func() {
  27. So(err, ShouldEqual, ErrInvalidCredentials)
  28. })
  29. Convey("it should call password validation", func() {
  30. So(sc.validatePasswordCalled, ShouldBeTrue)
  31. })
  32. Convey("it should not pupulate user object", func() {
  33. So(sc.loginUserQuery.User, ShouldBeNil)
  34. })
  35. })
  36. grafanaLoginScenario("When login with valid credentials", func(sc *grafanaLoginScenarioContext) {
  37. sc.withValidCredentials()
  38. err := loginUsingGrafanaDB(sc.loginUserQuery)
  39. Convey("it should not result in error", func() {
  40. So(err, ShouldBeNil)
  41. })
  42. Convey("it should call password validation", func() {
  43. So(sc.validatePasswordCalled, ShouldBeTrue)
  44. })
  45. Convey("it should pupulate user object", func() {
  46. So(sc.loginUserQuery.User, ShouldNotBeNil)
  47. So(sc.loginUserQuery.User.Login, ShouldEqual, sc.loginUserQuery.Username)
  48. So(sc.loginUserQuery.User.Password, ShouldEqual, sc.loginUserQuery.Password)
  49. })
  50. })
  51. })
  52. }
  53. type grafanaLoginScenarioContext struct {
  54. loginUserQuery *m.LoginUserQuery
  55. validatePasswordCalled bool
  56. }
  57. type grafanaLoginScenarioFunc func(c *grafanaLoginScenarioContext)
  58. func grafanaLoginScenario(desc string, fn grafanaLoginScenarioFunc) {
  59. Convey(desc, func() {
  60. origValidatePassword := validatePassword
  61. sc := &grafanaLoginScenarioContext{
  62. loginUserQuery: &m.LoginUserQuery{
  63. Username: "user",
  64. Password: "pwd",
  65. IpAddress: "192.168.1.1:56433",
  66. },
  67. validatePasswordCalled: false,
  68. }
  69. defer func() {
  70. validatePassword = origValidatePassword
  71. }()
  72. fn(sc)
  73. })
  74. }
  75. func mockPasswordValidation(valid bool, sc *grafanaLoginScenarioContext) {
  76. validatePassword = func(providedPassword string, userPassword string, userSalt string) error {
  77. sc.validatePasswordCalled = true
  78. if !valid {
  79. return ErrInvalidCredentials
  80. }
  81. return nil
  82. }
  83. }
  84. func (sc *grafanaLoginScenarioContext) getUserByLoginQueryReturns(user *m.User) {
  85. bus.AddHandler("test", func(query *m.GetUserByLoginQuery) error {
  86. if user == nil {
  87. return m.ErrUserNotFound
  88. }
  89. query.Result = user
  90. return nil
  91. })
  92. }
  93. func (sc *grafanaLoginScenarioContext) withValidCredentials() {
  94. sc.getUserByLoginQueryReturns(&m.User{
  95. Id: 1,
  96. Login: sc.loginUserQuery.Username,
  97. Password: sc.loginUserQuery.Password,
  98. Salt: "salt",
  99. })
  100. mockPasswordValidation(true, sc)
  101. }
  102. func (sc *grafanaLoginScenarioContext) withNonExistingUser() {
  103. sc.getUserByLoginQueryReturns(nil)
  104. }
  105. func (sc *grafanaLoginScenarioContext) withInvalidPassword() {
  106. sc.getUserByLoginQueryReturns(&m.User{
  107. Password: sc.loginUserQuery.Password,
  108. Salt: "salt",
  109. })
  110. mockPasswordValidation(false, sc)
  111. }