Explorar el Código

more auth token tests

Marcus Efraimsson hace 7 años
padre
commit
366e356e08
Se han modificado 2 ficheros con 117 adiciones y 5 borrados
  1. 6 5
      pkg/services/auth/auth_token.go
  2. 111 0
      pkg/services/auth/auth_token_test.go

+ 6 - 5
pkg/services/auth/auth_token.go

@@ -223,19 +223,20 @@ func (s *UserAuthTokenService) RefreshToken(token *models.UserAuthToken, clientI
 	newToken, _ := util.RandomHex(16)
 	newToken, _ := util.RandomHex(16)
 	hashedToken := hashToken(newToken)
 	hashedToken := hashToken(newToken)
 
 
+	// very important that auth_token_seen is set after the prev_auth_token = case when ... for mysql to function correctly
 	sql := `
 	sql := `
 		UPDATE user_auth_token
 		UPDATE user_auth_token
 		SET
 		SET
-			auth_token_seen = false,
-			seen_at = null,
+			seen_at = 0,
 			user_agent = ?,
 			user_agent = ?,
 			client_ip = ?,
 			client_ip = ?,
-			prev_auth_token = case when auth_token_seen then auth_token else prev_auth_token end,
+			prev_auth_token = case when auth_token_seen = ? then auth_token else prev_auth_token end,
 			auth_token = ?,
 			auth_token = ?,
+			auth_token_seen = ?,
 			rotated_at = ?
 			rotated_at = ?
-		WHERE id = ? AND (auth_token_seen or rotated_at < ?)`
+		WHERE id = ? AND (auth_token_seen = ? OR rotated_at < ?)`
 
 
-	res, err := s.SQLStore.NewSession().Exec(sql, userAgent, clientIP, hashedToken, now.Unix(), token.Id, now.Add(-UrgentRotateTime))
+	res, err := s.SQLStore.NewSession().Exec(sql, userAgent, clientIP, s.SQLStore.Dialect.BooleanStr(true), hashedToken, s.SQLStore.Dialect.BooleanStr(false), now.Unix(), token.Id, s.SQLStore.Dialect.BooleanStr(true), now.Add(-30*time.Second).Unix())
 	if err != nil {
 	if err != nil {
 		return false, err
 		return false, err
 	}
 	}

+ 111 - 0
pkg/services/auth/auth_token_test.go

@@ -162,11 +162,122 @@ func TestUserAuthToken(t *testing.T) {
 		})
 		})
 
 
 		Convey("keeps prev token valid for 1 minute after it is confirmed", func() {
 		Convey("keeps prev token valid for 1 minute after it is confirmed", func() {
+			token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
+			So(err, ShouldBeNil)
+			So(token, ShouldNotBeNil)
+
+			lookedUp, err := userAuthTokenService.LookupToken(token.UnhashedToken)
+			So(err, ShouldBeNil)
+			So(lookedUp, ShouldNotBeNil)
+
+			getTime = func() time.Time {
+				return t.Add(10 * time.Minute)
+			}
+
+			prevToken := token.UnhashedToken
+			refreshed, err := userAuthTokenService.RefreshToken(token, "1.1.1.1", "firefox")
+			So(err, ShouldBeNil)
+			So(refreshed, ShouldBeTrue)
+
+			getTime = func() time.Time {
+				return t.Add(20 * time.Minute)
+			}
 
 
+			current, err := userAuthTokenService.LookupToken(token.UnhashedToken)
+			So(err, ShouldBeNil)
+			So(current, ShouldNotBeNil)
+
+			prev, err := userAuthTokenService.LookupToken(prevToken)
+			So(err, ShouldBeNil)
+			So(prev, ShouldNotBeNil)
 		})
 		})
 
 
 		Convey("will not mark token unseen when prev and current are the same", func() {
 		Convey("will not mark token unseen when prev and current are the same", func() {
+			token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
+			So(err, ShouldBeNil)
+			So(token, ShouldNotBeNil)
+
+			lookedUp, err := userAuthTokenService.LookupToken(token.UnhashedToken)
+			So(err, ShouldBeNil)
+			So(lookedUp, ShouldNotBeNil)
+
+			lookedUp, err = userAuthTokenService.LookupToken(token.UnhashedToken)
+			So(err, ShouldBeNil)
+			So(lookedUp, ShouldNotBeNil)
 
 
+			lookedUp, err = ctx.getAuthTokenByID(lookedUp.Id)
+			So(err, ShouldBeNil)
+			So(lookedUp, ShouldNotBeNil)
+			So(lookedUp.AuthTokenSeen, ShouldBeTrue)
+		})
+
+		Convey("Rotate token", func() {
+			token, err := userAuthTokenService.CreateToken(userID, "192.168.10.11:1234", "some user agent")
+			So(err, ShouldBeNil)
+			So(token, ShouldNotBeNil)
+
+			prevToken := token.AuthToken
+
+			Convey("Should rotate current token and previous token when auth token seen", func() {
+				updated, err := ctx.markAuthTokenAsSeen(token.Id)
+				So(err, ShouldBeNil)
+				So(updated, ShouldBeTrue)
+
+				getTime = func() time.Time {
+					return t.Add(10 * time.Minute)
+				}
+
+				refreshed, err := userAuthTokenService.RefreshToken(token, "1.1.1.1", "firefox")
+				So(err, ShouldBeNil)
+				So(refreshed, ShouldBeTrue)
+
+				storedToken, err := ctx.getAuthTokenByID(token.Id)
+				So(err, ShouldBeNil)
+				So(storedToken, ShouldNotBeNil)
+				So(storedToken.AuthTokenSeen, ShouldBeFalse)
+				So(storedToken.PrevAuthToken, ShouldEqual, prevToken)
+				So(storedToken.AuthToken, ShouldNotEqual, prevToken)
+
+				prevToken = storedToken.AuthToken
+
+				updated, err = ctx.markAuthTokenAsSeen(token.Id)
+				So(err, ShouldBeNil)
+				So(updated, ShouldBeTrue)
+
+				getTime = func() time.Time {
+					return t.Add(20 * time.Minute)
+				}
+
+				refreshed, err = userAuthTokenService.RefreshToken(token, "1.1.1.1", "firefox")
+				So(err, ShouldBeNil)
+				So(refreshed, ShouldBeTrue)
+
+				storedToken, err = ctx.getAuthTokenByID(token.Id)
+				So(err, ShouldBeNil)
+				So(storedToken, ShouldNotBeNil)
+				So(storedToken.AuthTokenSeen, ShouldBeFalse)
+				So(storedToken.PrevAuthToken, ShouldEqual, prevToken)
+				So(storedToken.AuthToken, ShouldNotEqual, prevToken)
+			})
+
+			Convey("Should rotate current token, but keep previous token when auth token not seen", func() {
+				token.RotatedAt = getTime().Add(-2 * time.Minute).Unix()
+
+				getTime = func() time.Time {
+					return t.Add(2 * time.Minute)
+				}
+
+				refreshed, err := userAuthTokenService.RefreshToken(token, "1.1.1.1", "firefox")
+				So(err, ShouldBeNil)
+				So(refreshed, ShouldBeTrue)
+
+				storedToken, err := ctx.getAuthTokenByID(token.Id)
+				So(err, ShouldBeNil)
+				So(storedToken, ShouldNotBeNil)
+				So(storedToken.AuthTokenSeen, ShouldBeFalse)
+				So(storedToken.PrevAuthToken, ShouldEqual, prevToken)
+				So(storedToken.AuthToken, ShouldNotEqual, prevToken)
+			})
 		})
 		})
 
 
 		Reset(func() {
 		Reset(func() {