Changes
23 changed files (+547/-603)
-
-
@@ -1624,46 +1624,6 @@ func (err ErrUploadNotExist) Error() string {return fmt.Sprintf("attachment does not exist [id: %d, uuid: %s]", err.ID, err.UUID) } // ___________ __ .__ .____ .__ ____ ___ // \_ _____/__ ____/ |_ ___________ ____ _____ | | | | ____ ____ |__| ____ | | \______ ___________ // | __)_\ \/ /\ __\/ __ \_ __ \/ \\__ \ | | | | / _ \ / ___\| |/ \ | | / ___// __ \_ __ \ // | \> < | | \ ___/| | \/ | \/ __ \| |__ | |__( <_> ) /_/ > | | \ | | /\___ \\ ___/| | \/ // /_______ /__/\_ \ |__| \___ >__| |___| (____ /____/ |_______ \____/\___ /|__|___| / |______//____ >\___ >__| // \/ \/ \/ \/ \/ \/ /_____/ \/ \/ \/ // ErrExternalLoginUserAlreadyExist represents a "ExternalLoginUserAlreadyExist" kind of error. type ErrExternalLoginUserAlreadyExist struct { ExternalID string UserID int64 LoginSourceID int64 } // IsErrExternalLoginUserAlreadyExist checks if an error is a ExternalLoginUserAlreadyExist. func IsErrExternalLoginUserAlreadyExist(err error) bool { _, ok := err.(ErrExternalLoginUserAlreadyExist) return ok } func (err ErrExternalLoginUserAlreadyExist) Error() string { return fmt.Sprintf("external login user already exists [externalID: %s, userID: %d, loginSourceID: %d]", err.ExternalID, err.UserID, err.LoginSourceID) } // ErrExternalLoginUserNotExist represents a "ExternalLoginUserNotExist" kind of error. type ErrExternalLoginUserNotExist struct { UserID int64 LoginSourceID int64 } // IsErrExternalLoginUserNotExist checks if an error is a ExternalLoginUserNotExist. func IsErrExternalLoginUserNotExist(err error) bool { _, ok := err.(ErrExternalLoginUserNotExist) return ok } func (err ErrExternalLoginUserNotExist) Error() string { return fmt.Sprintf("external login user link does not exists [userID: %d, loginSourceID: %d]", err.UserID, err.LoginSourceID) } // .___ ________ .___ .__ // | | ______ ________ __ ____ \______ \ ____ ______ ____ ____ __| _/____ ____ ____ |__| ____ ______ // | |/ ___// ___/ | \_/ __ \ | | \_/ __ \\____ \_/ __ \ / \ / __ |/ __ \ / \_/ ___\| |/ __ \ / ___/
-
-
-
@@ -245,3 +245,23 @@ func UpdateReviewsMigrationsByType(tp structs.GitServiceType, originalAuthorID s}) return err } // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, userID int64) error { if err := UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { return err } return UpdateReviewsMigrationsByType(tp, externalUserID, userID) }
-
-
-
@@ -81,7 +81,7 @@ func (org *Organization) LoadTeams() ([]*Team, error) {} // GetMembers returns all members of organization. func (org *Organization) GetMembers() (UserList, map[int64]bool, error) { func (org *Organization) GetMembers() (user_model.UserList, map[int64]bool, error) { return FindOrgMembers(&FindOrgMembersOpts{ OrgID: org.ID, })
-
@@ -149,7 +149,7 @@ func CountOrgMembers(opts *FindOrgMembersOpts) (int64, error) {} // FindOrgMembers loads organization members according conditions func FindOrgMembers(opts *FindOrgMembersOpts) (UserList, map[int64]bool, error) { func FindOrgMembers(opts *FindOrgMembersOpts) (user_model.UserList, map[int64]bool, error) { ous, err := GetOrgUsersByOrgID(opts) if err != nil { return nil, nil, err
-
@@ -162,7 +162,7 @@ func FindOrgMembers(opts *FindOrgMembersOpts) (UserList, map[int64]bool, error)idsIsPublic[ou.UID] = ou.IsPublic } users, err := GetUsersByIDs(ids) users, err := user_model.GetUsersByIDs(ids) if err != nil { return nil, nil, err }
-
-
-
@@ -260,7 +260,7 @@ func DeleteUser(ctx context.Context, u *user_model.User) (err error) {} // ***** START: ExternalLoginUser ***** if err = removeAllAccountLinks(e, u); err != nil { if err = user_model.RemoveAllAccountLinks(ctx, u); err != nil { return fmt.Errorf("ExternalLoginUser: %v", err) } // ***** END: ExternalLoginUser *****
-
-
-
@@ -13,8 +13,10 @@ import ("strings" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "xorm.io/builder" )
-
@@ -275,3 +277,247 @@ func DeleteInactiveEmailAddresses(ctx context.Context) error {Delete(new(EmailAddress)) return err } // ActivateEmail activates the email address to given user. func ActivateEmail(email *EmailAddress) error { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if err := updateActivation(db.GetEngine(ctx), email, true); err != nil { return err } return committer.Commit() } func updateActivation(e db.Engine, email *EmailAddress, activate bool) error { user, err := GetUserByIDEngine(e, email.UID) if err != nil { return err } if user.Rands, err = GetUserSalt(); err != nil { return err } email.IsActivated = activate if _, err := e.ID(email.ID).Cols("is_activated").Update(email); err != nil { return err } return UpdateUserColsEngine(e, user, "rands") } // MakeEmailPrimary sets primary email address of given user. func MakeEmailPrimary(email *EmailAddress) error { has, err := db.GetEngine(db.DefaultContext).Get(email) if err != nil { return err } else if !has { return ErrEmailAddressNotExist{Email: email.Email} } if !email.IsActivated { return ErrEmailNotActivated } user := &User{} has, err = db.GetEngine(db.DefaultContext).ID(email.UID).Get(user) if err != nil { return err } else if !has { return ErrUserNotExist{ UID: email.UID, Name: "", KeyID: 0, } } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() sess := db.GetEngine(ctx) // 1. Update user table user.Email = email.Email if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil { return err } // 2. Update old primary email if _, err = sess.Where("uid=? AND is_primary=?", email.UID, true).Cols("is_primary").Update(&EmailAddress{ IsPrimary: false, }); err != nil { return err } // 3. update new primary email email.IsPrimary = true if _, err = sess.ID(email.ID).Cols("is_primary").Update(email); err != nil { return err } return committer.Commit() } // VerifyActiveEmailCode verifies active email code when active account func VerifyActiveEmailCode(code, email string) *EmailAddress { minutes := setting.Service.ActiveCodeLives if user := GetVerifyUser(code); user != nil { // time limit code prefix := code[:base.TimeLimitCodeLength] data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands) if base.VerifyTimeLimitCode(data, minutes, prefix) { emailAddress := &EmailAddress{UID: user.ID, Email: email} if has, _ := db.GetEngine(db.DefaultContext).Get(emailAddress); has { return emailAddress } } } return nil } // SearchEmailOrderBy is used to sort the results from SearchEmails() type SearchEmailOrderBy string func (s SearchEmailOrderBy) String() string { return string(s) } // Strings for sorting result const ( SearchEmailOrderByEmail SearchEmailOrderBy = "email_address.lower_email ASC, email_address.is_primary DESC, email_address.id ASC" SearchEmailOrderByEmailReverse SearchEmailOrderBy = "email_address.lower_email DESC, email_address.is_primary ASC, email_address.id DESC" SearchEmailOrderByName SearchEmailOrderBy = "`user`.lower_name ASC, email_address.is_primary DESC, email_address.id ASC" SearchEmailOrderByNameReverse SearchEmailOrderBy = "`user`.lower_name DESC, email_address.is_primary ASC, email_address.id DESC" ) // SearchEmailOptions are options to search e-mail addresses for the admin panel type SearchEmailOptions struct { db.ListOptions Keyword string SortType SearchEmailOrderBy IsPrimary util.OptionalBool IsActivated util.OptionalBool } // SearchEmailResult is an e-mail address found in the user or email_address table type SearchEmailResult struct { UID int64 Email string IsActivated bool IsPrimary bool // From User Name string FullName string } // SearchEmails takes options i.e. keyword and part of email name to search, // it returns results in given range and number of total results. func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error) { var cond builder.Cond = builder.Eq{"`user`.`type`": UserTypeIndividual} if len(opts.Keyword) > 0 { likeStr := "%" + strings.ToLower(opts.Keyword) + "%" cond = cond.And(builder.Or( builder.Like{"lower(`user`.full_name)", likeStr}, builder.Like{"`user`.lower_name", likeStr}, builder.Like{"email_address.lower_email", likeStr}, )) } switch { case opts.IsPrimary.IsTrue(): cond = cond.And(builder.Eq{"email_address.is_primary": true}) case opts.IsPrimary.IsFalse(): cond = cond.And(builder.Eq{"email_address.is_primary": false}) } switch { case opts.IsActivated.IsTrue(): cond = cond.And(builder.Eq{"email_address.is_activated": true}) case opts.IsActivated.IsFalse(): cond = cond.And(builder.Eq{"email_address.is_activated": false}) } count, err := db.GetEngine(db.DefaultContext).Join("INNER", "`user`", "`user`.ID = email_address.uid"). Where(cond).Count(new(EmailAddress)) if err != nil { return nil, 0, fmt.Errorf("Count: %v", err) } orderby := opts.SortType.String() if orderby == "" { orderby = SearchEmailOrderByEmail.String() } opts.SetDefaultValues() emails := make([]*SearchEmailResult, 0, opts.PageSize) err = db.GetEngine(db.DefaultContext).Table("email_address"). Select("email_address.*, `user`.name, `user`.full_name"). Join("INNER", "`user`", "`user`.ID = email_address.uid"). Where(cond). OrderBy(orderby). Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). Find(&emails) return emails, count, err } // ActivateUserEmail will change the activated state of an email address, // either primary or secondary (all in the email_address table) func ActivateUserEmail(userID int64, email string, activate bool) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() sess := db.GetEngine(ctx) // Activate/deactivate a user's secondary email address // First check if there's another user active with the same address addr := EmailAddress{UID: userID, LowerEmail: strings.ToLower(email)} if has, err := sess.Get(&addr); err != nil { return err } else if !has { 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: %v", email, err) } else if used { return ErrEmailAlreadyUsed{Email: email} } } if err = updateActivation(sess, &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 := User{ID: userID, Email: email} if has, err := sess.Get(&user); err != nil { return err } else if !has { 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: %v", err) } if err = UpdateUserColsEngine(sess, &user, "is_active", "rands"); err != nil { return fmt.Errorf("unable to updateUserCols() for user ID: %d: %v", userID, err) } } } return committer.Commit() }
-
-
-
@@ -9,6 +9,7 @@ import ("code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" )
-
@@ -130,3 +131,124 @@ func TestDeleteEmailAddresses(t *testing.T) {err := DeleteEmailAddresses(emails) assert.Error(t, err) } func TestMakeEmailPrimary(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) email := &EmailAddress{ Email: "user567890@example.com", } err := MakeEmailPrimary(email) assert.Error(t, err) assert.EqualError(t, err, ErrEmailAddressNotExist{Email: email.Email}.Error()) email = &EmailAddress{ Email: "user11@example.com", } err = MakeEmailPrimary(email) assert.Error(t, err) assert.EqualError(t, err, ErrEmailNotActivated.Error()) email = &EmailAddress{ Email: "user9999999@example.com", } err = MakeEmailPrimary(email) assert.Error(t, err) assert.True(t, IsErrUserNotExist(err)) email = &EmailAddress{ Email: "user101@example.com", } err = MakeEmailPrimary(email) assert.NoError(t, err) user, _ := GetUserByID(int64(10)) assert.Equal(t, "user101@example.com", user.Email) } func TestActivate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) email := &EmailAddress{ ID: int64(1), UID: int64(1), Email: "user11@example.com", } assert.NoError(t, ActivateEmail(email)) emails, _ := GetEmailAddresses(int64(1)) assert.Len(t, emails, 3) assert.True(t, emails[0].IsActivated) assert.True(t, emails[0].IsPrimary) assert.False(t, emails[1].IsPrimary) assert.True(t, emails[2].IsActivated) assert.False(t, emails[2].IsPrimary) } func TestListEmails(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Must find all users and their emails opts := &SearchEmailOptions{ ListOptions: db.ListOptions{ PageSize: 10000, }, } emails, count, err := SearchEmails(opts) assert.NoError(t, err) assert.NotEqual(t, int64(0), count) assert.True(t, count > 5) contains := func(match func(s *SearchEmailResult) bool) bool { for _, v := range emails { if match(v) { return true } } return false } assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 18 })) // 'user3' is an organization assert.False(t, contains(func(s *SearchEmailResult) bool { return s.UID == 3 })) // Must find no records opts = &SearchEmailOptions{Keyword: "NOTFOUND"} emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.Equal(t, int64(0), count) // Must find users 'user2', 'user28', etc. opts = &SearchEmailOptions{Keyword: "user2"} emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.NotEqual(t, int64(0), count) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 2 })) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 27 })) // Must find only primary addresses (i.e. from the `user` table) opts = &SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} emails, _, err = SearchEmails(opts) assert.NoError(t, err) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.IsPrimary })) assert.False(t, contains(func(s *SearchEmailResult) bool { return !s.IsPrimary })) // Must find only inactive addresses (i.e. not validated) opts = &SearchEmailOptions{IsActivated: util.OptionalBoolFalse} emails, _, err = SearchEmails(opts) assert.NoError(t, err) assert.True(t, contains(func(s *SearchEmailResult) bool { return !s.IsActivated })) assert.False(t, contains(func(s *SearchEmailResult) bool { return s.IsActivated })) // Must find more than one page, but retrieve only one opts = &SearchEmailOptions{ ListOptions: db.ListOptions{ PageSize: 5, Page: 1, }, } emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.Len(t, emails, 5) assert.Greater(t, count, int64(len(emails))) }
-
-
-
@@ -2,20 +2,53 @@// Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models package user import ( "context" "fmt" "time" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/structs" "github.com/markbates/goth" "xorm.io/builder" ) // ErrExternalLoginUserAlreadyExist represents a "ExternalLoginUserAlreadyExist" kind of error. type ErrExternalLoginUserAlreadyExist struct { ExternalID string UserID int64 LoginSourceID int64 } // IsErrExternalLoginUserAlreadyExist checks if an error is a ExternalLoginUserAlreadyExist. func IsErrExternalLoginUserAlreadyExist(err error) bool { _, ok := err.(ErrExternalLoginUserAlreadyExist) return ok } func (err ErrExternalLoginUserAlreadyExist) Error() string { return fmt.Sprintf("external login user already exists [externalID: %s, userID: %d, loginSourceID: %d]", err.ExternalID, err.UserID, err.LoginSourceID) } // ErrExternalLoginUserNotExist represents a "ExternalLoginUserNotExist" kind of error. type ErrExternalLoginUserNotExist struct { UserID int64 LoginSourceID int64 } // IsErrExternalLoginUserNotExist checks if an error is a ExternalLoginUserNotExist. func IsErrExternalLoginUserNotExist(err error) bool { _, ok := err.(ErrExternalLoginUserNotExist) return ok } func (err ErrExternalLoginUserNotExist) Error() string { return fmt.Sprintf("external login user link does not exists [userID: %d, loginSourceID: %d]", err.UserID, err.LoginSourceID) } // ExternalLoginUser makes the connecting between some existing user and additional external login sources type ExternalLoginUser struct { ExternalID string `xorm:"pk NOT NULL"`
-
@@ -47,7 +80,7 @@ func GetExternalLogin(externalLoginUser *ExternalLoginUser) (bool, error) {} // ListAccountLinks returns a map with the ExternalLoginUser and its LoginSource func ListAccountLinks(user *user_model.User) ([]*ExternalLoginUser, error) { func ListAccountLinks(user *User) ([]*ExternalLoginUser, error) { externalAccounts := make([]*ExternalLoginUser, 0, 5) err := db.GetEngine(db.DefaultContext).Where("user_id=?", user.ID). Desc("login_source_id").
-
@@ -60,7 +93,7 @@ func ListAccountLinks(user *user_model.User) ([]*ExternalLoginUser, error) {} // LinkExternalToUser link the external user to the user func LinkExternalToUser(user *user_model.User, externalLoginUser *ExternalLoginUser) error { func LinkExternalToUser(user *User, externalLoginUser *ExternalLoginUser) error { has, err := db.GetEngine(db.DefaultContext).Where("external_id=? AND login_source_id=?", externalLoginUser.ExternalID, externalLoginUser.LoginSourceID). NoAutoCondition(). Exist(externalLoginUser)
-
@@ -75,7 +108,7 @@ func LinkExternalToUser(user *user_model.User, externalLoginUser *ExternalLoginU} // RemoveAccountLink will remove all external login sources for the given user func RemoveAccountLink(user *user_model.User, loginSourceID int64) (int64, error) { func RemoveAccountLink(user *User, loginSourceID int64) (int64, error) { deleted, err := db.GetEngine(db.DefaultContext).Delete(&ExternalLoginUser{UserID: user.ID, LoginSourceID: loginSourceID}) if err != nil { return deleted, err
-
@@ -86,9 +119,9 @@ func RemoveAccountLink(user *user_model.User, loginSourceID int64) (int64, errorreturn deleted, err } // removeAllAccountLinks will remove all external login sources for the given user func removeAllAccountLinks(e db.Engine, user *user_model.User) error { _, err := e.Delete(&ExternalLoginUser{UserID: user.ID}) // RemoveAllAccountLinks will remove all external login sources for the given user func RemoveAllAccountLinks(ctx context.Context, user *User) error { _, err := db.GetEngine(ctx).Delete(&ExternalLoginUser{UserID: user.ID}) return err }
-
@@ -107,7 +140,7 @@ func GetUserIDByExternalUserID(provider, userID string) (int64, error) {} // UpdateExternalUser updates external user's information func UpdateExternalUser(user *user_model.User, gothUser goth.User) error { func UpdateExternalUser(user *User, gothUser goth.User) error { loginSource, err := login.GetActiveOAuth2LoginSourceByName(gothUser.Provider) if err != nil { return err
-
@@ -172,23 +205,3 @@ func FindExternalUsersByProvider(opts FindExternalUserOptions) ([]ExternalLoginU} return users, nil } // UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID string, userID int64) error { if err := UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateReleasesMigrationsByType(tp, externalUserID, userID); err != nil { return err } if err := UpdateReactionsMigrationsByType(tp, externalUserID, userID); err != nil { return err } return UpdateReviewsMigrationsByType(tp, externalUserID, userID) }
-
-
models/user/list.go (new)
-
@@ -0,0 +1,69 @@// Copyright 2019 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package user import ( "fmt" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" ) // UserList is a list of user. // This type provide valuable methods to retrieve information for a group of users efficiently. type UserList []*User //revive:disable-line:exported // GetUserIDs returns a slice of user's id func (users UserList) GetUserIDs() []int64 { userIDs := make([]int64, len(users)) for _, user := range users { userIDs = append(userIDs, user.ID) // Considering that user id are unique in the list } return userIDs } // GetTwoFaStatus return state of 2FA enrollement func (users UserList) GetTwoFaStatus() map[int64]bool { results := make(map[int64]bool, len(users)) for _, user := range users { results[user.ID] = false // Set default to false } tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext)) if err == nil { for _, token := range tokenMaps { results[token.UID] = true } } return results } func (users UserList) loadTwoFactorStatus(e db.Engine) (map[int64]*login.TwoFactor, error) { if len(users) == 0 { return nil, nil } userIDs := users.GetUserIDs() tokenMaps := make(map[int64]*login.TwoFactor, len(userIDs)) err := e. In("uid", userIDs). Find(&tokenMaps) if err != nil { return nil, fmt.Errorf("find two factor: %v", err) } return tokenMaps, nil } // GetUsersByIDs returns all resolved users from a list of Ids. func GetUsersByIDs(ids []int64) (UserList, error) { ous := make([]*User, 0, len(ids)) if len(ids) == 0 { return ous, nil } err := db.GetEngine(db.DefaultContext).In("id", ids). Asc("name"). Find(&ous) return ous, err }
-
-
models/user_email.go (deleted)
-
@@ -1,262 +0,0 @@// Copyright 2021 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models import ( "fmt" "strings" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base" "code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/util" "xorm.io/builder" ) // ActivateEmail activates the email address to given user. func ActivateEmail(email *user_model.EmailAddress) error { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() if err := updateActivation(db.GetEngine(ctx), email, true); err != nil { return err } return committer.Commit() } func updateActivation(e db.Engine, email *user_model.EmailAddress, activate bool) error { user, err := user_model.GetUserByIDEngine(e, email.UID) if err != nil { return err } if user.Rands, err = user_model.GetUserSalt(); err != nil { return err } email.IsActivated = activate if _, err := e.ID(email.ID).Cols("is_activated").Update(email); err != nil { return err } return user_model.UpdateUserColsEngine(e, user, "rands") } // MakeEmailPrimary sets primary email address of given user. func MakeEmailPrimary(email *user_model.EmailAddress) error { has, err := db.GetEngine(db.DefaultContext).Get(email) if err != nil { return err } else if !has { return user_model.ErrEmailAddressNotExist{Email: email.Email} } if !email.IsActivated { return user_model.ErrEmailNotActivated } user := &user_model.User{} has, err = db.GetEngine(db.DefaultContext).ID(email.UID).Get(user) if err != nil { return err } else if !has { return user_model.ErrUserNotExist{ UID: email.UID, Name: "", KeyID: 0, } } ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() sess := db.GetEngine(ctx) // 1. Update user table user.Email = email.Email if _, err = sess.ID(user.ID).Cols("email").Update(user); err != nil { return err } // 2. Update old primary email if _, err = sess.Where("uid=? AND is_primary=?", email.UID, true).Cols("is_primary").Update(&user_model.EmailAddress{ IsPrimary: false, }); err != nil { return err } // 3. update new primary email email.IsPrimary = true if _, err = sess.ID(email.ID).Cols("is_primary").Update(email); err != nil { return err } return committer.Commit() } // VerifyActiveEmailCode verifies active email code when active account func VerifyActiveEmailCode(code, email string) *user_model.EmailAddress { minutes := setting.Service.ActiveCodeLives if user := user_model.GetVerifyUser(code); user != nil { // time limit code prefix := code[:base.TimeLimitCodeLength] data := fmt.Sprintf("%d%s%s%s%s", user.ID, email, user.LowerName, user.Passwd, user.Rands) if base.VerifyTimeLimitCode(data, minutes, prefix) { emailAddress := &user_model.EmailAddress{UID: user.ID, Email: email} if has, _ := db.GetEngine(db.DefaultContext).Get(emailAddress); has { return emailAddress } } } return nil } // SearchEmailOrderBy is used to sort the results from SearchEmails() type SearchEmailOrderBy string func (s SearchEmailOrderBy) String() string { return string(s) } // Strings for sorting result const ( SearchEmailOrderByEmail SearchEmailOrderBy = "email_address.lower_email ASC, email_address.is_primary DESC, email_address.id ASC" SearchEmailOrderByEmailReverse SearchEmailOrderBy = "email_address.lower_email DESC, email_address.is_primary ASC, email_address.id DESC" SearchEmailOrderByName SearchEmailOrderBy = "`user`.lower_name ASC, email_address.is_primary DESC, email_address.id ASC" SearchEmailOrderByNameReverse SearchEmailOrderBy = "`user`.lower_name DESC, email_address.is_primary ASC, email_address.id DESC" ) // SearchEmailOptions are options to search e-mail addresses for the admin panel type SearchEmailOptions struct { db.ListOptions Keyword string SortType SearchEmailOrderBy IsPrimary util.OptionalBool IsActivated util.OptionalBool } // SearchEmailResult is an e-mail address found in the user or email_address table type SearchEmailResult struct { UID int64 Email string IsActivated bool IsPrimary bool // From User Name string FullName string } // SearchEmails takes options i.e. keyword and part of email name to search, // it returns results in given range and number of total results. func SearchEmails(opts *SearchEmailOptions) ([]*SearchEmailResult, int64, error) { var cond builder.Cond = builder.Eq{"`user`.`type`": user_model.UserTypeIndividual} if len(opts.Keyword) > 0 { likeStr := "%" + strings.ToLower(opts.Keyword) + "%" cond = cond.And(builder.Or( builder.Like{"lower(`user`.full_name)", likeStr}, builder.Like{"`user`.lower_name", likeStr}, builder.Like{"email_address.lower_email", likeStr}, )) } switch { case opts.IsPrimary.IsTrue(): cond = cond.And(builder.Eq{"email_address.is_primary": true}) case opts.IsPrimary.IsFalse(): cond = cond.And(builder.Eq{"email_address.is_primary": false}) } switch { case opts.IsActivated.IsTrue(): cond = cond.And(builder.Eq{"email_address.is_activated": true}) case opts.IsActivated.IsFalse(): cond = cond.And(builder.Eq{"email_address.is_activated": false}) } count, err := db.GetEngine(db.DefaultContext).Join("INNER", "`user`", "`user`.ID = email_address.uid"). Where(cond).Count(new(user_model.EmailAddress)) if err != nil { return nil, 0, fmt.Errorf("Count: %v", err) } orderby := opts.SortType.String() if orderby == "" { orderby = SearchEmailOrderByEmail.String() } opts.SetDefaultValues() emails := make([]*SearchEmailResult, 0, opts.PageSize) err = db.GetEngine(db.DefaultContext).Table("email_address"). Select("email_address.*, `user`.name, `user`.full_name"). Join("INNER", "`user`", "`user`.ID = email_address.uid"). Where(cond). OrderBy(orderby). Limit(opts.PageSize, (opts.Page-1)*opts.PageSize). Find(&emails) return emails, count, err } // ActivateUserEmail will change the activated state of an email address, // either primary or secondary (all in the email_address table) func ActivateUserEmail(userID int64, email string, activate bool) (err error) { ctx, committer, err := db.TxContext() if err != nil { return err } defer committer.Close() sess := db.GetEngine(ctx) // Activate/deactivate a user's secondary email address // First check if there's another user active with the same address addr := user_model.EmailAddress{UID: userID, LowerEmail: strings.ToLower(email)} if has, err := sess.Get(&addr); err != nil { return err } else if !has { 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 := user_model.IsEmailActive(ctx, email, addr.ID); err != nil { return fmt.Errorf("unable to check isEmailActive() for %s: %v", email, err) } else if used { return user_model.ErrEmailAlreadyUsed{Email: email} } } if err = updateActivation(sess, &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 := user_model.User{ID: userID, Email: email} if has, err := sess.Get(&user); err != nil { return err } else if !has { 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 = user_model.GetUserSalt(); err != nil { return fmt.Errorf("unable to generate salt: %v", err) } if err = user_model.UpdateUserColsEngine(sess, &user, "is_active", "rands"); err != nil { return fmt.Errorf("unable to updateUserCols() for user ID: %d: %v", userID, err) } } } return committer.Commit() }
-
-
models/user_email_test.go (deleted)
-
@@ -1,137 +0,0 @@// Copyright 2021 The Gitea Authors. All rights reserved. // Use of this source code is governed by a MIT-style // license that can be found in the LICENSE file. package models import ( "testing" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/unittest" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/util" "github.com/stretchr/testify/assert" ) func TestMakeEmailPrimary(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) email := &user_model.EmailAddress{ Email: "user567890@example.com", } err := MakeEmailPrimary(email) assert.Error(t, err) assert.EqualError(t, err, user_model.ErrEmailAddressNotExist{Email: email.Email}.Error()) email = &user_model.EmailAddress{ Email: "user11@example.com", } err = MakeEmailPrimary(email) assert.Error(t, err) assert.EqualError(t, err, user_model.ErrEmailNotActivated.Error()) email = &user_model.EmailAddress{ Email: "user9999999@example.com", } err = MakeEmailPrimary(email) assert.Error(t, err) assert.True(t, user_model.IsErrUserNotExist(err)) email = &user_model.EmailAddress{ Email: "user101@example.com", } err = MakeEmailPrimary(email) assert.NoError(t, err) user, _ := user_model.GetUserByID(int64(10)) assert.Equal(t, "user101@example.com", user.Email) } func TestActivate(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) email := &user_model.EmailAddress{ ID: int64(1), UID: int64(1), Email: "user11@example.com", } assert.NoError(t, ActivateEmail(email)) emails, _ := user_model.GetEmailAddresses(int64(1)) assert.Len(t, emails, 3) assert.True(t, emails[0].IsActivated) assert.True(t, emails[0].IsPrimary) assert.False(t, emails[1].IsPrimary) assert.True(t, emails[2].IsActivated) assert.False(t, emails[2].IsPrimary) } func TestListEmails(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) // Must find all users and their emails opts := &SearchEmailOptions{ ListOptions: db.ListOptions{ PageSize: 10000, }, } emails, count, err := SearchEmails(opts) assert.NoError(t, err) assert.NotEqual(t, int64(0), count) assert.True(t, count > 5) contains := func(match func(s *SearchEmailResult) bool) bool { for _, v := range emails { if match(v) { return true } } return false } assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 18 })) // 'user3' is an organization assert.False(t, contains(func(s *SearchEmailResult) bool { return s.UID == 3 })) // Must find no records opts = &SearchEmailOptions{Keyword: "NOTFOUND"} emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.Equal(t, int64(0), count) // Must find users 'user2', 'user28', etc. opts = &SearchEmailOptions{Keyword: "user2"} emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.NotEqual(t, int64(0), count) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 2 })) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.UID == 27 })) // Must find only primary addresses (i.e. from the `user` table) opts = &SearchEmailOptions{IsPrimary: util.OptionalBoolTrue} emails, _, err = SearchEmails(opts) assert.NoError(t, err) assert.True(t, contains(func(s *SearchEmailResult) bool { return s.IsPrimary })) assert.False(t, contains(func(s *SearchEmailResult) bool { return !s.IsPrimary })) // Must find only inactive addresses (i.e. not validated) opts = &SearchEmailOptions{IsActivated: util.OptionalBoolFalse} emails, _, err = SearchEmails(opts) assert.NoError(t, err) assert.True(t, contains(func(s *SearchEmailResult) bool { return !s.IsActivated })) assert.False(t, contains(func(s *SearchEmailResult) bool { return s.IsActivated })) // Must find more than one page, but retrieve only one opts = &SearchEmailOptions{ ListOptions: db.ListOptions{ PageSize: 5, Page: 1, }, } emails, count, err = SearchEmails(opts) assert.NoError(t, err) assert.Len(t, emails, 5) assert.Greater(t, count, int64(len(emails))) }
-
-
-
@@ -8,30 +8,17 @@ import ("fmt" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" ) // UserList is a list of user. // This type provide valuable methods to retrieve information for a group of users efficiently. type UserList []*user_model.User func (users UserList) getUserIDs() []int64 { userIDs := make([]int64, len(users)) for _, user := range users { userIDs = append(userIDs, user.ID) // Considering that user id are unique in the list } return userIDs } // IsUserOrgOwner returns true if user is in the owner team of given organization. func (users UserList) IsUserOrgOwner(orgID int64) map[int64]bool { func IsUserOrgOwner(users user_model.UserList, orgID int64) map[int64]bool { results := make(map[int64]bool, len(users)) for _, user := range users { results[user.ID] = false // Set default to false } ownerMaps, err := users.loadOrganizationOwners(db.GetEngine(db.DefaultContext), orgID) ownerMaps, err := loadOrganizationOwners(db.GetEngine(db.DefaultContext), users, orgID) if err == nil { for _, owner := range ownerMaps { results[owner.UID] = true
-
@@ -40,7 +27,7 @@ func (users UserList) IsUserOrgOwner(orgID int64) map[int64]bool {return results } func (users UserList) loadOrganizationOwners(e db.Engine, orgID int64) (map[int64]*TeamUser, error) { func loadOrganizationOwners(e db.Engine, users user_model.UserList, orgID int64) (map[int64]*TeamUser, error) { if len(users) == 0 { return nil, nil }
-
@@ -53,7 +40,7 @@ func (users UserList) loadOrganizationOwners(e db.Engine, orgID int64) (map[int6return nil, err } userIDs := users.getUserIDs() userIDs := users.GetUserIDs() ownerMaps := make(map[int64]*TeamUser) err = e.In("uid", userIDs). And("org_id=?", orgID).
-
@@ -64,47 +51,3 @@ func (users UserList) loadOrganizationOwners(e db.Engine, orgID int64) (map[int6} return ownerMaps, nil } // GetTwoFaStatus return state of 2FA enrollement func (users UserList) GetTwoFaStatus() map[int64]bool { results := make(map[int64]bool, len(users)) for _, user := range users { results[user.ID] = false // Set default to false } tokenMaps, err := users.loadTwoFactorStatus(db.GetEngine(db.DefaultContext)) if err == nil { for _, token := range tokenMaps { results[token.UID] = true } } return results } func (users UserList) loadTwoFactorStatus(e db.Engine) (map[int64]*login.TwoFactor, error) { if len(users) == 0 { return nil, nil } userIDs := users.getUserIDs() tokenMaps := make(map[int64]*login.TwoFactor, len(userIDs)) err := e. In("uid", userIDs). Find(&tokenMaps) if err != nil { return nil, fmt.Errorf("find two factor: %v", err) } return tokenMaps, nil } // GetUsersByIDs returns all resolved users from a list of Ids. func GetUsersByIDs(ids []int64) (UserList, error) { ous := make([]*user_model.User, 0, len(ids)) if len(ids) == 0 { return ous, nil } err := db.GetEngine(db.DefaultContext).In("id", ids). Asc("name"). Find(&ous) return ous, err }
-
-
-
@@ -64,32 +64,5 @@ func testUserListIsUserOrgOwner(t *testing.T, orgID int64, expected map[int64]boassert.NoError(t, err) members, _, err := org.GetMembers() assert.NoError(t, err) assert.Equal(t, expected, members.IsUserOrgOwner(orgID)) } func TestUserListIsTwoFaEnrolled(t *testing.T) { assert.NoError(t, unittest.PrepareTestDatabase()) tt := []struct { orgid int64 expected map[int64]bool }{ {3, map[int64]bool{2: false, 4: false, 28: false}}, {6, map[int64]bool{5: false, 28: false}}, {7, map[int64]bool{5: false}}, {25, map[int64]bool{24: true}}, {22, map[int64]bool{}}, } for _, v := range tt { t.Run(fmt.Sprintf("IsTwoFaEnrolledOfOrdIg%d", v.orgid), func(t *testing.T) { testUserListIsTwoFaEnrolled(t, v.orgid, v.expected) }) } } func testUserListIsTwoFaEnrolled(t *testing.T, orgID int64, expected map[int64]bool) { org, err := GetOrgByID(orgID) assert.NoError(t, err) members, _, err := org.GetMembers() assert.NoError(t, err) assert.Equal(t, expected, members.GetTwoFaStatus()) assert.Equal(t, expected, IsUserOrgOwner(members, orgID)) }
-
-
-
@@ -273,7 +273,7 @@ func GetIssueSubscribers(ctx *context.APIContext) {userIDs = append(userIDs, iw.UserID) } users, err := models.GetUsersByIDs(userIDs) users, err := user_model.GetUsersByIDs(userIDs) if err != nil { ctx.Error(http.StatusInternalServerError, "GetUsersByIDs", err) return
-
-
-
@@ -9,7 +9,6 @@ import ("net/http" "net/url" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base"
-
@@ -29,7 +28,7 @@ func Emails(ctx *context.Context) {ctx.Data["PageIsAdmin"] = true ctx.Data["PageIsAdminEmails"] = true opts := &models.SearchEmailOptions{ opts := &user_model.SearchEmailOptions{ ListOptions: db.ListOptions{ PageSize: setting.UI.Admin.UserPagingNum, Page: ctx.FormInt("page"),
-
@@ -41,31 +40,31 @@ func Emails(ctx *context.Context) {} type ActiveEmail struct { models.SearchEmailResult user_model.SearchEmailResult CanChange bool } var ( baseEmails []*models.SearchEmailResult baseEmails []*user_model.SearchEmailResult emails []ActiveEmail count int64 err error orderBy models.SearchEmailOrderBy orderBy user_model.SearchEmailOrderBy ) ctx.Data["SortType"] = ctx.FormString("sort") switch ctx.FormString("sort") { case "email": orderBy = models.SearchEmailOrderByEmail orderBy = user_model.SearchEmailOrderByEmail case "reverseemail": orderBy = models.SearchEmailOrderByEmailReverse orderBy = user_model.SearchEmailOrderByEmailReverse case "username": orderBy = models.SearchEmailOrderByName orderBy = user_model.SearchEmailOrderByName case "reverseusername": orderBy = models.SearchEmailOrderByNameReverse orderBy = user_model.SearchEmailOrderByNameReverse default: ctx.Data["SortType"] = "email" orderBy = models.SearchEmailOrderByEmail orderBy = user_model.SearchEmailOrderByEmail } opts.Keyword = ctx.FormTrim("q")
-
@@ -78,7 +77,7 @@ func Emails(ctx *context.Context) {} if len(opts.Keyword) == 0 || isKeywordValid(opts.Keyword) { baseEmails, count, err = models.SearchEmails(opts) baseEmails, count, err = user_model.SearchEmails(opts) if err != nil { ctx.ServerError("SearchEmails", err) return
-
@@ -127,7 +126,7 @@ func ActivateEmail(ctx *context.Context) {log.Info("Changing activation for User ID: %d, email: %s, primary: %v to %v", uid, email, primary, activate) if err := models.ActivateUserEmail(uid, email, activate); err != nil { if err := user_model.ActivateUserEmail(uid, email, activate); err != nil { log.Error("ActivateUserEmail(%v,%v,%v): %v", uid, email, activate, err) if user_model.IsErrEmailAlreadyUsed(err) { ctx.Flash.Error(ctx.Tr("admin.emails.duplicate_active"))
-
-
-
@@ -8,7 +8,6 @@ import ("bytes" "net/http" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/base"
-
@@ -79,7 +78,7 @@ func RenderUserSearch(ctx *context.Context, opts *user_model.SearchUserOptions,ctx.Data["Keyword"] = opts.Keyword ctx.Data["Total"] = count ctx.Data["Users"] = users ctx.Data["UsersTwoFaStatus"] = models.UserList(users).GetTwoFaStatus() ctx.Data["UsersTwoFaStatus"] = user_model.UserList(users).GetTwoFaStatus() ctx.Data["ShowUserEmail"] = setting.UI.ShowUserEmail ctx.Data["IsRepoIndexerEnabled"] = setting.Indexer.RepoIndexerEnabled
-
-
-
@@ -62,7 +62,7 @@ func Members(ctx *context.Context) {ctx.Data["Page"] = pager ctx.Data["Members"] = members ctx.Data["MembersIsPublicMember"] = membersIsPublic ctx.Data["MembersIsUserOrgOwner"] = members.IsUserOrgOwner(org.ID) ctx.Data["MembersIsUserOrgOwner"] = models.IsUserOrgOwner(members, org.ID) ctx.Data["MembersTwoFaStatus"] = members.GetTwoFaStatus() ctx.HTML(http.StatusOK, tplMembers)
-
-
-
@@ -12,7 +12,6 @@ import ("net/http" "strings" "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" user_model "code.gitea.io/gitea/models/user"
-
@@ -781,7 +780,7 @@ func handleOAuth2SignIn(ctx *context.Context, source *login.Source, u *user_mode} // update external user information if err := models.UpdateExternalUser(u, gothUser); err != nil { if err := user_model.UpdateExternalUser(u, gothUser); err != nil { log.Error("UpdateExternalUser failed: %v", err) }
-
@@ -844,11 +843,11 @@ func oAuth2UserLoginCallback(loginSource *login.Source, request *http.Request, r} // search in external linked users externalLoginUser := &models.ExternalLoginUser{ externalLoginUser := &user_model.ExternalLoginUser{ ExternalID: gothUser.UserID, LoginSourceID: loginSource.ID, } hasUser, err = models.GetExternalLogin(externalLoginUser) hasUser, err = user_model.GetExternalLogin(externalLoginUser) if err != nil { return nil, goth.User{}, err }
-
@@ -1355,7 +1354,7 @@ func handleUserCreated(ctx *context.Context, u *user_model.User, gothUser *goth.// update external user information if gothUser != nil { if err := models.UpdateExternalUser(u, *gothUser); err != nil { if err := user_model.UpdateExternalUser(u, *gothUser); err != nil { log.Error("UpdateExternalUser failed: %v", err) } }
-
@@ -1477,7 +1476,7 @@ func handleAccountActivation(ctx *context.Context, user *user_model.User) {return } if err := models.ActivateUserEmail(user.ID, user.Email, true); err != nil { if err := user_model.ActivateUserEmail(user.ID, user.Email, true); err != nil { log.Error("Unable to activate email for user: %-v with email: %s: %v", user, user.Email, err) ctx.ServerError("ActivateUserEmail", err) return
-
@@ -1505,8 +1504,8 @@ func ActivateEmail(ctx *context.Context) {emailStr := ctx.FormString("email") // Verify code. if email := models.VerifyActiveEmailCode(code, emailStr); email != nil { if err := models.ActivateEmail(email); err != nil { if email := user_model.VerifyActiveEmailCode(code, emailStr); email != nil { if err := user_model.ActivateEmail(email); err != nil { ctx.ServerError("ActivateEmail", err) }
-
-
-
@@ -94,7 +94,7 @@ func EmailPost(ctx *context.Context) {// Make emailaddress primary. if ctx.FormString("_method") == "PRIMARY" { if err := models.MakeEmailPrimary(&user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil { if err := user_model.MakeEmailPrimary(&user_model.EmailAddress{ID: ctx.FormInt64("id")}); err != nil { ctx.ServerError("MakeEmailPrimary", err) return }
-
-
-
@@ -43,7 +43,7 @@ func DeleteAccountLink(ctx *context.Context) {if id <= 0 { ctx.Flash.Error("Account link id is not given") } else { if _, err := models.RemoveAccountLink(ctx.User, id); err != nil { if _, err := user_model.RemoveAccountLink(ctx.User, id); err != nil { ctx.Flash.Error("RemoveAccountLink: " + err.Error()) } else { ctx.Flash.Success(ctx.Tr("settings.remove_account_link_success"))
-
@@ -76,7 +76,7 @@ func loadSecurityData(ctx *context.Context) {} ctx.Data["Tokens"] = tokens accountLinks, err := models.ListAccountLinks(ctx.User) accountLinks, err := user_model.ListAccountLinks(ctx.User) if err != nil { ctx.ServerError("ListAccountLinks", err) return
-
-
-
@@ -5,7 +5,6 @@package auth import ( "code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" user_model "code.gitea.io/gitea/models/user"
-
@@ -22,7 +21,7 @@ func DeleteLoginSource(source *login.Source) error {} } count, err = db.GetEngine(db.DefaultContext).Count(&models.ExternalLoginUser{LoginSourceID: source.ID}) count, err = db.GetEngine(db.DefaultContext).Count(&user_model.ExternalLoginUser{LoginSourceID: source.ID}) if err != nil { return err } else if count > 0 {
-
-
-
@@ -22,7 +22,7 @@ func LinkAccountToUser(user *user_model.User, gothUser goth.User) error {return err } externalLoginUser := &models.ExternalLoginUser{ externalLoginUser := &user_model.ExternalLoginUser{ ExternalID: gothUser.UserID, UserID: user.ID, LoginSourceID: loginSource.ID,
-
@@ -42,7 +42,7 @@ func LinkAccountToUser(user *user_model.User, gothUser goth.User) error {ExpiresAt: gothUser.ExpiresAt, } if err := models.LinkExternalToUser(user, externalLoginUser); err != nil { if err := user_model.LinkExternalToUser(user, externalLoginUser); err != nil { return err }
-
-
-
@@ -260,7 +260,7 @@ func (g *GiteaLocalUploader) CreateReleases(releases ...*base.Release) error {tp := g.gitServiceType.Name() if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", release.PublisherID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", release.PublisherID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -400,7 +400,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {tp := g.gitServiceType.Name() if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", issue.PosterID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", issue.PosterID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -425,7 +425,7 @@ func (g *GiteaLocalUploader) CreateIssues(issues ...*base.Issue) error {userid, ok := g.userMap[reaction.UserID] if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -483,7 +483,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {tp := g.gitServiceType.Name() if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", comment.PosterID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", comment.PosterID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -520,7 +520,7 @@ func (g *GiteaLocalUploader) CreateComments(comments ...*base.Comment) error {userid, ok := g.userMap[reaction.UserID] if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -564,7 +564,7 @@ func (g *GiteaLocalUploader) CreatePullRequests(prs ...*base.PullRequest) errortp := g.gitServiceType.Name() if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", pr.PosterID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", pr.PosterID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -744,7 +744,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullRuserid, ok := g.userMap[pr.PosterID] if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", pr.PosterID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", pr.PosterID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -766,7 +766,7 @@ func (g *GiteaLocalUploader) newPullRequest(pr *base.PullRequest) (*models.PullRuserid, ok := g.userMap[reaction.UserID] if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", reaction.UserID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
@@ -850,7 +850,7 @@ func (g *GiteaLocalUploader) CreateReviews(reviews ...*base.Review) error {tp := g.gitServiceType.Name() if !ok && tp != "" { var err error userid, err = models.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", review.ReviewerID)) userid, err = user_model.GetUserIDByExternalUserID(tp, fmt.Sprintf("%v", review.ReviewerID)) if err != nil { log.Error("GetUserIDByExternalUserID: %v", err) }
-
-
-
@@ -9,6 +9,7 @@ import ("code.gitea.io/gitea/models" "code.gitea.io/gitea/models/db" user_model "code.gitea.io/gitea/models/user" "code.gitea.io/gitea/modules/log" "code.gitea.io/gitea/modules/structs" )
-
@@ -45,7 +46,7 @@ func updateMigrationPosterIDByGitService(ctx context.Context, tp structs.GitServdefault: } users, err := models.FindExternalUsersByProvider(models.FindExternalUserOptions{ users, err := user_model.FindExternalUsersByProvider(user_model.FindExternalUserOptions{ Provider: provider, Start: start, Limit: batchSize,
-