Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test: cleanup content blocking tests #10360

Merged
merged 5 commits into from
Mar 1, 2024
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
80 changes: 71 additions & 9 deletions test/cli/content_blocking_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,9 @@ import (
"strings"
"testing"

"github.com/ipfs/go-cid"
"github.com/ipfs/kubo/test/cli/harness"
carstore "github.com/ipld/go-car/v2/blockstore"
"github.com/libp2p/go-libp2p"
"github.com/libp2p/go-libp2p/core/peer"
libp2phttp "github.com/libp2p/go-libp2p/p2p/http"
Expand All @@ -34,8 +36,10 @@ func TestContentBlocking(t *testing.T) {
node := h.NewNode().Init("--empty-repo", "--profile=test")

// Create CIDs we use in test
h.WriteFile("blocked-dir/subdir/indirectly-blocked-file.txt", "indirectly blocked file content")
parentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", filepath.Join(h.Dir, "blocked-dir")).Stdout.Trimmed()
h.WriteFile("parent-dir/blocked-subdir/indirectly-blocked-file.txt", "indirectly blocked file content")
allowedParentDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir")).Stdout.Trimmed()
blockedSubDirCID := node.IPFS("add", "--raw-leaves", "-Q", "-r", "--pin=false", filepath.Join(h.Dir, "parent-dir", "blocked-subdir")).Stdout.Trimmed()
node.IPFS("block", "rm", blockedSubDirCID)

h.WriteFile("directly-blocked-file.txt", "directly blocked file content")
blockedCID := node.IPFS("add", "--raw-leaves", "-Q", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed()
Expand All @@ -50,7 +54,7 @@ func TestContentBlocking(t *testing.T) {
"//8526ba05eec55e28f8db5974cc891d0d92c8af69d386fc6464f1e9f372caf549\n" + // Legacy CID double-hash block: sha256(bafkqahtcnrxwg23fmqqgi33vmjwgk2dbonuca3dfm5qwg6jamnuwicq/)
"//e5b7d2ce2594e2e09901596d8e1f29fa249b74c8c9e32ea01eda5111e4d33f07\n" + // Legacy Path double-hash block: sha256(bafyaagyscufaqalqaacauaqiaejao43vmjygc5didacauaqiae/subpath)
"/ipfs/" + blockedCID + "\n" + // block specific CID
"/ipfs/" + parentDirCID + "/subdir*\n" + // block only specific subpath
"/ipfs/" + allowedParentDirCID + "/blocked-subdir*\n" + // block only specific subpath
"/ipns/blocked-cid.example.com\n" +
"/ipns/blocked-dnslink.example.com\n")

Expand Down Expand Up @@ -94,22 +98,63 @@ func TestContentBlocking(t *testing.T) {
// Confirm parent of blocked subpath is not blocked
t.Run("Gateway Allows parent Path that is not blocked", func(t *testing.T) {
t.Parallel()
resp := client.Get("/ipfs/" + parentDirCID)
resp := client.Get("/ipfs/" + allowedParentDirCID)
assert.Equal(t, http.StatusOK, resp.StatusCode)
})

// Confirm CAR responses skip blocked subpaths
t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) {
resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car")
assert.Equal(t, http.StatusOK, resp.StatusCode)

bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil)
assert.NoError(t, err)

has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID))
assert.NoError(t, err)
assert.False(t, has)
})

/* TODO: this was already broken in 0.26, but we should fix it
t.Run("Gateway returns CAR without directly blocked CID", func(t *testing.T) {
allowedDirWithDirectlyBlockedCID := node.IPFS("add", "--raw-leaves", "-Q", "-rw", filepath.Join(h.Dir, "directly-blocked-file.txt")).Stdout.Trimmed()
resp := client.Get("/ipfs/" + allowedDirWithDirectlyBlockedCID + "?format=car")
assert.Equal(t, http.StatusOK, resp.StatusCode)

bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil)
assert.NoError(t, err)

has, err := bs.Has(context.Background(), cid.MustParse(blockedCID))
assert.NoError(t, err)
assert.False(t, has, "Returned CAR should not include blockedCID")
})
*/

// Confirm CAR responses skip blocked subpaths
t.Run("Gateway returns CAR without blocked subpath", func(t *testing.T) {
resp := client.Get("/ipfs/" + allowedParentDirCID + "/subdir?format=car")
assert.Equal(t, http.StatusOK, resp.StatusCode)

bs, err := carstore.NewReadOnly(strings.NewReader(resp.Body), nil)
assert.NoError(t, err)

has, err := bs.Has(context.Background(), cid.MustParse(blockedSubDirCID))
assert.NoError(t, err)
assert.False(t, has, "Returned CAR should not include blockedSubDirCID")
})

// Ok, now the full list of test cases we want to cover in both CLI and Gateway
testCases := []struct {
name string
path string
}{
{
name: "directly blocked CID",
name: "directly blocked file CID",
path: "/ipfs/" + blockedCID,
},
{
name: "indirectly blocked file (on a blocked subpath)",
path: "/ipfs/" + parentDirCID + "/subdir/indirectly-blocked-file.txt",
path: "/ipfs/" + allowedParentDirCID + "/blocked-subdir/indirectly-blocked-file.txt",
},
{
name: "/ipns path that resolves to a blocked CID",
Expand Down Expand Up @@ -161,9 +206,14 @@ func TestContentBlocking(t *testing.T) {
t.Run(cliTestName, func(t *testing.T) {
t.Parallel()
args := append(cmd, testCase.path)
errMsg := node.RunIPFS(args...).Stderr.Trimmed()
if !strings.Contains(errMsg, expectedMsg) {
t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, errMsg)
cmd := node.RunIPFS(args...)
stdout := cmd.Stdout.Trimmed()
stderr := cmd.Stderr.Trimmed()
if !strings.Contains(stderr, expectedMsg) {
t.Errorf("Expected STDERR error message %q, but got: %q", expectedMsg, stderr)
if stdout != "" {
t.Errorf("Expected STDOUT to be empty, but got: %q", stdout)
}
}
})
}
Expand Down Expand Up @@ -299,5 +349,17 @@ func TestContentBlocking(t *testing.T) {
assert.NotEqual(t, string(body), "directly blocked file content")
assert.Contains(t, string(body), blockedMsg, bodyExpl)
})

t.Run("Denies Blocked CID as CAR", func(t *testing.T) {
t.Parallel()
resp, err := libp2pClient.Get(fmt.Sprintf("/ipfs/%s?format=car", blockedCID))
require.NoError(t, err)
defer resp.Body.Close()
assert.Equal(t, http.StatusGone, resp.StatusCode, statusExpl)
body, err := io.ReadAll(resp.Body)
require.NoError(t, err)
assert.NotContains(t, string(body), "directly blocked file content")
assert.Contains(t, string(body), blockedMsg, bodyExpl)
})
})
}
Loading