Skip to content
Open
Show file tree
Hide file tree
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
6 changes: 6 additions & 0 deletions internal/opa/opa.go
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,12 @@ func Middleware(ctx context.Context, cfg Config, next http.Handler) (http.Handle
}
if !allowed {
logger.Warn("OPA denied request", "method", r.Method, "path", r.URL.Path, "remote_addr", r.RemoteAddr)
// The unread body is still on the wire, so the connection can't be reused. Saying so
// up front also stops net/http reading up to 256KiB of the body before replying, which
// it does because otelhttp replaces r.Body and hides the unread length from it.
Comment on lines +70 to +72

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Remove the prohibited inline comment

This three-line comment annotates a small six-line denial branch, despite the repository rule allowing comments only for relatively large blocks of at least 20 lines. The condition and header assignment are already concise, so remove the comment rather than introducing a repository-convention violation.

AGENTS.md reference: AGENTS.md:L19-L22

Useful? React with 👍 / 👎.

if r.ContentLength != 0 {
w.Header().Set("Connection", "close")
}
http.Error(w, "forbidden", http.StatusForbidden)
return
}
Expand Down
22 changes: 22 additions & 0 deletions internal/opa/opa_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"

"github.com/alecthomas/assert/v2"
Expand Down Expand Up @@ -365,6 +366,27 @@ test_delete_allowed if authz.allow with input as {"method": "DELETE"}
}
}

func TestMiddlewareDeniedUploadClosesConnection(t *testing.T) {
policy := `package cachew.authz
default allow := false
`
next := http.HandlerFunc(func(_ http.ResponseWriter, _ *http.Request) {})
handler, err := opa.Middleware(t.Context(), opa.Config{Policy: policy}, next)
assert.NoError(t, err)

upload := httptest.NewRequest(http.MethodPost, "/api/v1/object/ns/key", strings.NewReader("data"))
upload = upload.WithContext(logging.ContextWithLogger(upload.Context(), slog.Default()))
w := httptest.NewRecorder()
handler.ServeHTTP(w, upload)
assert.Equal(t, http.StatusForbidden, w.Code)
assert.Equal(t, "close", w.Header().Get("Connection"))

w = httptest.NewRecorder()
handler.ServeHTTP(w, newRequest(http.MethodGet, "/api/v1/object/ns/key"))
assert.Equal(t, http.StatusForbidden, w.Code)
assert.Equal(t, "", w.Header().Get("Connection"))
}

func TestMiddlewareEmptyPolicyDeniesAll(t *testing.T) {
policy := `package cachew.authz
`
Expand Down
Loading