* addUserFilterToQuery applies makes sure that a user can access only its own acl info by applying filter of userid and groupid to acl predicates. A query like Conversion pattern: - me(func: type(dgraph.type.Group)) -> me(func: type(dgraph.type.Group)) @filter(eq("dgraph.xid", groupIds...))
(gq *dql.GraphQuery, userId string, groupIds []string)
| 1180 | me(func: type(dgraph.type.User)) @filter(eq("dgraph.xid", userId)) |
| 1181 | */ |
| 1182 | func addUserFilterToQuery(gq *dql.GraphQuery, userId string, groupIds []string) { |
| 1183 | if gq.Func != nil && gq.Func.Name == "type" { |
| 1184 | // type function only supports one argument |
| 1185 | if len(gq.Func.Args) != 1 { |
| 1186 | return |
| 1187 | } |
| 1188 | arg := gq.Func.Args[0] |
| 1189 | // The case where value of some varialble v (say) is "dgraph.type.Group" and a |
| 1190 | // query comes like `eq(dgraph.type, val(v))`, will be ignored here. |
| 1191 | if arg.Value == "dgraph.type.User" { |
| 1192 | newFilter := userFilter(userId) |
| 1193 | gq.Filter = parentFilter(newFilter, gq.Filter) |
| 1194 | } else if arg.Value == "dgraph.type.Group" { |
| 1195 | newFilter := groupFilter(groupIds) |
| 1196 | gq.Filter = parentFilter(newFilter, gq.Filter) |
| 1197 | } |
| 1198 | } |
| 1199 | |
| 1200 | gq.Filter = addUserFilterToFilter(gq.Filter, userId, groupIds) |
| 1201 | |
| 1202 | switch gq.Attr { |
| 1203 | case "dgraph.user.group": |
| 1204 | newFilter := groupFilter(groupIds) |
| 1205 | gq.Filter = parentFilter(newFilter, gq.Filter) |
| 1206 | case "~dgraph.user.group": |
| 1207 | newFilter := userFilter(userId) |
| 1208 | gq.Filter = parentFilter(newFilter, gq.Filter) |
| 1209 | } |
| 1210 | |
| 1211 | for _, ch := range gq.Children { |
| 1212 | addUserFilterToQuery(ch, userId, groupIds) |
| 1213 | } |
| 1214 | } |
| 1215 | |
| 1216 | func parentFilter(newFilter, filter *dql.FilterTree) *dql.FilterTree { |
| 1217 | if filter == nil { |
no test coverage detected