diff --git a/graphql/e2e/custom_logic/custom_logic_test.go b/graphql/e2e/custom_logic/custom_logic_test.go index 9a0c08e85c4..1bd49a78b37 100644 --- a/graphql/e2e/custom_logic/custom_logic_test.go +++ b/graphql/e2e/custom_logic/custom_logic_test.go @@ -165,7 +165,7 @@ func TestCustomQueryShouldForwardHeaders(t *testing.T) { url: "http://mock:8888/verifyHeaders", method: "GET", forwardHeaders: ["X-App-Token", "X-User-Id"], - secretHeaders: ["Github-Api-Token", "X-App-Token"] + secretHeaders: ["Github-Api-Token"] }) } @@ -204,12 +204,12 @@ func TestCustomNameForwardHeaders(t *testing.T) { url: "http://mock:8888/verifyCustomNameHeaders", method: "GET", forwardHeaders: ["X-App-Token:App", "X-User-Id"], - secretHeaders: ["Authorization:Github-Api-Token", "X-App-Token"] + secretHeaders: ["Authorization:Github-Api-Token"] + introspectionHeaders: ["API:Github-Api-Token"] }) } # Dgraph.Secret Github-Api-Token "random-fake-token" - # Dgraph.Secret X-App-Token "should-be-overriden" ` updateSchemaRequireNoGQLErrors(t, schema) time.Sleep(2 * time.Second) @@ -254,8 +254,9 @@ func TestSchemaIntrospectionForCustomQueryShouldForwardHeaders(t *testing.T) { http: { url: "http://mock:8888/validatesecrettoken" method: "POST" - secretHeaders: ["GITHUB-API-TOKEN"] - graphql: "query($yo: CountryInput!) {countries(filter: $yo)}" + forwardHeaders: ["Content-Type"] + introspectionHeaders: ["GITHUB-API-TOKEN"] + graphql: "query($yo: CountryInput!) {countries(filter: $yo)}" } ) } diff --git a/graphql/schema/gqlschema.go b/graphql/schema/gqlschema.go index 6adc726ceb9..5cac866bc31 100644 --- a/graphql/schema/gqlschema.go +++ b/graphql/schema/gqlschema.go @@ -105,6 +105,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/rules.go b/graphql/schema/rules.go index b2362d09484..8f6453dd8bc 100644 --- a/graphql/schema/rules.go +++ b/graphql/schema/rules.go @@ -1599,40 +1599,82 @@ func customDirectiveValidation(sch *ast.Schema, // 12. Finally validate the given graphql operation on remote server, when all locally doable // validations have finished - si := httpArg.Value.Children.ForName("skipIntrospection") var skip bool - if si != nil { - skip, err = strconv.ParseBool(si.Raw) - if err != nil { - errs = append(errs, gqlerror.ErrorPosf(graphql.Position, - "Type %s; Field %s; skipIntrospection in @custom directive can only be "+ - "true/false, found: `%s`.", - typ.Name, field.Name, si.Raw)) + iHeaders := make(map[string]string) + if body != nil || graphql != nil { + var errPos *ast.Position + switch { + case body != nil: + errPos = body.Position + case graphql != nil: + errPos = graphql.Position + default: + // this case is not possible, as requiredFields will have non-0 length only if there was + // some body or graphql. Written only to satisfy logic flow, so that errPos is always + // non-nil. + errPos = dir.Position + } + si := httpArg.Value.Children.ForName("skipIntrospection") + if si != nil { + skip, err = strconv.ParseBool(si.Raw) + if err != nil { + errs = append(errs, gqlerror.ErrorPosf(errPos, + "Type %s; Field %s; skipIntrospection in @custom directive can only be "+ + "true/false, found: `%s`.", + typ.Name, field.Name, si.Raw)) + } } - } - forwardHeaders := httpArg.Value.Children.ForName("forwardHeaders") - if forwardHeaders != nil { - for _, h := range forwardHeaders.Children { - key := strings.Split(h.Value.Raw, ":") - if len(key) > 2 { - return append(errs, gqlerror.ErrorPosf(graphql.Position, - "Type %s; Field %s; forwardHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername'"+ - ", found: `%s`.", - typ.Name, field.Name, h.Value.Raw)) + forwardHeaders := httpArg.Value.Children.ForName("forwardHeaders") + fHeaders := make(map[string]bool) + if forwardHeaders != nil { + for _, h := range forwardHeaders.Children { + key := strings.Split(h.Value.Raw, ":") + if len(key) > 2 { + return append(errs, gqlerror.ErrorPosf(errPos, + "Type %s; Field %s; forwardHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername'"+ + ", found: `%s`.", + typ.Name, field.Name, h.Value.Raw)) + } + fHeaders[key[0]] = true } } - } - secretHeaders := httpArg.Value.Children.ForName("secretHeaders") - if secretHeaders != nil { - for _, h := range secretHeaders.Children { - key := strings.Split(h.Value.Raw, ":") - if len(key) > 2 { - return append(errs, gqlerror.ErrorPosf(graphql.Position, - "Type %s; Field %s; secretHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername'"+ - ", found: `%s`.", - typ.Name, field.Name, h.Value.Raw)) + secretHeaders := httpArg.Value.Children.ForName("secretHeaders") + if secretHeaders != nil { + for _, h := range secretHeaders.Children { + secretKey := strings.Split(h.Value.Raw, ":") + if len(secretKey) > 2 { + return append(errs, gqlerror.ErrorPosf(errPos, + "Type %s; Field %s; secretHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername'"+ + ", found: `%s`.", + typ.Name, field.Name, h.Value.Raw)) + } + if fHeaders != nil { + if fHeaders[secretKey[0]] { + return append(errs, gqlerror.ErrorPosf(errPos, + "Type %s; Field %s; secretHeaders and forwardHeaders in @custom directive cannot have overlapping headers"+ + ", found: `%s`.", + typ.Name, field.Name, h.Value.Raw)) + } + } + } + } + + introspectionHeaders := httpArg.Value.Children.ForName("introspectionHeaders") + if introspectionHeaders != nil { + for _, h := range introspectionHeaders.Children { + key := strings.Split(h.Value.Raw, ":") + if len(key) == 1 { + key = []string{h.Value.Raw, h.Value.Raw} + } + if len(key) > 2 { + return append(errs, gqlerror.ErrorPosf(errPos, + "Type %s; Field %s; introspectionHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername'"+ + ", found: `%s`.", + typ.Name, field.Name, h.Value.Raw)) + } + iHeaders[key[0]] = key[1] } } } @@ -1642,18 +1684,16 @@ func customDirectiveValidation(sch *ast.Schema, } if graphql != nil && !skip && graphqlOpDef != nil { - secretHeaders := httpArg.Value.Children.ForName("secretHeaders") headers := http.Header{} - if secretHeaders != nil { - for _, h := range secretHeaders.Children { - key := strings.Split(h.Value.Raw, ":") - if len(key) == 1 { - key = []string{h.Value.Raw, h.Value.Raw} - } - // We try and fetch the value from the stored secrets. - val := secrets[key[1]] - headers.Add(key[0], string(val)) + for key, val := range iHeaders { + // We try and fetch the value from the stored secrets. + value, ok := secrets[val] + if !ok { + return append(errs, gqlerror.ErrorPosf(graphql.Position, + "Type %s; Field %s; introspectionHeaders in @custom directive should use secrets to store the header value. To do that specify `%s` in this format '#Dgraph.Secret name value' at the bottom of your schema file.", + typ.Name, field.Name, val,)) } + headers.Add(key, string(value)) } if err := validateRemoteGraphql(&remoteGraphqlMetadata{ parentType: typ, diff --git a/graphql/schema/testdata/schemagen/output/authorization.graphql b/graphql/schema/testdata/schemagen/output/authorization.graphql index 5e2c301546d..c037af3c230 100644 --- a/graphql/schema/testdata/schemagen/output/authorization.graphql +++ b/graphql/schema/testdata/schemagen/output/authorization.graphql @@ -68,6 +68,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql b/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql index cb66a47ac6f..21318ed94a8 100755 --- a/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql +++ b/graphql/schema/testdata/schemagen/output/comments-and-descriptions.graphql @@ -73,6 +73,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/custom-mutation.graphql b/graphql/schema/testdata/schemagen/output/custom-mutation.graphql index 7a2388deb3b..7ad8eb3f8ae 100644 --- a/graphql/schema/testdata/schemagen/output/custom-mutation.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-mutation.graphql @@ -61,6 +61,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql b/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql index a2519a522ff..8fc1a2ae8f7 100755 --- a/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-nested-types.graphql @@ -78,6 +78,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql b/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql index a12aee7b2c9..92ed2c5bc6a 100644 --- a/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-mixed-types.graphql @@ -62,6 +62,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql index 340ec738c3a..ea2d63f4f3c 100755 --- a/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-not-dgraph-type.graphql @@ -61,6 +61,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql index f910401e05c..89d240f5890 100755 --- a/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/custom-query-with-dgraph-type.graphql @@ -57,6 +57,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/deprecated.graphql b/graphql/schema/testdata/schemagen/output/deprecated.graphql index 41d24b047e9..f5d9d047c84 100755 --- a/graphql/schema/testdata/schemagen/output/deprecated.graphql +++ b/graphql/schema/testdata/schemagen/output/deprecated.graphql @@ -57,6 +57,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql index 12f8f13b384..5db874e04ab 100755 --- a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-on-concrete-type-with-interfaces.graphql @@ -71,6 +71,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql index 40e9df828a3..856895d4693 100755 --- a/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/dgraph-reverse-directive-with-interfaces.graphql @@ -71,6 +71,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql index 4d05df98daa..eafaee45d60 100755 --- a/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/field-with-id-directive.graphql @@ -70,6 +70,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql b/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql index adc00f424c1..86e2c6a91c7 100755 --- a/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/field-with-reverse-predicate-in-dgraph-directive.graphql @@ -64,6 +64,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql index 527521ed53e..75a9b840b4b 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface-having-directive.graphql @@ -81,6 +81,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql index 6863a6d1d6b..6b587e3b847 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-interface.graphql @@ -82,6 +82,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql b/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql index 527521ed53e..75a9b840b4b 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse-with-type-having-directive.graphql @@ -81,6 +81,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/hasInverse.graphql b/graphql/schema/testdata/schemagen/output/hasInverse.graphql index 902d5c93e45..91bb8f77b97 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse.graphql @@ -62,6 +62,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql b/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql index 4541aa0d702..1e1b44d66c1 100755 --- a/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql +++ b/graphql/schema/testdata/schemagen/output/hasInverse_withSubscription.graphql @@ -62,6 +62,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql b/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql index 3d0e0279e13..46995298448 100755 --- a/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/ignore-unsupported-directive.graphql @@ -64,6 +64,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql b/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql index 0afb6757fe6..dcfc4e2769e 100755 --- a/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql +++ b/graphql/schema/testdata/schemagen/output/interface-with-id-directive.graphql @@ -66,6 +66,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql b/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql index d03920e66ec..3521e43a7cf 100755 --- a/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql +++ b/graphql/schema/testdata/schemagen/output/interface-with-no-ids.graphql @@ -66,6 +66,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql b/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql index 0255cbce2c2..d96207966e2 100755 --- a/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql +++ b/graphql/schema/testdata/schemagen/output/interfaces-with-types-and-password.graphql @@ -88,6 +88,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql b/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql index d430ef0dfd4..6fc76f6bdbc 100755 --- a/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql +++ b/graphql/schema/testdata/schemagen/output/interfaces-with-types.graphql @@ -88,6 +88,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql b/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql index 27aa7aa183d..d90a44c41a8 100755 --- a/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql +++ b/graphql/schema/testdata/schemagen/output/no-id-field-with-searchables.graphql @@ -56,6 +56,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/no-id-field.graphql b/graphql/schema/testdata/schemagen/output/no-id-field.graphql index aa6ae477261..7f38667c48c 100755 --- a/graphql/schema/testdata/schemagen/output/no-id-field.graphql +++ b/graphql/schema/testdata/schemagen/output/no-id-field.graphql @@ -68,6 +68,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/password-type.graphql b/graphql/schema/testdata/schemagen/output/password-type.graphql index cfd5b4c0204..6ef48355783 100755 --- a/graphql/schema/testdata/schemagen/output/password-type.graphql +++ b/graphql/schema/testdata/schemagen/output/password-type.graphql @@ -57,6 +57,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/searchables-references.graphql b/graphql/schema/testdata/schemagen/output/searchables-references.graphql index 8b58bd9ae8b..80842ff4a60 100755 --- a/graphql/schema/testdata/schemagen/output/searchables-references.graphql +++ b/graphql/schema/testdata/schemagen/output/searchables-references.graphql @@ -66,6 +66,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/searchables.graphql b/graphql/schema/testdata/schemagen/output/searchables.graphql index d2526583456..bfe7dc2dc8a 100755 --- a/graphql/schema/testdata/schemagen/output/searchables.graphql +++ b/graphql/schema/testdata/schemagen/output/searchables.graphql @@ -83,6 +83,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql b/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql index 3df4da1e289..1034a54ce73 100755 --- a/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql +++ b/graphql/schema/testdata/schemagen/output/single-type-with-enum.graphql @@ -65,6 +65,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/single-type.graphql b/graphql/schema/testdata/schemagen/output/single-type.graphql index 5d5b856ca3a..988f2349019 100755 --- a/graphql/schema/testdata/schemagen/output/single-type.graphql +++ b/graphql/schema/testdata/schemagen/output/single-type.graphql @@ -59,6 +59,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql b/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql index 329d90f291d..c340359f849 100755 --- a/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql +++ b/graphql/schema/testdata/schemagen/output/type-implements-multiple-interfaces.graphql @@ -72,6 +72,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/type-reference.graphql b/graphql/schema/testdata/schemagen/output/type-reference.graphql index cde87824e57..83365ff80c7 100755 --- a/graphql/schema/testdata/schemagen/output/type-reference.graphql +++ b/graphql/schema/testdata/schemagen/output/type-reference.graphql @@ -64,6 +64,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql b/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql index dcd2f9b8832..87011dc440e 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-arguments-on-field.graphql @@ -65,6 +65,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql b/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql index 2a130436d80..26ef4c48ca0 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-custom-field-on-dgraph-type.graphql @@ -64,6 +64,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql b/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql index 9351860d263..347a22698bb 100644 --- a/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql +++ b/graphql/schema/testdata/schemagen/output/type-with-custom-fields-on-remote-type.graphql @@ -64,6 +64,7 @@ input CustomHTTP { mode: Mode forwardHeaders: [String!] secretHeaders: [String!] + introspectionHeaders: [String!] skipIntrospection: Boolean } diff --git a/graphql/schema/wrappers.go b/graphql/schema/wrappers.go index a9f5a16e6fe..b17fb9387ae 100644 --- a/graphql/schema/wrappers.go +++ b/graphql/schema/wrappers.go @@ -860,7 +860,6 @@ func getCustomHTTPConfig(f *field, isQueryOrMutation bool) (FieldHTTPConfig, err forwardHeaders := httpArg.Value.Children.ForName("forwardHeaders") if forwardHeaders != nil { for _, h := range forwardHeaders.Children { - // We would override the header if it was also specified as part of secretHeaders. key := strings.Split(h.Value.Raw, ":") if len(key) == 1 { key = []string{h.Value.Raw, h.Value.Raw} diff --git a/graphql/schema/wrappers_test.go b/graphql/schema/wrappers_test.go index ed2ae96ebc2..8bf9372d3a8 100644 --- a/graphql/schema/wrappers_test.go +++ b/graphql/schema/wrappers_test.go @@ -796,7 +796,6 @@ func TestGraphQLQueryInCustomHTTPConfig(t *testing.T) { } func TestAllowedHeadersList(t *testing.T) { - // TODO Add Custom logic forward headers tests tcases := []struct { name string schemaStr string @@ -833,6 +832,86 @@ func TestAllowedHeadersList(t *testing.T) { } } +func TestCustomLogicHeaders(t *testing.T) { + tcases := []struct { + name string + schemaStr string + err error + }{ + { + "check for introspection header to always use value from secrets", + ` + type User @remote { + description: String + } + + type Query { + user(name: String!): User + @custom( + http: { + url: "http://api:8888/graphql" + method: "POST" + introspectionHeaders: ["Authorization:Api-Token"] + graphql: "query($name: String!) { getUser(name: $name) }" + } + ) + } + `, + errors.New("input:13: Type Query; Field user; introspectionHeaders in @custom directive should use secrets to store the header value. " + "To do that specify `Api-Token` in this format '#Dgraph.Secret name value' at the bottom of your schema file." + "\n"), + }, + { + "check for secret and forward headers overlapping", + ` + type User @remote { + description: String + } + + type Query { + user(name: String!): User + @custom( + http: { + url: "http://api:8888/graphql" + method: "POST" + forwardHeaders: ["API-Token", "Authorization"] + secretHeaders: ["Authorization"] + graphql: "query($name: String!) { getUser(name: $name) }" + } + ) + } + `, + errors.New("input:14: Type Query; Field user; secretHeaders and forwardHeaders in @custom directive cannot have overlapping headers, found: `Authorization`." + "\n"), + }, + { + "check for header structure", + ` + type User @remote { + description: String + } + + type Query { + user(name: String!): User + @custom( + http: { + url: "http://api:8888/graphql" + method: "POST" + forwardHeaders: ["API-Token", "Content-Type"] + secretHeaders: ["Authorization:Auth:random"] + graphql: "query($name: String!) { getUser(name: $name) }" + } + ) + } + `, + errors.New("input:14: Type Query; Field user; secretHeaders in @custom directive should be of the form 'remote_headername:local_headername' or just 'headername', found: `Authorization:Auth:random`." + "\n"), + }, + } + for _, test := range tcases { + t.Run(test.name, func(t *testing.T) { + _, err := NewHandler(test.schemaStr) + require.EqualError(t, err, test.err.Error()) + }) + } +} + func TestParseSecrets(t *testing.T) { tcases := []struct { name string