diff --git a/internal/auth/password/repository_account.go b/internal/auth/password/repository_account.go index f040de25f..7bde3b87a 100644 --- a/internal/auth/password/repository_account.go +++ b/internal/auth/password/repository_account.go @@ -191,7 +191,7 @@ func validUserName(u string) bool { // An attribute of a will be set to NULL in the database if the attribute // in a is the zero value and it is included in fieldMaskPaths. a.UserName // cannot be set to NULL. -func (r *Repository) UpdateAccount(ctx context.Context, a *Account, fieldMaskPaths []string, opt ...Option) (*Account, int, error) { +func (r *Repository) UpdateAccount(ctx context.Context, a *Account, version uint32, fieldMaskPaths []string, opt ...Option) (*Account, int, error) { if a == nil { return nil, db.NoRowsAffected, fmt.Errorf("update: password account: %w", db.ErrNilParameter) } @@ -201,6 +201,9 @@ func (r *Repository) UpdateAccount(ctx context.Context, a *Account, fieldMaskPat if a.PublicId == "" { return nil, db.NoRowsAffected, fmt.Errorf("update: password account: missing public id: %w", db.ErrInvalidParameter) } + if version == 0 { + return nil, db.NoRowsAffected, fmt.Errorf("update: password account: no version supplied: %w", db.ErrInvalidParameter) + } var changeUserName bool for _, f := range fieldMaskPaths { @@ -249,7 +252,7 @@ func (r *Repository) UpdateAccount(ctx context.Context, a *Account, fieldMaskPat func(_ db.Reader, w db.Writer) error { returnedAccount = a.clone() var err error - rowsUpdated, err = w.Update(ctx, returnedAccount, dbMask, nullFields, db.WithOplog(r.wrapper, metadata)) + rowsUpdated, err = w.Update(ctx, returnedAccount, dbMask, nullFields, db.WithOplog(r.wrapper, metadata), db.WithVersion(&version)) if err == nil && rowsUpdated > 1 { return db.ErrMultipleRecords } diff --git a/internal/auth/password/repository_account_test.go b/internal/auth/password/repository_account_test.go index 181448eec..aed741a0e 100644 --- a/internal/auth/password/repository_account_test.go +++ b/internal/auth/password/repository_account_test.go @@ -871,7 +871,7 @@ func TestRepository_UpdateAccount(t *testing.T) { if tt.chgFn != nil { orig = tt.chgFn(orig) } - got, gotCount, err := repo.UpdateAccount(context.Background(), orig, tt.masks) + got, gotCount, err := repo.UpdateAccount(context.Background(), orig, 1, tt.masks) if tt.wantIsErr != nil { assert.Truef(errors.Is(err, tt.wantIsErr), "want err: %q got: %q", tt.wantIsErr, err) assert.Equal(tt.wantCount, gotCount, "row count") @@ -922,7 +922,7 @@ func TestRepository_UpdateAccount(t *testing.T) { ab := acts[1] aa.Name = name - got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, []string{"name"}) + got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, 1, []string{"name"}) assert.NoError(err) require.NotNil(got1) assert.Equal(name, got1.Name) @@ -930,7 +930,7 @@ func TestRepository_UpdateAccount(t *testing.T) { assert.NoError(db.TestVerifyOplog(t, rw, aa.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))) ab.Name = name - got2, gotCount2, err := repo.UpdateAccount(context.Background(), ab, []string{"name"}) + got2, gotCount2, err := repo.UpdateAccount(context.Background(), ab, 1, []string{"name"}) assert.Truef(errors.Is(err, db.ErrNotUnique), "want err: %v got: %v", db.ErrNotUnique, err) assert.Nil(got2) assert.Equal(db.NoRowsAffected, gotCount2, "row count") @@ -975,7 +975,7 @@ func TestRepository_UpdateAccount(t *testing.T) { assert.NoError(err) require.NotNil(got2) got2.Name = got.Name - got3, gotCount3, err := repo.UpdateAccount(context.Background(), got2, []string{"name"}) + got3, gotCount3, err := repo.UpdateAccount(context.Background(), got2, 1, []string{"name"}) assert.NoError(err) require.NotNil(got3) assert.NotSame(got2, got3) @@ -1000,7 +1000,7 @@ func TestRepository_UpdateAccount(t *testing.T) { ab := acts[1] aa.UserName = userName - got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, []string{"UserName"}) + got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, 1, []string{"UserName"}) assert.NoError(err) require.NotNil(got1) assert.Equal(userName, got1.UserName) @@ -1008,7 +1008,7 @@ func TestRepository_UpdateAccount(t *testing.T) { assert.NoError(db.TestVerifyOplog(t, rw, aa.PublicId, db.WithOperation(oplog.OpType_OP_TYPE_UPDATE), db.WithCreateNotBefore(10*time.Second))) ab.UserName = userName - got2, gotCount2, err := repo.UpdateAccount(context.Background(), ab, []string{"UserName"}) + got2, gotCount2, err := repo.UpdateAccount(context.Background(), ab, 1, []string{"UserName"}) assert.Truef(errors.Is(err, db.ErrNotUnique), "want err: %v got: %v", db.ErrNotUnique, err) assert.Nil(got2) assert.Equal(db.NoRowsAffected, gotCount2, "row count") @@ -1050,7 +1050,7 @@ func TestRepository_UpdateAccount(t *testing.T) { assert.NoError(err) require.NotNil(got2) got2.UserName = got.UserName - got3, gotCount3, err := repo.UpdateAccount(context.Background(), got2, []string{"UserName"}) + got3, gotCount3, err := repo.UpdateAccount(context.Background(), got2, 1, []string{"UserName"}) assert.NoError(err) require.NotNil(got3) assert.NotSame(got2, got3) @@ -1080,7 +1080,7 @@ func TestRepository_UpdateAccount(t *testing.T) { aa.AuthMethodId = ab.AuthMethodId assert.Equal(aa.AuthMethodId, ab.AuthMethodId) - got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, []string{"name"}) + got1, gotCount1, err := repo.UpdateAccount(context.Background(), aa, 1, []string{"name"}) assert.NoError(err) require.NotNil(got1)