Skip to content

implement /state on alpha; login required if ACL enabled on alpha; al… #4435

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

Merged
merged 11 commits into from
Dec 23, 2019
21 changes: 21 additions & 0 deletions dgraph/cmd/alpha/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,26 @@ func healthCheck(w http.ResponseWriter, r *http.Request) {
_, _ = w.Write(data)
}

func stateHandler(w http.ResponseWriter, r *http.Request) {
var err error
x.AddCorsHeaders(w)
w.Header().Set("Content-Type", "application/json")

ctx := context.Background()
ctx = attachAccessJwt(ctx, r)

var aResp *api.Response
if aResp, err = (&edgraph.Server{}).State(ctx); err != nil {
x.SetStatus(w, x.Error, err.Error())
return
}

if _, err = w.Write(aResp.Json); err != nil {
x.SetStatus(w, x.Error, err.Error())
return
}
}

// storeStatsHandler outputs some basic stats for data store.
func storeStatsHandler(w http.ResponseWriter, r *http.Request) {
x.AddCorsHeaders(w)
Expand Down Expand Up @@ -390,6 +410,7 @@ func setupServer() {
http.HandleFunc("/commit", commitHandler)
http.HandleFunc("/alter", alterHandler)
http.HandleFunc("/health", healthCheck)
http.HandleFunc("/state", stateHandler)

// TODO: Figure out what this is for?
http.HandleFunc("/debug/store", storeStatsHandler)
Expand Down
5 changes: 5 additions & 0 deletions dgraph/cmd/zero/zero.go
Original file line number Diff line number Diff line change
Expand Up @@ -781,3 +781,8 @@ func (s *Server) applyLicense(ctx context.Context, signedData io.Reader) error {
glog.Infof("Enterprise license state proposed to the cluster")
return nil
}

// CurrentState return the current membership state.
func (s *Server) State(ctx context.Context, _ *api.Payload) (*pb.MembershipState, error) {
return s.latestMembershipState(ctx)
}
5 changes: 5 additions & 0 deletions edgraph/access.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,3 +64,8 @@ func authorizeQuery(ctx context.Context, parsedReq *gql.Result) error {
// always allow access
return nil
}

func authorizeState(ctx context.Context) error {
// always allow access
return nil
}
29 changes: 29 additions & 0 deletions edgraph/access_ee.go
Original file line number Diff line number Diff line change
Expand Up @@ -721,3 +721,32 @@ func authorizeQuery(ctx context.Context, parsedReq *gql.Result) error {

return err
}

// authorizeState authorizes the State operation
func authorizeState(ctx context.Context) error {
if len(worker.Config.HmacSecret) == 0 {
// the user has not turned on the acl feature
return nil
}

var userId string
// doAuthorizeState checks if the user is authorized to perform this API request
doAuthorizeState := func() error {
userData, err := extractUserAndGroups(ctx)
switch {
case err == errNoJwt:
return status.Error(codes.PermissionDenied, err.Error())
case err != nil:
return status.Error(codes.Unauthenticated, err.Error())
default:
userId = userData[0]
if userId == x.GrootId {
return nil
}
}
// Deny non groot users.
return status.Error(codes.PermissionDenied, err.Error())
}

return doAuthorizeState()
}
40 changes: 40 additions & 0 deletions edgraph/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
package edgraph

import (
"bytes"
"encoding/json"
"math"
"sort"
Expand All @@ -29,6 +30,7 @@ import (
"github.com/dgraph-io/dgo/v2/protos/api"

"github.com/dgraph-io/dgraph/chunker"
"github.com/dgraph-io/dgraph/conn"
"github.com/dgraph-io/dgraph/dgraph/cmd/zero"
"github.com/dgraph-io/dgraph/gql"
"github.com/dgraph-io/dgraph/posting"
Expand All @@ -39,6 +41,7 @@ import (
"github.com/dgraph-io/dgraph/types/facets"
"github.com/dgraph-io/dgraph/worker"
"github.com/dgraph-io/dgraph/x"
"github.com/gogo/protobuf/jsonpb"
"github.com/golang/glog"
"github.com/pkg/errors"
"golang.org/x/net/context"
Expand Down Expand Up @@ -580,6 +583,43 @@ type queryContext struct {
span *trace.Span
}

// State handles state requests
func (s *Server) State(ctx context.Context) (*api.Response, error) {
return s.doState(ctx, NeedAuthorize)
}

func (s *Server) doState(ctx context.Context, authorize int) (
*api.Response, error) {

if ctx.Err() != nil {
return nil, ctx.Err()
}

if authorize == NeedAuthorize {
if err := authorizeState(ctx); err != nil {
return nil, err
}
}

// Get the state info from Zero's CurrentState GRPC interface.
pl := conn.GetPools().Connect(x.WorkerConfig.ZeroAddr)
c := pb.NewZeroClient(pl.Get())
ms, err := c.State(ctx, &api.Payload{})
if err != nil {
return nil, err
}
if ms == nil {
return nil, errors.New("No membership state found")
}

m := jsonpb.Marshaler{}
var jsonState bytes.Buffer
if err := m.Marshal(&jsonState, ms); err != nil {
return nil, errors.New("Error marshalling state information to JSON")
}
return &api.Response{Json: jsonState.Bytes()}, nil
}

// Query handles queries or mutations
func (s *Server) Query(ctx context.Context, req *api.Request) (*api.Response, error) {
return s.doQuery(ctx, req, NeedAuthorize)
Expand Down
2 changes: 2 additions & 0 deletions protos/pb.proto
Original file line number Diff line number Diff line change
Expand Up @@ -453,6 +453,8 @@ service Zero {
rpc Connect (Member) returns (ConnectionState) {}
rpc UpdateMembership (Group) returns (api.Payload) {}
rpc StreamMembership (api.Payload) returns (stream MembershipState) {}
rpc State (api.Payload) returns (MembershipState) {}


rpc Oracle (api.Payload) returns (stream OracleDelta) {}
rpc ShouldServe (Tablet) returns (Tablet) {}
Expand Down
Loading