diff --git a/graphql/e2e/auth/schema.graphql b/graphql/e2e/auth/schema.graphql index 403aa736264..28951209a20 100644 --- a/graphql/e2e/auth/schema.graphql +++ b/graphql/e2e/auth/schema.graphql @@ -522,3 +522,50 @@ query($USER: String!) { id: ID! email: String! @dgraph(pred: "IOw80vnV") @search(by: [hash]) } + +type Contact @auth( + query: { rule: "{$ContactRole: { eq: \"ADMINISTRATOR\"}}" } +) { + id: ID! + nickName: String @search(by: [exact, term, fulltext, regexp]) + adminTasks: [AdminTask] @hasInverse(field: forContact) + tasks: [Task] @hasInverse(field: forContact) +} + +type AdminTask @auth( + query: { rule: "{$TaskRole: { eq: \"ADMINISTRATOR\"}}" } +) { + id: ID! + name: String @search(by: [exact, term, fulltext, regexp]) + occurrances: [TaskOccurance] @hasInverse(field: adminTask) + forContact: Contact @hasInverse(field: adminTasks) +} + +type Task { + id: ID! + name: String @search(by: [exact, term, fulltext, regexp]) + occurrances: [TaskOccurance] @hasInverse(field: task) + forContact: Contact @hasInverse(field: tasks) +} + +type TaskOccurance @auth( + query: { and : [ + {rule: "{$TaskOccuranceRole: { eq: \"ADMINISTRATOR\"}}"}, + {rule: """ + query($TaskOccuranceRole: String!) { + queryTaskOccurance(filter: {role: { eq: $TaskOccuranceRole}}) { + __typename + } + } + """} +] } +) { + id: ID! + due: DateTime @search + comp: DateTime @search + task: Task @hasInverse(field: occurrances) + adminTask: AdminTask @hasInverse(field: occurrances) + isPublic: Boolean @search + role: String @search(by: [exact, term, fulltext, regexp]) +} + diff --git a/graphql/resolve/auth_add_test.yaml b/graphql/resolve/auth_add_test.yaml index 177a82ba8ef..2c8c78d81d6 100644 --- a/graphql/resolve/auth_add_test.yaml +++ b/graphql/resolve/auth_add_test.yaml @@ -7,6 +7,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "secret": { "aSecret": "it is", @@ -35,6 +37,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "secrets": [ @@ -64,6 +68,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "secret": { "aSecret": "it is", @@ -94,6 +100,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "secrets": [ @@ -125,6 +133,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col": { "inProject": { "projID": "0x123" }, @@ -191,6 +201,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col": { @@ -257,6 +269,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col1": { "inProject": { "projID": "0x123" }, @@ -334,6 +348,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col1": { "inProject": { "projID": "0x123" }, @@ -418,6 +434,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col": { "inProject": { "projID": "0x123" }, @@ -493,6 +511,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "col": { "inProject": { "projID": "0x123" }, @@ -569,6 +589,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "proj": { @@ -658,6 +680,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "proj": { @@ -748,6 +772,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "log": { "logs": "log123", @@ -769,7 +795,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "log": { "logs": "log123", @@ -789,7 +817,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "proj": { @@ -811,7 +841,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "proj": { @@ -850,7 +882,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "issue": { "msg": "log123", @@ -900,7 +934,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "issue": { "msg": "log123", @@ -950,7 +986,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "log": { "logs": "log123", @@ -971,7 +1009,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "log": { "logs": "log123", diff --git a/graphql/resolve/auth_delete_test.yaml b/graphql/resolve/auth_delete_test.yaml index 14370f9311b..f8837eb2e2a 100644 --- a/graphql/resolve/auth_delete_test.yaml +++ b/graphql/resolve/auth_delete_test.yaml @@ -5,6 +5,8 @@ msg } } + jwtvar: + USER: "user1" variables: | { "filter": { "aSecret": { "anyofterms": "auth is applied" } } } dgmutations: @@ -29,6 +31,8 @@ msg } } + jwtvar: + USER: "user1" variables: | { "filter": { "title": { "anyofterms": "auth is applied" } } } dgmutations: @@ -90,6 +94,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "filter": { "title": { "anyofterms": "auth is applied" } } } dgmutations: @@ -206,7 +212,9 @@ { "projs" : ["0x01", "0x02"] } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgmutations: - deletejson: | [{ @@ -244,7 +252,9 @@ "id": ["0x1", "0x2"] } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgmutations: - deletejson: | [{ @@ -269,6 +279,8 @@ "username": { "eq": "userxyz" } } } + jwtvar: + USER: "user1" dgmutations: - deletejson: | [ @@ -297,6 +309,8 @@ msg } } + jwtvar: + USER: "user1" variables: | { "filter": { @@ -331,7 +345,9 @@ "id": ["0x1", "0x2"] } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgmutations: - deletejson: | [{ @@ -359,7 +375,9 @@ "id": ["0x1", "0x2"] } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgmutations: - deletejson: | [{ @@ -392,7 +410,9 @@ { "ids" : ["0x01", "0x02"] } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgmutations: - deletejson: | [{ "uid": "uid(x)" }] @@ -416,6 +436,8 @@ { "ids" : ["0x01", "0x02"] } + jwtvar: + USER: "user1" dgmutations: - deletejson: | [{ "uid": "uid(x)" }] @@ -442,7 +464,9 @@ "id": ["0x1", "0x2"] } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgmutations: - deletejson: | [{ @@ -474,7 +498,9 @@ "id": ["0x1", "0x2"] } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgmutations: - deletejson: | [{ @@ -498,7 +524,9 @@ "id": ["0x1", "0x2"] } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgmutations: - deletejson: | [{ @@ -522,7 +550,9 @@ "id": ["0x1", "0x2"] } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgmutations: - deletejson: | [{ diff --git a/graphql/resolve/auth_query_test.yaml b/graphql/resolve/auth_query_test.yaml index ba4b50bb28b..c099f1913c3 100644 --- a/graphql/resolve/auth_query_test.yaml +++ b/graphql/resolve/auth_query_test.yaml @@ -1,3 +1,192 @@ +- name: "Deep RBAC rule - All level true" + gqlquery: | + query { + queryContact { + id + nickName + adminTasks { + id + name + occurrances { + due + comp + } + } + } + } + jwtvar: + ContactRole: ADMINISTRATOR + TaskRole: ADMINISTRATOR + TaskOccuranceRole: ADMINISTRATOR + dgquery: |- + query { + queryContact(func: uid(ContactRoot)) { + id : uid + nickName : Contact.nickName + adminTasks : Contact.adminTasks @filter(uid(AdminTask5)) { + id : uid + name : AdminTask.name + occurrances : AdminTask.occurrances @filter(uid(TaskOccurance4)) { + due : TaskOccurance.due + comp : TaskOccurance.comp + dgraph.uid : uid + } + } + } + ContactRoot as var(func: uid(Contact6)) + Contact6 as var(func: type(Contact)) + var(func: uid(ContactRoot)) { + AdminTask1 as Contact.adminTasks + } + AdminTask5 as var(func: uid(AdminTask1)) + var(func: uid(AdminTask1)) { + TaskOccurance2 as AdminTask.occurrances + } + TaskOccurance4 as var(func: uid(TaskOccurance2)) @filter(uid(TaskOccuranceAuth3)) + TaskOccuranceAuth3 as var(func: uid(TaskOccurance2)) @filter(eq(TaskOccurance.role, "ADMINISTRATOR")) @cascade + } + +- name: "Deep RBAC rule - Level 0 false" + gqlquery: | + query { + queryContact { + id + nickName + adminTasks { + id + name + occurrances { + due + comp + } + } + } + } + jwtvar: + ContactRole: User + TaskRole: ADMINISTRATOR + TaskOccuranceRole: ADMINISTRATOR + dgquery: |- + query { + queryContact() + } + +- name: "Deep RBAC rule - Level 1 false" + gqlquery: | + query { + queryContact { + id + nickName + adminTasks { + id + name + occurrances { + due + comp + } + } + } + } + jwtvar: + ContactRole: ADMINISTRATOR + TaskRole: User + TaskOccuranceRole: ADMINISTRATOR + dgquery: |- + query { + queryContact(func: uid(ContactRoot)) { + id : uid + nickName : Contact.nickName + } + ContactRoot as var(func: uid(Contact5)) + Contact5 as var(func: type(Contact)) + } + +- name: "Deep RBAC rule - Level 2 false" + gqlquery: | + query { + queryContact { + id + nickName + adminTasks { + id + name + occurrances { + due + comp + } + } + } + } + jwtvar: + ContactRole: ADMINISTRATOR + TaskRole: ADMINISTRATOR + TaskOccuranceRole: User + dgquery: |- + query { + queryContact(func: uid(ContactRoot)) { + id : uid + nickName : Contact.nickName + adminTasks : Contact.adminTasks @filter(uid(AdminTask3)) { + id : uid + name : AdminTask.name + } + } + ContactRoot as var(func: uid(Contact4)) + Contact4 as var(func: type(Contact)) + var(func: uid(ContactRoot)) { + AdminTask1 as Contact.adminTasks + } + AdminTask3 as var(func: uid(AdminTask1)) + } + +- name: "Deep RBAC rule - Level 1 type without auth." + gqlquery: | + query { + queryContact { + id + nickName + tasks { + id + name + occurrances { + due + comp + } + } + } + } + jwtvar: + ContactRole: ADMINISTRATOR + TaskRole: ADMINISTRATOR + TaskOccuranceRole: ADMINISTRATOR + dgquery: |- + query { + queryContact(func: uid(ContactRoot)) { + id : uid + nickName : Contact.nickName + tasks : Contact.tasks @filter(uid(Task5)) { + id : uid + name : Task.name + occurrances : Task.occurrances @filter(uid(TaskOccurance4)) { + due : TaskOccurance.due + comp : TaskOccurance.comp + dgraph.uid : uid + } + } + } + ContactRoot as var(func: uid(Contact6)) + Contact6 as var(func: type(Contact)) + var(func: uid(ContactRoot)) { + Task1 as Contact.tasks + } + Task5 as var(func: uid(Task1)) + var(func: uid(Task1)) { + TaskOccurance2 as Task.occurrances + } + TaskOccurance4 as var(func: uid(TaskOccurance2)) @filter(uid(TaskOccuranceAuth3)) + TaskOccuranceAuth3 as var(func: uid(TaskOccurance2)) @filter(eq(TaskOccurance.role, "ADMINISTRATOR")) @cascade + } + - name: "Auth query with @dgraph pred." gqlquery: | query { @@ -5,7 +194,9 @@ email } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { queryStudent(func: uid(StudentRoot)) { @@ -24,7 +215,9 @@ email } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryStudent() @@ -41,6 +234,8 @@ } } } + jwtvar: + USER: "user1" dgquery: |- query { getProject(func: uid(ProjectRoot)) @filter(type(Project)) { @@ -83,6 +278,8 @@ ownedBy } } + jwtvar: + USER: "user1" dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot)) { @@ -102,6 +299,8 @@ ownedBy } } + jwtvar: + USER: "user1" dgquery: |- query { getUserSecret(func: uid(UserSecretRoot)) @filter(type(UserSecret)) { @@ -121,6 +320,8 @@ ownedBy } } + jwtvar: + USER: "user1" dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot)) { @@ -141,26 +342,28 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- - query { - queryUser(func: uid(UserRoot)) { - issues : User.issues @filter(uid(Issue3)) { - id : uid - } - dgraph.uid : uid - } - UserRoot as var(func: uid(User4)) - User4 as var(func: type(User)) - var(func: uid(UserRoot)) { - Issue1 as User.issues - } - Issue3 as var(func: uid(Issue1)) @filter(uid(IssueAuth2)) - IssueAuth2 as var(func: uid(Issue1)) @cascade { - owner : Issue.owner @filter(eq(User.username, "user1")) - dgraph.uid : uid + query { + queryUser(func: uid(UserRoot)) { + issues : User.issues @filter(uid(Issue3)) { + id : uid } + dgraph.uid : uid } + UserRoot as var(func: uid(User4)) + User4 as var(func: type(User)) + var(func: uid(UserRoot)) { + Issue1 as User.issues + } + Issue3 as var(func: uid(Issue1)) @filter(uid(IssueAuth2)) + IssueAuth2 as var(func: uid(Issue1)) @cascade { + owner : Issue.owner @filter(eq(User.username, "user1")) + dgraph.uid : uid + } + } - name: "Deep RBAC rules false" gqlquery: | @@ -172,7 +375,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryUser(func: uid(UserRoot)) { @@ -191,7 +396,9 @@ msg } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { queryIssue(func: uid(IssueRoot)) { @@ -213,7 +420,9 @@ logs } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { queryComplexLog(func: uid(ComplexLogRoot)) { @@ -231,7 +440,9 @@ logs } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryComplexLog() @@ -244,7 +455,9 @@ logs } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { queryLog(func: uid(LogRoot)) { @@ -262,7 +475,9 @@ logs } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryLog() @@ -275,7 +490,9 @@ msg } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryIssue() @@ -289,7 +506,9 @@ name } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { queryProject(func: uid(ProjectRoot)) { @@ -307,6 +526,8 @@ id } } + jwtvar: + USER: "user1" dgquery: |- query { queryGroup(func: uid(GroupRoot)) { @@ -331,7 +552,9 @@ name } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { queryProject(func: uid(ProjectRoot)) { @@ -357,6 +580,8 @@ ownedBy } } + jwtvar: + USER: "user1" dgquery: |- query { queryUserSecret(func: uid(UserSecretRoot), orderasc: UserSecret.aSecret) { @@ -376,6 +601,8 @@ title } } + jwtvar: + USER: "user1" dgquery: |- query { queryTicket(func: uid(TicketRoot)) { @@ -410,6 +637,8 @@ } } } + jwtvar: + USER: "user1" dgquery: |- query { queryUser(func: uid(UserRoot)) { @@ -452,6 +681,8 @@ } } } + jwtvar: + USER: "user1" dgquery: |- query { queryUser(func: uid(UserRoot)) { @@ -490,6 +721,8 @@ content } } + jwtvar: + USER: "user1" dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) { @@ -523,6 +756,8 @@ } } } + jwtvar: + USER: "user1" dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) @cascade { @@ -574,6 +809,8 @@ } } } + jwtvar: + USER: "user1" dgquery: |- query { queryMovie(func: uid(MovieRoot), orderasc: Movie.content) { @@ -632,6 +869,8 @@ content } } + jwtvar: + USER: "user1" dgquery: |- query { queryMovie(func: uid(MovieRoot)) { @@ -673,6 +912,8 @@ id } } + jwtvar: + USER: "user1" dgquery: |- query { getLog() @@ -706,7 +947,8 @@ name } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" dgquery: |- query { queryProject(func: uid(ProjectRoot)) { diff --git a/graphql/resolve/auth_test.go b/graphql/resolve/auth_test.go index 8d899d27612..018f76cf1e7 100644 --- a/graphql/resolve/auth_test.go +++ b/graphql/resolve/auth_test.go @@ -28,6 +28,7 @@ import ( "google.golang.org/grpc/metadata" dgoapi "github.com/dgraph-io/dgo/v200/protos/api" + "github.com/dgraph-io/dgraph/gql" "github.com/dgraph-io/dgraph/graphql/authorization" "github.com/dgraph-io/dgraph/graphql/dgraph" "github.com/dgraph-io/dgraph/graphql/schema" @@ -42,9 +43,8 @@ import ( type AuthQueryRewritingCase struct { Name string - // Values to come in the JWT - User string - Role string + // JWT variables + JWTVar map[string]interface{} // GQL query and variables GQLQuery string @@ -318,13 +318,10 @@ func queryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMeta) { require.NoError(t, err) gqlQuery := test.GetQuery(t, op) - authMeta.AuthVars = map[string]interface{}{ - "ROLE": tcase.Role, - } - - // Skipping $USER for specific rules. - if !strings.HasPrefix(tcase.Name, "Query with missing variable") { - authMeta.AuthVars["USER"] = "user1" + // Clear the map and initialize it. + authMeta.AuthVars = make(map[string]interface{}) + for k, v := range tcase.JWTVar { + authMeta.AuthVars[k] = v } ctx := context.Background() @@ -336,6 +333,10 @@ func queryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMeta) { dgQuery, err := testRewriter.Rewrite(ctx, gqlQuery) require.Nil(t, err) require.Equal(t, tcase.DGQuery, dgraph.AsString(dgQuery)) + + // Check for unused variables. + _, err = gql.Parse(gql.Request{Str: dgraph.AsString(dgQuery)}) + require.NoError(t, err) }) } } @@ -488,6 +489,10 @@ func mutationQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMet // -- Assert -- require.Nil(t, err) require.Equal(t, tt.dgQuery, dgraph.AsString(dgQuery)) + + // Check for unused variables. + _, err = gql.Parse(gql.Request{Str: dgraph.AsString(dgQuery)}) + require.NoError(t, err) }) } @@ -538,13 +543,12 @@ func deleteQueryRewriting(t *testing.T, sch string, authMeta *testutil.AuthMeta) mut := test.GetMutation(t, op) rewriterToTest := NewDeleteRewriter() - authMeta.AuthVars = map[string]interface{}{ - "USER": "user1", + // Clear the map and initialize it. + authMeta.AuthVars = make(map[string]interface{}) + for k, v := range tcase.JWTVar { + authMeta.AuthVars[k] = v } - if tcase.Role != "" { - authMeta.AuthVars["ROLE"] = tcase.Role - } ctx, err := authMeta.AddClaimsToContext(context.Background()) require.NoError(t, err) @@ -650,10 +654,12 @@ func checkAddUpdateCase( require.NoError(t, err) mut := test.GetMutation(t, op) - authMeta.AuthVars = map[string]interface{}{ - "USER": "user1", - "ROLE": tcase.Role, + // Clear the map and initialize it. + authMeta.AuthVars = make(map[string]interface{}) + for k, v := range tcase.JWTVar { + authMeta.AuthVars[k] = v } + ctx, err := authMeta.AddClaimsToContext(context.Background()) require.NoError(t, err) diff --git a/graphql/resolve/auth_tests.yaml b/graphql/resolve/auth_tests.yaml index 5deb5a865eb..69170db2286 100644 --- a/graphql/resolve/auth_tests.yaml +++ b/graphql/resolve/auth_tests.yaml @@ -7,7 +7,9 @@ isPublic } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -20,7 +22,9 @@ name } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -34,7 +38,9 @@ msg } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -47,7 +53,9 @@ name } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -60,7 +68,9 @@ title } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -73,7 +83,9 @@ logs } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -94,7 +106,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -109,7 +123,9 @@ disabled } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -130,7 +146,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" dgquery: |- query { } @@ -143,7 +161,9 @@ name } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -157,7 +177,9 @@ msg } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -170,7 +192,9 @@ name } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -183,7 +207,9 @@ title } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -196,7 +222,9 @@ logs } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -217,7 +245,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -232,7 +262,9 @@ disabled } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } @@ -253,7 +285,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" dgquery: |- query { } diff --git a/graphql/resolve/auth_update_test.yaml b/graphql/resolve/auth_update_test.yaml index 70e7323da4e..cccd7b236fa 100644 --- a/graphql/resolve/auth_update_test.yaml +++ b/graphql/resolve/auth_update_test.yaml @@ -7,6 +7,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { "filter": { "id": [ "0x123" ] }, @@ -34,6 +36,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -101,6 +105,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -171,6 +177,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -238,6 +246,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -306,6 +316,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -375,6 +387,8 @@ } } } + jwtvar: + USER: "user1" variables: | { "upd": { @@ -445,7 +459,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "log": { @@ -470,7 +486,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "log": { @@ -499,7 +517,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "proj": { @@ -534,7 +554,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "proj": { @@ -562,7 +584,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "issue": { @@ -594,7 +618,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "issue": { @@ -618,7 +644,9 @@ } } } - role: "ADMIN" + jwtvar: + ROLE: "ADMIN" + USER: "user1" variables: | { "log": { @@ -646,7 +674,9 @@ } } } - role: "USER" + jwtvar: + ROLE: "USER" + USER: "user1" variables: | { "log": { diff --git a/graphql/resolve/query_rewriter.go b/graphql/resolve/query_rewriter.go index 3e17592f998..21cde2e5fa1 100644 --- a/graphql/resolve/query_rewriter.go +++ b/graphql/resolve/query_rewriter.go @@ -735,11 +735,19 @@ func addSelectionSetFrom( q.Children = append(q.Children, child) } - if rbac != schema.Uncertain { + // If RBAC rules are evaluated to Negative, we don't write queries for deeper levels. + // Hence we don't need to do any further processing for this field. + if rbac == schema.Negative { continue } - fieldAuth, authFilter := auth.rewriteAuthQueries(f.Type()) + var fieldAuth []*gql.GraphQuery + var authFilter *gql.FilterTree + // If RBAC rules are evaluated to `Uncertain` then we add the Auth rules. + if rbac == schema.Uncertain { + fieldAuth, authFilter = auth.rewriteAuthQueries(f.Type()) + } + if authFilter != nil { if child.Filter == nil { child.Filter = authFilter