From 991f72f77c3e24bfcb3d533b94d01d76c19713a0 Mon Sep 17 00:00:00 2001 From: Arijit Das Date: Wed, 2 Sep 2020 18:09:23 +0530 Subject: [PATCH] fix(GraphQL): Remove auth error from mutation. (#6329) * Remove auth error from add mutation. --- dgraph/cmd/alpha/run.go | 2 + graphql/e2e/auth/add_mutation_test.go | 59 ++++---- graphql/e2e/auth/auth_test.go | 75 ++++------ graphql/e2e/auth/debug_off/debugoff_test.go | 136 ++++++++++++++++++ graphql/e2e/auth/debug_off/docker-compose.yml | 69 +++++++++ graphql/e2e/auth/delete_mutation_test.go | 22 +-- graphql/e2e/auth/docker-compose.yml | 4 +- graphql/e2e/auth/update_mutation_test.go | 20 +-- graphql/e2e/common/admin.go | 4 +- graphql/e2e/common/common.go | 52 ++++++- graphql/e2e/common/error.go | 6 +- graphql/e2e/common/fragment.go | 8 +- graphql/e2e/common/mutation.go | 134 ++++++++--------- graphql/e2e/common/query.go | 90 ++++++------ graphql/e2e/common/schema.go | 2 +- graphql/e2e/debug/docker-compose.yml | 69 +++++++++ graphql/resolve/auth_test.go | 2 +- graphql/schema/response.go | 9 ++ testutil/graphql.go | 11 +- x/config.go | 4 +- 20 files changed, 537 insertions(+), 241 deletions(-) create mode 100644 graphql/e2e/auth/debug_off/debugoff_test.go create mode 100644 graphql/e2e/auth/debug_off/docker-compose.yml create mode 100644 graphql/e2e/debug/docker-compose.yml diff --git a/dgraph/cmd/alpha/run.go b/dgraph/cmd/alpha/run.go index f1fbd257b97..c5562ac6a64 100644 --- a/dgraph/cmd/alpha/run.go +++ b/dgraph/cmd/alpha/run.go @@ -200,6 +200,7 @@ they form a Raft group and provide synchronous replication. grpc.EnableTracing = false flag.Bool("graphql_introspection", true, "Set to false for no GraphQL schema introspection") + flag.Bool("graphql_debug", false, "Enable debug mode in GraphQL. This returns auth errors to clients. We do not recommend turning it on for production.") flag.Bool("ludicrous_mode", false, "Run alpha in ludicrous mode") flag.Int("ludicrous_concurrency", 2000, "Number of concurrent threads in ludicrous mode") flag.Bool("graphql_extensions", true, "Set to false if extensions not required in GraphQL response body") @@ -720,6 +721,7 @@ func run() { x.Config.NormalizeNodeLimit = cast.ToInt(Alpha.Conf.GetString("normalize_node_limit")) x.Config.PollInterval = Alpha.Conf.GetDuration("graphql_poll_interval") x.Config.GraphqlExtension = Alpha.Conf.GetBool("graphql_extensions") + x.Config.GraphqlDebug = Alpha.Conf.GetBool("graphql_debug") x.PrintVersion() glog.Infof("x.Config: %+v", x.Config) diff --git a/graphql/e2e/auth/add_mutation_test.go b/graphql/e2e/auth/add_mutation_test.go index b89ac9d6cde..7fab72ffb11 100644 --- a/graphql/e2e/auth/add_mutation_test.go +++ b/graphql/e2e/auth/add_mutation_test.go @@ -26,25 +26,9 @@ import ( "github.com/stretchr/testify/require" ) -func (us *UserSecret) delete(t *testing.T, user, role string) { - getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), - Query: ` - mutation deleteUserSecret($ids: [ID!]) { - deleteUserSecret(filter:{id:$ids}) { - msg - } - } - `, - Variables: map[string]interface{}{"ids": []string{us.Id}}, - } - gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) - require.Nil(t, gqlResponse.Errors) -} - func (p *Project) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteProject($ids: [ID!]) { deleteProject(filter:{projID:$ids}) { @@ -60,7 +44,7 @@ func (p *Project) delete(t *testing.T, user, role string) { func (c *Column) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteColumn($colids: [ID!]) { deleteColumn(filter:{colID:$colids}) { @@ -76,7 +60,7 @@ func (c *Column) delete(t *testing.T, user, role string) { func (i *Issue) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteIssue($ids: [ID!]) { deleteIssue(filter:{id:$ids}) { @@ -92,7 +76,7 @@ func (i *Issue) delete(t *testing.T, user, role string) { func (l *Log) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteLog($ids: [ID!]) { deleteLog(filter:{id:$ids}) { @@ -108,7 +92,7 @@ func (l *Log) delete(t *testing.T, user, role string) { func (m *Movie) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteMovie($ids: [ID!]) { deleteMovie(filter:{id:$ids}) { @@ -197,7 +181,7 @@ func TestAddDeepFilter(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -205,6 +189,7 @@ func TestAddDeepFilter(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -293,7 +278,7 @@ func TestAddOrRBACFilter(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -301,6 +286,7 @@ func TestAddOrRBACFilter(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -371,7 +357,7 @@ func TestAddAndRBACFilterMultiple(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -379,6 +365,7 @@ func TestAddAndRBACFilterMultiple(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -445,7 +432,7 @@ func TestAddAndRBACFilter(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -453,6 +440,7 @@ func TestAddAndRBACFilter(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -548,7 +536,7 @@ func TestAddComplexFilter(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -556,6 +544,7 @@ func TestAddComplexFilter(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -613,7 +602,7 @@ func TestAddRBACFilter(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -621,6 +610,7 @@ func TestAddRBACFilter(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -646,14 +636,14 @@ func TestAddGQLOnly(t *testing.T) { testCases := []TestCase{{ user: "user1", result: `{"addUserSecret":{"usersecret":[{"aSecret":"secret1"}]}}`, - variables: map[string]interface{}{"user": &UserSecret{ + variables: map[string]interface{}{"user": &common.UserSecret{ ASecret: "secret1", OwnedBy: "user1", }}, }, { user: "user2", result: ``, - variables: map[string]interface{}{"user": &UserSecret{ + variables: map[string]interface{}{"user": &common.UserSecret{ ASecret: "secret2", OwnedBy: "user1", }}, @@ -670,13 +660,13 @@ func TestAddGQLOnly(t *testing.T) { ` var expected, result struct { AddUserSecret struct { - UserSecret []*UserSecret + UserSecret []*common.UserSecret } } for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: tcase.variables, } @@ -684,6 +674,7 @@ func TestAddGQLOnly(t *testing.T) { gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL) if tcase.result == "" { require.Equal(t, len(gqlResponse.Errors), 1) + require.Contains(t, gqlResponse.Errors[0].Message, "authorization failed") continue } @@ -691,16 +682,16 @@ func TestAddGQLOnly(t *testing.T) { err := json.Unmarshal([]byte(tcase.result), &expected) require.NoError(t, err) - err = json.Unmarshal([]byte(gqlResponse.Data), &result) + err = json.Unmarshal(gqlResponse.Data, &result) require.NoError(t, err) - opt := cmpopts.IgnoreFields(UserSecret{}, "Id") + opt := cmpopts.IgnoreFields(common.UserSecret{}, "Id") if diff := cmp.Diff(expected, result, opt); diff != "" { t.Errorf("result mismatch (-want +got):\n%s", diff) } for _, i := range result.AddUserSecret.UserSecret { - i.delete(t, tcase.user, tcase.role) + i.Delete(t, tcase.user, tcase.role, metaInfo) } } } diff --git a/graphql/e2e/auth/auth_test.go b/graphql/e2e/auth/auth_test.go index bdd323f7f1a..57419ebd797 100644 --- a/graphql/e2e/auth/auth_test.go +++ b/graphql/e2e/auth/auth_test.go @@ -21,11 +21,9 @@ import ( "encoding/json" "fmt" "io/ioutil" - "net/http" "os" "strings" "testing" - "time" "github.com/dgraph-io/dgraph/graphql/authorization" "github.com/dgraph-io/dgraph/graphql/e2e/common" @@ -57,12 +55,6 @@ type User struct { Disabled bool `json:"disabled,omitempty"` } -type UserSecret struct { - Id string `json:"id,omitempty"` - ASecret string `json:"aSecret,omitempty"` - OwnedBy string `json:"ownedBy,omitempty"` -} - type Region struct { Id string `json:"id,omitempty"` Name string `json:"name,omitempty"` @@ -174,7 +166,7 @@ func (tasks Tasks) add(t *testing.T) { func (r *Region) add(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation addRegion($region: AddRegionInput!) { addRegion(input: [$region]) { @@ -190,7 +182,7 @@ func (r *Region) add(t *testing.T, user, role string) { func (r *Region) delete(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation deleteRegion($name: String) { deleteRegion(filter:{name: { eq: $name}}) { @@ -204,24 +196,6 @@ func (r *Region) delete(t *testing.T, user, role string) { require.Nil(t, gqlResponse.Errors) } -func getJWT(t *testing.T, user, role string) http.Header { - metaInfo.AuthVars = map[string]interface{}{} - if user != "" { - metaInfo.AuthVars["USER"] = user - } - - if role != "" { - metaInfo.AuthVars["ROLE"] = role - } - - jwtToken, err := metaInfo.GetSignedToken("./sample_private_key.pem", 300*time.Second) - require.NoError(t, err) - - h := make(http.Header) - h.Add(metaInfo.Header, jwtToken) - return h -} - func TestOptimizedNestedAuthQuery(t *testing.T) { query := ` query { @@ -238,7 +212,7 @@ func TestOptimizedNestedAuthQuery(t *testing.T) { role := "ADMIN" getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: query, } @@ -340,7 +314,7 @@ func TestAuthWithDgraphDirective(t *testing.T) { t.Run(tcase.role+"_"+tcase.user, func(t *testing.T) { queryParams := &common.GraphQLParams{ Query: queryStudent, - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), } gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) common.RequireNoGQLErrors(t, gqlResponse) @@ -413,14 +387,14 @@ func TestAuthRulesWithMissingJWT(t *testing.T) { testInvalidKey := strings.HasSuffix(tcase.name, "invalid JWT Token") if testInvalidKey { - queryParams.Headers = getJWT(t, tcase.user, tcase.role) + queryParams.Headers = common.GetJWT(t, tcase.user, tcase.role, metaInfo) jwtVar := queryParams.Headers.Get(metaInfo.Header) // Create a invalid JWT signature. jwtVar = jwtVar + "A" queryParams.Headers.Set(metaInfo.Header, jwtVar) } else if tcase.user != "" || tcase.role != "" { - queryParams.Headers = getJWT(t, tcase.user, tcase.role) + queryParams.Headers = common.GetJWT(t, tcase.user, tcase.role, metaInfo) } gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) @@ -532,7 +506,7 @@ func TestOrderAndOffset(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -619,7 +593,7 @@ func TestOrRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -646,7 +620,7 @@ func getColID(t *testing.T, tcase TestCase) string { } getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"name": tcase.name}, } @@ -698,7 +672,7 @@ func TestRootGetFilter(t *testing.T) { for _, tcase := range tcases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"id": tcase.name}, } @@ -725,7 +699,7 @@ func getProjectID(t *testing.T, tcase TestCase) string { } getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"name": tcase.name}, } @@ -780,7 +754,7 @@ func TestRootGetDeepFilter(t *testing.T) { for _, tcase := range tcases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"id": tcase.name}, } @@ -825,7 +799,7 @@ func TestDeepFilter(t *testing.T) { for _, tcase := range tcases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"name": tcase.name}, } @@ -861,7 +835,7 @@ func TestRootFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -893,7 +867,7 @@ func TestDeepRBACValue(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -922,7 +896,7 @@ func TestRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -959,7 +933,7 @@ func TestAndRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -1071,7 +1045,7 @@ func TestNestedFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, } @@ -1118,7 +1092,7 @@ func TestDeleteAuthRule(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{ "filter": tcase.filter, @@ -1228,7 +1202,7 @@ func TestDeleteDeepAuthRule(t *testing.T) { for _, tcase := range testCases { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{ "filter": tcase.filter, @@ -1266,10 +1240,11 @@ func TestMain(m *testing.M) { authMeta := testutil.SetAuthMeta(string(authSchema)) metaInfo = &testutil.AuthMeta{ - PublicKey: authMeta.VerificationKey, - Namespace: authMeta.Namespace, - Algo: authMeta.Algo, - Header: authMeta.Header, + PublicKey: authMeta.VerificationKey, + Namespace: authMeta.Namespace, + Algo: authMeta.Algo, + Header: authMeta.Header, + PrivateKeyPath: "./sample_private_key.pem", } common.BootstrapServer(authSchema, data) diff --git a/graphql/e2e/auth/debug_off/debugoff_test.go b/graphql/e2e/auth/debug_off/debugoff_test.go new file mode 100644 index 00000000000..83a8f295c8b --- /dev/null +++ b/graphql/e2e/auth/debug_off/debugoff_test.go @@ -0,0 +1,136 @@ +package debugoff + +import ( + "encoding/json" + "io/ioutil" + "os" + "testing" + + "github.com/dgraph-io/dgraph/graphql/authorization" + "github.com/dgraph-io/dgraph/graphql/e2e/common" + "github.com/dgraph-io/dgraph/testutil" + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/pkg/errors" + "github.com/stretchr/testify/require" +) + +var ( + metaInfo *testutil.AuthMeta +) + +type TestCase struct { + user string + role string + result string + name string + variables map[string]interface{} +} + +func TestAddGQL(t *testing.T) { + testCases := []TestCase{{ + user: "user1", + result: `{"addUserSecret":{"usersecret":[{"aSecret":"secret1"}]}}`, + variables: map[string]interface{}{"user": &common.UserSecret{ + ASecret: "secret1", + OwnedBy: "user1", + }}, + }, { + user: "user2", + result: ``, + variables: map[string]interface{}{"user": &common.UserSecret{ + ASecret: "secret2", + OwnedBy: "user1", + }}, + }} + + query := ` + mutation addUser($user: AddUserSecretInput!) { + addUserSecret(input: [$user]) { + userSecret { + aSecret + } + } + } + ` + var expected, result struct { + AddUserSecret struct { + UserSecret []*common.UserSecret + } + } + + for _, tcase := range testCases { + getUserParams := &common.GraphQLParams{ + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), + Query: query, + Variables: tcase.variables, + } + gqlResponse := getUserParams.ExecuteAsPost(t, common.GraphqlURL) + if tcase.result == "" { + require.Equal(t, len(gqlResponse.Errors), 0) + continue + } + + require.Nil(t, gqlResponse.Errors) + + err := json.Unmarshal([]byte(tcase.result), &expected) + require.NoError(t, err) + err = json.Unmarshal([]byte(gqlResponse.Data), &result) + require.NoError(t, err) + + opt := cmpopts.IgnoreFields(common.UserSecret{}, "Id") + if diff := cmp.Diff(expected, result, opt); diff != "" { + t.Errorf("result mismatch (-want +got):\n%s", diff) + } + + for _, i := range result.AddUserSecret.UserSecret { + i.Delete(t, tcase.user, tcase.role, metaInfo) + } + } +} + +func TestMain(m *testing.M) { + schemaFile := "../schema.graphql" + schema, err := ioutil.ReadFile(schemaFile) + if err != nil { + panic(err) + } + + jsonFile := "../test_data.json" + data, err := ioutil.ReadFile(jsonFile) + if err != nil { + panic(errors.Wrapf(err, "Unable to read file %s.", jsonFile)) + } + + jwtAlgo := []string{authorization.HMAC256, authorization.RSA256} + for _, algo := range jwtAlgo { + authSchema, err := testutil.AppendAuthInfo(schema, algo, "../sample_public_key.pem") + if err != nil { + panic(err) + } + + authMeta, err := authorization.Parse(string(authSchema)) + if err != nil { + panic(err) + } + + metaInfo = &testutil.AuthMeta{ + PublicKey: authMeta.VerificationKey, + Namespace: authMeta.Namespace, + Algo: authMeta.Algo, + Header: authMeta.Header, + PrivateKeyPath: "../sample_private_key.pem", + } + + common.BootstrapServer(authSchema, data) + // Data is added only in the first iteration, but the schema is added every iteration. + if data != nil { + data = nil + } + exitCode := m.Run() + if exitCode != 0 { + os.Exit(exitCode) + } + } + os.Exit(0) +} diff --git a/graphql/e2e/auth/debug_off/docker-compose.yml b/graphql/e2e/auth/debug_off/docker-compose.yml new file mode 100644 index 00000000000..0f5bb630435 --- /dev/null +++ b/graphql/e2e/auth/debug_off/docker-compose.yml @@ -0,0 +1,69 @@ +version: "3.5" +services: + zero: + image: dgraph/dgraph:latest + container_name: zero1 + working_dir: /data/zero1 + ports: + - 5180:5180 + - 6180:6180 + labels: + cluster: test + service: zero1 + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + command: /gobin/dgraph zero -o 100 --logtostderr -v=2 --bindall --expose_trace --profile_mode block --block_rate 10 --my=zero1:5180 + + alpha: + image: dgraph/dgraph:latest + container_name: alpha1 + working_dir: /data/alpha1 + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + ports: + - 8180:8180 + - 9180:9180 + labels: + cluster: test + service: alpha1 + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zero1:5180 -o 100 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=3 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alpha1:7180 + + zeroAdmin: + image: dgraph/dgraph:latest + container_name: zeroAdmin + working_dir: /data/zeroAdmin + ports: + - 5280:5280 + - 6280:6280 + labels: + cluster: admintest + service: zeroAdmin + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + command: /gobin/dgraph zero -o 200 --logtostderr -v=2 --bindall --expose_trace --profile_mode block --block_rate 10 --my=zeroAdmin:5280 + + alphaAdmin: + image: dgraph/dgraph:latest + container_name: alphaAdmin + working_dir: /data/alphaAdmin + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + ports: + - 8280:8280 + - 9280:9280 + labels: + cluster: admintest + service: alphaAdmin + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zeroAdmin:5280 -o 200 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=2 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alphaAdmin:7280 diff --git a/graphql/e2e/auth/delete_mutation_test.go b/graphql/e2e/auth/delete_mutation_test.go index e458e26eec0..2106c9d875b 100644 --- a/graphql/e2e/auth/delete_mutation_test.go +++ b/graphql/e2e/auth/delete_mutation_test.go @@ -10,7 +10,7 @@ import ( func (c *Column) add(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation addColumn($column: AddColumnInput!) { addColumn(input: [$column]) { @@ -26,7 +26,7 @@ func (c *Column) add(t *testing.T, user, role string) { func (l *Log) add(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation addLog($log: AddLogInput!) { addLog(input: [$log]) { @@ -42,7 +42,7 @@ func (l *Log) add(t *testing.T, user, role string) { func (i *Issue) add(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation addIssue($issue: AddIssueInput!) { addIssue(input: [$issue]) { @@ -58,7 +58,7 @@ func (i *Issue) add(t *testing.T, user, role string) { func (m *Movie) add(t *testing.T, user, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, user, role), + Headers: common.GetJWT(t, user, role, metaInfo), Query: ` mutation addMovie($movie: AddMovieInput!) { addMovie(input: [$movie]) { @@ -74,7 +74,7 @@ func (m *Movie) add(t *testing.T, user, role string) { func (cl *ComplexLog) add(t *testing.T, role string) { getParams := &common.GraphQLParams{ - Headers: getJWT(t, "", role), + Headers: common.GetJWT(t, "", role, metaInfo), Query: ` mutation addComplexLog($complexlog: AddComplexLogInput!) { addComplexLog(input: [$complexlog]) { @@ -101,7 +101,7 @@ func getComplexLog(t *testing.T, role string) ([]*ComplexLog, []string) { `, } - getParams.Headers = getJWT(t, "", role) + getParams.Headers = common.GetJWT(t, "", role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -154,7 +154,7 @@ func TestDeleteRootFilter(t *testing.T) { deleteColumns, _ := getAllColumns(t, []string{tcase.user}, []string{tcase.role}) getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"cols": allColumnIds}, } @@ -199,7 +199,7 @@ func TestDeleteRBACFilter(t *testing.T) { deletedLogs, _ := getAllLogs(t, []string{tcase.user}, []string{tcase.role}) getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"logs": allLogIds}, } @@ -240,7 +240,7 @@ func TestDeleteOrRBACFilter(t *testing.T) { require.True(t, len(allComplexLogIds) == 2) getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": allComplexLogIds}, } @@ -292,7 +292,7 @@ func TestDeleteAndRBACFilter(t *testing.T) { deletedIssues, _ := getAllIssues(t, []string{tcase.user}, []string{tcase.role}) getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": ids}, } @@ -345,7 +345,7 @@ func TestDeleteNestedFilter(t *testing.T) { deleteMovies, _ := getAllMovies(t, []string{tcase.user}, []string{tcase.role}) getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": ids}, } diff --git a/graphql/e2e/auth/docker-compose.yml b/graphql/e2e/auth/docker-compose.yml index 0f5bb630435..04925abaaea 100644 --- a/graphql/e2e/auth/docker-compose.yml +++ b/graphql/e2e/auth/docker-compose.yml @@ -32,7 +32,7 @@ services: labels: cluster: test service: alpha1 - command: /gobin/dgraph alpha --lru_mb=1024 --zero=zero1:5180 -o 100 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=3 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alpha1:7180 + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zero1:5180 -o 100 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=3 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alpha1:7180 --graphql_debug=true zeroAdmin: image: dgraph/dgraph:latest @@ -66,4 +66,4 @@ services: labels: cluster: admintest service: alphaAdmin - command: /gobin/dgraph alpha --lru_mb=1024 --zero=zeroAdmin:5280 -o 200 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=2 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alphaAdmin:7280 + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zeroAdmin:5280 -o 200 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=2 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alphaAdmin:7280 --graphql_debug=true diff --git a/graphql/e2e/auth/update_mutation_test.go b/graphql/e2e/auth/update_mutation_test.go index cd1ab7e641e..f643fe0bc67 100644 --- a/graphql/e2e/auth/update_mutation_test.go +++ b/graphql/e2e/auth/update_mutation_test.go @@ -42,7 +42,7 @@ func getAllProjects(t *testing.T, users, roles []string) []string { ids := make(map[string]struct{}) for _, user := range users { for _, role := range roles { - getParams.Headers = getJWT(t, user, role) + getParams.Headers = common.GetJWT(t, user, role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -88,7 +88,7 @@ func getAllColumns(t *testing.T, users, roles []string) ([]*Column, []string) { var columns []*Column for _, user := range users { for _, role := range roles { - getParams.Headers = getJWT(t, user, role) + getParams.Headers = common.GetJWT(t, user, role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -137,7 +137,7 @@ func getAllIssues(t *testing.T, users, roles []string) ([]*Issue, []string) { var issues []*Issue for _, user := range users { for _, role := range roles { - getParams.Headers = getJWT(t, user, role) + getParams.Headers = common.GetJWT(t, user, role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -186,7 +186,7 @@ func getAllMovies(t *testing.T, users, roles []string) ([]*Movie, []string) { var movies []*Movie for _, user := range users { for _, role := range roles { - getParams.Headers = getJWT(t, user, role) + getParams.Headers = common.GetJWT(t, user, role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -232,7 +232,7 @@ func getAllLogs(t *testing.T, users, roles []string) ([]*Log, []string) { var logs []*Log for _, user := range users { for _, role := range roles { - getParams.Headers = getJWT(t, user, role) + getParams.Headers = common.GetJWT(t, user, role, metaInfo) gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) require.Nil(t, gqlResponse.Errors) @@ -288,7 +288,7 @@ func TestUpdateOrRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"projs": ids}, } @@ -330,7 +330,7 @@ func TestUpdateRootFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"cols": ids}, } @@ -363,7 +363,7 @@ func TestUpdateRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": ids}, } @@ -406,7 +406,7 @@ func TestUpdateAndRBACFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": ids}, } @@ -445,7 +445,7 @@ func TestUpdateNestedFilter(t *testing.T) { for _, tcase := range testCases { t.Run(tcase.role+tcase.user, func(t *testing.T) { getUserParams := &common.GraphQLParams{ - Headers: getJWT(t, tcase.user, tcase.role), + Headers: common.GetJWT(t, tcase.user, tcase.role, metaInfo), Query: query, Variables: map[string]interface{}{"ids": ids}, } diff --git a/graphql/e2e/common/admin.go b/graphql/e2e/common/admin.go index c6a0f0c3b99..063488d3a9d 100644 --- a/graphql/e2e/common/admin.go +++ b/graphql/e2e/common/admin.go @@ -743,7 +743,7 @@ func testCors(t *testing.T) { time.Sleep(2 * time.Second) client := &http.Client{} - req, err := http.NewRequest("GET", graphqlURL, nil) + req, err := http.NewRequest("GET", GraphqlURL, nil) require.NoError(t, err) req.Header.Add("Origin", "google.com") resp, err := client.Do(req) @@ -754,7 +754,7 @@ func testCors(t *testing.T) { require.Equal(t, resp.Header.Get("Access-Control-Allow-Credentials"), "true") client = &http.Client{} - req, err = http.NewRequest("GET", graphqlURL, nil) + req, err = http.NewRequest("GET", GraphqlURL, nil) require.NoError(t, err) req.Header.Add("Origin", "googl.com") resp, err = client.Do(req) diff --git a/graphql/e2e/common/common.go b/graphql/e2e/common/common.go index 73fe6e20cba..9975f094e44 100644 --- a/graphql/e2e/common/common.go +++ b/graphql/e2e/common/common.go @@ -30,6 +30,7 @@ import ( "github.com/dgraph-io/dgo/v200" "github.com/dgraph-io/dgo/v200/protos/api" + "github.com/dgraph-io/dgraph/testutil" "github.com/dgraph-io/dgraph/x" "github.com/pkg/errors" "github.com/stretchr/testify/require" @@ -37,7 +38,7 @@ import ( ) const ( - graphqlURL = "http://localhost:8180/graphql" + GraphqlURL = "http://localhost:8180/graphql" graphqlAdminURL = "http://localhost:8180/admin" AlphagRPC = "localhost:9180" @@ -172,6 +173,28 @@ type student struct { TaughtBy []*teacher `json:"taughtBy,omitempty"` } +type UserSecret struct { + Id string `json:"id,omitempty"` + ASecret string `json:"aSecret,omitempty"` + OwnedBy string `json:"ownedBy,omitempty"` +} + +func (us *UserSecret) Delete(t *testing.T, user, role string, metaInfo *testutil.AuthMeta) { + getParams := &GraphQLParams{ + Headers: GetJWT(t, user, role, metaInfo), + Query: ` + mutation deleteUserSecret($ids: [ID!]) { + deleteUserSecret(filter:{id:$ids}) { + msg + } + } + `, + Variables: map[string]interface{}{"ids": []string{us.Id}}, + } + gqlResponse := getParams.ExecuteAsPost(t, GraphqlURL) + require.Nil(t, gqlResponse.Errors) +} + func BootstrapServer(schema, data []byte) { err := checkGraphQLStarted(graphqlAdminURL) if err != nil { @@ -379,7 +402,7 @@ func gzipCompressionHeader(t *testing.T) { }`, } - req, err := queryCountry.createGQLPost(graphqlURL) + req, err := queryCountry.createGQLPost(GraphqlURL) require.NoError(t, err) req.Header.Set("Content-Encoding", "gzip") @@ -406,7 +429,7 @@ func gzipCompressionNoHeader(t *testing.T) { gzipEncoding: true, } - req, err := queryCountry.createGQLPost(graphqlURL) + req, err := queryCountry.createGQLPost(GraphqlURL) require.NoError(t, err) req.Header.Del("Content-Encoding") @@ -432,7 +455,7 @@ func getQueryEmptyVariable(t *testing.T) { } }`, } - req, err := queryCountry.createGQLGet(graphqlURL) + req, err := queryCountry.createGQLGet(GraphqlURL) require.NoError(t, err) q := req.URL.Query() @@ -642,7 +665,7 @@ func allCountriesAdded() ([]*country, error) { return nil, errors.Wrap(err, "unable to build GraphQL query") } - req, err := http.NewRequest("POST", graphqlURL, bytes.NewBuffer(body)) + req, err := http.NewRequest("POST", GraphqlURL, bytes.NewBuffer(body)) if err != nil { return nil, errors.Wrap(err, "unable to build GraphQL request") } @@ -806,3 +829,22 @@ func addSchemaThroughAdminSchemaEndpt(url, schema string) error { return nil } + +func GetJWT(t *testing.T, user, role string, metaInfo *testutil.AuthMeta) http.Header { + metaInfo.AuthVars = map[string]interface{}{} + if user != "" { + metaInfo.AuthVars["USER"] = user + } + + if role != "" { + metaInfo.AuthVars["ROLE"] = role + } + + require.NotNil(t, metaInfo.PrivateKeyPath) + jwtToken, err := metaInfo.GetSignedToken(metaInfo.PrivateKeyPath, 300*time.Second) + require.NoError(t, err) + + h := make(http.Header) + h.Add(metaInfo.Header, jwtToken) + return h +} diff --git a/graphql/e2e/common/error.go b/graphql/e2e/common/error.go index b16ac7aec8f..d2818ffc5aa 100644 --- a/graphql/e2e/common/error.go +++ b/graphql/e2e/common/error.go @@ -78,7 +78,7 @@ func graphQLCompletionOn(t *testing.T) { } // Check that the error is valid - gqlResponse := queryCountry.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCountry.ExecuteAsPost(t, GraphqlURL) require.NotNil(t, gqlResponse.Errors) require.Equal(t, 1, len(gqlResponse.Errors)) require.Contains(t, gqlResponse.Errors[0].Error(), @@ -166,7 +166,7 @@ func deepMutationErrors(t *testing.T) { }, } - gqlResponse := executeRequest(t, graphqlURL, updateCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, updateCountryParams) require.NotNil(t, gqlResponse.Errors) require.Equal(t, 1, len(gqlResponse.Errors)) require.EqualError(t, gqlResponse.Errors[0], tcase.exp) @@ -192,7 +192,7 @@ func requestValidationErrors(t *testing.T) { Query: tcase.GQLRequest, Variables: tcase.variables, } - gqlResponse := test.ExecuteAsPost(t, graphqlURL) + gqlResponse := test.ExecuteAsPost(t, GraphqlURL) require.Nil(t, gqlResponse.Data) if diff := cmp.Diff(tcase.Errors, gqlResponse.Errors); diff != "" { diff --git a/graphql/e2e/common/fragment.go b/graphql/e2e/common/fragment.go index 3b1b8ff2549..5e54ecaa19a 100644 --- a/graphql/e2e/common/fragment.go +++ b/graphql/e2e/common/fragment.go @@ -47,7 +47,7 @@ func fragmentInMutation(t *testing.T) { }}, } - gqlResponse := addStarshipParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addStarshipParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) addStarshipExpected := ` @@ -100,7 +100,7 @@ func fragmentInQuery(t *testing.T) { }, } - gqlResponse := queryStarshipParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryStarshipParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) queryStarshipExpected := fmt.Sprintf(` @@ -221,7 +221,7 @@ func fragmentInQueryOnInterface(t *testing.T) { `, } - gqlResponse := queryCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) queryCharacterExpected := fmt.Sprintf(` @@ -342,7 +342,7 @@ func fragmentInQueryOnObject(t *testing.T) { `, } - gqlResponse := queryHumanParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryHumanParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) queryCharacterExpected := fmt.Sprintf(` diff --git a/graphql/e2e/common/mutation.go b/graphql/e2e/common/mutation.go index 4db58c14dbc..2c69eccc260 100644 --- a/graphql/e2e/common/mutation.go +++ b/graphql/e2e/common/mutation.go @@ -94,7 +94,7 @@ func addCountry(t *testing.T, executeRequest requestExecutor) *country { addCountryExpected := ` { "addCountry": { "country": [{ "id": "_UID_", "name": "Testland" }] } }` - gqlResponse := executeRequest(t, graphqlURL, addCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCountryParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -139,7 +139,7 @@ func requireCountry(t *testing.T, uid string, expectedCountry *country, includeS }`, Variables: map[string]interface{}{"id": uid, "includeStates": includeStates}, } - gqlResponse := executeRequest(t, graphqlURL, params) + gqlResponse := executeRequest(t, GraphqlURL, params) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -197,7 +197,7 @@ func addAuthor(t *testing.T, countryUID string, }] } }`, countryUID) - gqlResponse := executeRequest(t, graphqlURL, addAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, addAuthorParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -249,7 +249,7 @@ func requireAuthor(t *testing.T, authorID string, expectedAuthor *author, }`, Variables: map[string]interface{}{"id": authorID}, } - gqlResponse := executeRequest(t, graphqlURL, params) + gqlResponse := executeRequest(t, GraphqlURL, params) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -278,7 +278,7 @@ func addCategory(t *testing.T, executeRequest requestExecutor) *category { addCategoryExpected := ` { "addCategory": { "category": [{ "id": "_UID_", "name": "A Category" }] } }` - gqlResponse := executeRequest(t, graphqlURL, addCategoryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCategoryParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -400,7 +400,7 @@ func deepMutationsTest(t *testing.T, executeRequest requestExecutor) { }, } - gqlResponse := executeRequest(t, graphqlURL, updateAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, updateAuthorParams) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -536,7 +536,7 @@ func addMultipleAuthorFromRef(t *testing.T, newAuthor []*author, Variables: map[string]interface{}{"author": newAuthor}, } - gqlResponse := executeRequest(t, graphqlURL, addAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, addAuthorParams) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -586,7 +586,7 @@ func addComments(t *testing.T, ids []string) { }, } - gqlResponse := postExecutor(t, graphqlURL, params) + gqlResponse := postExecutor(t, GraphqlURL, params) RequireNoGQLErrors(t, gqlResponse) } @@ -810,7 +810,7 @@ func testThreeLevelXID(t *testing.T) { for name, tc := range cases { t.Run(name, func(t *testing.T) { addComments(t, tc.Comments) - gqlResponse := postExecutor(t, graphqlURL, addPostParams) + gqlResponse := postExecutor(t, GraphqlURL, addPostParams) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, tc.Expected, string(gqlResponse.Data)) @@ -854,7 +854,7 @@ func deepXIDTest(t *testing.T, executeRequest requestExecutor) { Variables: map[string]interface{}{"input": newCountry}, } - gqlResponse := executeRequest(t, graphqlURL, addCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCountryParams) RequireNoGQLErrors(t, gqlResponse) var addResult struct { @@ -924,7 +924,7 @@ func deepXIDTest(t *testing.T, executeRequest requestExecutor) { }, } - gqlResponse = executeRequest(t, graphqlURL, updateCountryParams) + gqlResponse = executeRequest(t, GraphqlURL, updateCountryParams) RequireNoGQLErrors(t, gqlResponse) var updResult struct { @@ -1011,7 +1011,7 @@ func addPost(t *testing.T, authorID, countryID string, }] } }`, authorID, countryID) - gqlResponse := executeRequest(t, graphqlURL, addPostParams) + gqlResponse := executeRequest(t, GraphqlURL, addPostParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -1085,7 +1085,7 @@ func addPostWithNullText(t *testing.T, authorID, countryID string, }] } }`, authorID, countryID) - gqlResponse := executeRequest(t, graphqlURL, addPostParams) + gqlResponse := executeRequest(t, GraphqlURL, addPostParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -1141,7 +1141,7 @@ func requirePost( }, } - gqlResponse := executeRequest(t, graphqlURL, params) + gqlResponse := executeRequest(t, GraphqlURL, params) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -1255,7 +1255,7 @@ func updateRemove(t *testing.T) { Variables: map[string]interface{}{"filter": filter, "rem": remPatch}, } - gqlResponse := updateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{ @@ -1294,7 +1294,7 @@ func updateCountry(t *testing.T, filter map[string]interface{}, newName string, Variables: map[string]interface{}{"filter": filter, "newName": newName}, } - gqlResponse := updateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -1376,7 +1376,7 @@ func filterInUpdate(t *testing.T) { }, } - gqlResponse := updateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -1481,7 +1481,7 @@ func addMutationUpdatesRefs(t *testing.T, executeRequest requestExecutor) { "posts": []interface{}{newPost}, }}, } - gqlResponse := executeRequest(t, graphqlURL, addAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, addAuthorParams) RequireNoGQLErrors(t, gqlResponse) var addResult struct { @@ -1528,7 +1528,7 @@ func addMutationUpdatesRefsXID(t *testing.T, executeRequest requestExecutor) { Variables: map[string]interface{}{"input": newCountry}, } - gqlResponse := executeRequest(t, graphqlURL, addCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCountryParams) RequireNoGQLErrors(t, gqlResponse) var addResult struct { @@ -1587,7 +1587,7 @@ func updateMutationUpdatesRefs(t *testing.T, executeRequest requestExecutor) { "set": map[string]interface{}{"posts": []interface{}{newPost}}, }, } - gqlResponse := executeRequest(t, graphqlURL, updateAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, updateAuthorParams) RequireNoGQLErrors(t, gqlResponse) // The original author no longer has newPost in its list of posts @@ -1638,7 +1638,7 @@ func updateMutationOnlyUpdatesRefsIfDifferent(t *testing.T, executeRequest reque "author": newAuthor}, }, } - gqlResponse := executeRequest(t, graphqlURL, updateAuthorParams) + gqlResponse := executeRequest(t, GraphqlURL, updateAuthorParams) RequireNoGQLErrors(t, gqlResponse) // The expected post was updated @@ -1676,7 +1676,7 @@ func updateMutationUpdatesRefsXID(t *testing.T, executeRequest requestExecutor) Variables: map[string]interface{}{"input": newCountry}, } - gqlResponse := executeRequest(t, graphqlURL, addCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCountryParams) RequireNoGQLErrors(t, gqlResponse) var addResult struct { @@ -1710,7 +1710,7 @@ func updateMutationUpdatesRefsXID(t *testing.T, executeRequest requestExecutor) }, } - gqlResponse = executeRequest(t, graphqlURL, updateCountryParams) + gqlResponse = executeRequest(t, GraphqlURL, updateCountryParams) RequireNoGQLErrors(t, gqlResponse) // newCountry doesn't have "ABC" in it's states list @@ -1754,7 +1754,7 @@ func deleteMutationSingleReference(t *testing.T, executeRequest requestExecutor) Variables: map[string]interface{}{"input": newCountry}, } - gqlResponse := executeRequest(t, graphqlURL, addCountryParams) + gqlResponse := executeRequest(t, GraphqlURL, addCountryParams) RequireNoGQLErrors(t, gqlResponse) var addResult struct { @@ -1778,7 +1778,7 @@ func deleteMutationSingleReference(t *testing.T, executeRequest requestExecutor) }`, Variables: map[string]interface{}{"id": addResult.AddCountry.Country[0].States[0].ID}, } - gqlResponse = getCatParams.ExecuteAsPost(t, graphqlURL) + gqlResponse = getCatParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{"getState":{"country":null}}`, string(gqlResponse.Data)) @@ -1801,7 +1801,7 @@ func deleteMutationMultipleReferences(t *testing.T, executeRequest requestExecut "set": map[string]interface{}{"category": newCategory}}, } - gqlResponse := updateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) // show that this post is in the author's posts @@ -1829,7 +1829,7 @@ func deleteMutationMultipleReferences(t *testing.T, executeRequest requestExecut }`, Variables: map[string]interface{}{"id": newCategory.ID}, } - gqlResponse = getCatParams.ExecuteAsPost(t, graphqlURL) + gqlResponse = getCatParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{"getCategory":{"posts":[]}}`, string(gqlResponse.Data)) @@ -1883,7 +1883,7 @@ func deleteWrongID(t *testing.T) { Variables: map[string]interface{}{"filter": filter}, } - gqlResponse := deleteCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := deleteCountryParams.ExecuteAsPost(t, GraphqlURL) require.JSONEq(t, expectedData, string(gqlResponse.Data)) cleanUp(t, []*country{newCountry}, []*author{newAuthor}, []*post{}) @@ -1919,7 +1919,7 @@ func manyMutations(t *testing.T) { "add2": { "country": [{ "id": "_UID_", "name": "Testland2" }] } }` - gqlResponse := multiMutationParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := multiMutationParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -2016,7 +2016,7 @@ func testSelectionInAddObject(t *testing.T) { }, } - gqlResponse := postExecutor(t, graphqlURL, addPostParams) + gqlResponse := postExecutor(t, GraphqlURL, addPostParams) RequireNoGQLErrors(t, gqlResponse) var result struct { AddPost struct { @@ -2056,7 +2056,7 @@ func mutationEmptyDelete(t *testing.T) { }`, } - gqlResponse := updatePostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updatePostParams.ExecuteAsPost(t, GraphqlURL) require.NotNil(t, gqlResponse.Errors) require.Equal(t, gqlResponse.Errors[0].Error(), "couldn't rewrite mutation updatePost"+ " because failed to rewrite mutation payload because id is not provided") @@ -2105,7 +2105,7 @@ func mutationWithDeepFilter(t *testing.T) { }] } }` - gqlResponse := addPostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addPostParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -2200,7 +2200,7 @@ func manyMutationsWithQueryError(t *testing.T) { Locations: []x.Location{{Line: 18, Column: 7}}, Path: []interface{}{"add2", "author", float64(0), "country", "name"}}} - gqlResponse := multiMutationParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := multiMutationParams.ExecuteAsPost(t, GraphqlURL) if diff := cmp.Diff(expectedErrors, gqlResponse.Errors); diff != "" { t.Errorf("errors mismatch (-want +got):\n%s", diff) @@ -2275,7 +2275,7 @@ func addStarship(t *testing.T) *starship { }}, } - gqlResponse := addStarshipParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addStarshipParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) addStarshipExpected := `{"addStarship":{ @@ -2325,7 +2325,7 @@ func addHuman(t *testing.T, starshipID string) string { }}, } - gqlResponse := addHumanParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addHumanParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -2358,7 +2358,7 @@ func addDroid(t *testing.T) string { }}, } - gqlResponse := addDroidParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addDroidParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -2391,7 +2391,7 @@ func addThingOne(t *testing.T) string { }}, } - gqlResponse := addDroidParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addDroidParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -2424,7 +2424,7 @@ func addThingTwo(t *testing.T) string { }}, } - gqlResponse := addDroidParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addDroidParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -2470,7 +2470,7 @@ func updateCharacter(t *testing.T, id string) { }}, } - gqlResponse := updateCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) } @@ -2501,7 +2501,7 @@ func queryInterfaceAfterAddMutation(t *testing.T) { }`, } - gqlResponse := queryCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := fmt.Sprintf(`{ @@ -2551,7 +2551,7 @@ func queryInterfaceAfterAddMutation(t *testing.T) { }`, } - gqlResponse := queryCharacterByNameParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterByNameParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := fmt.Sprintf(`{ @@ -2589,7 +2589,7 @@ func queryInterfaceAfterAddMutation(t *testing.T) { }`, } - gqlResponse := queryHumanParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryHumanParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := fmt.Sprintf(`{ @@ -2627,7 +2627,7 @@ func queryInterfaceAfterAddMutation(t *testing.T) { }`, } - gqlResponse := queryHumanParamsByName.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryHumanParamsByName.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := fmt.Sprintf(`{ @@ -2686,7 +2686,7 @@ func requireState(t *testing.T, uid string, expectedState *state, }`, Variables: map[string]interface{}{"id": uid}, } - gqlResponse := executeRequest(t, graphqlURL, params) + gqlResponse := executeRequest(t, GraphqlURL, params) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -2716,7 +2716,7 @@ func addState(t *testing.T, name string, executeRequest requestExecutor) *state addStateExpected := ` { "addState": { "state": [{ "id": "_UID_", "name": "` + name + `", "xcode": "cal" } ]} }` - gqlResponse := executeRequest(t, graphqlURL, addStateParams) + gqlResponse := executeRequest(t, GraphqlURL, addStateParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -2763,7 +2763,7 @@ func deleteGqlType( Variables: map[string]interface{}{"filter": filter}, } - gqlResponse := deleteTypeParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := deleteTypeParams.ExecuteAsPost(t, GraphqlURL) if len(expectedErrors) == 0 { RequireNoGQLErrors(t, gqlResponse) @@ -2810,7 +2810,7 @@ func addMutationWithXid(t *testing.T, executeRequest requestExecutor) { Variables: map[string]interface{}{"name": name, "xcode": "cal"}, } - gqlResponse := executeRequest(t, graphqlURL, addStateParams) + gqlResponse := executeRequest(t, GraphqlURL, addStateParams) require.NotNil(t, gqlResponse.Errors) require.Contains(t, gqlResponse.Errors[0].Error(), "because id cal already exists for type State") @@ -2871,7 +2871,7 @@ func addMultipleMutationWithOneError(t *testing.T) { anotherGoodPost}}, } - gqlResponse := postExecutor(t, graphqlURL, addPostParams) + gqlResponse := postExecutor(t, GraphqlURL, addPostParams) addPostExpected := fmt.Sprintf(`{ "addPost": { "post": [{ @@ -2921,7 +2921,7 @@ func addMovie(t *testing.T, executeRequest requestExecutor) *movie { addMovieExpected := ` { "addMovie": { "movie": [{ "id": "_UID_", "name": "Testmovie", "director": [] }] } }` - gqlResponse := executeRequest(t, graphqlURL, addMovieParams) + gqlResponse := executeRequest(t, GraphqlURL, addMovieParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -2968,7 +2968,7 @@ func cleanupMovieAndDirector(t *testing.T, movieID, directorID string) { "deleteMovieDirector" : { "msg": "Deleted" } }` - gqlResponse := multiMutationParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := multiMutationParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, multiMutationExpected, string(gqlResponse.Data)) @@ -2998,7 +2998,7 @@ func addMutationWithReverseDgraphEdge(t *testing.T) { addMovieDirectorExpected := `{ "addMovieDirector": { "movieDirector": [{ "id": "_UID_", "name": "Spielberg" }] } }` - gqlResponse := postExecutor(t, graphqlURL, addMovieDirectorParams) + gqlResponse := postExecutor(t, GraphqlURL, addMovieDirectorParams) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -3036,7 +3036,7 @@ func addMutationWithReverseDgraphEdge(t *testing.T) { }, } - gqlResponse = getMovieParams.ExecuteAsPost(t, graphqlURL) + gqlResponse = getMovieParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expectedResponse := `{"getMovie":{"name":"Testmovie","director":[{"name":"Spielberg"}]}}` require.Equal(t, expectedResponse, string(gqlResponse.Data)) @@ -3087,7 +3087,7 @@ func testNumUids(t *testing.T) { } } - gqlResponse := postExecutor(t, graphqlURL, addAuthorParams) + gqlResponse := postExecutor(t, GraphqlURL, addAuthorParams) RequireNoGQLErrors(t, gqlResponse) t.Run("Test numUID in add", func(t *testing.T) { @@ -3115,7 +3115,7 @@ func testNumUids(t *testing.T) { }}, } - gqlResponse = postExecutor(t, graphqlURL, updatePostParams) + gqlResponse = postExecutor(t, GraphqlURL, updatePostParams) RequireNoGQLErrors(t, gqlResponse) var updateResult struct { @@ -3155,7 +3155,7 @@ func testNumUids(t *testing.T) { }, }, } - gqlResponse = postExecutor(t, graphqlURL, deleteAuthorParams) + gqlResponse = postExecutor(t, GraphqlURL, deleteAuthorParams) RequireNoGQLErrors(t, gqlResponse) var deleteResult struct { @@ -3192,7 +3192,7 @@ func checkUser(t *testing.T, userObj, expectedObj *user) { }, } - gqlResponse := checkUserParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := checkUserParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -3250,7 +3250,7 @@ func passwordTest(t *testing.T) { } t.Run("Test add and update user", func(t *testing.T) { - gqlResponse := postExecutor(t, graphqlURL, addUserParams) + gqlResponse := postExecutor(t, GraphqlURL, addUserParams) RequireNoGQLErrors(t, gqlResponse) require.Equal(t, `{"addUser":{"user":[{"name":"Test User"}]}}`, string(gqlResponse.Data)) @@ -3258,7 +3258,7 @@ func passwordTest(t *testing.T) { checkUser(t, newUser, newUser) checkUser(t, &user{Name: "Test User", Password: "Wrong Pass"}, nil) - gqlResponse = postExecutor(t, graphqlURL, updateUserParams) + gqlResponse = postExecutor(t, GraphqlURL, updateUserParams) RequireNoGQLErrors(t, gqlResponse) require.Equal(t, `{"updateUser":{"user":[{"name":"Test User"}]}}`, string(gqlResponse.Data)) @@ -3315,7 +3315,7 @@ func threeLevelDeepMutation(t *testing.T) { Variables: map[string]interface{}{"input": newStudents}, } - gqlResponse := postExecutor(t, graphqlURL, addStudentParams) + gqlResponse := postExecutor(t, GraphqlURL, addStudentParams) RequireNoGQLErrors(t, gqlResponse) var actualResult struct { @@ -3391,7 +3391,7 @@ func deepMutationDuplicateXIDsSameObjectTest(t *testing.T) { Variables: map[string]interface{}{"input": newStudents}, } - gqlResponse := postExecutor(t, graphqlURL, addStudentParams) + gqlResponse := postExecutor(t, GraphqlURL, addStudentParams) RequireNoGQLErrors(t, gqlResponse) var actualResult struct { @@ -3478,7 +3478,7 @@ func queryTypenameInMutationPayload(t *testing.T) { }`, } - gqlResponse := addStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) addStateExpected := `{ @@ -3512,7 +3512,7 @@ func ensureAliasInMutationPayload(t *testing.T) { }`, } - gqlResponse := addStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) addStateExpected := `{ @@ -3541,7 +3541,7 @@ func mutationsHaveExtensions(t *testing.T) { } touchedUidskey := "touched_uids" - gqlResponse := mutation.ExecuteAsPost(t, graphqlURL) + gqlResponse := mutation.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.Contains(t, gqlResponse.Extensions, touchedUidskey) require.Greater(t, int(gqlResponse.Extensions[touchedUidskey].(float64)), 0) @@ -3586,7 +3586,7 @@ func mutationsWithAlias(t *testing.T) { "del" : { "message": "Deleted", "uids": 1 } }` - gqlResponse := aliasMutationParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := aliasMutationParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, multiMutationExpected, string(gqlResponse.Data)) @@ -3607,7 +3607,7 @@ func updateMutationWithoutSetRemove(t *testing.T) { }`, Variables: map[string]interface{}{"id": country.ID}, } - gqlResponse := updateCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := updateCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{ @@ -3633,7 +3633,7 @@ func checkCascadeWithMutationWithoutIDField(t *testing.T) { }`, } - gqlResponse := addStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := addStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) addStateExpected := `{ @@ -3648,4 +3648,4 @@ func checkCascadeWithMutationWithoutIDField(t *testing.T) { filter := map[string]interface{}{"xcode": map[string]interface{}{"eq": "S2"}} deleteState(t, filter, 1, nil) -} \ No newline at end of file +} diff --git a/graphql/e2e/common/query.go b/graphql/e2e/common/query.go index 6bed9aeaa79..53b00f5af07 100644 --- a/graphql/e2e/common/query.go +++ b/graphql/e2e/common/query.go @@ -44,7 +44,7 @@ func queryCountryByRegExp(t *testing.T, regexp string, expectedCountries []*coun Variables: map[string]interface{}{"regexp": regexp}, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -72,7 +72,7 @@ func touchedUidsHeader(t *testing.T) { } }`, } - req, err := query.createGQLPost(graphqlURL) + req, err := query.createGQLPost(GraphqlURL) require.NoError(t, err) client := http.Client{Timeout: 10 * time.Second} @@ -122,7 +122,7 @@ func queryByTypeWithEncoding(t *testing.T, acceptGzip, gzipEncoding bool) { gzipEncoding: gzipEncoding, } - gqlResponse := queryCountry.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCountry.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -157,7 +157,7 @@ func uidAlias(t *testing.T) { UID string } - gqlResponse := queryCountry.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCountry.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -185,7 +185,7 @@ func orderAtRoot(t *testing.T) { }`, } - gqlResponse := queryCountry.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCountry.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -213,7 +213,7 @@ func pageAtRoot(t *testing.T) { }`, } - gqlResponse := queryCountry.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCountry.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -257,7 +257,7 @@ func multipleSearchIndexes(t *testing.T) { Variables: map[string]interface{}{"filter": filter}, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -285,7 +285,7 @@ func multipleSearchIndexesWrongField(t *testing.T) { }`, } - gqlResponse := queryPostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryPostParams.ExecuteAsPost(t, GraphqlURL) require.NotNil(t, gqlResponse.Errors) expected := `Field "regexp" is not defined by type StringFullTextFilter_StringTermFilter` @@ -302,7 +302,7 @@ func hashSearch(t *testing.T) { }`, } - gqlResponse := queryAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var expected, result struct { @@ -332,7 +332,7 @@ func allPosts(t *testing.T) []*post { } }`, } - gqlResponse := queryPostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryPostParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -358,7 +358,7 @@ func deepFilter(t *testing.T) { }`, } - gqlResponse := getAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -394,7 +394,7 @@ func deepHasFilter(t *testing.T) { }`, } - gqlResponse := getAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -444,7 +444,7 @@ func manyQueries(t *testing.T) { Query: bld.String(), } - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result map[string]*post @@ -547,7 +547,7 @@ func queryOrderAtRoot(t *testing.T) { }, } - gqlResponse := getParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected.QueryPost = test.Expected @@ -599,7 +599,7 @@ func queriesWithError(t *testing.T) { Query: bld.String(), } - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) require.Len(t, gqlResponse.Errors, 1, "expected 1 error from malformed query") var result map[string]*post @@ -686,7 +686,7 @@ func authorTest(t *testing.T, filter interface{}, expected []*author) { Variables: map[string]interface{}{"filter": filter}, } - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -951,7 +951,7 @@ func postTest(t *testing.T, filter interface{}, expected []*post) { Variables: map[string]interface{}{"filter": filter}, } - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -983,7 +983,7 @@ func skipDirective(t *testing.T) { }, } - gqlResponse := getAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{"queryAuthor":[{"name":"Ann Other Author", @@ -1008,7 +1008,7 @@ func includeDirective(t *testing.T) { }, } - gqlResponse := getAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{"queryAuthor":[{"name":"Ann Other Author","dob":"1988-01-01T00:00:00Z"}]}` @@ -1038,7 +1038,7 @@ func includeAndSkipDirective(t *testing.T) { }, } - gqlResponse := getAuthorParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getAuthorParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{"queryAuthor":[{"name":"Ann Other Author"}]}` @@ -1069,7 +1069,7 @@ func queryByMultipleIds(t *testing.T) { }}, } - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -1137,7 +1137,7 @@ func enumFilter(t *testing.T) { t.Run(name, func(t *testing.T) { queryParams.Variables = map[string]interface{}{"filter": test.Filter} - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) var result struct { @@ -1173,7 +1173,7 @@ func queryApplicationGraphQl(t *testing.T) { }`, } - gqlResponse := getCountryParams.ExecuteAsPostApplicationGraphql(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPostApplicationGraphql(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1197,7 +1197,7 @@ func queryTypename(t *testing.T) { }`, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1234,7 +1234,7 @@ func queryNestedTypename(t *testing.T) { }`, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1299,7 +1299,7 @@ func typenameForInterface(t *testing.T) { ] }` - gqlResponse := queryCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, expected, string(gqlResponse.Data)) }) @@ -1321,7 +1321,7 @@ func queryOnlyTypename(t *testing.T) { }`, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1361,7 +1361,7 @@ func querynestedOnlyTypename(t *testing.T) { }`, } - gqlResponse := getCountryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getCountryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1423,7 +1423,7 @@ func onlytypenameForInterface(t *testing.T) { ] }` - gqlResponse := queryCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, expected, string(gqlResponse.Data)) }) @@ -1451,7 +1451,7 @@ func defaultEnumFilter(t *testing.T) { }`, } - gqlResponse := queryCharacterParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryCharacterParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) expected := `{ @@ -1492,7 +1492,7 @@ func queryByMultipleInvalidIds(t *testing.T) { // Since the ids are invalid and can't be converted to uint64, the query sent to Dgraph should // have func: uid() at root and should return 0 results. - gqlResponse := queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.Equal(t, `{"queryPost":[]}`, string(gqlResponse.Data)) @@ -1513,7 +1513,7 @@ func getStateByXid(t *testing.T) { }`, } - gqlResponse := getStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.Equal(t, `{"getState":{"name":"NSW"}}`, string(gqlResponse.Data)) } @@ -1527,7 +1527,7 @@ func getStateWithoutArgs(t *testing.T) { }`, } - gqlResponse := getStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{"getState":null}`, string(gqlResponse.Data)) } @@ -1541,7 +1541,7 @@ func getStateByBothXidAndUid(t *testing.T) { }`, } - gqlResponse := getStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, `{"getState":null}`, string(gqlResponse.Data)) } @@ -1555,7 +1555,7 @@ func queryStateByXid(t *testing.T) { }`, } - gqlResponse := getStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.Equal(t, `{"queryState":[{"name":"NSW"}]}`, string(gqlResponse.Data)) } @@ -1569,7 +1569,7 @@ func queryStateByXidRegex(t *testing.T) { }`, } - gqlResponse := getStateParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := getStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, `{"queryState":[{"name":"Nusa"},{"name": "NSW"}]}`, string(gqlResponse.Data)) @@ -1627,7 +1627,7 @@ func multipleOperations(t *testing.T) { for _, test := range cases { t.Run(test.name, func(t *testing.T) { params.OperationName = test.operationName - gqlResponse := params.ExecuteAsPost(t, graphqlURL) + gqlResponse := params.ExecuteAsPost(t, GraphqlURL) if test.expectedError != "" { require.NotNil(t, gqlResponse.Errors) require.Equal(t, test.expectedError, gqlResponse.Errors[0].Error()) @@ -1661,7 +1661,7 @@ func queryPostWithAuthor(t *testing.T) { }`, } - gqlResponse := queryPostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryPostParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, `{"queryPost":[{"title":"Introducing GraphQL in Dgraph","author":{"name":"Ann Author"}}]}`, @@ -1678,7 +1678,7 @@ func queriesHaveExtensions(t *testing.T) { } touchedUidskey := "touched_uids" - gqlResponse := query.ExecuteAsPost(t, graphqlURL) + gqlResponse := query.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.Contains(t, gqlResponse.Extensions, touchedUidskey) require.Greater(t, int(gqlResponse.Extensions[touchedUidskey].(float64)), 0) @@ -1698,7 +1698,7 @@ func queryWithAlias(t *testing.T) { }`, } - gqlResponse := queryPostParams.ExecuteAsPost(t, graphqlURL) + gqlResponse := queryPostParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) testutil.CompareJSON(t, `{ @@ -1723,7 +1723,7 @@ func DgraphDirectiveWithSpecialCharacters(t *testing.T) { }`, } result := `{"addMessage":{"message":[{"content":"content1","author":"author1"}]}}` - gqlResponse := mutation.ExecuteAsPost(t, graphqlURL) + gqlResponse := mutation.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, result, string(gqlResponse.Data)) @@ -1737,7 +1737,7 @@ func DgraphDirectiveWithSpecialCharacters(t *testing.T) { }`, } result = `{"queryMessage":[{"content":"content1","author":"author1"}]}` - gqlResponse = queryParams.ExecuteAsPost(t, graphqlURL) + gqlResponse = queryParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, gqlResponse) require.JSONEq(t, result, string(gqlResponse.Data)) } @@ -1788,7 +1788,7 @@ func queryWithCascade(t *testing.T) { }`, Variables: map[string]interface{}{"input": states}, } - resp := addStateParams.ExecuteAsPost(t, graphqlURL) + resp := addStateParams.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, resp) testutil.CompareJSON(t, `{"addState":{"numUids":2}}`, string(resp.Data)) getStateByXidQuery := `query ($xid: String!) { @@ -1898,7 +1898,7 @@ func queryWithCascade(t *testing.T) { } }`, variables: map[string]interface{}{"ids": authorIds}, - respData:`{ + respData: `{ "queryAuthor": [ { "reputation": 4.6, @@ -2070,7 +2070,7 @@ func queryWithCascade(t *testing.T) { Query: tcase.query, Variables: tcase.variables, } - resp := params.ExecuteAsPost(t, graphqlURL) + resp := params.ExecuteAsPost(t, GraphqlURL) RequireNoGQLErrors(t, resp) testutil.CompareJSON(t, tcase.respData, string(resp.Data)) }) diff --git a/graphql/e2e/common/schema.go b/graphql/e2e/common/schema.go index 8848f356d49..ebccc782792 100644 --- a/graphql/e2e/common/schema.go +++ b/graphql/e2e/common/schema.go @@ -152,7 +152,7 @@ func graphQLDescriptions(t *testing.T) { }, } - introspectionResult := introspect.ExecuteAsPost(t, graphqlURL) + introspectionResult := introspect.ExecuteAsPost(t, GraphqlURL) require.Nil(t, introspectionResult.Errors) require.JSONEq(t, tCase.expected, string(introspectionResult.Data)) diff --git a/graphql/e2e/debug/docker-compose.yml b/graphql/e2e/debug/docker-compose.yml new file mode 100644 index 00000000000..04925abaaea --- /dev/null +++ b/graphql/e2e/debug/docker-compose.yml @@ -0,0 +1,69 @@ +version: "3.5" +services: + zero: + image: dgraph/dgraph:latest + container_name: zero1 + working_dir: /data/zero1 + ports: + - 5180:5180 + - 6180:6180 + labels: + cluster: test + service: zero1 + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + command: /gobin/dgraph zero -o 100 --logtostderr -v=2 --bindall --expose_trace --profile_mode block --block_rate 10 --my=zero1:5180 + + alpha: + image: dgraph/dgraph:latest + container_name: alpha1 + working_dir: /data/alpha1 + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + ports: + - 8180:8180 + - 9180:9180 + labels: + cluster: test + service: alpha1 + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zero1:5180 -o 100 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=3 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alpha1:7180 --graphql_debug=true + + zeroAdmin: + image: dgraph/dgraph:latest + container_name: zeroAdmin + working_dir: /data/zeroAdmin + ports: + - 5280:5280 + - 6280:6280 + labels: + cluster: admintest + service: zeroAdmin + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + command: /gobin/dgraph zero -o 200 --logtostderr -v=2 --bindall --expose_trace --profile_mode block --block_rate 10 --my=zeroAdmin:5280 + + alphaAdmin: + image: dgraph/dgraph:latest + container_name: alphaAdmin + working_dir: /data/alphaAdmin + volumes: + - type: bind + source: $GOPATH/bin + target: /gobin + read_only: true + ports: + - 8280:8280 + - 9280:9280 + labels: + cluster: admintest + service: alphaAdmin + command: /gobin/dgraph alpha --lru_mb=1024 --zero=zeroAdmin:5280 -o 200 --expose_trace --trace 1.0 --profile_mode block --block_rate 10 --logtostderr -v=2 --whitelist 10.0.0.0/8,172.16.0.0/12,192.168.0.0/16 --my=alphaAdmin:7280 --graphql_debug=true diff --git a/graphql/resolve/auth_test.go b/graphql/resolve/auth_test.go index f35c253cf63..76b959f64d1 100644 --- a/graphql/resolve/auth_test.go +++ b/graphql/resolve/auth_test.go @@ -694,7 +694,7 @@ func checkAddUpdateCase( // -- Assert -- // most cases are built into the authExecutor - if tcase.Error != nil || resolved.Err != nil { + if tcase.Error != nil { require.Equal(t, tcase.Error.Error(), resolved.Err.Error()) } } diff --git a/graphql/schema/response.go b/graphql/schema/response.go index 418ca925a59..ac2e722f8dd 100644 --- a/graphql/schema/response.go +++ b/graphql/schema/response.go @@ -21,6 +21,7 @@ import ( "encoding/json" "fmt" "io" + "strings" "time" "github.com/golang/glog" @@ -67,6 +68,14 @@ func (r *Response) GetExtensions() *Extensions { // WithError generates GraphQL errors from err and records those in r. func (r *Response) WithError(err error) { + if err == nil { + return + } + + if !x.Config.GraphqlDebug && strings.Contains(err.Error(), "authorization failed") { + return + } + r.Errors = append(r.Errors, AsGQLErrors(err)...) } diff --git a/testutil/graphql.go b/testutil/graphql.go index 671b6db0d79..98136d70386 100644 --- a/testutil/graphql.go +++ b/testutil/graphql.go @@ -146,11 +146,12 @@ func (c clientCustomClaims) MarshalJSON() ([]byte, error) { } type AuthMeta struct { - PublicKey string - Namespace string - Algo string - Header string - AuthVars map[string]interface{} + PublicKey string + Namespace string + Algo string + Header string + AuthVars map[string]interface{} + PrivateKeyPath string } func (a *AuthMeta) GetSignedToken(privateKeyFile string, diff --git a/x/config.go b/x/config.go index 6ae516c3d3e..f0c4d2bf9cd 100644 --- a/x/config.go +++ b/x/config.go @@ -32,8 +32,10 @@ type Options struct { NormalizeNodeLimit int // PollInterval is the polling interval for graphql subscription. PollInterval time.Duration - //GraphqlExtension wiil be set to see extensions in graphql results + // GraphqlExtension will be set to see extensions in graphql results GraphqlExtension bool + // GraphqlDebug will enable debug mode in GraphQL + GraphqlDebug bool } // Config stores the global instance of this package's options.