forked from forgejo/forgejo
Update migrated repositories' issues/comments/prs poster id if user has a github external user saved (#7751)
* update migrated issues/comments when login as github * add get userid when migrating or login with github oauth2 * fix lint * add migrations for repository service type * fix build * remove unnecessary dependencies on migrations * add cron task to update migrations poster ids and fix posterid when migrating * fix lint * fix lint * improve code * fix lint * improve code * replace releases publish id to actual author id * fix import * fix bug * fix lint * fix rawdata definition * fix some bugs * fix error message
This commit is contained in:
parent
ba201aaa44
commit
e3e44a59d0
21 changed files with 740 additions and 159 deletions
|
@ -4,13 +4,34 @@
|
|||
|
||||
package models
|
||||
|
||||
import "github.com/markbates/goth"
|
||||
import (
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/modules/structs"
|
||||
|
||||
"github.com/markbates/goth"
|
||||
"xorm.io/builder"
|
||||
)
|
||||
|
||||
// ExternalLoginUser makes the connecting between some existing user and additional external login sources
|
||||
type ExternalLoginUser struct {
|
||||
ExternalID string `xorm:"pk NOT NULL"`
|
||||
UserID int64 `xorm:"INDEX NOT NULL"`
|
||||
LoginSourceID int64 `xorm:"pk NOT NULL"`
|
||||
ExternalID string `xorm:"pk NOT NULL"`
|
||||
UserID int64 `xorm:"INDEX NOT NULL"`
|
||||
LoginSourceID int64 `xorm:"pk NOT NULL"`
|
||||
RawData map[string]interface{} `xorm:"TEXT JSON"`
|
||||
Provider string `xorm:"index VARCHAR(25)"`
|
||||
Email string
|
||||
Name string
|
||||
FirstName string
|
||||
LastName string
|
||||
NickName string
|
||||
Description string
|
||||
AvatarURL string
|
||||
Location string
|
||||
AccessToken string
|
||||
AccessTokenSecret string
|
||||
RefreshToken string
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
// GetExternalLogin checks if a externalID in loginSourceID scope already exists
|
||||
|
@ -32,23 +53,15 @@ func ListAccountLinks(user *User) ([]*ExternalLoginUser, error) {
|
|||
return externalAccounts, nil
|
||||
}
|
||||
|
||||
// LinkAccountToUser link the gothUser to the user
|
||||
func LinkAccountToUser(user *User, gothUser goth.User) error {
|
||||
loginSource, err := GetActiveOAuth2LoginSourceByName(gothUser.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
externalLoginUser := &ExternalLoginUser{
|
||||
ExternalID: gothUser.UserID,
|
||||
UserID: user.ID,
|
||||
LoginSourceID: loginSource.ID,
|
||||
}
|
||||
has, err := x.Get(externalLoginUser)
|
||||
// LinkExternalToUser link the external user to the user
|
||||
func LinkExternalToUser(user *User, externalLoginUser *ExternalLoginUser) error {
|
||||
has, err := x.Where("external_id=? AND login_source_id=?", externalLoginUser.ExternalID, externalLoginUser.LoginSourceID).
|
||||
NoAutoCondition().
|
||||
Exist(externalLoginUser)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrExternalLoginUserAlreadyExist{gothUser.UserID, user.ID, loginSource.ID}
|
||||
return ErrExternalLoginUserAlreadyExist{externalLoginUser.ExternalID, user.ID, externalLoginUser.LoginSourceID}
|
||||
}
|
||||
|
||||
_, err = x.Insert(externalLoginUser)
|
||||
|
@ -72,3 +85,97 @@ func removeAllAccountLinks(e Engine, user *User) error {
|
|||
_, err := e.Delete(&ExternalLoginUser{UserID: user.ID})
|
||||
return err
|
||||
}
|
||||
|
||||
// GetUserIDByExternalUserID get user id according to provider and userID
|
||||
func GetUserIDByExternalUserID(provider string, userID string) (int64, error) {
|
||||
var id int64
|
||||
_, err := x.Table("external_login_user").
|
||||
Select("user_id").
|
||||
Where("provider=?", provider).
|
||||
And("external_id=?", userID).
|
||||
Get(&id)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return id, nil
|
||||
}
|
||||
|
||||
// UpdateExternalUser updates external user's information
|
||||
func UpdateExternalUser(user *User, gothUser goth.User) error {
|
||||
loginSource, err := GetActiveOAuth2LoginSourceByName(gothUser.Provider)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
externalLoginUser := &ExternalLoginUser{
|
||||
ExternalID: gothUser.UserID,
|
||||
UserID: user.ID,
|
||||
LoginSourceID: loginSource.ID,
|
||||
RawData: gothUser.RawData,
|
||||
Provider: gothUser.Provider,
|
||||
Email: gothUser.Email,
|
||||
Name: gothUser.Name,
|
||||
FirstName: gothUser.FirstName,
|
||||
LastName: gothUser.LastName,
|
||||
NickName: gothUser.NickName,
|
||||
Description: gothUser.Description,
|
||||
AvatarURL: gothUser.AvatarURL,
|
||||
Location: gothUser.Location,
|
||||
AccessToken: gothUser.AccessToken,
|
||||
AccessTokenSecret: gothUser.AccessTokenSecret,
|
||||
RefreshToken: gothUser.RefreshToken,
|
||||
ExpiresAt: gothUser.ExpiresAt,
|
||||
}
|
||||
|
||||
has, err := x.Where("external_id=? AND login_source_id=?", gothUser.UserID, loginSource.ID).
|
||||
NoAutoCondition().
|
||||
Exist(externalLoginUser)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if !has {
|
||||
return ErrExternalLoginUserNotExist{user.ID, loginSource.ID}
|
||||
}
|
||||
|
||||
_, err = x.Where("external_id=? AND login_source_id=?", gothUser.UserID, loginSource.ID).AllCols().Update(externalLoginUser)
|
||||
return err
|
||||
}
|
||||
|
||||
// FindExternalUserOptions represents an options to find external users
|
||||
type FindExternalUserOptions struct {
|
||||
Provider string
|
||||
Limit int
|
||||
Start int
|
||||
}
|
||||
|
||||
func (opts FindExternalUserOptions) toConds() builder.Cond {
|
||||
var cond = builder.NewCond()
|
||||
if len(opts.Provider) > 0 {
|
||||
cond = cond.And(builder.Eq{"provider": opts.Provider})
|
||||
}
|
||||
return cond
|
||||
}
|
||||
|
||||
// FindExternalUsersByProvider represents external users via provider
|
||||
func FindExternalUsersByProvider(opts FindExternalUserOptions) ([]ExternalLoginUser, error) {
|
||||
var users []ExternalLoginUser
|
||||
err := x.Where(opts.toConds()).
|
||||
Limit(opts.Limit, opts.Start).
|
||||
Asc("id").
|
||||
Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return users, nil
|
||||
}
|
||||
|
||||
// UpdateMigrationsByType updates all migrated repositories' posterid from gitServiceType to replace originalAuthorID to posterID
|
||||
func UpdateMigrationsByType(tp structs.GitServiceType, externalUserID, userID int64) error {
|
||||
if err := UpdateIssuesMigrationsByType(tp, externalUserID, userID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err := UpdateCommentsMigrationsByType(tp, externalUserID, userID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return UpdateReleasesMigrationsByType(tp, externalUserID, userID)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue