MCPcopy
hub / github.com/dgraph-io/dgraph / TestValidateAlterOperationAuthGate

Function TestValidateAlterOperationAuthGate

edgraph/alter_noauth_test.go:24–69  ·  view source on GitHub ↗

TestValidateAlterOperationAuthGate isolates the authorization gate that an in-process Alter caller hits. It proves the bug (a context with no gRPC peer is rejected at the IP-whitelist check) and the fix (NoAuthorize skips that check), without booting a cluster. The full Alter body past validateAlter

(t *testing.T)

Source from the content-addressed store, hash-verified

22// check), without booting a cluster. The full Alter body past
23// validateAlterOperation needs a running cluster.
24func TestValidateAlterOperationAuthGate(t *testing.T) {
25 // validateAlterOperation calls x.HealthCheck before the auth checks; mark
26 // the node healthy so we reach the gate we want to exercise.
27 x.UpdateHealthStatus(true)
28 defer x.UpdateHealthStatus(false)
29
30 op := &api.Operation{Schema: "name: string @index(exact) @upsert ."}
31
32 t.Run("bug: background context is rejected at the IP whitelist", func(t *testing.T) {
33 // context.Background() carries no gRPC peer, so x.HasWhitelistedIP can't
34 // find a source IP. This is exactly what an in-process caller passes, and
35 // it fails on every config — not only under --security whitelist.
36 err := validateAlterOperation(context.Background(), op, NeedAuthorize)
37 require.ErrorContains(t, err, "unable to find source ip")
38 })
39
40 t.Run("the whitelist check is what rejects a non-loopback peer", func(t *testing.T) {
41 // A real but non-whitelisted peer is rejected for a different reason,
42 // confirming the gate we bypass below is the IP whitelist.
43 ctx := peer.NewContext(context.Background(), &peer.Peer{
44 Addr: &net.TCPAddr{IP: net.ParseIP("8.8.8.8"), Port: 4321},
45 })
46 err := validateAlterOperation(ctx, op, NeedAuthorize)
47 require.ErrorContains(t, err, "unauthorized ip address: 8.8.8.8")
48 })
49
50 t.Run("fix: NoAuthorize skips the IP whitelist for in-process callers", func(t *testing.T) {
51 // AlterNoAuth threads NoAuthorize through to here; the same background
52 // context that failed above now passes validation.
53 err := validateAlterOperation(context.Background(), op, NoAuthorize)
54 require.NoError(t, err)
55 })
56
57 t.Run("NoAuthorize still enforces structural validation", func(t *testing.T) {
58 // Skipping auth must not skip the "at least one field set" check.
59 err := validateAlterOperation(context.Background(), &api.Operation{}, NoAuthorize)
60 require.ErrorContains(t, err, "at least one field set")
61 })
62
63 t.Run("NoAuthorize still enforces the health check", func(t *testing.T) {
64 x.UpdateHealthStatus(false)
65 defer x.UpdateHealthStatus(true)
66 err := validateAlterOperation(context.Background(), op, NoAuthorize)
67 require.Error(t, err)
68 })
69}
70
71// TestAlterNoAuthRejectsDrops proves AlterNoAuth is schema-only: every drop
72// form is refused before reaching the cluster, so bypassing auth can never be

Callers

nothing calls this directly

Calls 4

UpdateHealthStatusFunction · 0.92
validateAlterOperationFunction · 0.85
RunMethod · 0.45
ErrorMethod · 0.45

Tested by

no test coverage detected