@@ -179,8 +179,10 @@ module.exports = function(Role) {
179179 }
180180 var modelClass = context . model ;
181181 var modelId = context . modelId ;
182- var userId = context . getUserId ( ) ;
183- Role . isOwner ( modelClass , modelId , userId , callback ) ;
182+ var user = context . getUser ( ) ;
183+ var userId = user && user . id ;
184+ var principalType = user && user . principalType ;
185+ Role . isOwner ( modelClass , modelId , userId , principalType , callback ) ;
184186 } ) ;
185187
186188 function isUserClass ( modelClass ) {
@@ -210,18 +212,26 @@ module.exports = function(Role) {
210212 * @param {Function } modelClass The model class
211213 * @param {* } modelId The model ID
212214 * @param {* } userId The user ID
215+ * @param {String } principalType The user principalType (optional)
213216 * @callback {Function } [callback] The callback function
214217 * @param {String|Error } err The error string or object
215218 * @param {Boolean } isOwner True if the user is an owner.
216219 * @promise
217220 */
218- Role . isOwner = function isOwner ( modelClass , modelId , userId , callback ) {
221+ Role . isOwner = function isOwner ( modelClass , modelId , userId , principalType , callback ) {
222+ if ( ! callback && typeof principalType === 'function' ) {
223+ callback = principalType ;
224+ principalType = undefined ;
225+ }
226+ principalType = principalType || Principal . USER ;
227+
219228 assert ( modelClass , 'Model class is required' ) ;
220229 if ( ! callback ) callback = utils . createPromiseCallback ( ) ;
221230
222- debug ( 'isOwner(): %s %s userId: %s' , modelClass && modelClass . modelName , modelId , userId ) ;
231+ debug ( 'isOwner(): %s %s userId: %s principalType: %s' ,
232+ modelClass && modelClass . modelName , modelId , userId , principalType ) ;
223233
224- // No userId is present
234+ // Return false if userId is missing
225235 if ( ! userId ) {
226236 process . nextTick ( function ( ) {
227237 callback ( null , false ) ;
@@ -231,44 +241,58 @@ module.exports = function(Role) {
231241
232242 // Is the modelClass User or a subclass of User?
233243 if ( isUserClass ( modelClass ) ) {
234- process . nextTick ( function ( ) {
235- callback ( null , matches ( modelId , userId ) ) ;
236- } ) ;
244+ var userModelName = modelClass . modelName ;
245+ // matching ids is enough if principalType is USER or matches given user model name
246+ if ( principalType === Principal . USER || principalType === userModelName ) {
247+ process . nextTick ( function ( ) {
248+ callback ( null , matches ( modelId , userId ) ) ;
249+ } ) ;
250+ }
237251 return callback . promise ;
238252 }
239253
240254 modelClass . findById ( modelId , function ( err , inst ) {
241255 if ( err || ! inst ) {
242256 debug ( 'Model not found for id %j' , modelId ) ;
243- if ( callback ) callback ( err , false ) ;
244- return ;
257+ return callback ( err , false ) ;
245258 }
246259 debug ( 'Model found: %j' , inst ) ;
260+
261+ // Historically, for principalType USER, we were resolving isOwner()
262+ // as true if the model has "userId" or "owner" property matching
263+ // id of the current user (principalId), even though there was no
264+ // belongsTo relation set up.
247265 var ownerId = inst . userId || inst . owner ;
248- // Ensure ownerId exists and is not a function/relation
249- if ( ownerId && 'function' !== typeof ownerId ) {
250- if ( callback ) callback ( null , matches ( ownerId , userId ) ) ;
251- return ;
252- } else {
253- // Try to follow belongsTo
254- for ( var r in modelClass . relations ) {
255- var rel = modelClass . relations [ r ] ;
256- if ( rel . type === 'belongsTo' && isUserClass ( rel . modelTo ) ) {
257- debug ( 'Checking relation %s to %s: %j' , r , rel . modelTo . modelName , rel ) ;
258- inst [ r ] ( processRelatedUser ) ;
259- return ;
260- }
266+ if ( principalType === Principal . USER && ownerId && 'function' !== typeof ownerId ) {
267+ return callback ( null , matches ( ownerId , userId ) ) ;
268+ }
269+
270+ // Try to follow belongsTo
271+ for ( var r in modelClass . relations ) {
272+ var rel = modelClass . relations [ r ] ;
273+ // relation should be belongsTo and target a User based class
274+ var belongsToUser = rel . type === 'belongsTo' && isUserClass ( rel . modelTo ) ;
275+ if ( ! belongsToUser ) {
276+ continue ;
277+ }
278+ // checking related user
279+ var userModelName = rel . modelTo . modelName ;
280+ if ( principalType === Principal . USER || principalType === userModelName ) {
281+ debug ( 'Checking relation %s to %s: %j' , r , userModelName , rel ) ;
282+ inst [ r ] ( processRelatedUser ) ;
283+ return ;
261284 }
262- debug ( 'No matching belongsTo relation found for model %j and user: %j' , modelId , userId ) ;
263- if ( callback ) callback ( null , false ) ;
264285 }
286+ debug ( 'No matching belongsTo relation found for model %j - user %j principalType %j' ,
287+ modelId , userId , principalType ) ;
288+ callback ( null , false ) ;
265289
266290 function processRelatedUser ( err , user ) {
267291 if ( ! err && user ) {
268292 debug ( 'User found: %j' , user . id ) ;
269- if ( callback ) callback ( null , matches ( user . id , userId ) ) ;
293+ callback ( null , matches ( user . id , userId ) ) ;
270294 } else {
271- if ( callback ) callback ( err , false ) ;
295+ callback ( err , false ) ;
272296 }
273297 }
274298 } ) ;
0 commit comments