Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
41 changes: 37 additions & 4 deletions auth/middleware/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,39 @@ const (
pluginName string = "plugin-auth"
)

// unmarshalErrorResponse unmarshals a JSON response body into commons.Response,
// tolerating a numeric "code" field (the auth service may return code as a number).
func unmarshalErrorResponse(body []byte) (commons.Response, error) {
var raw struct {
EntityType string `json:"entityType,omitempty"`
Title string `json:"title,omitempty"`
Message string `json:"message,omitempty"`
Code json.RawMessage `json:"code,omitempty"`
}

if err := json.Unmarshal(body, &raw); err != nil {
return commons.Response{}, err
}

resp := commons.Response{
EntityType: raw.EntityType,
Title: raw.Title,
Message: raw.Message,
}

if len(raw.Code) > 0 {
var code string
if err := json.Unmarshal(raw.Code, &code); err == nil {
resp.Code = code
} else {
// Numeric code — use raw representation (e.g. "401")
resp.Code = string(raw.Code)
}
}

return resp, nil
}
Comment on lines +52 to +83
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

Add regression tests for mixed code types before merging.

This helper changes auth error parsing behavior in a critical middleware path, but there’s no test coverage for string/number/null/invalid code variants. Please add table-driven tests to lock this behavior and avoid reintroducing 500s on auth errors.

I can draft a complete table-driven _test.go for this helper and both call paths if you want.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@auth/middleware/middleware.go` around lines 52 - 83, unmarshalErrorResponse
now accepts mixed JSON types for the "code" field but lacks tests; add
table-driven tests for unmarshalErrorResponse covering cases: string code (e.g.
"ERR"), numeric code (e.g. 401), null code, missing code, empty string, and
invalid JSON for code to ensure it returns the expected commons.Response.Code
(string or raw numeric string) and no unexpected errors/500s. In the test file
create subtests that call unmarshalErrorResponse with representative bodies and
assert returned resp.Code and error match expected values; also add tests that
exercise the middleware path(s) that call unmarshalErrorResponse so end-to-end
behavior is locked in.


func logErrorf(ctx context.Context, logger log.Logger, format string, args ...any) {
if logger == nil {
return
Expand Down Expand Up @@ -321,8 +354,8 @@ func (auth *AuthClient) checkAuthorization(ctx context.Context, sub, resource, a
return false, http.StatusInternalServerError, fmt.Errorf("failed to read response body: %w", err)
}

var respError commons.Response
if err := json.Unmarshal(body, &respError); err != nil {
respError, err := unmarshalErrorResponse(body)
if err != nil {
logErrorf(ctx, auth.Logger, "Failed to unmarshal auth error response: %v", err)

opentelemetry.HandleSpanError(span, "Failed to unmarshal auth error response", err)
Expand Down Expand Up @@ -423,8 +456,8 @@ func (auth *AuthClient) GetApplicationToken(ctx context.Context, clientID, clien
return "", fmt.Errorf("failed to read response body: %w", err)
}

var respError commons.Response
if err := json.Unmarshal(body, &respError); err != nil {
respError, err := unmarshalErrorResponse(body)
if err != nil {
logErrorf(ctx, auth.Logger, "Failed to unmarshal auth error response: %v", err)

opentelemetry.HandleSpanError(span, "Failed to unmarshal auth error response", err)
Expand Down
Loading