Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(GraphQl): Allow case insensitive auth header for graphql subscriptions. #6141

Merged
merged 11 commits into from
Aug 12, 2020
74 changes: 74 additions & 0 deletions graphql/e2e/subscription/subscription_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -864,3 +864,77 @@ func TestSubscriptionAuth_SameQueryDifferentClaimsAndExpiry_ShouldExpireIndepend
require.NoError(t, err)
require.Nil(t, res)
}

func TestSubscriptionAuthHeaderCaseInsensitive(t *testing.T) {
dg, err := testutil.DgraphClient(groupOnegRPC)
require.NoError(t, err)
testutil.DropAll(t, dg)

add := &common.GraphQLParams{
Query: `mutation updateGQLSchema($sch: String!) {
updateGQLSchema(input: { set: { schema: $sch }}) {
gqlSchema {
schema
}
}
}`,
Variables: map[string]interface{}{"sch": schAuth},
}
addResult := add.ExecuteAsPost(t, adminEndpoint)
require.Nil(t, addResult.Errors)
time.Sleep(time.Second * 2)

metaInfo := &testutil.AuthMeta{
PublicKey: "secret",
Namespace: "https://dgraph.io",
Algo: "HS256",
Header: "authorization",
}
metaInfo.AuthVars = map[string]interface{}{
"USER": "jatin",
"ROLE": "USER",
}

add = &common.GraphQLParams{
Query: `mutation{
addTodo(input: [
{text : "GraphQL is exciting!!",
owner : "jatin"}
])
{
todo{
text
owner
}
}
}`,
}

addResult = add.ExecuteAsPost(t, graphQLEndpoint)
require.Nil(t, addResult.Errors)

jwtToken, err := metaInfo.GetSignedToken("secret", 10*time.Second)
require.NoError(t, err)

payload := fmt.Sprintf(`{"Authorization": "%s"}`, jwtToken)
subscriptionClient, err := common.NewGraphQLSubscription(subscriptionEndpoint, &schema.Request{
Query: `subscription{
queryTodo{
owner
text
}
}`,
}, payload)
require.Nil(t, err)

res, err := subscriptionClient.RecvMsg()
require.NoError(t, err)

var resp common.GraphQLResponse
err = json.Unmarshal(res, &resp)
require.NoError(t, err)

require.Nil(t, resp.Errors)
require.JSONEq(t, `{"queryTodo":[{"owner":"jatin","text":"GraphQL is exciting!!"}]}`,
string(resp.Data))
}
21 changes: 14 additions & 7 deletions graphql/web/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,13 @@ import (
"encoding/json"
"github.com/dgrijalva/jwt-go/v4"
"google.golang.org/grpc/metadata"
"strconv"
"time"

"io"
"io/ioutil"
"mime"
"net/http"
"strconv"
"strings"
"time"

"github.com/dgraph-io/dgraph/graphql/api"
"github.com/dgraph-io/dgraph/graphql/authorization"
Expand Down Expand Up @@ -119,7 +118,7 @@ type graphqlSubscription struct {

func (gs *graphqlSubscription) Subscribe(
ctx context.Context,
document string,
document,
operationName string,
variableValues map[string]interface{}) (payloads <-chan interface{},
err error) {
Expand All @@ -138,11 +137,19 @@ func (gs *graphqlSubscription) Subscribe(
}

name := authorization.GetHeader()
val, ok := payload[name].(string)
if ok {
var val interface{}
var key string
var ok bool
for key, val = range payload {
if strings.EqualFold(key, name) {
ok = true
break
}
}

if ok {
md := metadata.New(map[string]string{
"authorizationJwt": val,
"authorizationJwt": val.(string),
})
ctx = metadata.NewIncomingContext(ctx, md)

Expand Down