History

fix(auth): validate antigravity token userinfo email

hkfires committed 9 months ago

Commit e95be101 parent f3d58fa3 files · +57 −32Browse files

Unified · Split

3 files
  1. internal/api/handlers/management/auth_files.go +23 −18
  2. internal/auth/antigravity/auth.go +20 −7
  3. sdk/auth/antigravity.go +14 −7
internal/api/handlers/management/auth_files.go+23−18
@@ -1148,13 +1148,9 @@ func (h *Handler) RequestGeminiCLIToken(c *gin.Context) { · 1147 unmodified lines
11481148 }
11491149
11501150 ifToken["token_uri"] = "https://oauth2.googleapis.com/token"
1151− ifToken["client_id"] = "681255809395-oo8ft2oprdrnp9e3aqf6av3hmdib135j.apps.googleusercontent.com"
1152− ifToken["client_secret"] = "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"
1153− ifToken["scopes"] = []string{
1154− "https://www.googleapis.com/auth/cloud-platform",
1155− "https://www.googleapis.com/auth/userinfo.email",
1156− "https://www.googleapis.com/auth/userinfo.profile",
1157− }
1151+ ifToken["client_id"] = geminiAuth.ClientID
1152+ ifToken["client_secret"] = geminiAuth.ClientSecret
1153+ ifToken["scopes"] = geminiAuth.Scopes
11581154 ifToken["universe_domain"] = "googleapis.com"
11591155
11601156 ts := geminiAuth.GeminiTokenStorage{
@@ -1478,20 +1474,29 @@ func (h *Handler) RequestAntigravityToken(c *gin.Context) { · 317 unmodified lines
14781474 return
14791475 }
14801476
1481− email := ""
1482− if strings.TrimSpace(tokenResp.AccessToken) != "" {
1483− fetchedEmail, errInfo := authSvc.FetchUserInfo(ctx, tokenResp.AccessToken)
1484− if errInfo != nil {
1485− log.Errorf("Failed to fetch user info: %v", errInfo)
1486− SetOAuthSessionError(state, "Failed to fetch user info")
1487− return
1488− }
1489− email = strings.TrimSpace(fetchedEmail)
1477+ accessToken := strings.TrimSpace(tokenResp.AccessToken)
1478+ if accessToken == "" {
1479+ log.Error("antigravity: token exchange returned empty access token")
1480+ SetOAuthSessionError(state, "Failed to exchange token")
1481+ return
1482+ }
1483+
1484+ email, errInfo := authSvc.FetchUserInfo(ctx, accessToken)
1485+ if errInfo != nil {
1486+ log.Errorf("Failed to fetch user info: %v", errInfo)
1487+ SetOAuthSessionError(state, "Failed to fetch user info")
1488+ return
1489+ }
1490+ email = strings.TrimSpace(email)
1491+ if email == "" {
1492+ log.Error("antigravity: user info returned empty email")
1493+ SetOAuthSessionError(state, "Failed to fetch user info")
1494+ return
14901495 }
14911496
14921497 projectID := ""
1493− if strings.TrimSpace(tokenResp.AccessToken) != "" {
1494− fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, tokenResp.AccessToken)
1498+ if accessToken != "" {
1499+ fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, accessToken)
14951500 if errProject != nil {
14961501 log.Warnf("antigravity: failed to fetch project ID: %v", errProject)
14971502 } else {
internal/auth/antigravity/auth.go+20−7
@@ -100,18 +100,19 @@ func (o *AntigravityAuth) ExchangeCodeForTokens(ctx context.Context, code, redir · 99 unmodified lines
100100
101101 // FetchUserInfo retrieves user email from Google
102102 func (o *AntigravityAuth) FetchUserInfo(ctx context.Context, accessToken string) (string, error) {
103− if strings.TrimSpace(accessToken) == "" {
104− return "", nil
103+ accessToken = strings.TrimSpace(accessToken)
104+ if accessToken == "" {
105+ return "", fmt.Errorf("antigravity userinfo: missing access token")
105106 }
106107 req, err := http.NewRequestWithContext(ctx, http.MethodGet, UserInfoEndpoint, nil)
107108 if err != nil {
108− return "", err
109+ return "", fmt.Errorf("antigravity userinfo: create request: %w", err)
109110 }
110111 req.Header.Set("Authorization", "Bearer "+accessToken)
111112
112113 resp, errDo := o.httpClient.Do(req)
113114 if errDo != nil {
114− return "", errDo
115+ return "", fmt.Errorf("antigravity userinfo: execute request: %w", errDo)
115116 }
116117 defer func() {
117118 if errClose := resp.Body.Close(); errClose != nil {
@@ -120,13 +121,25 @@ func (o *AntigravityAuth) FetchUserInfo(ctx context.Context, accessToken string) · 2 unmodified lines
120121 }()
121122
122123 if resp.StatusCode < http.StatusOK || resp.StatusCode >= http.StatusMultipleChoices {
123− return "", nil
124+ bodyBytes, errRead := io.ReadAll(io.LimitReader(resp.Body, 8<<10))
125+ if errRead != nil {
126+ return "", fmt.Errorf("antigravity userinfo: read response: %w", errRead)
127+ }
128+ body := strings.TrimSpace(string(bodyBytes))
129+ if body == "" {
130+ return "", fmt.Errorf("antigravity userinfo: request failed: status %d", resp.StatusCode)
131+ }
132+ return "", fmt.Errorf("antigravity userinfo: request failed: status %d: %s", resp.StatusCode, body)
124133 }
125134 var info userInfo
126135 if errDecode := json.NewDecoder(resp.Body).Decode(&info); errDecode != nil {
127− return "", errDecode
136+ return "", fmt.Errorf("antigravity userinfo: decode response: %w", errDecode)
137+ }
138+ email := strings.TrimSpace(info.Email)
139+ if email == "" {
140+ return "", fmt.Errorf("antigravity userinfo: response missing email")
128141 }
129− return info.Email, nil
142+ return email, nil
130143 }
131144
132145 // FetchProjectID retrieves the project ID for the authenticated user via loadCodeAssist
sdk/auth/antigravity.go+14−7
@@ -153,17 +153,24 @@ waitForCallback: · 152 unmodified lines
153153 return nil, fmt.Errorf("antigravity: token exchange failed: %w", errToken)
154154 }
155155
156− email := ""
157− if tokenResp.AccessToken != "" {
158− if fetchedEmail, errInfo := authSvc.FetchUserInfo(ctx, tokenResp.AccessToken); errInfo == nil && strings.TrimSpace(fetchedEmail) != "" {
159− email = strings.TrimSpace(fetchedEmail)
160− }
156+ accessToken := strings.TrimSpace(tokenResp.AccessToken)
157+ if accessToken == "" {
158+ return nil, fmt.Errorf("antigravity: token exchange returned empty access token")
159+ }
160+
161+ email, errInfo := authSvc.FetchUserInfo(ctx, accessToken)
162+ if errInfo != nil {
163+ return nil, fmt.Errorf("antigravity: fetch user info failed: %w", errInfo)
164+ }
165+ email = strings.TrimSpace(email)
166+ if email == "" {
167+ return nil, fmt.Errorf("antigravity: empty email returned from user info")
161168 }
162169
163170 // Fetch project ID via loadCodeAssist (same approach as Gemini CLI)
164171 projectID := ""
165− if tokenResp.AccessToken != "" {
166− fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, tokenResp.AccessToken)
172+ if accessToken != "" {
173+ fetchedProjectID, errProject := authSvc.FetchProjectID(ctx, accessToken)
167174 if errProject != nil {
168175 log.Warnf("antigravity: failed to fetch project ID: %v", errProject)
169176 } else {