Skip to content

Commit 13b423d

Browse files
author
Harshil Goel
authored
fix(core): Fix namespace used by unique query generator (#9119)
Currently namespace used by unique generator uses edge predicate to validate. This shouldn't be the case, we should use the namespace provided in context.
1 parent ee57c5e commit 13b423d

File tree

2 files changed

+58
-8
lines changed

2 files changed

+58
-8
lines changed

edgraph/server.go

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1344,7 +1344,7 @@ func (s *Server) doQuery(ctx context.Context, req *Request) (resp *api.Response,
13441344
graphql: isGraphQL,
13451345
gqlField: req.gqlField,
13461346
}
1347-
if rerr = parseRequest(qc); rerr != nil {
1347+
if rerr = parseRequest(ctx, qc); rerr != nil {
13481348
return
13491349
}
13501350

@@ -1565,7 +1565,7 @@ func processQuery(ctx context.Context, qc *queryContext) (*api.Response, error)
15651565
}
15661566

15671567
// parseRequest parses the incoming request
1568-
func parseRequest(qc *queryContext) error {
1568+
func parseRequest(ctx context.Context, qc *queryContext) error {
15691569
start := time.Now()
15701570
defer func() {
15711571
qc.latency.Parsing = time.Since(start)
@@ -1585,7 +1585,7 @@ func parseRequest(qc *queryContext) error {
15851585
qc.gmuList = append(qc.gmuList, gmu)
15861586
}
15871587

1588-
if err := addQueryIfUnique(qc); err != nil {
1588+
if err := addQueryIfUnique(ctx, qc); err != nil {
15891589
return err
15901590
}
15911591

@@ -1698,19 +1698,38 @@ func verifyUnique(qc *queryContext, qr query.Request) error {
16981698
}
16991699

17001700
// addQueryIfUnique adds dummy queries in the request for checking whether predicate is unique in the db
1701-
func addQueryIfUnique(qc *queryContext) error {
1701+
func addQueryIfUnique(qctx context.Context, qc *queryContext) error {
17021702
if len(qc.gmuList) == 0 {
17031703
return nil
17041704
}
17051705

1706-
ctx := context.WithValue(context.Background(), schema.IsWrite, false)
1706+
ctx := context.WithValue(qctx, schema.IsWrite, false)
1707+
namespace, err := x.ExtractNamespace(ctx)
1708+
if err != nil {
1709+
// It's okay to ignore this here. If namespace is not set, it could mean either there is no
1710+
// authorization or it's trying to be bypassed. So the namespace is either 0 or the mutation would fail.
1711+
glog.Errorf("Error while extracting namespace, assuming default %s", err)
1712+
namespace = 0
1713+
}
1714+
isGalaxyQuery := x.IsGalaxyOperation(ctx)
1715+
17071716
qc.uniqueVars = map[uint64]uniquePredMeta{}
17081717
var buildQuery strings.Builder
17091718
for gmuIndex, gmu := range qc.gmuList {
17101719
for rdfIndex, pred := range gmu.Set {
1711-
predSchema, _ := schema.State().Get(ctx, x.NamespaceAttr(pred.Namespace, pred.Predicate))
1712-
if !predSchema.Unique {
1713-
continue
1720+
if isGalaxyQuery {
1721+
// The caller should make sure that the directed edges contain the namespace we want
1722+
// to insert into.
1723+
namespace = pred.Namespace
1724+
}
1725+
if pred.Predicate != "dgraph.xid" {
1726+
// [TODO] Don't check if it's dgraph.xid. It's a bug as this node might not be aware
1727+
// of the schema for the given predicate. This is a bug issue for dgraph.xid hence
1728+
// we are bypassing it manually until the bug is fixed.
1729+
predSchema, ok := schema.State().Get(ctx, x.NamespaceAttr(namespace, pred.Predicate))
1730+
if !ok || !predSchema.Unique {
1731+
continue
1732+
}
17141733
}
17151734
var predicateName string
17161735
if pred.Lang != "" {

ee/acl/acl_integration_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -439,6 +439,37 @@ func (asuite *AclTestSuite) TestWrongPermission() {
439439
require.Contains(t, err.Error(), "Value for this predicate should be between 0 and 7")
440440
}
441441

442+
func (asuite *AclTestSuite) TestACLNamespaceEdge() {
443+
t := asuite.T()
444+
gc, cleanup, err := asuite.dc.Client()
445+
require.NoError(t, err)
446+
defer cleanup()
447+
require.NoError(t, gc.LoginIntoNamespace(context.Background(),
448+
dgraphapi.DefaultUser, dgraphapi.DefaultPassword, x.GalaxyNamespace))
449+
450+
json := `
451+
{
452+
"set": [
453+
{
454+
"dgraph.xid": "groot",
455+
"dgraph.password": "password",
456+
"dgraph.type": "dgraph.type.User",
457+
"dgraph.user.group": {
458+
"dgraph.xid": "guardians",
459+
"dgraph.type": "dgraph.type.Group",
460+
"namespace": 1
461+
},
462+
"namespace": 1
463+
}
464+
]
465+
}`
466+
467+
mu := &api.Mutation{SetJson: []byte(json), CommitNow: true}
468+
_, err = gc.Mutate(mu)
469+
require.Error(t, err)
470+
require.ErrorContains(t, err, "could not insert duplicate value") // Could be gaurdian or groot
471+
}
472+
442473
func (asuite *AclTestSuite) TestACLDuplicateGrootUser() {
443474
t := asuite.T()
444475
gc, cleanup, err := asuite.dc.Client()

0 commit comments

Comments
 (0)