fix(oauth): remove pending oauth auto-binding and enforce oidc policies

- Complete removal of completePendingOAuthBinding logic to prevent unintended account takeovers (AUTH-ROUTE-1).
- Add strict OIDC policy checks (global switch and source active states) across authorization and callback paths (AUTH-POLICY-1).
- Fix OIDC test cases to properly clear the Redis-backed system config cache using composite keys.
This commit is contained in:
ryan
2026-06-13 10:06:49 +08:00
parent 895788974c
commit 5412c385dc
5 changed files with 153 additions and 59 deletions
-43
View File
@@ -241,50 +241,7 @@ func validateRegisterEmailVerification(ctx context.Context, req *registerRequest
return nil
}
// completePendingOAuthBinding 完成登录后的 OAuth 待绑定绑定流程
func completePendingOAuthBinding(ctx context.Context, session sessions.Session, user *model.User) {
pendingSourceID := session.Get(oauth.PendingOAuthSourceIDKey)
pendingExternalID := session.Get(oauth.PendingOAuthExternalIDKey)
pendingExternalUsername := session.Get(oauth.PendingOAuthExternalUsernameKey)
pendingEmail := session.Get(oauth.PendingOAuthEmailKey)
if pendingSourceID == nil || pendingExternalID == nil {
return
}
var sourceID uint64
switch v := pendingSourceID.(type) {
case uint64:
sourceID = v
case int:
if v >= 0 {
sourceID = uint64(v)
}
case float64:
if v >= 0 && v <= 18446744073709551615.0 {
sourceID = uint64(v)
}
}
externalID, _ := pendingExternalID.(string)
externalUsername, _ := pendingExternalUsername.(string)
email, _ := pendingEmail.(string)
if sourceID != 0 && externalID != "" {
_ = model.BindExternalAccount(ctx, &model.ExternalAccount{
AuthSourceID: sourceID,
UserID: user.ID,
ExternalID: externalID,
ExternalUsername: externalUsername,
Email: email,
})
}
session.Delete(oauth.PendingOAuthSourceIDKey)
session.Delete(oauth.PendingOAuthExternalIDKey)
session.Delete(oauth.PendingOAuthExternalUsernameKey)
session.Delete(oauth.PendingOAuthEmailKey)
_ = session.Save()
}
type updateProfileRequest struct {
Nickname string `json:"nickname"`
-3
View File
@@ -164,9 +164,6 @@ func Login(c *gin.Context) {
return
}
// 检查是否有未完成 of OAuth/OIDC 绑定
completePendingOAuthBinding(ctx, session, &user)
c.JSON(http.StatusOK, util.OK(oauth.BuildBasicUserInfo(&user, needChangePassword)))
}