Repository: supabase/gotrue
Pull request #659 (2022-09-01 09:33:51)

refactor: add `GrantParams` for issuing refresh tokens
Useful for parametrizing the issuing of refresh tokens. Both MFA and SAML branches need a concept like this.


Patch:
diff --git a/api/token.go b/api/token.go
index b92aedb1..cd535670 100644
--- a/api/token.go
+++ b/api/token.go
@@ -556,7 +556,7 @@ func (a *API) issueRefreshToken(ctx context.Context, conn *storage.Connection, u
 
 	err := conn.Transaction(func(tx *storage.Connection) error {
 		var terr error
-		refreshToken, terr = models.GrantAuthenticatedUser(tx, user)
+		refreshToken, terr = models.GrantAuthenticatedUser(tx, user, models.GrantParams{})
 		if terr != nil {
 			return internalServerError("Database error granting user").WithInternalError(terr)
 		}
diff --git a/models/refresh_token.go b/models/refresh_token.go
index 5f1bc463..eb2ab3d5 100644
--- a/models/refresh_token.go
+++ b/models/refresh_token.go
@@ -36,9 +36,14 @@ func (RefreshToken) TableName() string {
 	return tableName
 }
 
+// GrantParams is used to pass session-specific parameters when issuing a new
+// refresh token to authenticated users.
+type GrantParams struct {
+}
+
 // GrantAuthenticatedUser creates a refresh token for the provided user.
-func GrantAuthenticatedUser(tx *storage.Connection, user *User) (*RefreshToken, error) {
-	return createRefreshToken(tx, user, nil)
+func GrantAuthenticatedUser(tx *storage.Connection, user *User, params GrantParams) (*RefreshToken, error) {
+	return createRefreshToken(tx, user, nil, &params)
 }
 
 // GrantRefreshTokenSwap swaps a refresh token for a new one, revoking the provided token.
@@ -54,7 +59,7 @@ func GrantRefreshTokenSwap(r *http.Request, tx *storage.Connection, user *User,
 		if terr = tx.UpdateOnly(token, "revoked"); terr != nil {
 			return terr
 		}
-		newToken, terr = createRefreshToken(rtx, user, token)
+		newToken, terr = createRefreshToken(rtx, user, token, nil)
 		return terr
 	})
 	return newToken, err
@@ -94,7 +99,7 @@ func GetValidChildToken(tx *storage.Connection, token *RefreshToken) (*RefreshTo
 	return refreshToken, nil
 }
 
-func createRefreshToken(tx *storage.Connection, user *User, oldToken *RefreshToken) (*RefreshToken, error) {
+func createRefreshToken(tx *storage.Connection, user *User, oldToken *RefreshToken, params *GrantParams) (*RefreshToken, error) {
 	token := &RefreshToken{
 		UserID: user.ID,
 		Token:  crypto.SecureToken(),


Test patch:
diff --git a/api/token_test.go b/api/token_test.go
index 3ff75803..c8d36377 100644
--- a/api/token_test.go
+++ b/api/token_test.go
@@ -50,7 +50,7 @@ func (ts *TokenTestSuite) SetupTest() {
 	u.BannedUntil = nil
 	require.NoError(ts.T(), ts.API.db.Create(u), "Error saving new test user")
 
-	ts.RefreshToken, err = models.GrantAuthenticatedUser(ts.API.db, u)
+	ts.RefreshToken, err = models.GrantAuthenticatedUser(ts.API.db, u, models.GrantParams{})
 	require.NoError(ts.T(), err, "Error creating refresh token")
 }
 
@@ -153,7 +153,7 @@ func (ts *TokenTestSuite) TestTokenRefreshTokenRotation() {
 	t := time.Now()
 	u.EmailConfirmedAt = &t
 	require.NoError(ts.T(), ts.API.db.Create(u), "Error saving foo user")
-	first, err := models.GrantAuthenticatedUser(ts.API.db, u)
+	first, err := models.GrantAuthenticatedUser(ts.API.db, u, models.GrantParams{})
 	require.NoError(ts.T(), err)
 	second, err := models.GrantRefreshTokenSwap(&http.Request{}, ts.API.db, u, first)
 	require.NoError(ts.T(), err)
@@ -245,7 +245,7 @@ func (ts *TokenTestSuite) createBannedUser() *models.User {
 	u.BannedUntil = &t
 	require.NoError(ts.T(), ts.API.db.Create(u), "Error saving new test banned user")
 
-	ts.RefreshToken, err = models.GrantAuthenticatedUser(ts.API.db, u)
+	ts.RefreshToken, err = models.GrantAuthenticatedUser(ts.API.db, u, models.GrantParams{})
 	require.NoError(ts.T(), err, "Error creating refresh token")
 
 	return u
diff --git a/models/refresh_token_test.go b/models/refresh_token_test.go
index cbf32af2..6da738ba 100644
--- a/models/refresh_token_test.go
+++ b/models/refresh_token_test.go
@@ -37,7 +37,7 @@ func TestRefreshToken(t *testing.T) {
 
 func (ts *RefreshTokenTestSuite) TestGrantAuthenticatedUser() {
 	u := ts.createUser()
-	r, err := GrantAuthenticatedUser(ts.db, u)
+	r, err := GrantAuthenticatedUser(ts.db, u, GrantParams{})
 	require.NoError(ts.T(), err)
 
 	require.NotEmpty(ts.T(), r.Token)
@@ -46,7 +46,7 @@ func (ts *RefreshTokenTestSuite) TestGrantAuthenticatedUser() {
 
 func (ts *RefreshTokenTestSuite) TestGrantRefreshTokenSwap() {
 	u := ts.createUser()
-	r, err := GrantAuthenticatedUser(ts.db, u)
+	r, err := GrantAuthenticatedUser(ts.db, u, GrantParams{})
 	require.NoError(ts.T(), err)
 
 	s, err := GrantRefreshTokenSwap(&http.Request{}, ts.db, u, r)
@@ -64,7 +64,7 @@ func (ts *RefreshTokenTestSuite) TestGrantRefreshTokenSwap() {
 
 func (ts *RefreshTokenTestSuite) TestLogout() {
 	u := ts.createUser()
-	r, err := GrantAuthenticatedUser(ts.db, u)
+	r, err := GrantAuthenticatedUser(ts.db, u, GrantParams{})
 	require.NoError(ts.T(), err)
 
 	require.NoError(ts.T(), Logout(ts.db, u.ID))
diff --git a/models/user_test.go b/models/user_test.go
index 8ff308a4..eb75a599 100644
--- a/models/user_test.go
+++ b/models/user_test.go
@@ -148,7 +148,7 @@ func (ts *UserTestSuite) TestFindUserByRecoveryToken() {
 
 func (ts *UserTestSuite) TestFindUserWithRefreshToken() {
 	u := ts.createUser()
-	r, err := GrantAuthenticatedUser(ts.db, u)
+	r, err := GrantAuthenticatedUser(ts.db, u, GrantParams{})
 	require.NoError(ts.T(), err)
 
 	n, nr, err := FindUserWithRefreshToken(ts.db, r.Token)