Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Conversation

@ReneWerner87
Copy link
Member

Summary

  • parse nested struct blocks so session config migrations handle deeply nested fields
  • migrate cookie-based KeyLookup even when session configs contain nested structs
  • cover nested KeyLookup with regression tests
  • stabilize dev escort watcher test to prevent flakiness

Testing

  • make lint
  • make test

https://chatgpt.com/codex/tasks/task_e_68a9fd340f648326afb03608e21e15d6

@coderabbitai
Copy link

coderabbitai bot commented Aug 23, 2025

Warning

Rate limit exceeded

@ReneWerner87 has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 6 minutes and 6 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 50c0900 and 268ae7f.

📒 Files selected for processing (10)
  • cmd/dev_test.go (1 hunks)
  • cmd/internal/migrations/lists.go (5 hunks)
  • cmd/internal/migrations/v3/common.go (3 hunks)
  • cmd/internal/migrations/v3/csrfconfig.go (1 hunks)
  • cmd/internal/migrations/v3/csrfconfig_test.go (1 hunks)
  • cmd/internal/migrations/v3/key_auth_config.go (3 hunks)
  • cmd/internal/migrations/v3/key_auth_config_test.go (1 hunks)
  • cmd/internal/migrations/v3/session_config.go (1 hunks)
  • cmd/internal/migrations/v3/session_config_test.go (3 hunks)
  • cmd/internal/migrations/v3/session_extractor.go (1 hunks)
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch codex/2025-08-23-19-58-04

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai or @coderabbitai title anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@github-actions github-actions bot added the ☢️ Bug Something isn't working label Aug 23, 2025
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Summary of Changes

Hello @ReneWerner87, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!

This pull request primarily focuses on enhancing the migration process for KeyLookup configurations within various middleware (CSRF, KeyAuth, Session) to correctly handle complex and deeply nested struct values. It introduces robust parsing utilities to ensure accurate migration of these fields and improves the overall error reporting for migrations. Additionally, a flaky development test has been stabilized.

Highlights

  • Improved KeyLookup Migration: Enhanced the migration logic for KeyLookup fields in CSRF, KeyAuth, and Session configurations to correctly parse and transform complex or nested values, including those defined by functions or multiple sources.
  • Robust Go Code Parsing Utilities: Introduced new internal utilities (replaceKeyLookup, extractBlock) to accurately parse Go struct literals, handle nested delimiters, and manage quoted strings, which are crucial for reliable code migrations.
  • Enhanced Migration Error Handling: The DoMigration function now collects and reports all migration errors using errors.Join instead of stopping on the first error, providing a more comprehensive overview of migration issues.
  • Test Suite Expansion: Added comprehensive regression tests for KeyLookup migrations across CSRF, KeyAuth, and Session middleware to ensure the new parsing logic works as expected for various scenarios.
  • Development Test Stabilization: Addressed flakiness in the dev_test.go by adjusting sleep timings, making the test more reliable.
Using Gemini Code Assist

The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.

Invoking Gemini

You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in issue comments and review comments.
Help /gemini help Displays a list of available commands.

Customization

To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.

Limitations & Feedback

Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here.

You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.

Footnotes

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@ReneWerner87 ReneWerner87 merged commit 089114d into master Aug 23, 2025
13 checks passed
@ReneWerner87 ReneWerner87 deleted the codex/2025-08-23-19-58-04 branch August 23, 2025 20:00
Copy link
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

Code Review

This pull request effectively addresses the handling of complex values in KeyLookup migrations by introducing robust parsing for nested struct blocks. The use of extractBlock is a solid improvement. The changes are well-supported by new regression tests, which is great to see. My feedback includes a suggestion to improve the robustness of one migration for consistency and to refactor some duplicated code for better maintainability.

