forked from forgejo/forgejo
Move more model into models/user (#17826)
* Move more model into models/user * Remove unnecessary comment Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
This commit is contained in:
parent
b1df890951
commit
9defddb286
23 changed files with 547 additions and 603 deletions
207
models/user/external_login_user.go
Normal file
207
models/user/external_login_user.go
Normal file
|
@ -0,0 +1,207 @@
|
|||
// Copyright 2017 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 (
|
||||
"context"
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/gitea/models/db"
|
||||
"code.gitea.io/gitea/models/login"
|
||||
|
||||
"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"`
|
||||
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 `xorm:"TEXT"`
|
||||
AccessTokenSecret string `xorm:"TEXT"`
|
||||
RefreshToken string `xorm:"TEXT"`
|
||||
ExpiresAt time.Time
|
||||
}
|
||||
|
||||
func init() {
|
||||
db.RegisterModel(new(ExternalLoginUser))
|
||||
}
|
||||
|
||||
// GetExternalLogin checks if a externalID in loginSourceID scope already exists
|
||||
func GetExternalLogin(externalLoginUser *ExternalLoginUser) (bool, error) {
|
||||
return db.GetEngine(db.DefaultContext).Get(externalLoginUser)
|
||||
}
|
||||
|
||||
// ListAccountLinks returns a map with the ExternalLoginUser and its LoginSource
|
||||
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").
|
||||
Find(&externalAccounts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return externalAccounts, nil
|
||||
}
|
||||
|
||||
// LinkExternalToUser link the external user to the user
|
||||
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)
|
||||
if err != nil {
|
||||
return err
|
||||
} else if has {
|
||||
return ErrExternalLoginUserAlreadyExist{externalLoginUser.ExternalID, user.ID, externalLoginUser.LoginSourceID}
|
||||
}
|
||||
|
||||
_, err = db.GetEngine(db.DefaultContext).Insert(externalLoginUser)
|
||||
return err
|
||||
}
|
||||
|
||||
// RemoveAccountLink will remove all external login sources for the given user
|
||||
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
|
||||
}
|
||||
if deleted < 1 {
|
||||
return deleted, ErrExternalLoginUserNotExist{user.ID, loginSourceID}
|
||||
}
|
||||
return deleted, err
|
||||
}
|
||||
|
||||
// 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
|
||||
}
|
||||
|
||||
// GetUserIDByExternalUserID get user id according to provider and userID
|
||||
func GetUserIDByExternalUserID(provider, userID string) (int64, error) {
|
||||
var id int64
|
||||
_, err := db.GetEngine(db.DefaultContext).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 := login.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 := db.GetEngine(db.DefaultContext).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 = db.GetEngine(db.DefaultContext).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 {
|
||||
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 := db.GetEngine(db.DefaultContext).Where(opts.toConds()).
|
||||
Limit(opts.Limit, opts.Start).
|
||||
OrderBy("login_source_id ASC, external_id ASC").
|
||||
Find(&users)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return users, nil
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue