Skip to content

feat: add file input option to JwtInfo#23

Merged
xenOs76 merged 3 commits intomainfrom
feat/jwtinfo_file_input
Mar 26, 2026
Merged

feat: add file input option to JwtInfo#23
xenOs76 merged 3 commits intomainfrom
feat/jwtinfo_file_input

Conversation

@xenOs76
Copy link
Copy Markdown
Owner

@xenOs76 xenOs76 commented Mar 26, 2026

Summary by CodeRabbit

  • New Features

    • Added a --request-values-file CLI option to load request values from a JSON file.
  • Documentation

    • Updated JwtInfo help text and usage examples to cover inline values, file-based values, and optional JWKS validation.
  • Bug Fixes / Behavior

    • Command now shows help and exits when neither request values nor a request URL are provided; file-loading errors are reported early.
  • Tests

    • Added unit tests and helpers covering file loading, parsing, and error cases.

@xenOs76 xenOs76 self-assigned this Mar 26, 2026
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

Warning

Rate limit exceeded

@xenOs76 has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 12 minutes and 50 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.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: be84ffd8-0529-4691-9196-37c96af214d8

📥 Commits

Reviewing files that changed from the base of the PR and between 6eaabd7 and 6a85c1d.

📒 Files selected for processing (1)
  • internal/jwtinfo/jwtinfo_test.go
📝 Walkthrough

Walkthrough

Adds a new CLI flag --request-values-file to load JSON-encoded request values from disk, implements file-reading/merging logic in the jwtinfo package, updates cmd help/flow, and adds tests, a test helper, and dev scripts for provider-specific runs.

Changes

Cohort / File(s) Summary
CLI
cmd/jwtinfo.go
Added --request-values-file flag, updated command help/examples, added control flow to require either request values (inline/file) or --request-url, and invoke file-loading/merge prior to parsing inline JSON.
Core logic
internal/jwtinfo/jwtinfo.go
Added ReadRequestValuesFile(fileName string, reqValuesMap map[string]string) (map[string]string, error) to read a JSON file, parse via existing parser, merge into provided map, and wrap file/parse errors.
Tests
internal/jwtinfo/jwtinfo_test.go, internal/jwtinfo/main_test.go
Added TestReadRequestValuesFile (success, invalid JSON, missing file) and a helper createTmpFileWithContent for creating temp files with controlled permissions; slight refactor of an existing test's map initialization.
Dev scripts
devenv.nix
Added scripts.run-jwtinfo-test-auth0-values-file.exec and scripts.run-jwtinfo-test-keycloak-values-file.exec entries to run jwtinfo with --request-values-file and provider-specific validation URLs.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

🐰 I dug a file beneath the tree,
JSON carrots for the JWT,
I read, I merge, then skip no test,
Hop—values loaded—life is best! 🥕

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ 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 accurately summarizes the main change: adding a new file input option (--request-values-file) to the JwtInfo CLI command, which is reflected across all modified files.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/jwtinfo_file_input

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
Copy Markdown

@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 (3)
internal/jwtinfo/jwtinfo_test.go (1)

68-68: Redundant cleanup: t.TempDir() automatically removes the directory.

The t.Cleanup call is unnecessary because t.TempDir() already registers automatic cleanup when the test completes. This line can be removed.

🧹 Proposed fix
 			require.NoError(t, err)
 			require.Equal(t, "jsonValue", outputMap["jsonKey"])
 			require.Equal(t, "testValue", outputMap["testKey"])
-
-			t.Cleanup(func() { os.RemoveAll(tmpDir) })
 		})
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/jwtinfo/jwtinfo_test.go` at line 68, Remove the redundant manual
cleanup that calls os.RemoveAll on the temporary directory created with
t.TempDir(): locate the test using t.TempDir() (the tmpDir variable) and remove
the t.Cleanup(func() { os.RemoveAll(tmpDir) }) line so cleanup is handled by
testing.T's automatic TempDir cleanup mechanism.
internal/jwtinfo/main_test.go (1)

251-272: Consider writing directly to the file handle instead of using os.WriteFile.

The function creates a file with os.CreateTemp and obtains a file handle f, but then uses os.WriteFile(f.Name(), ...) which opens the file again separately. Writing directly to the handle would be more efficient and idiomatic.

♻️ Proposed refactor
 func createTmpFileWithContent(
 	tempDir string,
 	filePattern string,
 	fileContent []byte,
 ) (filePath string, err error) {
 	f, err := os.CreateTemp(tempDir, filePattern)
 	if err != nil {
 		return emptyString, err
 	}
 
 	defer func() {
 		if closeErr := f.Close(); closeErr != nil {
 			err = errors.Join(err, closeErr)
 		}
 	}()
 
-	if err = os.WriteFile(f.Name(), fileContent, 0o600); err != nil {
+	if _, err = f.Write(fileContent); err != nil {
 		return emptyString, err
 	}
 
 	return f.Name(), nil
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/jwtinfo/main_test.go` around lines 251 - 272, The helper
createTmpFileWithContent currently calls os.CreateTemp to get a file handle f
but then reopens the file via os.WriteFile(f.Name(), ...); change this to write
directly to the opened file handle (use f.Write or io.WriteFull semantics) and
preserve the existing deferred close logic and permission handling; ensure any
write error is assigned to the named err return so the deferred close can join
errors as before (refer to function createTmpFileWithContent and variable f).
cmd/jwtinfo.go (1)

53-56: Consider simplifying the early-return condition for readability.

The current condition len(requestJSONValues+requestURL) == 0 && len(requestValuesFile+requestURL) == 0 is logically correct but hard to parse. It essentially checks: "if requestURL is empty AND neither value source is provided."

A clearer formulation would make the intent more obvious.

♻️ Proposed refactor
-		if len(requestJSONValues+requestURL) == 0 && len(requestValuesFile+requestURL) == 0 {
+		if requestURL == "" && requestJSONValues == "" && requestValuesFile == "" {
 			_ = cmd.Help()
 			return
 		}
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@cmd/jwtinfo.go` around lines 53 - 56, The compound length check is hard to
read; replace the expression `len(requestJSONValues+requestURL) == 0 &&
len(requestValuesFile+requestURL) == 0` with an explicit emptiness check such as
`requestURL == "" && requestJSONValues == "" && requestValuesFile == ""` inside
the same early-return block (the one that calls `cmd.Help()` and returns) so the
intent — no URL and no values provided — is clear; update the condition in the
function in which these variables are used (the block that currently calls
`cmd.Help()`).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/jwtinfo/jwtinfo_test.go`:
- Around line 17-70: The test shares the single inputMap across parallel
subtests which causes a data race because ReadRequestValuesFile (and
ParseRequestJSONValues which uses maps.Copy) mutates the passed map; fix by
giving each subtest its own copy of the input map before calling
ReadRequestValuesFile (e.g., create a new map and copy entries from inputMap
inside the t.Run closure) so ReadRequestValuesFile and ParseRequestJSONValues
operate on a per-subtest map rather than the shared inputMap.

In `@internal/jwtinfo/jwtinfo.go`:
- Around line 152-170: In ReadRequestValuesFile, fix the typo in the error
message when ParseRequestJSONValues fails: change the fmt.Errorf string that
currently reads "unable to parse JSON from requests's values file: %w" to use
"request's" (single apostrophe) so it matches the earlier message and avoids the
double apostrophe; update the error formatting in the return statement inside
ReadRequestValuesFile accordingly.

---

Nitpick comments:
In `@cmd/jwtinfo.go`:
- Around line 53-56: The compound length check is hard to read; replace the
expression `len(requestJSONValues+requestURL) == 0 &&
len(requestValuesFile+requestURL) == 0` with an explicit emptiness check such as
`requestURL == "" && requestJSONValues == "" && requestValuesFile == ""` inside
the same early-return block (the one that calls `cmd.Help()` and returns) so the
intent — no URL and no values provided — is clear; update the condition in the
function in which these variables are used (the block that currently calls
`cmd.Help()`).

In `@internal/jwtinfo/jwtinfo_test.go`:
- Line 68: Remove the redundant manual cleanup that calls os.RemoveAll on the
temporary directory created with t.TempDir(): locate the test using t.TempDir()
(the tmpDir variable) and remove the t.Cleanup(func() { os.RemoveAll(tmpDir) })
line so cleanup is handled by testing.T's automatic TempDir cleanup mechanism.

In `@internal/jwtinfo/main_test.go`:
- Around line 251-272: The helper createTmpFileWithContent currently calls
os.CreateTemp to get a file handle f but then reopens the file via
os.WriteFile(f.Name(), ...); change this to write directly to the opened file
handle (use f.Write or io.WriteFull semantics) and preserve the existing
deferred close logic and permission handling; ensure any write error is assigned
to the named err return so the deferred close can join errors as before (refer
to function createTmpFileWithContent and variable f).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e6a6f456-99c8-46c0-a41b-01e7f5bd560e

📥 Commits

Reviewing files that changed from the base of the PR and between 6631032 and a9b7c3e.

📒 Files selected for processing (5)
  • cmd/jwtinfo.go
  • devenv.nix
  • internal/jwtinfo/jwtinfo.go
  • internal/jwtinfo/jwtinfo_test.go
  • internal/jwtinfo/main_test.go

Copy link
Copy Markdown

@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: 1

♻️ Duplicate comments (2)
internal/jwtinfo/jwtinfo_test.go (2)

85-130: ⚠️ Potential issue | 🟠 Major

Avoid shared mutable map across parallel subtests.

inputMap is shared by all t.Parallel() cases, but ParseRequestJSONValues mutates the map. This can race and make outcomes nondeterministic.

Suggested fix
-	inputMap := map[string]string{
+	baseInputMap := map[string]string{
 		"testKey": "testValue",
 	}
@@
 		t.Run(tt.name, func(t *testing.T) {
 			t.Parallel()
 
+			inputMap := map[string]string{}
+			maps.Copy(inputMap, baseInputMap)
+
 			outputMap, err := ParseRequestJSONValues(
 				tt.jsonStr,
 				inputMap,
 			)
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/jwtinfo/jwtinfo_test.go` around lines 85 - 130, The test shares the
mutable variable inputMap across parallel subtests while ParseRequestJSONValues
mutates it, causing data races; fix by giving each subtest its own independent
map copy before calling ParseRequestJSONValues (e.g., clone inputMap into a new
local variable inside the t.Run closure) so t.Parallel() tests don't mutate
shared state, ensuring deterministic results when running the test cases for
ParseRequestJSONValues.

29-33: ⚠️ Potential issue | 🟠 Major

Update stale expected error string in the invalid-JSON case.

Line 32 still asserts requests's, but the production error is now request's, so this subtest will fail.

Suggested fix
-			errMsg:      "unable to parse JSON from requests's values file",
+			errMsg:      "unable to parse JSON from request's values file",
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@internal/jwtinfo/jwtinfo_test.go` around lines 29 - 33, Update the expected
error string in the "No JSON content" subtest in jwtinfo_test.go: replace the
stale "unable to parse JSON from requests's values file" value assigned to the
subtest's errMsg with the current production message "unable to parse JSON from
request's values file" so the expErr/errMsg check in the test matches the actual
error returned by the code.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@internal/jwtinfo/jwtinfo_test.go`:
- Around line 72-78: The failing subtest "fileNotExist" references inputMap
which is defined only inside another t.Run and is out of scope; update the test
so inputMap is visible by either declaring and initializing inputMap in the
outer scope before the t.Run closures or by creating a new local map inside the
"fileNotExist" closure, then call ReadRequestValuesFile("fileNotExist",
inputMap) using that valid variable.

---

Duplicate comments:
In `@internal/jwtinfo/jwtinfo_test.go`:
- Around line 85-130: The test shares the mutable variable inputMap across
parallel subtests while ParseRequestJSONValues mutates it, causing data races;
fix by giving each subtest its own independent map copy before calling
ParseRequestJSONValues (e.g., clone inputMap into a new local variable inside
the t.Run closure) so t.Parallel() tests don't mutate shared state, ensuring
deterministic results when running the test cases for ParseRequestJSONValues.
- Around line 29-33: Update the expected error string in the "No JSON content"
subtest in jwtinfo_test.go: replace the stale "unable to parse JSON from
requests's values file" value assigned to the subtest's errMsg with the current
production message "unable to parse JSON from request's values file" so the
expErr/errMsg check in the test matches the actual error returned by the code.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1bd31768-78be-4aa6-b050-5f509a12acba

📥 Commits

Reviewing files that changed from the base of the PR and between a9b7c3e and 6eaabd7.

📒 Files selected for processing (2)
  • internal/jwtinfo/jwtinfo.go
  • internal/jwtinfo/jwtinfo_test.go

@xenOs76
Copy link
Copy Markdown
Owner Author

xenOs76 commented Mar 26, 2026

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Mar 26, 2026

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@xenOs76 xenOs76 merged commit db0e21e into main Mar 26, 2026
3 checks passed
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.

1 participant