mirror of
				https://github.com/superseriousbusiness/gotosocial.git
				synced 2025-10-31 06:22:25 -05:00 
			
		
		
		
	[chore] reversion: use specific columns for updating user again (#1059)
This commit is contained in:
		
					parent
					
						
							
								8598dea98b
							
						
					
				
			
			
				commit
				
					
						940abc279c
					
				
			
		
					 4 changed files with 37 additions and 27 deletions
				
			
		|  | @ -151,8 +151,7 @@ var Promote action.GTSAction = func(ctx context.Context) error { | ||||||
| 
 | 
 | ||||||
| 	admin := true | 	admin := true | ||||||
| 	u.Admin = &admin | 	u.Admin = &admin | ||||||
| 	u.UpdatedAt = time.Now() | 	if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil { | ||||||
| 	if err := dbConn.UpdateUser(ctx, u); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -186,8 +185,7 @@ var Demote action.GTSAction = func(ctx context.Context) error { | ||||||
| 
 | 
 | ||||||
| 	admin := false | 	admin := false | ||||||
| 	u.Admin = &admin | 	u.Admin = &admin | ||||||
| 	u.UpdatedAt = time.Now() | 	if err := dbConn.UpdateUser(ctx, u, "admin"); err != nil { | ||||||
| 	if err := dbConn.UpdateUser(ctx, u); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -221,8 +219,7 @@ var Disable action.GTSAction = func(ctx context.Context) error { | ||||||
| 
 | 
 | ||||||
| 	disabled := true | 	disabled := true | ||||||
| 	u.Disabled = &disabled | 	u.Disabled = &disabled | ||||||
| 	u.UpdatedAt = time.Now() | 	if err := dbConn.UpdateUser(ctx, u, "disabled"); err != nil { | ||||||
| 	if err := dbConn.UpdateUser(ctx, u); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  | @ -268,8 +265,7 @@ var Password action.GTSAction = func(ctx context.Context) error { | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	u.EncryptedPassword = string(pw) | 	u.EncryptedPassword = string(pw) | ||||||
| 	u.UpdatedAt = time.Now() | 	if err := dbConn.UpdateUser(ctx, u, "encrypted_password"); err != nil { | ||||||
| 	if err := dbConn.UpdateUser(ctx, u); err != nil { |  | ||||||
| 		return err | 		return err | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -20,7 +20,7 @@ type AuthAuthorizeTestSuite struct { | ||||||
| 
 | 
 | ||||||
| type authorizeHandlerTestCase struct { | type authorizeHandlerTestCase struct { | ||||||
| 	description            string | 	description            string | ||||||
| 	mutateUserAccount      func(*gtsmodel.User, *gtsmodel.Account) | 	mutateUserAccount      func(*gtsmodel.User, *gtsmodel.Account) []string | ||||||
| 	expectedStatusCode     int | 	expectedStatusCode     int | ||||||
| 	expectedLocationHeader string | 	expectedLocationHeader string | ||||||
| } | } | ||||||
|  | @ -29,40 +29,44 @@ func (suite *AuthAuthorizeTestSuite) TestAccountAuthorizeHandler() { | ||||||
| 	tests := []authorizeHandlerTestCase{ | 	tests := []authorizeHandlerTestCase{ | ||||||
| 		{ | 		{ | ||||||
| 			description: "user has their email unconfirmed", | 			description: "user has their email unconfirmed", | ||||||
| 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) { | 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) []string { | ||||||
| 				// nothing to do, weed_lord420 already has their email unconfirmed | 				user.ConfirmedAt = time.Time{} | ||||||
|  | 				return []string{"confirmed_at"} | ||||||
| 			}, | 			}, | ||||||
| 			expectedStatusCode:     http.StatusSeeOther, | 			expectedStatusCode:     http.StatusSeeOther, | ||||||
| 			expectedLocationHeader: auth.CheckYourEmailPath, | 			expectedLocationHeader: auth.CheckYourEmailPath, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			description: "user has their email confirmed but is not approved", | 			description: "user has their email confirmed but is not approved", | ||||||
| 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) { | 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) []string { | ||||||
| 				user.ConfirmedAt = time.Now() | 				user.ConfirmedAt = time.Now() | ||||||
| 				user.Email = user.UnconfirmedEmail | 				user.Email = user.UnconfirmedEmail | ||||||
|  | 				return []string{"confirmed_at", "email"} | ||||||
| 			}, | 			}, | ||||||
| 			expectedStatusCode:     http.StatusSeeOther, | 			expectedStatusCode:     http.StatusSeeOther, | ||||||
| 			expectedLocationHeader: auth.WaitForApprovalPath, | 			expectedLocationHeader: auth.WaitForApprovalPath, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			description: "user has their email confirmed and is approved, but User entity has been disabled", | 			description: "user has their email confirmed and is approved, but User entity has been disabled", | ||||||
| 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) { | 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) []string { | ||||||
| 				user.ConfirmedAt = time.Now() | 				user.ConfirmedAt = time.Now() | ||||||
| 				user.Email = user.UnconfirmedEmail | 				user.Email = user.UnconfirmedEmail | ||||||
| 				user.Approved = testrig.TrueBool() | 				user.Approved = testrig.TrueBool() | ||||||
| 				user.Disabled = testrig.TrueBool() | 				user.Disabled = testrig.TrueBool() | ||||||
|  | 				return []string{"confirmed_at", "email", "approved", "disabled"} | ||||||
| 			}, | 			}, | ||||||
| 			expectedStatusCode:     http.StatusSeeOther, | 			expectedStatusCode:     http.StatusSeeOther, | ||||||
| 			expectedLocationHeader: auth.AccountDisabledPath, | 			expectedLocationHeader: auth.AccountDisabledPath, | ||||||
| 		}, | 		}, | ||||||
| 		{ | 		{ | ||||||
| 			description: "user has their email confirmed and is approved, but Account entity has been suspended", | 			description: "user has their email confirmed and is approved, but Account entity has been suspended", | ||||||
| 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) { | 			mutateUserAccount: func(user *gtsmodel.User, account *gtsmodel.Account) []string { | ||||||
| 				user.ConfirmedAt = time.Now() | 				user.ConfirmedAt = time.Now() | ||||||
| 				user.Email = user.UnconfirmedEmail | 				user.Email = user.UnconfirmedEmail | ||||||
| 				user.Approved = testrig.TrueBool() | 				user.Approved = testrig.TrueBool() | ||||||
| 				user.Disabled = testrig.FalseBool() | 				user.Disabled = testrig.FalseBool() | ||||||
| 				account.SuspendedAt = time.Now() | 				account.SuspendedAt = time.Now() | ||||||
|  | 				return []string{"confirmed_at", "email", "approved", "disabled"} | ||||||
| 			}, | 			}, | ||||||
| 			expectedStatusCode:     http.StatusSeeOther, | 			expectedStatusCode:     http.StatusSeeOther, | ||||||
| 			expectedLocationHeader: auth.AccountDisabledPath, | 			expectedLocationHeader: auth.AccountDisabledPath, | ||||||
|  | @ -77,7 +81,6 @@ func (suite *AuthAuthorizeTestSuite) TestAccountAuthorizeHandler() { | ||||||
| 
 | 
 | ||||||
| 		*user = *suite.testUsers["unconfirmed_account"] | 		*user = *suite.testUsers["unconfirmed_account"] | ||||||
| 		*account = *suite.testAccounts["unconfirmed_account"] | 		*account = *suite.testAccounts["unconfirmed_account"] | ||||||
| 		user.SignInCount++ // cannot be 0 or fails NULL constraint |  | ||||||
| 
 | 
 | ||||||
| 		testSession := sessions.Default(ctx) | 		testSession := sessions.Default(ctx) | ||||||
| 		testSession.Set(sessionUserID, user.ID) | 		testSession.Set(sessionUserID, user.ID) | ||||||
|  | @ -86,11 +89,11 @@ func (suite *AuthAuthorizeTestSuite) TestAccountAuthorizeHandler() { | ||||||
| 			panic(fmt.Errorf("failed on case %s: %w", testCase.description, err)) | 			panic(fmt.Errorf("failed on case %s: %w", testCase.description, err)) | ||||||
| 		} | 		} | ||||||
| 
 | 
 | ||||||
| 		testCase.mutateUserAccount(user, account) | 		columns := testCase.mutateUserAccount(user, account) | ||||||
| 
 | 
 | ||||||
| 		testCase.description = fmt.Sprintf("%s, %t, %s", user.Email, *user.Disabled, account.SuspendedAt) | 		testCase.description = fmt.Sprintf("%s, %t, %s", user.Email, *user.Disabled, account.SuspendedAt) | ||||||
| 
 | 
 | ||||||
| 		err := suite.db.UpdateUser(context.Background(), user) | 		err := suite.db.UpdateUser(context.Background(), user, columns...) | ||||||
| 		suite.NoError(err) | 		suite.NoError(err) | ||||||
| 		err = suite.db.UpdateAccount(context.Background(), account) | 		err = suite.db.UpdateAccount(context.Background(), account) | ||||||
| 		suite.NoError(err) | 		suite.NoError(err) | ||||||
|  |  | ||||||
|  | @ -133,18 +133,29 @@ func (u *userDB) PutUser(ctx context.Context, user *gtsmodel.User) db.Error { | ||||||
| 	}) | 	}) | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (u *userDB) UpdateUser(ctx context.Context, user *gtsmodel.User) db.Error { | func (u *userDB) UpdateUser(ctx context.Context, user *gtsmodel.User, columns ...string) db.Error { | ||||||
| 	// Update the user's last-updated | 	// Update the user's last-updated | ||||||
| 	user.UpdatedAt = time.Now() | 	user.UpdatedAt = time.Now() | ||||||
| 
 | 
 | ||||||
| 	return u.cache.Store(user, func() error { | 	if len(columns) > 0 { | ||||||
| 		_, err := u.conn. | 		// If we're updating by column, ensure "updated_at" is included | ||||||
| 			NewUpdate(). | 		columns = append(columns, "updated_at") | ||||||
| 			Model(user). | 	} | ||||||
| 			Where("? = ?", bun.Ident("user.id"), user.ID). | 
 | ||||||
| 			Exec(ctx) | 	// Update the user in DB | ||||||
|  | 	_, err := u.conn. | ||||||
|  | 		NewUpdate(). | ||||||
|  | 		Model(user). | ||||||
|  | 		Where("? = ?", bun.Ident("user.id"), user.ID). | ||||||
|  | 		Column(columns...). | ||||||
|  | 		Exec(ctx) | ||||||
|  | 	if err != nil { | ||||||
| 		return u.conn.ProcessError(err) | 		return u.conn.ProcessError(err) | ||||||
| 	}) | 	} | ||||||
|  | 
 | ||||||
|  | 	// Invalidate in cache | ||||||
|  | 	u.cache.Invalidate("ID", user.ID) | ||||||
|  | 	return nil | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (u *userDB) DeleteUserByID(ctx context.Context, userID string) db.Error { | func (u *userDB) DeleteUserByID(ctx context.Context, userID string) db.Error { | ||||||
|  |  | ||||||
|  | @ -36,8 +36,8 @@ type User interface { | ||||||
| 	GetUserByConfirmationToken(ctx context.Context, confirmationToken string) (*gtsmodel.User, Error) | 	GetUserByConfirmationToken(ctx context.Context, confirmationToken string) (*gtsmodel.User, Error) | ||||||
| 	// PutUser will attempt to place user in the database | 	// PutUser will attempt to place user in the database | ||||||
| 	PutUser(ctx context.Context, user *gtsmodel.User) Error | 	PutUser(ctx context.Context, user *gtsmodel.User) Error | ||||||
| 	// UpdateUser updates one user by its primary key. | 	// UpdateUser updates one user by its primary key, updating either only the specified columns, or all of them. | ||||||
| 	UpdateUser(ctx context.Context, user *gtsmodel.User) Error | 	UpdateUser(ctx context.Context, user *gtsmodel.User, columns ...string) Error | ||||||
| 	// DeleteUserByID deletes one user by its ID. | 	// DeleteUserByID deletes one user by its ID. | ||||||
| 	DeleteUserByID(ctx context.Context, userID string) Error | 	DeleteUserByID(ctx context.Context, userID string) Error | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue