Merge branch 'main' into ssh-mirroring

This commit is contained in:
techknowlogick
2025-09-11 15:00:41 -04:00
committed by GitHub
632 changed files with 19973 additions and 21115 deletions
+4 -5
View File
@@ -8,7 +8,6 @@ import (
"strings"
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
"code.gitea.io/gitea/modules/setting"
"code.gitea.io/gitea/modules/storage"
@@ -23,12 +22,12 @@ func TestUserAvatarLink(t *testing.T) {
defer test.MockVariableValue(&setting.AppSubURL, "")()
u := &User{ID: 1, Avatar: "avatar.png"}
link := u.AvatarLink(db.DefaultContext)
link := u.AvatarLink(t.Context())
assert.Equal(t, "https://localhost/avatars/avatar.png", link)
setting.AppURL = "https://localhost/sub-path/"
setting.AppSubURL = "/sub-path"
link = u.AvatarLink(db.DefaultContext)
link = u.AvatarLink(t.Context())
assert.Equal(t, "https://localhost/sub-path/avatars/avatar.png", link)
}
@@ -43,7 +42,7 @@ func TestUserAvatarGenerate(t *testing.T) {
// there was no avatar, generate a new one
assert.Empty(t, u.Avatar)
err = GenerateRandomAvatar(db.DefaultContext, u)
err = GenerateRandomAvatar(t.Context(), u)
require.NoError(t, err)
assert.NotEmpty(t, u.Avatar)
@@ -56,7 +55,7 @@ func TestUserAvatarGenerate(t *testing.T) {
require.NoError(t, err)
// try to generate again
err = GenerateRandomAvatar(db.DefaultContext, u)
err = GenerateRandomAvatar(t.Context(), u)
require.NoError(t, err)
assert.Equal(t, oldAvatarPath, u.CustomAvatarRelativePath())
f, err := storage.Avatars.Open(u.CustomAvatarRelativePath())
+40 -45
View File
@@ -442,58 +442,53 @@ func SearchEmails(ctx context.Context, opts *SearchEmailOptions) ([]*SearchEmail
// ActivateUserEmail will change the activated state of an email address,
// either primary or secondary (all in the email_address table)
func ActivateUserEmail(ctx context.Context, userID int64, email string, activate bool) (err error) {
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
}
defer committer.Close()
// Activate/deactivate a user's secondary email address
// First check if there's another user active with the same address
addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)})
if err != nil {
return err
} else if !exist {
return fmt.Errorf("no such email: %d (%s)", userID, email)
}
if addr.IsActivated == activate {
// Already in the desired state; no action
return nil
}
if activate {
if used, err := IsEmailActive(ctx, email, addr.ID); err != nil {
return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err)
} else if used {
return ErrEmailAlreadyUsed{Email: email}
}
}
if err = updateActivation(ctx, addr, activate); err != nil {
return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err)
}
// Activate/deactivate a user's primary email address and account
if addr.IsPrimary {
user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID})
return db.WithTx(ctx, func(ctx context.Context) error {
// Activate/deactivate a user's secondary email address
// First check if there's another user active with the same address
addr, exist, err := db.Get[EmailAddress](ctx, builder.Eq{"uid": userID, "lower_email": strings.ToLower(email)})
if err != nil {
return err
} else if !exist || !strings.EqualFold(user.Email, email) {
return fmt.Errorf("no user with ID: %d and Email: %s", userID, email)
} else if !exist {
return fmt.Errorf("no such email: %d (%s)", userID, email)
}
// The user's activation state should be synchronized with the primary email
if user.IsActive != activate {
user.IsActive = activate
if user.Rands, err = GetUserSalt(); err != nil {
return fmt.Errorf("unable to generate salt: %w", err)
}
if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil {
return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err)
if addr.IsActivated == activate {
// Already in the desired state; no action
return nil
}
if activate {
if used, err := IsEmailActive(ctx, email, addr.ID); err != nil {
return fmt.Errorf("unable to check isEmailActive() for %s: %w", email, err)
} else if used {
return ErrEmailAlreadyUsed{Email: email}
}
}
}
if err = updateActivation(ctx, addr, activate); err != nil {
return fmt.Errorf("unable to updateActivation() for %d:%s: %w", addr.ID, addr.Email, err)
}
return committer.Commit()
// Activate/deactivate a user's primary email address and account
if addr.IsPrimary {
user, exist, err := db.Get[User](ctx, builder.Eq{"id": userID})
if err != nil {
return err
} else if !exist || !strings.EqualFold(user.Email, email) {
return fmt.Errorf("no user with ID: %d and Email: %s", userID, email)
}
// The user's activation state should be synchronized with the primary email
if user.IsActive != activate {
user.IsActive = activate
if user.Rands, err = GetUserSalt(); err != nil {
return fmt.Errorf("unable to generate salt: %w", err)
}
if err = UpdateUserCols(ctx, user, "is_active", "rands"); err != nil {
return fmt.Errorf("unable to updateUserCols() for user ID: %d: %w", userID, err)
}
}
}
return nil
})
}
// validateEmailBasic checks whether the email complies with the rules
+18 -18
View File
@@ -18,14 +18,14 @@ import (
func TestGetEmailAddresses(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1))
if assert.Len(t, emails, 3) {
assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[2].IsActivated)
assert.False(t, emails[2].IsPrimary)
}
emails, _ = user_model.GetEmailAddresses(db.DefaultContext, int64(2))
emails, _ = user_model.GetEmailAddresses(t.Context(), int64(2))
if assert.Len(t, emails, 2) {
assert.True(t, emails[0].IsPrimary)
assert.True(t, emails[0].IsActivated)
@@ -35,36 +35,36 @@ func TestGetEmailAddresses(t *testing.T) {
func TestIsEmailUsed(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
isExist, _ := user_model.IsEmailUsed(db.DefaultContext, "")
isExist, _ := user_model.IsEmailUsed(t.Context(), "")
assert.True(t, isExist)
isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user11@example.com")
isExist, _ = user_model.IsEmailUsed(t.Context(), "user11@example.com")
assert.True(t, isExist)
isExist, _ = user_model.IsEmailUsed(db.DefaultContext, "user1234567890@example.com")
isExist, _ = user_model.IsEmailUsed(t.Context(), "user1234567890@example.com")
assert.False(t, isExist)
}
func TestMakeEmailPrimary(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
err := user_model.MakeActiveEmailPrimary(db.DefaultContext, 9999999)
err := user_model.MakeActiveEmailPrimary(t.Context(), 9999999)
assert.Error(t, err)
assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{})
email := unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user11@example.com"})
err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID)
err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID)
assert.Error(t, err)
assert.ErrorIs(t, err, user_model.ErrEmailAddressNotExist{}) // inactive email is considered as not exist for "MakeActiveEmailPrimary"
email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user9999999@example.com"})
err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID)
err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID)
assert.Error(t, err)
assert.True(t, user_model.IsErrUserNotExist(err))
email = unittest.AssertExistsAndLoadBean(t, &user_model.EmailAddress{Email: "user101@example.com"})
err = user_model.MakeActiveEmailPrimary(db.DefaultContext, email.ID)
err = user_model.MakeActiveEmailPrimary(t.Context(), email.ID)
assert.NoError(t, err)
user, _ := user_model.GetUserByID(db.DefaultContext, int64(10))
user, _ := user_model.GetUserByID(t.Context(), int64(10))
assert.Equal(t, "user101@example.com", user.Email)
}
@@ -76,9 +76,9 @@ func TestActivate(t *testing.T) {
UID: int64(1),
Email: "user11@example.com",
}
assert.NoError(t, user_model.ActivateEmail(db.DefaultContext, email))
assert.NoError(t, user_model.ActivateEmail(t.Context(), email))
emails, _ := user_model.GetEmailAddresses(db.DefaultContext, int64(1))
emails, _ := user_model.GetEmailAddresses(t.Context(), int64(1))
assert.Len(t, emails, 3)
assert.True(t, emails[0].IsActivated)
assert.True(t, emails[0].IsPrimary)
@@ -96,7 +96,7 @@ func TestListEmails(t *testing.T) {
PageSize: 10000,
},
}
emails, count, err := user_model.SearchEmails(db.DefaultContext, opts)
emails, count, err := user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.Greater(t, count, int64(5))
@@ -110,13 +110,13 @@ func TestListEmails(t *testing.T) {
// Must find no records
opts = &user_model.SearchEmailOptions{Keyword: "NOTFOUND"}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
emails, count, err = user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.Equal(t, int64(0), count)
// Must find users 'user2', 'user28', etc.
opts = &user_model.SearchEmailOptions{Keyword: "user2"}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
emails, count, err = user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.NotEqual(t, int64(0), count)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.UID == 2 }))
@@ -124,14 +124,14 @@ func TestListEmails(t *testing.T) {
// Must find only primary addresses (i.e. from the `user` table)
opts = &user_model.SearchEmailOptions{IsPrimary: optional.Some(true)}
emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
emails, _, err = user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsPrimary }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsPrimary }))
// Must find only inactive addresses (i.e. not validated)
opts = &user_model.SearchEmailOptions{IsActivated: optional.Some(false)}
emails, _, err = user_model.SearchEmails(db.DefaultContext, opts)
emails, _, err = user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.True(t, contains(func(s *user_model.SearchEmailResult) bool { return !s.IsActivated }))
assert.False(t, contains(func(s *user_model.SearchEmailResult) bool { return s.IsActivated }))
@@ -143,7 +143,7 @@ func TestListEmails(t *testing.T) {
Page: 1,
},
}
emails, count, err = user_model.SearchEmails(db.DefaultContext, opts)
emails, count, err = user_model.SearchEmails(t.Context(), opts)
assert.NoError(t, err)
assert.Len(t, emails, 5)
assert.Greater(t, count, int64(len(emails)))
+5 -6
View File
@@ -6,7 +6,6 @@ package user_test
import (
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -15,9 +14,9 @@ import (
func TestIsFollowing(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
assert.True(t, user_model.IsFollowing(db.DefaultContext, 4, 2))
assert.False(t, user_model.IsFollowing(db.DefaultContext, 2, 4))
assert.False(t, user_model.IsFollowing(db.DefaultContext, 5, unittest.NonexistentID))
assert.False(t, user_model.IsFollowing(db.DefaultContext, unittest.NonexistentID, 5))
assert.False(t, user_model.IsFollowing(db.DefaultContext, unittest.NonexistentID, unittest.NonexistentID))
assert.True(t, user_model.IsFollowing(t.Context(), 4, 2))
assert.False(t, user_model.IsFollowing(t.Context(), 2, 4))
assert.False(t, user_model.IsFollowing(t.Context(), 5, unittest.NonexistentID))
assert.False(t, user_model.IsFollowing(t.Context(), unittest.NonexistentID, 5))
assert.False(t, user_model.IsFollowing(t.Context(), unittest.NonexistentID, unittest.NonexistentID))
}
+7 -8
View File
@@ -6,7 +6,6 @@ package user_test
import (
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -17,7 +16,7 @@ import (
func TestGetUserOpenIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(1))
oids, err := user_model.GetUserOpenIDs(t.Context(), int64(1))
if assert.NoError(t, err) && assert.Len(t, oids, 2) {
assert.Equal(t, "https://user1.domain1.tld/", oids[0].URI)
assert.False(t, oids[0].Show)
@@ -25,7 +24,7 @@ func TestGetUserOpenIDs(t *testing.T) {
assert.True(t, oids[1].Show)
}
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2))
if assert.NoError(t, err) && assert.Len(t, oids, 1) {
assert.Equal(t, "https://domain1.tld/user2/", oids[0].URI)
assert.True(t, oids[0].Show)
@@ -34,23 +33,23 @@ func TestGetUserOpenIDs(t *testing.T) {
func TestToggleUserOpenIDVisibility(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
oids, err := user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
oids, err := user_model.GetUserOpenIDs(t.Context(), int64(2))
require.NoError(t, err)
require.Len(t, oids, 1)
assert.True(t, oids[0].Show)
err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID)
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID)
require.NoError(t, err)
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2))
require.NoError(t, err)
require.Len(t, oids, 1)
assert.False(t, oids[0].Show)
err = user_model.ToggleUserOpenIDVisibility(db.DefaultContext, oids[0].ID)
err = user_model.ToggleUserOpenIDVisibility(t.Context(), oids[0].ID)
require.NoError(t, err)
oids, err = user_model.GetUserOpenIDs(db.DefaultContext, int64(2))
oids, err = user_model.GetUserOpenIDs(t.Context(), int64(2))
require.NoError(t, err)
if assert.Len(t, oids, 1) {
assert.True(t, oids[0].Show)
+2 -3
View File
@@ -6,7 +6,6 @@ package user_test
import (
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -16,10 +15,10 @@ import (
func TestLookupUserRedirect(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
userID, err := user_model.LookupUserRedirect(db.DefaultContext, "olduser1")
userID, err := user_model.LookupUserRedirect(t.Context(), "olduser1")
assert.NoError(t, err)
assert.EqualValues(t, 1, userID)
_, err = user_model.LookupUserRedirect(db.DefaultContext, "doesnotexist")
_, err = user_model.LookupUserRedirect(t.Context(), "doesnotexist")
assert.True(t, user_model.IsErrUserRedirectNotExist(err))
}
+9 -10
View File
@@ -6,7 +6,6 @@ package user_test
import (
"testing"
"code.gitea.io/gitea/models/db"
"code.gitea.io/gitea/models/unittest"
user_model "code.gitea.io/gitea/models/user"
@@ -20,41 +19,41 @@ func TestSettings(t *testing.T) {
newSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Gitea User Setting Test"}
// create setting
err := user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
err := user_model.SetUserSetting(t.Context(), newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
assert.NoError(t, err)
// test about saving unchanged values
err = user_model.SetUserSetting(db.DefaultContext, newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
err = user_model.SetUserSetting(t.Context(), newSetting.UserID, newSetting.SettingKey, newSetting.SettingValue)
assert.NoError(t, err)
// get specific setting
settings, err := user_model.GetSettings(db.DefaultContext, 99, []string{keyName})
settings, err := user_model.GetSettings(t.Context(), 99, []string{keyName})
assert.NoError(t, err)
assert.Len(t, settings, 1)
assert.Equal(t, newSetting.SettingValue, settings[keyName].SettingValue)
settingValue, err := user_model.GetUserSetting(db.DefaultContext, 99, keyName)
settingValue, err := user_model.GetUserSetting(t.Context(), 99, keyName)
assert.NoError(t, err)
assert.Equal(t, newSetting.SettingValue, settingValue)
settingValue, err = user_model.GetUserSetting(db.DefaultContext, 99, "no_such")
settingValue, err = user_model.GetUserSetting(t.Context(), 99, "no_such")
assert.NoError(t, err)
assert.Empty(t, settingValue)
// updated setting
updatedSetting := &user_model.Setting{UserID: 99, SettingKey: keyName, SettingValue: "Updated"}
err = user_model.SetUserSetting(db.DefaultContext, updatedSetting.UserID, updatedSetting.SettingKey, updatedSetting.SettingValue)
err = user_model.SetUserSetting(t.Context(), updatedSetting.UserID, updatedSetting.SettingKey, updatedSetting.SettingValue)
assert.NoError(t, err)
// get all settings
settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99)
settings, err = user_model.GetUserAllSettings(t.Context(), 99)
assert.NoError(t, err)
assert.Len(t, settings, 1)
assert.Equal(t, updatedSetting.SettingValue, settings[updatedSetting.SettingKey].SettingValue)
// delete setting
err = user_model.DeleteUserSetting(db.DefaultContext, 99, keyName)
err = user_model.DeleteUserSetting(t.Context(), 99, keyName)
assert.NoError(t, err)
settings, err = user_model.GetUserAllSettings(db.DefaultContext, 99)
settings, err = user_model.GetUserAllSettings(t.Context(), 99)
assert.NoError(t, err)
assert.Empty(t, settings)
}
+74 -71
View File
@@ -27,6 +27,7 @@ import (
"code.gitea.io/gitea/modules/base"
"code.gitea.io/gitea/modules/container"
"code.gitea.io/gitea/modules/git"
"code.gitea.io/gitea/modules/httplib"
"code.gitea.io/gitea/modules/log"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
@@ -303,8 +304,8 @@ func (u *User) HomeLink() string {
}
// HTMLURL returns the user or organization's full link.
func (u *User) HTMLURL() string {
return setting.AppURL + url.PathEscape(u.Name)
func (u *User) HTMLURL(ctx context.Context) string {
return httplib.MakeAbsoluteURL(ctx, u.HomeLink())
}
// OrganisationLink returns the organization sub page link.
@@ -715,90 +716,82 @@ func createUser(ctx context.Context, u *User, meta *Meta, createdByAdmin bool, o
}
}
ctx, committer, err := db.TxContext(ctx)
if err != nil {
return err
}
defer committer.Close()
isExist, err := IsUserExist(ctx, 0, u.Name)
if err != nil {
return err
} else if isExist {
return ErrUserAlreadyExist{u.Name}
}
isExist, err = IsEmailUsed(ctx, u.Email)
if err != nil {
return err
} else if isExist {
return ErrEmailAlreadyUsed{
Email: u.Email,
return db.WithTx(ctx, func(ctx context.Context) error {
isExist, err := IsUserExist(ctx, 0, u.Name)
if err != nil {
return err
} else if isExist {
return ErrUserAlreadyExist{u.Name}
}
}
// prepare for database
isExist, err = IsEmailUsed(ctx, u.Email)
if err != nil {
return err
} else if isExist {
return ErrEmailAlreadyUsed{
Email: u.Email,
}
}
u.LowerName = strings.ToLower(u.Name)
u.AvatarEmail = u.Email
if u.Rands, err = GetUserSalt(); err != nil {
return err
}
if u.Passwd != "" {
if err = u.SetPassword(u.Passwd); err != nil {
// prepare for database
u.LowerName = strings.ToLower(u.Name)
u.AvatarEmail = u.Email
if u.Rands, err = GetUserSalt(); err != nil {
return err
}
} else {
u.Salt = ""
u.PasswdHashAlgo = ""
}
if u.Passwd != "" {
if err = u.SetPassword(u.Passwd); err != nil {
return err
}
} else {
u.Salt = ""
u.PasswdHashAlgo = ""
}
// save changes to database
// save changes to database
if err = DeleteUserRedirect(ctx, u.Name); err != nil {
return err
}
if u.CreatedUnix == 0 {
// Caller expects auto-time for creation & update timestamps.
err = db.Insert(ctx, u)
} else {
// Caller sets the timestamps themselves. They are responsible for ensuring
// both `CreatedUnix` and `UpdatedUnix` are set appropriately.
_, err = db.GetEngine(ctx).NoAutoTime().Insert(u)
}
if err != nil {
return err
}
if setting.RecordUserSignupMetadata {
// insert initial IP and UserAgent
if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil {
if err = DeleteUserRedirect(ctx, u.Name); err != nil {
return err
}
// trim user agent string to a reasonable length, if necessary
userAgent := strings.TrimSpace(meta.InitialUserAgent)
if len(userAgent) > 255 {
userAgent = userAgent[:255]
if u.CreatedUnix == 0 {
// Caller expects auto-time for creation & update timestamps.
err = db.Insert(ctx, u)
} else {
// Caller sets the timestamps themselves. They are responsible for ensuring
// both `CreatedUnix` and `UpdatedUnix` are set appropriately.
_, err = db.GetEngine(ctx).NoAutoTime().Insert(u)
}
if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil {
if err != nil {
return err
}
}
// insert email address
if err := db.Insert(ctx, &EmailAddress{
UID: u.ID,
Email: u.Email,
LowerEmail: strings.ToLower(u.Email),
IsActivated: u.IsActive,
IsPrimary: true,
}); err != nil {
return err
}
if setting.RecordUserSignupMetadata {
// insert initial IP and UserAgent
if err = SetUserSetting(ctx, u.ID, SignupIP, meta.InitialIP); err != nil {
return err
}
return committer.Commit()
// trim user agent string to a reasonable length, if necessary
userAgent := strings.TrimSpace(meta.InitialUserAgent)
if len(userAgent) > 255 {
userAgent = userAgent[:255]
}
if err = SetUserSetting(ctx, u.ID, SignupUserAgent, userAgent); err != nil {
return err
}
}
// insert email address
return db.Insert(ctx, &EmailAddress{
UID: u.ID,
Email: u.Email,
LowerEmail: strings.ToLower(u.Email),
IsActivated: u.IsActive,
IsPrimary: true,
})
})
}
// ErrDeleteLastAdminUser represents a "DeleteLastAdminUser" kind of error.
@@ -955,6 +948,16 @@ func UpdateUserCols(ctx context.Context, u *User, cols ...string) error {
return err
}
// UpdateUserColsNoAutoTime update user according special columns
func UpdateUserColsNoAutoTime(ctx context.Context, u *User, cols ...string) error {
if err := ValidateUser(u, cols...); err != nil {
return err
}
_, err := db.GetEngine(ctx).ID(u.ID).Cols(cols...).NoAutoTime().Update(u)
return err
}
// GetInactiveUsers gets all inactive users
func GetInactiveUsers(ctx context.Context, olderThan time.Duration) ([]*User, error) {
cond := builder.And(
+3 -5
View File
@@ -6,27 +6,25 @@ package user
import (
"testing"
"code.gitea.io/gitea/models/db"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestSystemUser(t *testing.T) {
u, err := GetPossibleUserByID(db.DefaultContext, -1)
u, err := GetPossibleUserByID(t.Context(), -1)
require.NoError(t, err)
assert.Equal(t, "Ghost", u.Name)
assert.Equal(t, "ghost", u.LowerName)
assert.True(t, u.IsGhost())
assert.True(t, IsGhostUserName("gHost"))
u, err = GetPossibleUserByID(db.DefaultContext, -2)
u, err = GetPossibleUserByID(t.Context(), -2)
require.NoError(t, err)
assert.Equal(t, "gitea-actions", u.Name)
assert.Equal(t, "gitea-actions", u.LowerName)
assert.True(t, u.IsGiteaActions())
assert.True(t, IsGiteaActionsUserName("Gitea-actionS"))
_, err = GetPossibleUserByID(db.DefaultContext, -3)
_, err = GetPossibleUserByID(t.Context(), -3)
require.Error(t, err)
}
+28 -28
View File
@@ -44,7 +44,7 @@ func TestIsUsableUsername(t *testing.T) {
func TestOAuth2Application_LoadUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
app := unittest.AssertExistsAndLoadBean(t, &auth.OAuth2Application{ID: 1})
user, err := user_model.GetUserByID(db.DefaultContext, app.UID)
user, err := user_model.GetUserByID(t.Context(), app.UID)
assert.NoError(t, err)
assert.NotNil(t, user)
}
@@ -53,14 +53,14 @@ func TestUserEmails(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
t.Run("GetUserEmailsByNames", func(t *testing.T) {
// ignore none active user email
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user9"}))
assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "user5"}))
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(db.DefaultContext, []string{"user8", "org7"}))
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "user9"}))
assert.ElementsMatch(t, []string{"user8@example.com", "user5@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "user5"}))
assert.ElementsMatch(t, []string{"user8@example.com"}, user_model.GetUserEmailsByNames(t.Context(), []string{"user8", "org7"}))
})
t.Run("GetUsersByEmails", func(t *testing.T) {
defer test.MockVariableValue(&setting.Service.NoReplyAddress, "NoReply.gitea.internal")()
testGetUserByEmail := func(t *testing.T, email string, uid int64) {
m, err := user_model.GetUsersByEmails(db.DefaultContext, []string{email})
m, err := user_model.GetUsersByEmails(t.Context(), []string{email})
require.NoError(t, err)
user := m.GetByEmail(email)
if uid == 0 {
@@ -114,7 +114,7 @@ func TestCanCreateOrganization(t *testing.T) {
func TestSearchUsers(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(opts user_model.SearchUserOptions, expectedUserOrOrgIDs []int64) {
users, _, err := user_model.SearchUsers(db.DefaultContext, opts)
users, _, err := user_model.SearchUsers(t.Context(), opts)
assert.NoError(t, err)
cassText := fmt.Sprintf("ids: %v, opts: %v", expectedUserOrOrgIDs, opts)
if assert.Len(t, users, len(expectedUserOrOrgIDs), "case: %s", cassText) {
@@ -243,7 +243,7 @@ func BenchmarkHashPassword(b *testing.B) {
func TestNewGitSig(t *testing.T) {
users := make([]*user_model.User, 0, 20)
err := db.GetEngine(db.DefaultContext).Find(&users)
err := db.GetEngine(t.Context()).Find(&users)
assert.NoError(t, err)
for _, user := range users {
@@ -257,7 +257,7 @@ func TestNewGitSig(t *testing.T) {
func TestDisplayName(t *testing.T) {
users := make([]*user_model.User, 0, 20)
err := db.GetEngine(db.DefaultContext).Find(&users)
err := db.GetEngine(t.Context()).Find(&users)
assert.NoError(t, err)
for _, user := range users {
@@ -280,7 +280,7 @@ func TestCreateUserInvalidEmail(t *testing.T) {
MustChangePassword: false,
}
err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{})
err := user_model.CreateUser(t.Context(), user, &user_model.Meta{})
assert.Error(t, err)
assert.True(t, user_model.IsErrEmailCharIsNotSupported(err))
}
@@ -294,7 +294,7 @@ func TestCreateUserEmailAlreadyUsed(t *testing.T) {
user.Name = "testuser"
user.LowerName = strings.ToLower(user.Name)
user.ID = 0
err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{})
err := user_model.CreateUser(t.Context(), user, &user_model.Meta{})
assert.Error(t, err)
assert.True(t, user_model.IsErrEmailAlreadyUsed(err))
}
@@ -311,7 +311,7 @@ func TestCreateUserCustomTimestamps(t *testing.T) {
user.ID = 0
user.Email = "unique@example.com"
user.CreatedUnix = creationTimestamp
err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{})
err := user_model.CreateUser(t.Context(), user, &user_model.Meta{})
assert.NoError(t, err)
fetched, err := user_model.GetUserByID(t.Context(), user.ID)
@@ -336,7 +336,7 @@ func TestCreateUserWithoutCustomTimestamps(t *testing.T) {
user.Email = "unique@example.com"
user.CreatedUnix = 0
user.UpdatedUnix = 0
err := user_model.CreateUser(db.DefaultContext, user, &user_model.Meta{})
err := user_model.CreateUser(t.Context(), user, &user_model.Meta{})
assert.NoError(t, err)
timestampEnd := time.Now().Unix()
@@ -355,12 +355,12 @@ func TestGetUserIDsByNames(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
// ignore non existing
IDs, err := user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "user2", "none_existing_user"}, true)
IDs, err := user_model.GetUserIDsByNames(t.Context(), []string{"user1", "user2", "none_existing_user"}, true)
assert.NoError(t, err)
assert.Equal(t, []int64{1, 2}, IDs)
// ignore non existing
IDs, err = user_model.GetUserIDsByNames(db.DefaultContext, []string{"user1", "do_not_exist"}, false)
IDs, err = user_model.GetUserIDsByNames(t.Context(), []string{"user1", "do_not_exist"}, false)
assert.Error(t, err)
assert.Equal(t, []int64(nil), IDs)
}
@@ -368,14 +368,14 @@ func TestGetUserIDsByNames(t *testing.T) {
func TestGetMaileableUsersByIDs(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
results, err := user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, false)
results, err := user_model.GetMailableUsersByIDs(t.Context(), []int64{1, 4}, false)
assert.NoError(t, err)
assert.Len(t, results, 1)
if len(results) > 1 {
assert.Equal(t, 1, results[0].ID)
}
results, err = user_model.GetMailableUsersByIDs(db.DefaultContext, []int64{1, 4}, true)
results, err = user_model.GetMailableUsersByIDs(t.Context(), []int64{1, 4}, true)
assert.NoError(t, err)
assert.Len(t, results, 2)
if len(results) > 2 {
@@ -389,7 +389,7 @@ func TestNewUserRedirect(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -406,7 +406,7 @@ func TestNewUserRedirect2(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 1})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "olduser1"))
assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "olduser1"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -423,7 +423,7 @@ func TestNewUserRedirect3(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
user := unittest.AssertExistsAndLoadBean(t, &user_model.User{ID: 2})
assert.NoError(t, user_model.NewUserRedirect(db.DefaultContext, user.ID, user.Name, "newusername"))
assert.NoError(t, user_model.NewUserRedirect(t.Context(), user.ID, user.Name, "newusername"))
unittest.AssertExistsAndLoadBean(t, &user_model.Redirect{
LowerName: user.LowerName,
@@ -434,17 +434,17 @@ func TestNewUserRedirect3(t *testing.T) {
func TestGetUserByOpenID(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
_, err := user_model.GetUserByOpenID(db.DefaultContext, "https://unknown")
_, err := user_model.GetUserByOpenID(t.Context(), "https://unknown")
if assert.Error(t, err) {
assert.True(t, user_model.IsErrUserNotExist(err))
}
user, err := user_model.GetUserByOpenID(db.DefaultContext, "https://user1.domain1.tld")
user, err := user_model.GetUserByOpenID(t.Context(), "https://user1.domain1.tld")
if assert.NoError(t, err) {
assert.Equal(t, int64(1), user.ID)
}
user, err = user_model.GetUserByOpenID(db.DefaultContext, "https://domain1.tld/user2/")
user, err = user_model.GetUserByOpenID(t.Context(), "https://domain1.tld/user2/")
if assert.NoError(t, err) {
assert.Equal(t, int64(2), user.ID)
}
@@ -454,7 +454,7 @@ func TestFollowUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(follower, followed *user_model.User) {
assert.NoError(t, user_model.FollowUser(db.DefaultContext, follower, followed))
assert.NoError(t, user_model.FollowUser(t.Context(), follower, followed))
unittest.AssertExistsAndLoadBean(t, &user_model.Follow{UserID: follower.ID, FollowID: followed.ID})
}
@@ -465,7 +465,7 @@ func TestFollowUser(t *testing.T) {
testSuccess(user4, user2)
testSuccess(user5, user2)
assert.NoError(t, user_model.FollowUser(db.DefaultContext, user2, user2))
assert.NoError(t, user_model.FollowUser(t.Context(), user2, user2))
unittest.CheckConsistencyFor(t, &user_model.User{})
}
@@ -474,7 +474,7 @@ func TestUnfollowUser(t *testing.T) {
assert.NoError(t, unittest.PrepareTestDatabase())
testSuccess := func(followerID, followedID int64) {
assert.NoError(t, user_model.UnfollowUser(db.DefaultContext, followerID, followedID))
assert.NoError(t, user_model.UnfollowUser(t.Context(), followerID, followedID))
unittest.AssertNotExistsBean(t, &user_model.Follow{UserID: followerID, FollowID: followedID})
}
testSuccess(4, 2)
@@ -501,7 +501,7 @@ func TestIsUserVisibleToViewer(t *testing.T) {
}
return u.Name
}
assert.Equal(t, expected, user_model.IsUserVisibleToViewer(db.DefaultContext, u, viewer), "user %v should be visible to viewer %v: %v", name(u), name(viewer), expected)
assert.Equal(t, expected, user_model.IsUserVisibleToViewer(t.Context(), u, viewer), "user %v should be visible to viewer %v: %v", name(u), name(viewer), expected)
}
// admin viewer
@@ -636,11 +636,11 @@ func TestGetInactiveUsers(t *testing.T) {
// all inactive users
// user1's createdunix is 1730468968
users, err := user_model.GetInactiveUsers(db.DefaultContext, 0)
users, err := user_model.GetInactiveUsers(t.Context(), 0)
assert.NoError(t, err)
assert.Len(t, users, 1)
interval := time.Now().Unix() - 1730468968 + 3600*24
users, err = user_model.GetInactiveUsers(db.DefaultContext, time.Duration(interval*int64(time.Second)))
users, err = user_model.GetInactiveUsers(t.Context(), time.Duration(interval*int64(time.Second)))
assert.NoError(t, err)
assert.Empty(t, users)
}