func MigrateKeyAuthConfig(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
reConfig := regexp.MustCompile(`keyauth\.Config{[^}]*}`)
reKeyLookup := regexp.MustCompile(`(?m)(\s*)KeyLookup:\s*("[^"]+")(,?)(\n?)`)
reConfig := regexp.MustCompile(`keyauth\.Config{(?:[^{}]|{[^{}]*})*}`)
Copy link
Contributor

Choose a reason for hiding this comment

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

high

This regex to find keyauth.Config blocks is less robust than the extractBlock approach used in other migrations in this PR (e.g., MigrateCSRFConfig). It only handles one level of nested braces and might fail for more complex, deeply nested struct literals.

For consistency and robustness, I recommend refactoring this migration to use regexp.MustCompile(keyauth\.Config{) to find the start of the block, and then use extractBlock to find its end. This would align it with MigrateCSRFConfig, MigrateSessionConfig, and MigrateSessionExtractor.

Here is an example of how MigrateKeyAuthConfig could be refactored:

func MigrateKeyAuthConfig(cmd *cobra.Command, cwd string, _, _ *semver.Version) error {
	reConfig := regexp.MustCompile(`keyauth\\.Config{`)
	reAuthScheme := regexp.MustCompile(`(?m)\\s*AuthScheme:\\s*([^,\\n]+)`)

	changed, err := internal.ChangeFileContent(cwd, func(content string) string {
		matches := reConfig.FindAllStringIndex(content, -1)
		if len(matches) == 0 {
			return content
		}

		var b strings.Builder
		last := 0
		for _, m := range matches {
			if _, err := b.WriteString(content[last:m[0]]); err != nil {
				return content
			}
			start := m[0]
			end := extractBlock(content, m[1], '{', '}')
			cfg := content[start:end]

			cfg = replaceKeyLookup(cfg, func(indent, val, comma, comment, newline string) string {
				scheme := "Bearer"
				if am := reAuthScheme.FindStringSubmatch(cfg); len(am) > 1 {
					scheme = strings.TrimSpace(am[1])
					if uq, err := strconv.Unquote(scheme); err == nil {
						scheme = uq
					}
				}

				parts := strings.Split(val, ",")
				var extractors []string
				for _, p := range parts {
					p = strings.TrimSpace(p)
					switch {
					case strings.HasPrefix(p, "header:"):
						header := strings.TrimPrefix(p, "header:")
						if strings.EqualFold(header, "Authorization") {
							extractors = append(extractors, fmt.Sprintf("keyauth.FromAuthHeader(%q, %q)", header, scheme))
						} else {
							extractors = append(extractors, fmt.Sprintf("keyauth.FromHeader(%q)", header))
						}
					case strings.HasPrefix(p, "query:"):
						extractors = append(extractors, fmt.Sprintf("keyauth.FromQuery(%q)", strings.TrimPrefix(p, "query:")))
					case strings.HasPrefix(p, "param:"):
						extractors = append(extractors, fmt.Sprintf("keyauth.FromParam(%q)", strings.TrimPrefix(p, "param:")))
					case strings.HasPrefix(p, "form:"):
						extractors = append(extractors, fmt.Sprintf("keyauth.FromForm(%q)", strings.TrimPrefix(p, "form:")))
					case strings.HasPrefix(p, "cookie:"):
						extractors = append(extractors, fmt.Sprintf("keyauth.FromCookie(%q)", strings.TrimPrefix(p, "cookie:")))
					default:
						if comment != "" {
							comment = " " + comment
						}
						return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
					}
				}

				extractor := ""
				if len(extractors) == 1 {
					extractor = extractors[0]
				} else if len(extractors) > 1 {
					extractor = fmt.Sprintf("keyauth.Chain(%s)", strings.Join(extractors, ", "))
				}
				if extractor == "" {
					if comment != "" {
						comment = " " + comment
					}
					return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
				}

				if comment != "" {
					comment = " " + comment
				}
				return fmt.Sprintf("%sExtractor: %s%s%s%s", indent, extractor, comma, comment, newline)
			})

			cfg = removeConfigField(cfg, "AuthScheme")

			if _, err := b.WriteString(cfg); err != nil {
				return content
			}
			last = end
		}
		if _, err := b.WriteString(content[last:]); err != nil {
			return content
		}
		return b.String()
	})
	if err != nil {
		return fmt.Errorf("failed to migrate keyauth configs: %w", err)
	}
	if !changed {
		return nil
	}

	cmd.Println("Migrating keyauth middleware configs")
	return nil
}

Comment on lines +36 to +54
var extractor string
switch {
case strings.HasPrefix(val, "header:"):
extractor = fmt.Sprintf("Extractor: csrf.FromHeader(%q)", strings.TrimPrefix(val, "header:"))
case strings.HasPrefix(val, "form:"):
extractor = fmt.Sprintf("Extractor: csrf.FromForm(%q)", strings.TrimPrefix(val, "form:"))
case strings.HasPrefix(val, "query:"):
extractor = fmt.Sprintf("Extractor: csrf.FromQuery(%q)", strings.TrimPrefix(val, "query:"))
default:
if comment != "" {
comment = " " + comment
}
return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
}

return fmt.Sprintf("%s%s%s%s", indent, extractor, comma, newline)
})
if comment != "" {
comment = " " + comment
}
return fmt.Sprintf("%s%s%s%s%s", indent, extractor, comma, comment, newline)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic to prepend a space to the comment if it exists is duplicated. You can simplify this by handling it once at the start of the function.

                                if comment != "" {
					comment = " " + comment
				}

				var extractor string
				switch {
				case strings.HasPrefix(val, "header:"):
					extractor = fmt.Sprintf("Extractor: csrf.FromHeader(%q)", strings.TrimPrefix(val, "header:"))
				case strings.HasPrefix(val, "form:"):
					extractor = fmt.Sprintf("Extractor: csrf.FromForm(%q)", strings.TrimPrefix(val, "form:"))
				case strings.HasPrefix(val, "query:"):
					extractor = fmt.Sprintf("Extractor: csrf.FromQuery(%q)", strings.TrimPrefix(val, "query:"))
				default:
					return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
				}

				return fmt.Sprintf("%s%s%s%s%s", indent, extractor, comma, comment, newline)

