mirror of
https://github.com/go-gitea/gitea.git
synced 2026-09-23 11:06:47 +02:00
Merge branch 'main' into ssh-mirroring
This commit is contained in:
@@ -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())
|
||||
|
||||
@@ -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,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)))
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
}
|
||||
|
||||
@@ -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
@@ -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(
|
||||
|
||||
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user