@@ -5,6 +5,7 @@ import Deprecator from './Deprecator/Deprecator';
5
5
import { logger } from './logger' ;
6
6
import RestQuery from './RestQuery' ;
7
7
import RestWrite from './RestWrite' ;
8
+ import MongoStorageAdapter from './Adapters/Storage/Mongo/MongoStorageAdapter' ;
8
9
9
10
// An Auth object tells you who is requesting something and whether
10
11
// the master key was used.
@@ -139,7 +140,6 @@ const getAuthForSessionToken = async function ({
139
140
limit : 1 ,
140
141
include : 'user' ,
141
142
} ;
142
- const RestQuery = require ( './RestQuery' ) ;
143
143
const query = new RestQuery ( config , master ( config ) , '_Session' , { sessionToken } , restOptions ) ;
144
144
results = ( await query . execute ( ) ) . results ;
145
145
} else {
@@ -183,7 +183,6 @@ var getAuthForLegacySessionToken = function ({ config, sessionToken, installatio
183
183
var restOptions = {
184
184
limit : 1 ,
185
185
} ;
186
- const RestQuery = require ( './RestQuery' ) ;
187
186
var query = new RestQuery ( config , master ( config ) , '_User' , { sessionToken } , restOptions ) ;
188
187
return query . execute ( ) . then ( response => {
189
188
var results = response . results ;
@@ -221,17 +220,113 @@ Auth.prototype.getRolesForUser = async function () {
221
220
//Stack all Parse.Role
222
221
const results = [ ] ;
223
222
if ( this . config ) {
224
- const restWhere = {
225
- users : {
226
- __type : 'Pointer' ,
227
- className : '_User' ,
228
- objectId : this . user . id ,
229
- } ,
230
- } ;
231
- const RestQuery = require ( './RestQuery' ) ;
232
- await new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) . each ( result =>
233
- results . push ( result )
234
- ) ;
223
+ if ( this . config . database . adapter instanceof MongoStorageAdapter ) {
224
+ const prefix = this . config . databaseAdapter . _collectionPrefix || '' ;
225
+ const result = await new RestQuery (
226
+ this . config ,
227
+ master ( this . config ) ,
228
+ '_Join:users:_Role' ,
229
+ { } ,
230
+ {
231
+ pipeline : [
232
+ {
233
+ $match : {
234
+ relatedId : this . user . id ,
235
+ } ,
236
+ } ,
237
+ {
238
+ $graphLookup : {
239
+ from : `${ prefix } _Join:roles:_Role` ,
240
+ startWith : '$owningId' ,
241
+ connectFromField : 'owningId' ,
242
+ connectToField : 'relatedId' ,
243
+ as : 'childRolePath' ,
244
+ } ,
245
+ } ,
246
+ {
247
+ $facet : {
248
+ directRoles : [
249
+ {
250
+ $lookup : {
251
+ from : `${ prefix } _Role` ,
252
+ localField : 'owningId' ,
253
+ foreignField : '_id' ,
254
+ as : 'Roles' ,
255
+ } ,
256
+ } ,
257
+ {
258
+ $unwind : {
259
+ path : '$Roles' ,
260
+ } ,
261
+ } ,
262
+ {
263
+ $replaceRoot : {
264
+ newRoot : {
265
+ $ifNull : [ '$Roles' , { $literal : { } } ] ,
266
+ } ,
267
+ } ,
268
+ } ,
269
+ {
270
+ $project : {
271
+ name : 1 ,
272
+ } ,
273
+ } ,
274
+ ] ,
275
+ childRoles : [
276
+ {
277
+ $lookup : {
278
+ from : `${ prefix } _Role` ,
279
+ localField : 'childRolePath.owningId' ,
280
+ foreignField : '_id' ,
281
+ as : 'Roles' ,
282
+ } ,
283
+ } ,
284
+ {
285
+ $unwind : {
286
+ path : '$Roles' ,
287
+ } ,
288
+ } ,
289
+ {
290
+ $replaceRoot : {
291
+ newRoot : {
292
+ $ifNull : [ '$Roles' , { $literal : { } } ] ,
293
+ } ,
294
+ } ,
295
+ } ,
296
+ {
297
+ $project : {
298
+ name : 1 ,
299
+ } ,
300
+ } ,
301
+ ] ,
302
+ } ,
303
+ } ,
304
+ ] ,
305
+ }
306
+ ) . execute ( ) ;
307
+ const { directRoles, childRoles } = result . results [ 0 ] || {
308
+ directRoles : [ ] ,
309
+ childRoles : [ ] ,
310
+ } ;
311
+ const roles = [ ...directRoles , ...childRoles ] ;
312
+ for ( const role of roles ) {
313
+ const roleName = `role:${ role . name } ` ;
314
+ if ( ! results . includes ( roleName ) ) {
315
+ results . push ( role ) ;
316
+ }
317
+ }
318
+ } else {
319
+ const restWhere = {
320
+ users : {
321
+ __type : 'Pointer' ,
322
+ className : '_User' ,
323
+ objectId : this . user . id ,
324
+ } ,
325
+ } ;
326
+ await new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) . each ( result =>
327
+ results . push ( result )
328
+ ) ;
329
+ }
235
330
} else {
236
331
await new Parse . Query ( Parse . Role )
237
332
. equalTo ( 'users' , this . user )
@@ -257,25 +352,29 @@ Auth.prototype._loadRoles = async function () {
257
352
this . userRoles = [ ] ;
258
353
this . fetchedRoles = true ;
259
354
this . rolePromise = null ;
260
-
261
355
this . cacheRoles ( ) ;
262
356
return this . userRoles ;
263
357
}
264
358
265
- const rolesMap = results . reduce (
266
- ( m , r ) => {
267
- m . names . push ( r . name ) ;
268
- m . ids . push ( r . objectId ) ;
269
- return m ;
270
- } ,
271
- { ids : [ ] , names : [ ] }
272
- ) ;
359
+ if ( typeof results [ 0 ] === 'object' ) {
360
+ const rolesMap = results . reduce (
361
+ ( m , r ) => {
362
+ m . names . push ( r . name ) ;
363
+ m . ids . push ( r . objectId ) ;
364
+ return m ;
365
+ } ,
366
+ { ids : [ ] , names : [ ] }
367
+ ) ;
368
+
369
+ // run the recursive finding
370
+ const roleNames = await this . _getAllRolesNamesForRoleIds ( rolesMap . ids , rolesMap . names ) ;
371
+ this . userRoles = roleNames . map ( r => {
372
+ return 'role:' + r ;
373
+ } ) ;
374
+ } else {
375
+ this . userRoles = results ;
376
+ }
273
377
274
- // run the recursive finding
275
- const roleNames = await this . _getAllRolesNamesForRoleIds ( rolesMap . ids , rolesMap . names ) ;
276
- this . userRoles = roleNames . map ( r => {
277
- return 'role:' + r ;
278
- } ) ;
279
378
this . fetchedRoles = true ;
280
379
this . rolePromise = null ;
281
380
this . cacheRoles ( ) ;
@@ -322,7 +421,6 @@ Auth.prototype.getRolesByIds = async function (ins) {
322
421
} ;
323
422
} ) ;
324
423
const restWhere = { roles : { $in : roles } } ;
325
- const RestQuery = require ( './RestQuery' ) ;
326
424
await new RestQuery ( this . config , master ( this . config ) , '_Role' , restWhere , { } ) . each ( result =>
327
425
results . push ( result )
328
426
) ;
0 commit comments