From cef413acfc67f2798c3437ba52bff44bfd9749a3 Mon Sep 17 00:00:00 2001 From: JASWINDER BHAMRA Date: Tue, 8 Aug 2023 13:35:22 +0530 Subject: [PATCH] DGRAPHCORE-355: Allow data deletion for non-internal predicates --- ee/acl/acl_test.go | 4 +-- query/mutation.go | 5 +++- query/mutation_test.go | 49 ++++++++++++++++++++++++++++++++++- systest/bgindex/count_test.go | 2 +- 4 files changed, 55 insertions(+), 5 deletions(-) diff --git a/ee/acl/acl_test.go b/ee/acl/acl_test.go index de5dd017cd9..c8cbaf61209 100644 --- a/ee/acl/acl_test.go +++ b/ee/acl/acl_test.go @@ -2793,13 +2793,13 @@ func (asuite *AclTestSuite) TestDeleteGrootAndGuardiansUsingDelNQuadShouldFail() // Try deleting groot user _, err = gc.Mutate(mu) require.Error(t, err, "Deleting groot user should have returned an error") - require.Contains(t, err.Error(), "Properties of guardians group and groot user cannot be deleted") + require.Contains(t, err.Error(), "properties of guardians group and groot user cannot be deleted") mu = &api.Mutation{DelNquads: []byte(fmt.Sprintf("%s %s %s .", "<"+guardiansUid+">", "*", "*")), CommitNow: true} // Try deleting guardians group _, err = gc.Mutate(mu) require.Error(t, err, "Deleting guardians group should have returned an error") - require.Contains(t, err.Error(), "Properties of guardians group and groot user cannot be deleted") + require.Contains(t, err.Error(), "properties of guardians group and groot user cannot be deleted") } func deleteGuardiansGroupAndGrootUserShouldFail(t *testing.T, hc *dgraphtest.HTTPClient) { diff --git a/query/mutation.go b/query/mutation.go index 274870c1e2f..df586c58b61 100644 --- a/query/mutation.go +++ b/query/mutation.go @@ -286,6 +286,9 @@ func checkIfDeletingAclOperation(ctx context.Context, edges []*pb.DirectedEdge) isDeleteAclOperation := false for _, edge := range edges { + if !x.IsReservedPredicate(edge.Attr) { + continue + } // Disallow deleting of guardians group if edge.Entity == guardianUid && edge.Op == pb.DirectedEdge_DEL { isDeleteAclOperation = true @@ -298,7 +301,7 @@ func checkIfDeletingAclOperation(ctx context.Context, edges []*pb.DirectedEdge) } } if isDeleteAclOperation { - return errors.Errorf("Properties of guardians group and groot user cannot be deleted.") + return errors.Errorf("Reserved properties of guardians group and groot user cannot be deleted.") } return nil } diff --git a/query/mutation_test.go b/query/mutation_test.go index f76287b968d..29535f6d278 100644 --- a/query/mutation_test.go +++ b/query/mutation_test.go @@ -20,15 +20,20 @@ package query import ( "context" + "encoding/json" + "fmt" + "strconv" "testing" "time" "github.com/stretchr/testify/require" "github.com/dgraph-io/dgo/v230/protos/api" + "github.com/dgraph-io/dgraph/dgraphtest" + "github.com/dgraph-io/dgraph/x" ) -func TestReserverPredicateForMutation(t *testing.T) { +func TestReservedPredicateForMutation(t *testing.T) { err := addTriplesToCluster(`_:x "df"`) require.Error(t, err, "Cannot mutate graphql reserved predicate dgraph.graphql.schema") } @@ -70,3 +75,45 @@ func TestAlteringReservedTypesAndPredicatesShouldFail(t *testing.T) { require.Contains(t, err.Error(), "Can't store predicate `dgraph.name` as it is prefixed with "+ "`dgraph.` which is reserved as the namespace for dgraph's internal types/predicates.") } + +func TestUnreservedPredicateForDeletion(t *testing.T) { + dg, cleanup, err := dc.Client() + require.NoError(t, err) + defer cleanup() + ctx := context.Background() + require.NoError(t, dg.LoginIntoNamespace(ctx, dgraphtest.DefaultUser, dgraphtest.DefaultPassword, x.GalaxyNamespace)) + + grootUserQuery := ` + { + grootUser(func:eq(dgraph.xid, "groot")){ + uid + } + }` + + // Structs to parse groot user query response + type userNode struct { + Uid string `json:"uid"` + } + + type userQryResp struct { + GrootUser []userNode `json:"grootUser"` + } + + resp, err := dg.Query(grootUserQuery) + require.NoError(t, err, "groot user query failed") + + var userResp userQryResp + if err := json.Unmarshal(resp.GetJson(), &userResp); err != nil { + t.Fatal("Couldn't unmarshal response from groot user query") + } + grootsUidStr := userResp.GrootUser[0].Uid + require.Greater(t, len(grootsUidStr), 0) + grootsUidInt, err := strconv.ParseUint(grootsUidStr, 10, 64) + require.Greater(t, grootsUidInt, 0) + + err = addTriplesToCluster(fmt.Sprintf(`<%s> "Betelgeuse" .`, grootsUid)) + if err != nil { + panic(fmt.Errorf("could not add triple to cluster")) + } + require.NoError(t, dg.DropPredicate(``)) +} diff --git a/systest/bgindex/count_test.go b/systest/bgindex/count_test.go index 6f259affe84..5f278301ad0 100644 --- a/systest/bgindex/count_test.go +++ b/systest/bgindex/count_test.go @@ -123,7 +123,7 @@ func TestCountIndex(t *testing.T) { CommitNow: true, DelNquads: []byte(fmt.Sprintf(`<%v> "%v" .`, uid, ec-1)), }); err != nil && (errors.Is(err, dgo.ErrAborted) || - strings.Contains(err.Error(), "Properties of guardians group and groot user cannot be deleted")) { + strings.Contains(err.Error(), "properties of guardians group and groot user cannot be deleted")) { return } else if err != nil { t.Fatalf("error in deletion :: %v\n", err)