Skip to content

Commit

Permalink
fix(GraphQl): Allow case insensitive auth header for graphql subscrip…
Browse files Browse the repository at this point in the history
…tions. (#6141)

This PR allows case insensitive auth header for graphql subscriptions.
  • Loading branch information
JatinDev543 committed Aug 12, 2020
1 parent 0b4cd73 commit d807eb7
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 10 deletions.
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))
}
22 changes: 12 additions & 10 deletions graphql/web/http.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,16 +20,13 @@ import (
"compress/gzip"
"context"
"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 All @@ -38,9 +35,11 @@ import (
"github.com/dgraph-io/dgraph/graphql/subscription"
"github.com/dgraph-io/dgraph/x"
"github.com/dgraph-io/graphql-transport-ws/graphqlws"
"github.com/dgrijalva/jwt-go/v4"
"github.com/golang/glog"
"github.com/pkg/errors"
"go.opencensus.io/trace"
"google.golang.org/grpc/metadata"
)

type Headerkey string
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,19 +137,22 @@ func (gs *graphqlSubscription) Subscribe(
}

name := authorization.GetHeader()
val, ok := payload[name].(string)
if ok {
for key, val := range payload {
if !strings.EqualFold(key, name) {
continue
}

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

customClaims, err = authorization.ExtractCustomClaims(ctx)
if err != nil {
return nil, err
}
break
}

}
// for the cases when no expiry is given in jwt or subscription doesn't have any authorization,
// we set their expiry to zero time
Expand Down

0 comments on commit d807eb7

Please sign in to comment.