Skip to content

Conversation

Pleasurecruise
Copy link

@Pleasurecruise Pleasurecruise commented Oct 13, 2025

Fix #1350

Refactored GitHub and OIDC OAuth handlers to better handle existing users by email, prevent conflicting account bindings, and only allow new user registration if enabled. This improves account linking consistency and provides clearer error messages for users.

Summary by CodeRabbit

  • New Features

    • Automatically link GitHub and OIDC sign-ins to existing accounts when verified email matches; update display name when appropriate.
    • Registration-disabled setting is enforced only when actually creating a new account for consistent behavior.
  • Bug Fixes

    • Prevent linking when an email is already bound to a different OAuth identity; return a clear error.
    • Settings > Account Management: binding buttons (WeChat, GitHub, OIDC, LinuxDO) show correct status (未启用/已绑定/绑定) and are disabled when bound or not enabled.

Refactored GitHub and OIDC OAuth handlers to better handle existing users by email, prevent conflicting account bindings, and only allow new user registration if enabled. This improves account linking consistency and provides clearer error messages for users.
Copy link
Contributor

coderabbitai bot commented Oct 13, 2025

Walkthrough

Add email-based account linking to GitHub and OIDC login flows, defer registration gating to the point of creating new users, and update frontend account-binding buttons to show enabled / bound states and disable appropriately.

Changes

Cohort / File(s) Summary
Auth controllers: GitHub email linking & gating
controller/github.go
Use email to locate and link existing users when GitHubId isn't found; error if email is bound to a different GitHubId; update GitHubId and DisplayName when appropriate; move registration-enabled check to user-creation path; import gorm for ErrRecordNotFound handling.
Auth controllers: OIDC email linking, verification & gating
controller/oidc.go
Require/verify email, use email to find and link existing users when OidcId isn't found; error on conflicts where email is bound to another OIDC ID; update OidcId and DisplayName as needed; gate new-user creation by RegisterEnabled; import gorm for DB error checks.
Frontend: account binding UI labels & disabled state
web/src/components/settings/personal/cards/AccountManagement.jsx
Update binding buttons (WeChat, GitHub, OIDC, LinuxDO) to display 未启用 / 已绑定 / 绑定 and disable when provider is disabled or already bound; preserve Email/Telegram behavior.

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant U as User
  participant GH as GitHub OAuth
  participant C as Controller (github.go)
  participant DB as Database

  U->>GH: OAuth login
  GH-->>C: Callback (github_id, email, name)
  C->>DB: Find user by GitHubId
  alt Found by GitHubId
    DB-->>C: user
    C-->>U: Login existing user
  else Not found by GitHubId
    alt Email present
      C->>DB: Find user by email
      alt Found by email
        DB-->>C: user
        alt GitHubId empty or matches
          C->>DB: Update user.GitHubId (+ DisplayName if missing)
          DB-->>C: updated user
          C-->>U: Login linked user
        else Conflict (different GitHubId)
          C-->>U: Error (email bound to different GitHub)
        end
      else Email not found
        alt RegisterEnabled
          C->>DB: Create user
          DB-->>C: new user
          C-->>U: Login new user
        else Registration disabled
          C-->>U: Error (registration closed)
        end
      end
    else No email
      alt RegisterEnabled
        C->>DB: Create user
        DB-->>C: new user
        C-->>U: Login new user
      else Registration disabled
        C-->>U: Error (registration closed)
      end
    end
  end
Loading
sequenceDiagram
  autonumber
  participant U as User
  participant OP as OIDC Provider
  participant C as Controller (oidc.go)
  participant DB as Database

  U->>OP: OIDC login
  OP-->>C: Callback (oidc_id, email, email_verified, name, preferred_username)
  C->>DB: Find user by OidcId
  alt Found by OidcId
    DB-->>C: user
    C-->>U: Login existing user
  else Not found by OidcId
    alt Email present and verified
      C->>DB: Find user by email
      alt Found by email
        DB-->>C: user
        alt OidcId empty or matches
          C->>DB: Update user.OidcId (+ DisplayName if missing)
          DB-->>C: updated user
          C-->>U: Login linked user
        else Conflict (different OidcId)
          C-->>U: Error (email bound to another OIDC account)
        end
      else Email not found
        alt RegisterEnabled
          C->>DB: Create user (username from preferred_username or generated)
          DB-->>C: new user
          C-->>U: Login new user
        else Registration disabled
          C-->>U: Error (registration closed)
        end
      end
    else Email missing or not verified
      C-->>U: Error (email required/verified)
    end
  end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested reviewers

  • seefs001

Poem

I hop through logins, light and quick,
I stitch emails to OAuth's click.
When a name is missing, I lend a paw,
Gates swing only when a new nest's law.
Thump-thump—rabbit cheers, bindings fixed! 🐇✨

Pre-merge checks and finishing touches

❌ Failed checks (3 warnings)
Check name Status Explanation Resolution
Linked Issues Check ⚠️ Warning Although the PR refactors OAuth handlers and improves account linking, it does not implement any workflow for OAuth‐registered users to set or change a password without an existing password, which is the core requirement of issue #1350. Add functionality and appropriate endpoints to allow users created via third‐party OAuth to establish or reset a password without requiring an existing password, satisfying the linked issue’s requirements.
Out of Scope Changes Check ⚠️ Warning The pull request includes UI updates to multiple OAuth provider binding cards and other binding logic that have no relation to restoring password workflows for third‐party–registered users, indicating changes beyond the scope of the linked issue. Remove or relocate the UI binding changes into a separate pull request and concentrate this PR solely on implementing the password creation and reset functionality required by issue #1350.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title succinctly captures the primary change of enhancing OAuth user binding and registration logic and aligns directly with the modifications to the GitHub and OIDC handlers without extraneous details.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between eac0570 and 3956ba1.

📒 Files selected for processing (1)
  • controller/oidc.go (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
controller/oidc.go (4)
model/user.go (1)
  • User (20-49)
model/main.go (1)
  • DB (64-64)
common/gin.go (1)
  • ApiError (97-102)
common/constants.go (1)
  • RegisterEnabled (51-51)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🧹 Nitpick comments (1)
controller/oidc.go (1)

175-181: Registration gating at creation point is correct; consider adding inviter support.

The gating check is good. To keep parity with GitHub, pass inviter via session "aff" when inserting:

- err := user.Insert(0)
+ affCode := session.Get("aff")
+ inviterId := 0
+ if affCode != nil {
+   inviterId, _ = model.GetUserIdByAffCode(affCode.(string))
+ }
+ err := user.Insert(inviterId)
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 384cba9 and 6746f67.

⛔ Files ignored due to path filters (1)
  • web/bun.lock is excluded by !**/*.lock
📒 Files selected for processing (3)
  • controller/github.go (2 hunks)
  • controller/oidc.go (2 hunks)
  • web/src/components/settings/personal/cards/AccountManagement.jsx (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
web/src/components/settings/personal/cards/AccountManagement.jsx (2)
web/src/components/auth/LoginForm.jsx (2)
  • status (99-102)
  • userState (68-68)
web/src/components/settings/PersonalSetting.jsx (2)
  • status (61-61)
  • userState (48-48)
controller/oidc.go (4)
model/user.go (1)
  • User (20-49)
model/main.go (1)
  • DB (64-64)
common/gin.go (1)
  • ApiError (97-102)
common/constants.go (1)
  • RegisterEnabled (51-51)
controller/github.go (4)
model/user.go (1)
  • User (20-49)
model/main.go (1)
  • DB (64-64)
common/gin.go (1)
  • ApiError (97-102)
common/constants.go (1)
  • RegisterEnabled (51-51)
🔇 Additional comments (7)
web/src/components/settings/personal/cards/AccountManagement.jsx (4)

196-205: WeChat binding state UX is correct.

Disabled + label logic aligns with status and binding state. LGTM.


246-250: GitHub binding label logic LGTM; verify config presence.

Looks good. Ensure status.github_client_id is set whenever status.github_oauth is true to avoid a disabled-state mismatch.


293-297: OIDC binding label logic LGTM.

States are consistent with disabled condition.


413-417: LinuxDO binding label logic LGTM.

Consistent with disabled condition and bound state.

controller/github.go (2)

17-17: Import gorm is appropriate for ErrRecordNotFound checks.


165-173: Registration gating at creation point is good.

This defers the “registration disabled” check until you know a new user is needed. LGTM.

controller/oidc.go (1)

19-19: Import gorm is appropriate for DB not-found checks.

Comment on lines +135 to +165
if githubUser.Email != "" {
var existingUser model.User
err := model.DB.Where("email = ?", githubUser.Email).First(&existingUser).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
common.ApiError(c, err)
return
}
if err == nil {
if existingUser.GitHubId != "" && existingUser.GitHubId != githubUser.Login {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "该邮箱对应的账户已绑定其他 GitHub 账户",
})
return
}
existingUser.GitHubId = githubUser.Login
if existingUser.DisplayName == "" {
if githubUser.Name != "" {
existingUser.DisplayName = githubUser.Name
} else {
existingUser.DisplayName = "GitHub User"
}
}
if err := existingUser.Update(false); err != nil {
common.ApiError(c, err)
return
}
user = existingUser
}
}
if user.Id == 0 {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Do not link accounts using unverified GitHub emails (account takeover risk).

GitHub’s user.email may be empty or unverified and can be set to arbitrary addresses. Linking by this field enables hijacking existing accounts. Fetch the verified primary email via the /user/emails endpoint (requires scope user:email) and only link when verified.

Apply these changes:

  1. Return the access token from getGitHubUserInfoByCode so you can call /user/emails:
- func getGitHubUserInfoByCode(code string) (*GitHubUser, error) {
+ func getGitHubUserInfoByCode(code string) (*GitHubUser, string, error) {
@@
-   if code == "" {
-     return nil, errors.New("无效的参数")
+   if code == "" {
+     return nil, "", errors.New("无效的参数")
    }
@@
-   if err != nil {
-     return nil, err
+   if err != nil {
+     return nil, "", err
    }
@@
-   if err != nil {
-     return nil, err
+   if err != nil {
+     return nil, "", err
    }
@@
-   if githubUser.Login == "" {
-     return nil, errors.New("返回值非法,用户字段为空,请稍后重试!")
+   if githubUser.Login == "" {
+     return nil, "", errors.New("返回值非法,用户字段为空,请稍后重试!")
    }
-   return &githubUser, nil
+   return &githubUser, oAuthResponse.AccessToken, nil
 }
  1. Add a helper to fetch the verified primary email:
type GitHubEmail struct {
  Email    string `json:"email"`
  Primary  bool   `json:"primary"`
  Verified bool   `json:"verified"`
}

func fetchGitHubVerifiedPrimaryEmail(token string) (string, error) {
  req, _ := http.NewRequest("GET", "https://api.github.com/user/emails", nil)
  req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
  req.Header.Set("Accept", "application/vnd.github+json")
  client := http.Client{Timeout: 5 * time.Second}
  res, err := client.Do(req)
  if err != nil {
    return "", err
  }
  defer res.Body.Close()
  var emails []GitHubEmail
  if err := json.NewDecoder(res.Body).Decode(&emails); err != nil {
    return "", err
  }
  for _, e := range emails {
    if e.Primary && e.Verified && e.Email != "" {
      return strings.ToLower(e.Email), nil
    }
  }
  return "", errors.New("未找到已验证的主邮箱")
}
  1. Update call site and linking logic:
- githubUser, err := getGitHubUserInfoByCode(code)
+ githubUser, accessToken, err := getGitHubUserInfoByCode(code)
@@
- if githubUser.Email != "" {
+ verifiedEmail := ""
+ if accessToken != "" {
+   if e, ferr := fetchGitHubVerifiedPrimaryEmail(accessToken); ferr == nil {
+     verifiedEmail = e
+   }
+ }
+ if verifiedEmail != "" {
   var existingUser model.User
-  err := model.DB.Where("email = ?", githubUser.Email).First(&existingUser).Error
+  err := model.DB.Where("LOWER(email) = ?", verifiedEmail).First(&existingUser).Error
   if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
     common.ApiError(c, err)
     return
   }
   if err == nil {
     if existingUser.GitHubId != "" && existingUser.GitHubId != githubUser.Login {
       c.JSON(http.StatusOK, gin.H{
         "success": false,
         "message": "该邮箱对应的账户已绑定其他 GitHub 账户",
       })
       return
     }
     existingUser.GitHubId = githubUser.Login
@@
     if err := existingUser.Update(false); err != nil {
       common.ApiError(c, err)
       return
     }
     user = existingUser
   }
 }

Additionally:

  • Normalize stored emails to lowercase whenever assigning (e.g., user.Email = strings.ToLower(verifiedEmail)).
  • Ensure github_id has a unique DB index to prevent races/double-binding.

🏁 Script executed:

#!/bin/bash
# Locate getGitHubUserInfoByCode definition and GitHubUser struct
rg -n "func getGitHubUserInfoByCode" -C5
rg -n "type GitHubUser" -C5 controller/github.go

Length of output: 900


🏁 Script executed:

#!/bin/bash
# Display full implementation of getGitHubUserInfoByCode
sed -n '1,200p' controller/github.go | sed -n '1,200!d'

Length of output: 0


🏁 Script executed:

#!/bin/bash
# Show implementation of getGitHubUserInfoByCode from lines 30–120
sed -n '30,120p' controller/github.go

Length of output: 2425


Secure GitHub email linking by verifying the primary email
Fetch and use only the user’s verified primary email instead of the public email field to prevent account takeover:

  • Change
    func getGitHubUserInfoByCode(code string) (*GitHubUser, error)
    to return (githubUser *GitHubUser, accessToken string, err error) so you can call /user/emails.
  • Add fetchGitHubVerifiedPrimaryEmail(token string) (string, error) that GETs https://api.github.com/user/emails, decodes []{Email,Primary,Verified}, and returns the primary verified email (lowercased).
  • In GitHubOAuth, use that verified email for model.DB.Where("LOWER(email)=?", verifiedEmail).First(&existingUser) and normalize all stored emails via strings.ToLower.
  • Add a unique index on github_id in your database to prevent race conditions or double-binding.

Comment on lines +146 to +173
var existingUser model.User
err := model.DB.Where("email = ?", oidcUser.Email).First(&existingUser).Error
if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
common.ApiError(c, err)
return
}
if err == nil {
if existingUser.OidcId != "" && existingUser.OidcId != oidcUser.OpenID {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "该邮箱对应的账户已绑定其他 OIDC 账户",
})
return
}
existingUser.OidcId = oidcUser.OpenID
if existingUser.DisplayName == "" {
if oidcUser.Name != "" {
existingUser.DisplayName = oidcUser.Name
} else {
existingUser.DisplayName = "OIDC User"
}
}
if err := existingUser.Update(false); err != nil {
common.ApiError(c, err)
return
}
user = existingUser
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

Require OIDC email_verified before email-based linking.

Linking on an unverified email can hijack existing accounts. Include and enforce the email_verified claim from userinfo.

Apply these changes:

  1. Capture email_verified in OidcUser:
 type OidcUser struct {
   OpenID            string `json:"sub"`
   Email             string `json:"email"`
+  EmailVerified     bool   `json:"email_verified"`
   Name              string `json:"name"`
   PreferredUsername string `json:"preferred_username"`
   Picture           string `json:"picture"`
 }
  1. Refuse linking if not verified; normalize email on lookup:
- var existingUser model.User
- err := model.DB.Where("email = ?", oidcUser.Email).First(&existingUser).Error
+ if !oidcUser.EmailVerified {
+   c.JSON(http.StatusOK, gin.H{
+     "success": false,
+     "message": "OIDC 邮箱未验证,无法通过邮箱自动绑定",
+   })
+   return
+ }
+ var existingUser model.User
+ err := model.DB.Where("LOWER(email) = ?", strings.ToLower(oidcUser.Email)).First(&existingUser).Error
@@
- existingUser.OidcId = oidcUser.OpenID
+ existingUser.OidcId = oidcUser.OpenID

Also, when creating a new user, store email lowercased:

- user.Email = oidcUser.Email
+ user.Email = strings.ToLower(oidcUser.Email)

🏁 Script executed:

#!/bin/bash
file=$(fd -t f oidc.go | head -n1)
echo "File: $file"
echo "=== OidcUser struct ==="
sed -n '/type OidcUser/,/}/p' "$file"
echo
echo "=== Imports ==="
sed -n '1,50p' "$file" | grep -E '^import'
echo
echo "=== user.Email assignments ==="
grep -R "user\.Email" -n "$file"

Length of output: 383


🏁 Script executed:

#!/bin/bash
echo "=== Import block ==="
sed -n '1,200p' controller/oidc.go | sed -n '/import (/,/)/p'
echo
echo "=== strings usage/import ==="
grep -R "strings" -n controller/oidc.go

Length of output: 498


Require verified email before OIDC account linking

  • Add EmailVerified bool json:"email_verified" to OidcUser.
  • Abort linking with a failure response if !oidcUser.EmailVerified.
  • Lookup existing users case-insensitively:
    model.DB.Where("LOWER(email)=?", strings.ToLower(oidcUser.Email))…
  • On new user creation, store user.Email = strings.ToLower(oidcUser.Email).
🤖 Prompt for AI Agents
In controller/oidc.go around lines 146-173: enforce verified email and
case-insensitive email handling when linking/creating users. Add EmailVerified
bool json:"email_verified" to the OidcUser struct, immediately abort linking
with a failure response if oidcUser.EmailVerified is false, change the lookup to
use case-insensitive matching (e.g. WHERE LOWER(email)=? with
strings.ToLower(oidcUser.Email)), and when creating a new user set user.Email =
strings.ToLower(oidcUser.Email). Ensure imports/use of strings as needed.

@seefs001
Copy link
Collaborator

考虑到Github和OIDC的邮箱有未验证的情况,这个暂时还不能合并

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 0

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
controller/oidc.go (1)

198-206: Extend password-reset flow for OAuth-only users
user.Insert(0) inserts an empty-string ("") password—which satisfies the NOT NULL constraint—but the /user/reset endpoint only accepts email and token. Per issue #1350, add a password field to PasswordResetRequest and update ResetPassword to set an initial password without requiring the old one.

♻️ Duplicate comments (1)
controller/oidc.go (1)

151-158: Normalize and match email case-insensitively; handle duplicate-email ambiguity.

Current lookup is case-sensitive and stores raw case. This can miss existing accounts (leading to duplicate accounts) and can bind unpredictably if duplicates exist. Normalize to lowercase on read/write and reject ambiguous matches. Also avoid shadowing err with :=.

Apply this diff:

@@
-    var existingUser model.User
-    err := model.DB.Where("email = ?", oidcUser.Email).First(&existingUser).Error
-    if err != nil && !errors.Is(err, gorm.ErrRecordNotFound) {
-      common.ApiError(c, err)
-      return
-    }
-    if err == nil {
-      if existingUser.OidcId != "" && existingUser.OidcId != oidcUser.OpenID {
-        c.JSON(http.StatusOK, gin.H{
-          "success": false,
-          "message": "该邮箱对应的账户已绑定其他 OIDC 账户",
-        })
-        return
-      }
-      existingUser.OidcId = oidcUser.OpenID
-      if existingUser.DisplayName == "" {
-        if oidcUser.Name != "" {
-          existingUser.DisplayName = oidcUser.Name
-        } else {
-          existingUser.DisplayName = "OIDC User"
-        }
-      }
-      if err := existingUser.Update(false); err != nil {
-        common.ApiError(c, err)
-        return
-      }
-      user = existingUser
-    }
+    normalizedEmail := strings.ToLower(strings.TrimSpace(oidcUser.Email))
+    var matches []model.User
+    err = model.DB.Where("LOWER(email) = ?", normalizedEmail).Limit(2).Find(&matches).Error
+    if err != nil {
+      common.ApiError(c, err)
+      return
+    }
+    if len(matches) > 1 {
+      c.JSON(http.StatusOK, gin.H{
+        "success": false,
+        "message": "该邮箱对应多个账户,请联系管理员处理",
+      })
+      return
+    }
+    if len(matches) == 1 {
+      existingUser := matches[0]
+      if existingUser.OidcId != "" && existingUser.OidcId != oidcUser.OpenID {
+        c.JSON(http.StatusOK, gin.H{
+          "success": false,
+          "message": "该邮箱对应的账户已绑定其他 OIDC 账户",
+        })
+        return
+      }
+      existingUser.OidcId = oidcUser.OpenID
+      if existingUser.DisplayName == "" {
+        if oidcUser.Name != "" {
+          existingUser.DisplayName = oidcUser.Name
+        } else {
+          existingUser.DisplayName = "OIDC User"
+        }
+      }
+      if err = existingUser.Update(false); err != nil {
+        common.ApiError(c, err)
+        return
+      }
+      user = existingUser
+    }
@@
-      user.Email = oidcUser.Email
+      user.Email = normalizedEmail

Based on learnings (GORM).

Also applies to: 187-187

🧹 Nitpick comments (4)
controller/oidc.go (4)

31-38: Adding EmailVerified to OidcUser is good. Consider pointer if some IdPs omit the claim.

If you encounter IdPs that don’t include email_verified in userinfo, switching to a pointer can distinguish “absent” from “false”:

  • Change to: EmailVerified *bool json:"email_verified"
  • Then check: if oidcUser.EmailVerified == nil || !*oidcUser.EmailVerified { … }

110-119: Invalidate oauth_state after successful validation to prevent replay.

Delete the state from the session once checked.

Apply this diff:

   if state == "" || session.Get("oauth_state") == nil || state != session.Get("oauth_state").(string) {
     c.JSON(http.StatusForbidden, gin.H{
       "success": false,
       "message": "state is empty or not same",
     })
     return
   }
+  // Invalidate state to prevent replay
+  session.Delete("oauth_state")
+  _ = session.Save()

188-193: Ensure username is valid, unique, and collision-safe.

PreferredUsername may exceed limits or collide with existing usernames. Consider:

  • sanitize/trim to allowed charset and length,
  • check for uniqueness; on conflict, fall back to a generated slug (e.g., oidc_) with retry on unique violation.

243-247: Avoid panic on session id type assertion.

session.Get("id") may not be int (e.g., float64/string depending on store). Safely handle types.

Apply this diff:

-  id := session.Get("id")
-  // id := c.GetInt("id")  // critical bug!
-  user.Id = id.(int)
+  sid := session.Get("id")
+  switch v := sid.(type) {
+  case int:
+    user.Id = v
+  case int64:
+    user.Id = int(v)
+  case float64:
+    user.Id = int(v)
+  default:
+    c.JSON(http.StatusOK, gin.H{
+      "success": false,
+      "message": "session 无效,请重新登录",
+    })
+    return
+  }
📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6746f67 and eac0570.

📒 Files selected for processing (1)
  • controller/oidc.go (4 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
controller/oidc.go (5)
common/sys_log.go (1)
  • SysLog (11-14)
model/user.go (1)
  • User (20-49)
model/main.go (1)
  • DB (64-64)
common/gin.go (1)
  • ApiError (97-102)
common/constants.go (1)
  • RegisterEnabled (51-51)
🔇 Additional comments (3)
controller/oidc.go (3)

19-19: LGTM: gorm import is appropriate for ErrRecordNotFound checks.


103-106: Requiring verified email before linking is correct.

Prevents hijacking via unverified addresses. Confirm your supported IdPs reliably populate this claim in userinfo.

Can you confirm all supported OIDC providers return email_verified in the userinfo response for accounts with an email?


179-186: LGTM: Gate new-user creation behind RegisterEnabled.

Prevents unintended signups while still allowing linking for existing users.

This reverts commit eac0570.
@Pleasurecruise
Copy link
Author

#1350 这个问题确实存在 通过第三方登录会绕过邮箱唯一性约束
且通过第三方登录创建的账号仅能通过第三方进行登录 无法进行密码更改
Github是一定会有一个经过验证的主邮箱

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

第三方注册登录无法密码,而修改密码需要已有密码

2 participants