Comment on lines +44 to +66
if comment != "" {
comment = " " + comment
}
return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
}
}

parts := strings.Split(val, ",")
var extractors []string
for _, p := range parts {
p = strings.TrimSpace(p)
switch {
case strings.HasPrefix(p, "cookie:"):
extractors = append(extractors, fmt.Sprintf("session.FromCookie(%q)", strings.TrimPrefix(p, "cookie:")))
case strings.HasPrefix(p, "header:"):
extractors = append(extractors, fmt.Sprintf("session.FromHeader(%q)", strings.TrimPrefix(p, "header:")))
case strings.HasPrefix(p, "query:"):
extractors = append(extractors, fmt.Sprintf("session.FromQuery(%q)", strings.TrimPrefix(p, "query:")))
default:
return ""
if len(extractors) == 0 {
if comment != "" {
comment = " " + comment
}
return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
}
}

if len(extractors) == 0 {
return ""
}
extractor := extractors[0]
if len(extractors) > 1 {
extractor = fmt.Sprintf("session.Chain(%s)", strings.Join(extractors, ", "))
}

extractor := extractors[0]
if len(extractors) > 1 {
extractor = fmt.Sprintf("session.Chain(%s)", strings.Join(extractors, ", "))
if comment != "" {
comment = " " + comment
}
return fmt.Sprintf("%sExtractor: %s%s%s%s", indent, extractor, comma, comment, newline)
Copy link
Contributor

Choose a reason for hiding this comment

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

medium

The logic to prepend a space to the comment if it exists is duplicated. This can be simplified by handling it once.

						if comment != "" {
							comment = " " + comment
						}
						return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
					}
				}

				if comment != "" {
					comment = " " + comment
				}

				if len(extractors) == 0 {
					return fmt.Sprintf("%s// TODO: migrate KeyLookup: %s%s%s", indent, val, comment, newline)
				}

				extractor := extractors[0]
				if len(extractors) > 1 {
					extractor = fmt.Sprintf("session.Chain(%s)", strings.Join(extractors, ", "))
				}

				return fmt.Sprintf("%sExtractor: %s%s%s%s", indent, extractor, comma, comment, newline)

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

Labels

☢️ Bug Something isn't working codex

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants