Skip to content

feat(graphql): adding auth token support for regexp, in and arrays #7039

New issue

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

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

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
Dec 14, 2020
Merged
85 changes: 84 additions & 1 deletion graphql/e2e/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,17 @@ import (
"context"
"encoding/json"
"fmt"
"net/http"
"os"
"strings"
"testing"

"github.com/dgrijalva/jwt-go/v4"

"github.com/google/go-cmp/cmp/cmpopts"

"github.com/dgraph-io/dgraph/graphql/e2e/common"
"github.com/dgraph-io/dgraph/testutil"
"github.com/dgrijalva/jwt-go/v4"
"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)
Expand Down Expand Up @@ -1890,3 +1892,84 @@ func TestAuthWithSecretDirective(t *testing.T) {
require.JSONEq(t, `{"checkLogPassword": null}`, string(gqlResponse.Data))
deleteLog(t, logID)
}

func TestAuthRBACEvaluation(t *testing.T) {
query := `query {
queryBook{
bookId
name
desc
}
}`
tcs := []struct {
name string
header http.Header
}{
{
name: "Test Auth Eq Filter With Object As Token Val",
header: common.GetJWT(t, map[string]interface{}{"a": "b"}, nil, metaInfo),
},
{
name: "Test Auth Eq Filter With Float Token Val",
header: common.GetJWT(t, 123.12, nil, metaInfo),
},
{
name: "Test Auth Eq Filter With Int64 Token Val",
header: common.GetJWT(t, 1237890123456, nil, metaInfo),
},
{
name: "Test Auth Eq Filter With Int Token Val",
header: common.GetJWT(t, 1234, nil, metaInfo),
},
{
name: "Test Auth Eq Filter With Bool Token Val",
header: common.GetJWT(t, true, nil, metaInfo),
},
{
name: "Test Auth In Filter With Object As Token Val",
header: common.GetJWT(t, map[string]interface{}{"e": "f"}, nil, metaInfo),
},
{
name: "Test Auth In Filter With Float Token Val",
header: common.GetJWT(t, 312.124, nil, metaInfo),
},
{
name: "Test Auth In Filter With Int64 Token Val",
header: common.GetJWT(t, 1246879976444232435, nil, metaInfo),
},
{
name: "Test Auth In Filter With Int Token Val",
header: common.GetJWT(t, 6872, nil, metaInfo),
},
{
name: "Test Auth Eq Filter From Token With Array Val",
header: common.GetJWT(t, []int{456, 1234}, nil, metaInfo),
},
{
name: "Test Auth In Filter From Token With Array Val",
header: common.GetJWT(t, []int{124324, 6872}, nil, metaInfo),
},
{
name: "Test Auth Regex Filter",
header: common.GetJWT(t, "xyz@dgraph.io", nil, metaInfo),
},
{
name: "Test Auth Regex Filter From Token With Array Val",
header: common.GetJWT(t, []string{"abc@def.com", "xyz@dgraph.io"}, nil, metaInfo),
},
}
bookResponse := `{"queryBook":[{"bookId":"book1","name":"Introduction","desc":"Intro book"}]}`
for _, tc := range tcs {
t.Run(tc.name, func(t *testing.T) {
queryParams := &common.GraphQLParams{
Headers: tc.header,
Query: query,
}

gqlResponse := queryParams.ExecuteAsPost(t, common.GraphqlURL)
common.RequireNoGQLErrors(t, gqlResponse)
require.JSONEq(t, string(gqlResponse.Data), bookResponse)
})

}
}
21 changes: 21 additions & 0 deletions graphql/e2e/auth/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -754,3 +754,24 @@ type Todo {
owner: String
text: String
}

type Book @auth(
query: { or: [
{rule: "{$USER: { eq: {\"a\": \"b\"} } }"}, # this will be used to test eq with object
{rule: "{$USER: { eq: 123.12 } }"}, # this will be used to test eq with float
{rule: "{$USER: { eq: 1237890123456 } }"}, # this will be used to test eq with int64
{rule: "{$USER: { eq: 1234 } }"}, # this will be used to test eq with int and array too
{rule: "{$USER: { eq: true } }"}, # this will be used to test eq with boolean

{rule: "{$USER: { in: [{\"c\": \"d\"}, {\"e\":\"f\"}] } }"}, # this will be used to test in with object
{rule: "{$USER: { in: [456.23, 312.124] } }"}, # this will be used to test in with float
{rule: "{$USER: { in: [9876543219876543, 1246879976444232435] } }"}, # this will be used to test in with int64
{rule: "{$USER: { in: [5678, 6872] } }"}, # this will be used to test in with int and array too

{rule: "{$USER: { regexp: \"^(.*)@dgraph.io$\" } }"}
]}
){
bookId: String!
name: String!
desc: String!
}
7 changes: 7 additions & 0 deletions graphql/e2e/auth/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -242,6 +242,13 @@
"UserSecret.aSecret": "Sensitive information",
"UserSecret.ownedBy": "user1"
},
{
"uid": "_:book1",
"dgraph.type": "Book",
"Book.bookId": "book1",
"Book.name": "Introduction",
"Book.desc": "Intro book"
},
{"uid":"_:Question1","Post.text":"A Question"},
{"uid":"_:Question2","Post.text":"B Question"},
{"uid":"_:Question3","Post.text":"C Question"},
Expand Down
10 changes: 5 additions & 5 deletions graphql/e2e/common/common.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import (
"testing"
"time"

"github.com/prometheus/common/log"
"github.com/golang/glog"

"github.com/dgraph-io/dgo/v200"
"github.com/dgraph-io/dgo/v200/protos/api"
Expand Down Expand Up @@ -509,7 +509,7 @@ func addSchemaAndData(schema, data []byte, client *dgo.Dgraph) {
}

if containsRetryableUpdateGQLSchemaError(err.Error()) {
log.Infof("Got error while addSchemaAndData: %v. Retrying...\n", err)
glog.Infof("Got error while addSchemaAndData: %v. Retrying...\n", err)
time.Sleep(time.Second)
continue
}
Expand Down Expand Up @@ -1158,13 +1158,13 @@ func addSchema(url, schema string) error {
return nil
}

func GetJWT(t *testing.T, user, role string, metaInfo *testutil.AuthMeta) http.Header {
func GetJWT(t *testing.T, user, role interface{}, metaInfo *testutil.AuthMeta) http.Header {
metaInfo.AuthVars = map[string]interface{}{}
if user != "" {
if user != nil {
metaInfo.AuthVars["USER"] = user
}

if role != "" {
if role != nil {
metaInfo.AuthVars["ROLE"] = role
}

Expand Down
Loading