From f59767d914bc849f7f08ffff18530f2f1b43368e Mon Sep 17 00:00:00 2001 From: Snowykami Date: Tue, 23 Sep 2025 17:55:25 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E5=9C=A8=20OidcLogin=20=E6=96=B9?= =?UTF-8?q?=E6=B3=95=E4=B8=AD=E6=B7=BB=E5=8A=A0=E5=BD=93=E5=89=8D=E7=94=A8?= =?UTF-8?q?=E6=88=B7=E8=8E=B7=E5=8F=96=E9=80=BB=E8=BE=91=EF=BC=8C=E4=BC=98?= =?UTF-8?q?=E5=8C=96=E7=94=A8=E6=88=B7=E7=BB=91=E5=AE=9A=E6=B5=81=E7=A8=8B?= =?UTF-8?q?=20Closes=20#20?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- internal/model/user.go | 52 ++++++++++++++++++++-------------------- internal/service/user.go | 19 +++++++++------ 2 files changed, 38 insertions(+), 33 deletions(-) diff --git a/internal/model/user.go b/internal/model/user.go index defd269..7403ec6 100644 --- a/internal/model/user.go +++ b/internal/model/user.go @@ -1,39 +1,39 @@ package model import ( - "github.com/snowykami/neo-blog/internal/dto" - "gorm.io/gorm" + "github.com/snowykami/neo-blog/internal/dto" + "gorm.io/gorm" ) type User struct { - gorm.Model - Username string `gorm:"uniqueIndex;not null"` // 用户名,唯一 - Nickname string `gorm:"default:''"` // 昵称 - AvatarUrl string - Email string `gorm:"uniqueIndex"` - Gender string `gorm:"default:''"` - Role string `gorm:"default:'user'"` // user editor admin - Language string `gorm:"default:'en'"` - Password string // 密码,存储加密后的值 + gorm.Model + Username string `gorm:"uniqueIndex;not null"` // 用户名,唯一 + Nickname string `gorm:"default:''"` // 昵称 + AvatarUrl string + Email string `gorm:"uniqueIndex"` + Gender string `gorm:"default:''"` + Role string `gorm:"default:'user'"` // user editor admin + Language string `gorm:"default:'en'"` + Password string // 密码,存储加密后的值 } type UserOpenID struct { - gorm.Model - UserID uint `gorm:"uniqueIndex"` - User User `gorm:"foreignKey:UserID;references:ID"` - Issuer string `gorm:"index"` // OIDC Issuer - Sub string `gorm:"index"` // OIDC Sub openid + gorm.Model + UserID uint `gorm:"index"` + User User `gorm:"foreignKey:UserID;references:ID"` + Issuer string `gorm:"index"` // OIDC Issuer + Sub string `gorm:"index"` // OIDC Sub openid } func (user *User) ToDto() dto.UserDto { - return dto.UserDto{ - ID: user.ID, - Username: user.Username, - Nickname: user.Nickname, - AvatarUrl: user.AvatarUrl, - Email: user.Email, - Gender: user.Gender, - Role: user.Role, - Language: user.Language, - } + return dto.UserDto{ + ID: user.ID, + Username: user.Username, + Nickname: user.Nickname, + AvatarUrl: user.AvatarUrl, + Email: user.Email, + Gender: user.Gender, + Role: user.Role, + Language: user.Language, + } } diff --git a/internal/service/user.go b/internal/service/user.go index ebd2d2b..865e9bd 100644 --- a/internal/service/user.go +++ b/internal/service/user.go @@ -180,6 +180,7 @@ func (s *UserService) ListOidcConfigs() ([]dto.UserOidcConfigDto, error) { func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dto.OidcLoginResp, error) { // 验证state + currentUser, userOk := ctxutils.GetCurrentUser(ctx) kvStore := utils.KV.GetInstance() storedName, ok := kvStore.Get(constant.KVKeyOidcState + req.State) if !ok || storedName != req.Name { @@ -211,7 +212,7 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt return nil, errs.ErrInternalServer } - // 绑定过登录 + // 1.绑定过登录 userOpenID, err := repo.User.GetUserOpenIDByIssuerAndSub(oidcConfig.Issuer, userInfo.Sub) if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { return nil, errs.ErrInternalServer @@ -233,12 +234,16 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt } return resp, nil } else { - // 若没有绑定过登录,则先通过邮箱查找用户,若没有再创建新用户 - user, err := repo.User.GetUserByEmail(userInfo.Email) - if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { - logrus.Errorln("Failed to get user by email:", err) - return nil, errs.ErrInternalServer + // 2.若没有绑定过登录,则判断当前有无用户登录,有则绑定,没有登录先通过邮箱查找用户 + user := currentUser + if user == nil || !userOk { + user, err = repo.User.GetUserByEmail(userInfo.Email) + if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) { + logrus.Errorln("Failed to get user by email:", err) + return nil, errs.ErrInternalServer + } } + if user != nil { userOpenID = &model.UserOpenID{ UserID: user.ID, @@ -262,7 +267,7 @@ func (s *UserService) OidcLogin(ctx context.Context, req *dto.OidcLoginReq) (*dt } return resp, nil } else { - // 第一次登录,创建新用户时才获取头像 + // 3.第一次登录,创建新用户时才获取头像 user = &model.User{ Username: userInfo.PreferredUsername, Nickname: userInfo.Name,