From f6f07437c7bb760eae13fdc288ba611871734484 Mon Sep 17 00:00:00 2001 From: mattthew Date: Tue, 3 Jun 2025 20:53:44 -0400 Subject: [PATCH 1/3] Check context for string namespace metadata Attach that namespace if found -- will be overwritten if JWL-ACLs namespaces are found --- edgraph/server.go | 16 +++++++++++++++- x/x.go | 13 +++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/edgraph/server.go b/edgraph/server.go index da496fd8637..a63b31dff29 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -1194,7 +1194,21 @@ func (s *Server) Query(ctx context.Context, req *api.Request) (*api.Response, er // Query handles queries or mutations func (s *Server) QueryNoGrpc(ctx context.Context, req *api.Request) (*api.Response, error) { - ctx = x.AttachJWTNamespace(ctx) + // if the `namespace-str` is present in the metadata, use it to attach the namespace + // otherwise, use the namespace from the JWT. + nsStr, err := x.ExtractNamespaceStr(ctx) + if err == nil { + ns, err := getNamespaceIDFromName(x.AttachNamespace(ctx, x.RootNamespace), nsStr) + if err == nil { + ctx = x.AttachNamespace(ctx, ns) + } else { + ctx = x.AttachJWTNamespace(ctx) + } + } else { + ctx = x.AttachJWTNamespace(ctx) + } + // if acl is enabled, then the namespace from the JWT will be applied in the test below + // overriding any namespace from the metadata obtained from the `namespace-str` above. if x.WorkerConfig.AclEnabled && req.GetStartTs() != 0 { // A fresh StartTs is assigned if it is 0. ns, err := x.ExtractNamespace(ctx) diff --git a/x/x.go b/x/x.go index db2053f0706..bb1e5c59c77 100644 --- a/x/x.go +++ b/x/x.go @@ -268,6 +268,19 @@ func ExtractNamespace(ctx context.Context) (uint64, error) { return namespace, nil } +// ExtractNamespaceStr parses the namespace string value from the incoming gRPC context. +func ExtractNamespaceStr(ctx context.Context) (string, error) { + md, ok := metadata.FromIncomingContext(ctx) + if !ok { + return "", errors.New("No metadata in the context") + } + ns := md.Get("namespace-str") + if len(ns) == 0 { + return "", errors.New("No namespace-str in the metadata of context") + } + return ns[0], nil +} + func IsRootNsOperation(ctx context.Context) bool { md, ok := metadata.FromIncomingContext(ctx) if !ok { From 88129600c97fb3384aef6238098f3cd578f182d1 Mon Sep 17 00:00:00 2001 From: mattthew Date: Thu, 5 Jun 2025 13:15:09 -0400 Subject: [PATCH 2/3] Add a namespace not found Error type --- x/x.go | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/x.go b/x/x.go index bb1e5c59c77..2e5c2cc4bb5 100644 --- a/x/x.go +++ b/x/x.go @@ -65,6 +65,8 @@ var ( ErrConflict = errors.New("Transaction conflict") // ErrHashMismatch is returned when the hash does not matches the startTs ErrHashMismatch = errors.New("hash mismatch the claimed startTs|namespace") + // ErrNamespaceNotFound is returned when a namespace is not found. + ErrNamespaceNotFound = errors.New("namespace not found") ) const ( From bedbb2824c1088934e9bedfab42b6eecb74827fa Mon Sep 17 00:00:00 2001 From: mattthew Date: Thu, 5 Jun 2025 13:16:23 -0400 Subject: [PATCH 3/3] Add log output if error from getting workspace by name is something other than "not found" --- edgraph/namespace.go | 2 +- edgraph/server.go | 17 +++++++++++------ 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/edgraph/namespace.go b/edgraph/namespace.go index 4531ea05469..e7373b109b7 100644 --- a/edgraph/namespace.go +++ b/edgraph/namespace.go @@ -310,7 +310,7 @@ func getNamespaceIDFromName(ctx context.Context, nsName string) (uint64, error) return 0, err } if len(data.Namespaces) == 0 { - return 0, errors.Errorf("namespace %q not found", nsName) + return 0, errors.Wrapf(x.ErrNamespaceNotFound, "namespace %q not found", nsName) } glog.Infof("Found namespace [%v] with id [%d]", nsName, data.Namespaces[0].ID) diff --git a/edgraph/server.go b/edgraph/server.go index a63b31dff29..1f4cf4242cf 100644 --- a/edgraph/server.go +++ b/edgraph/server.go @@ -1194,20 +1194,25 @@ func (s *Server) Query(ctx context.Context, req *api.Request) (*api.Response, er // Query handles queries or mutations func (s *Server) QueryNoGrpc(ctx context.Context, req *api.Request) (*api.Response, error) { - // if the `namespace-str` is present in the metadata, use it to attach the namespace + // If the `namespace-str` is present in the metadata, use it to attach the namespace // otherwise, use the namespace from the JWT. - nsStr, err := x.ExtractNamespaceStr(ctx) - if err == nil { + var attached bool + nsStr, _ := x.ExtractNamespaceStr(ctx) + if nsStr != "" { ns, err := getNamespaceIDFromName(x.AttachNamespace(ctx, x.RootNamespace), nsStr) if err == nil { ctx = x.AttachNamespace(ctx, ns) + attached = true } else { - ctx = x.AttachJWTNamespace(ctx) + if !errors.Is(err, x.ErrNamespaceNotFound) { + glog.Warningf("Error getting namespace ID from name: %v. Defaulting to default or JWT namespace", err) + } } - } else { + } + if !attached { ctx = x.AttachJWTNamespace(ctx) } - // if acl is enabled, then the namespace from the JWT will be applied in the test below + // If acl is enabled, then the namespace from the JWT will be applied in the test below // overriding any namespace from the metadata obtained from the `namespace-str` above. if x.WorkerConfig.AclEnabled && req.GetStartTs() != 0 { // A fresh StartTs is assigned if it is 0.