Skip to content

Commit

Permalink
graphql: Added RBAC and related tests (#5392)
Browse files Browse the repository at this point in the history
* added rbac

* fixed some tests
  • Loading branch information
harshil-goel authored May 10, 2020
1 parent 1b311d5 commit f9d8509
Show file tree
Hide file tree
Showing 7 changed files with 441 additions and 46 deletions.
140 changes: 107 additions & 33 deletions graphql/e2e/auth/auth_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
"os"
"testing"

Expand Down Expand Up @@ -112,20 +113,59 @@ type uidResult struct {
}
}

func getJWT(t *testing.T, user, role string) string {
metaInfo.AuthVars = map[string]interface{}{
"USER": user,
"ROLE": role,
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")
require.NoError(t, err)
return jwtToken

h := make(http.Header)
h.Add(metaInfo.Header, jwtToken)
return h
}

func TestOrRBACFilter(t *testing.T) {
t.Skip()
testCases := []TestCase{}
testCases := []TestCase{{
user: "user1",
role: "ADMIN",
result: `{
"queryProject": [
{
"name": "Project1"
},
{
"name": "Project2"
}
]
}`,
}, {
user: "user1",
role: "USER",
result: `{
"queryProject": [
{
"name": "Project1"
}
]
}`,
}, {
user: "user4",
role: "USER",
result: `{
"queryProject": [
{
"name": "Project2"
}
]
}`,
}}

query := `
query {
Expand All @@ -138,10 +178,9 @@ func TestOrRBACFilter(t *testing.T) {
for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand All @@ -166,11 +205,10 @@ func getColID(t *testing.T, tcase TestCase) string {
}

getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
Variables: map[string]interface{}{"name": tcase.name},
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down Expand Up @@ -220,11 +258,10 @@ func TestRootGetFilter(t *testing.T) {
for _, tcase := range tcases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
Variables: map[string]interface{}{"id": tcase.name},
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down Expand Up @@ -266,11 +303,10 @@ func TestDeepFilter(t *testing.T) {
for _, tcase := range tcases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
Variables: map[string]interface{}{"name": tcase.name},
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down Expand Up @@ -298,16 +334,46 @@ func TestRootFilter(t *testing.T) {
queryColumn(order: {asc: name}) {
name
}
}`

for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)

require.JSONEq(t, string(gqlResponse.Data), tcase.result)
})
}
}

func TestDeepRBACValue(t *testing.T) {
testCases := []TestCase{
{user: "user1", role: "USER", result: `{"queryUser": [{"username": "user1", "issues":[]}]}`},
{user: "user1", role: "ADMIN", result: `{"queryUser":[{"username":"user1","issues":[{"msg":"Issue1"}]}]}`},
}

query := `
{
queryUser (filter:{username:{eq:"user1"}}) {
username
issues {
msg
}
}
}
`

for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand All @@ -318,8 +384,11 @@ func TestRootFilter(t *testing.T) {
}

func TestRBACFilter(t *testing.T) {
t.Skip()
testCases := []TestCase{}
testCases := []TestCase{
{role: "USER", result: `{"queryLog": []}`},
{result: `{"queryLog": []}`},
{role: "ADMIN", result: `{"queryLog": [{"logs": "Log1"},{"logs": "Log2"}]}`}}

query := `
query {
queryLog (order: {asc: logs}) {
Expand All @@ -331,10 +400,9 @@ func TestRBACFilter(t *testing.T) {
for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand All @@ -345,8 +413,19 @@ func TestRBACFilter(t *testing.T) {
}

func TestAndRBACFilter(t *testing.T) {
t.Skip()
testCases := []TestCase{}
testCases := []TestCase{{
user: "user1",
role: "USER",
result: `{"queryIssue": []}`,
}, {
user: "user2",
role: "USER",
result: `{"queryIssue": []}`,
}, {
user: "user2",
role: "ADMIN",
result: `{"queryIssue": [{"msg": "Issue2"}]}`,
}}
query := `
query {
queryIssue (order: {asc: msg}) {
Expand All @@ -358,18 +437,16 @@ func TestAndRBACFilter(t *testing.T) {
for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)

require.JSONEq(t, string(gqlResponse.Data), tcase.result)
})
}

}

func TestNestedFilter(t *testing.T) {
Expand Down Expand Up @@ -456,10 +533,9 @@ func TestNestedFilter(t *testing.T) {
for _, tcase := range testCases {
t.Run(tcase.role+tcase.user, func(t *testing.T) {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down Expand Up @@ -504,13 +580,12 @@ func TestDeleteAuthRule(t *testing.T) {

for _, tcase := range testCases {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
Variables: map[string]interface{}{
"filter": tcase.filter,
},
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down Expand Up @@ -540,7 +615,7 @@ func AddDeleteDeepAuthTestData(t *testing.T) {
require.NoError(t, err)

userQuery := `{
query(func: type(User)) @filter(eq(User.username, "user1") or eq(User.username, "user3") or
query(func: type(User)) @filter(eq(User.username, "user1") or eq(User.username, "user3") or
eq(User.username, "user5") ) {
uid
} }`
Expand Down Expand Up @@ -615,13 +690,12 @@ func TestDeleteDeepAuthRule(t *testing.T) {

for _, tcase := range testCases {
getUserParams := &common.GraphQLParams{
Headers: map[string][]string{},
Headers: getJWT(t, tcase.user, tcase.role),
Query: query,
Variables: map[string]interface{}{
"filter": tcase.filter,
},
}
getUserParams.Headers.Add(metaInfo.Header, getJWT(t, tcase.user, tcase.role))

gqlResponse := getUserParams.ExecuteAsPost(t, graphqlURL)
require.Nil(t, gqlResponse.Errors)
Expand Down
16 changes: 15 additions & 1 deletion graphql/e2e/auth/schema.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ type User @auth(
disabled: Boolean
tickets: [Ticket] @hasInverse(field: assignedTo)
secrets: [UserSecret]
issues: [Issue]
}

type UserSecret @auth(
Expand Down Expand Up @@ -131,8 +132,19 @@ type Log @auth(
logs: String
}

type ComplexLog @auth(
query: { and : [
{ rule: "{$ROLE: { eq: \"ADMIN\" }}" },
{ not : { rule: "{$ROLE: { eq: \"USER\" }}" }}
]}
) {
id: ID!
logs: String
}

type Project @auth(
query: { rule: """query($USER: String!) {
query: { or: [
{ rule: """query($USER: String!) {
queryProject {
roles(filter: { permission: { eq: VIEW } }) {
assignedTo(filter: { username: { eq: $USER } }) {
Expand All @@ -141,6 +153,8 @@ type Project @auth(
}
}
}""" },
{ rule: "{$ROLE: { eq: \"ADMIN\" }}" }
]}
) {
projID: ID!
name: String!
Expand Down
6 changes: 4 additions & 2 deletions graphql/e2e/auth/test_data.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
"User.age": 10,
"User.username": "user1",
"User.isPublic": true,
"User.disabled": false
"User.disabled": false,
"User.issues": [{"uid": "_:issue1"}]
},
{
"uid": "_:user2",
"dgraph.type": "User",
"User.age": 11,
"User.username": "user2",
"User.isPublic": true,
"User.disabled": true
"User.disabled": true,
"User.issues": [{"uid": "_:issue2"}]
},
{
"uid": "_:user3",
Expand Down
Loading

0 comments on commit f9d8509

Please sign in to comment.