auth_token_test.go 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. package auth
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/grafana/grafana/pkg/setting"
  6. "github.com/grafana/grafana/pkg/log"
  7. "github.com/grafana/grafana/pkg/models"
  8. "github.com/grafana/grafana/pkg/services/sqlstore"
  9. . "github.com/smartystreets/goconvey/convey"
  10. )
  11. func TestUserAuthToken(t *testing.T) {
  12. Convey("Test user auth token", t, func() {
  13. ctx := createTestContext(t)
  14. userAuthTokenService := ctx.tokenService
  15. userID := int64(10)
  16. t := time.Date(2018, 12, 13, 13, 45, 0, 0, time.UTC)
  17. now = func() time.Time {
  18. return t
  19. }
  20. Convey("When creating token", func() {
  21. token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
  22. So(err, ShouldBeNil)
  23. So(token, ShouldNotBeNil)
  24. So(token.AuthTokenSeen, ShouldBeFalse)
  25. Convey("When lookup unhashed token should return user auth token", func() {
  26. LookupToken, err := userAuthTokenService.LookupToken(token.UnhashedToken)
  27. So(err, ShouldBeNil)
  28. So(LookupToken, ShouldNotBeNil)
  29. So(LookupToken.UserId, ShouldEqual, userID)
  30. So(LookupToken.AuthTokenSeen, ShouldBeTrue)
  31. storedAuthToken, err := ctx.getAuthTokenByID(LookupToken.Id)
  32. So(err, ShouldBeNil)
  33. So(storedAuthToken, ShouldNotBeNil)
  34. So(storedAuthToken.AuthTokenSeen, ShouldBeTrue)
  35. })
  36. Convey("When lookup hashed token should return user auth token not found error", func() {
  37. LookupToken, err := userAuthTokenService.LookupToken(token.AuthToken)
  38. So(err, ShouldEqual, ErrAuthTokenNotFound)
  39. So(LookupToken, ShouldBeNil)
  40. })
  41. })
  42. Convey("expires correctly", func() {
  43. token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
  44. So(err, ShouldBeNil)
  45. So(token, ShouldNotBeNil)
  46. _, err = userAuthTokenService.LookupToken(token.UnhashedToken)
  47. So(err, ShouldBeNil)
  48. token, err = ctx.getAuthTokenByID(token.Id)
  49. So(err, ShouldBeNil)
  50. now = func() time.Time {
  51. return t.Add(time.Hour)
  52. }
  53. refreshed, err := userAuthTokenService.RefreshToken(token, "192.168.10.11:1234", "some user agent")
  54. So(err, ShouldBeNil)
  55. So(refreshed, ShouldBeTrue)
  56. _, err = userAuthTokenService.LookupToken(token.UnhashedToken)
  57. So(err, ShouldBeNil)
  58. stillGood, err := userAuthTokenService.LookupToken(token.UnhashedToken)
  59. So(err, ShouldBeNil)
  60. So(stillGood, ShouldNotBeNil)
  61. now = func() time.Time {
  62. return t.Add(24 * 7 * time.Hour)
  63. }
  64. notGood, err := userAuthTokenService.LookupToken(token.UnhashedToken)
  65. So(err, ShouldEqual, ErrAuthTokenNotFound)
  66. So(notGood, ShouldBeNil)
  67. })
  68. Convey("can properly rotate tokens", func() {
  69. token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
  70. So(err, ShouldBeNil)
  71. So(token, ShouldNotBeNil)
  72. prevToken := token.AuthToken
  73. unhashedPrev := token.UnhashedToken
  74. refreshed, err := userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
  75. So(err, ShouldBeNil)
  76. So(refreshed, ShouldBeFalse)
  77. ctx.markAuthTokenAsSeen(token.Id)
  78. token, err = ctx.getAuthTokenByID(token.Id)
  79. So(err, ShouldBeNil)
  80. // ability to auth using an old token
  81. now = func() time.Time {
  82. return t.Add(time.Hour)
  83. }
  84. refreshed, err = userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
  85. So(err, ShouldBeNil)
  86. So(refreshed, ShouldBeTrue)
  87. unhashedToken := token.UnhashedToken
  88. token, err = ctx.getAuthTokenByID(token.Id)
  89. So(err, ShouldBeNil)
  90. token.UnhashedToken = unhashedToken
  91. So(token.RotatedAt, ShouldEqual, t.Unix())
  92. So(token.ClientIp, ShouldEqual, "192.168.10.12")
  93. So(token.UserAgent, ShouldEqual, "a new user agent")
  94. So(token.AuthTokenSeen, ShouldBeFalse)
  95. So(token.SeenAt, ShouldEqual, 0)
  96. So(token.PrevAuthToken, ShouldEqual, prevToken)
  97. lookedUp, err := userAuthTokenService.LookupToken(token.UnhashedToken)
  98. So(err, ShouldBeNil)
  99. So(lookedUp, ShouldNotBeNil)
  100. So(lookedUp.AuthTokenSeen, ShouldBeTrue)
  101. So(lookedUp.SeenAt, ShouldEqual, t.Unix())
  102. lookedUp, err = userAuthTokenService.LookupToken(unhashedPrev)
  103. So(err, ShouldBeNil)
  104. So(lookedUp, ShouldNotBeNil)
  105. So(lookedUp.Id, ShouldEqual, token.Id)
  106. now = func() time.Time {
  107. return t.Add(2 * time.Minute)
  108. }
  109. lookedUp, err = userAuthTokenService.LookupToken(unhashedPrev)
  110. So(err, ShouldBeNil)
  111. So(lookedUp, ShouldNotBeNil)
  112. lookedUp, err = ctx.getAuthTokenByID(lookedUp.Id)
  113. So(err, ShouldBeNil)
  114. So(lookedUp, ShouldNotBeNil)
  115. So(lookedUp.AuthTokenSeen, ShouldBeFalse)
  116. refreshed, err = userAuthTokenService.RefreshToken(token, "192.168.10.12:1234", "a new user agent")
  117. So(err, ShouldBeNil)
  118. So(refreshed, ShouldBeTrue)
  119. token, err = ctx.getAuthTokenByID(token.Id)
  120. So(err, ShouldBeNil)
  121. So(token, ShouldNotBeNil)
  122. So(token.SeenAt, ShouldEqual, 0)
  123. })
  124. Convey("keeps prev token valid for 1 minute after it is confirmed", func() {
  125. })
  126. Convey("will not mark token unseen when prev and current are the same", func() {
  127. })
  128. Reset(func() {
  129. now = time.Now
  130. })
  131. })
  132. }
  133. func createTestContext(t *testing.T) *testContext {
  134. t.Helper()
  135. sqlstore := sqlstore.InitTestDB(t)
  136. tokenService := &UserAuthTokenService{
  137. SQLStore: sqlstore,
  138. log: log.New("test-logger"),
  139. }
  140. RotateTime = 10 * time.Minute
  141. UrgentRotateTime = time.Minute
  142. setting.LogInRememberDays = 7
  143. return &testContext{
  144. sqlstore: sqlstore,
  145. tokenService: tokenService,
  146. }
  147. }
  148. type testContext struct {
  149. sqlstore *sqlstore.SqlStore
  150. tokenService *UserAuthTokenService
  151. }
  152. func (c *testContext) getAuthTokenByID(id int64) (*models.UserAuthToken, error) {
  153. sess := c.sqlstore.NewSession()
  154. var t models.UserAuthToken
  155. found, err := sess.ID(id).Get(&t)
  156. if err != nil || !found {
  157. return nil, err
  158. }
  159. return &t, nil
  160. }
  161. func (c *testContext) markAuthTokenAsSeen(id int64) (bool, error) {
  162. sess := c.sqlstore.NewSession()
  163. res, err := sess.Exec("UPDATE user_auth_token SET auth_token_seen = ? WHERE id = ?", c.sqlstore.Dialect.BooleanStr(true), id)
  164. if err != nil {
  165. return false, err
  166. }
  167. rowsAffected, err := res.RowsAffected()
  168. if err != nil {
  169. return false, err
  170. }
  171. return rowsAffected == 1, nil
  172. }