Check if User has Role - Parse Cloud Code
Asked Answered
E

3

7

Writing a Parse Cloud Function (which uses Parse Javascript SDK) and I am having trouble checking to see if the current user has role "Admin". I'm looking at the web view of the Role class and a role with the name "Admin" exists, if I click "View Relations" for users, it shows the current user. I doubt it should matter, but "Admin" is the only role and the current user is the only user with a role. Lastly, the "Admin" role has an ACL of Public Read, so that shouldn't be causing any issues either.

Code is as follows:

...
var queryRole = new Parse.Query(Parse.Role);
queryRole.equalTo('name', 'Admin'); 
queryRole.equalTo("users", Parse.User.current());
queryRole.first({
    success: function(result) { // Role Object
        var role = result;
        role ? authorized = true : console.log('Shiet, user not Admin');
    },
    error: function(error) {
        console.log("Bruh, queryRole error");
    }
})
console.log('After test: Auth = ' + authorized);
if (!authorized) {
    response.error("You ain't no admin, measly user");
    return;    
}
...

This results in the following in the log:

Before test: Auth = false

After test: Auth = false

Embankment answered 21/3, 2015 at 0:14 Comment(2)
You need to use promises. You are reading the value before the query finishes.Lowney
Yeah, I realized that from Bryan's code below which worked, I suggested an edit that included more than "give this a shot" but it got "refused".Embankment
S
12

Give this a shot:

var authorized = false;
console.log('Before test: Auth = ' + authorized);

var queryRole = new Parse.Query(Parse.Role);
queryRole.equalTo('name', 'Admin');
queryRole.first({
    success: function(result) { // Role Object
        console.log("Okay, that's a start... in success 1 with results: " + result);

        var role = result;
        var adminRelation = new Parse.Relation(role, 'users');
        var queryAdmins = adminRelation.query();

        queryAdmins.equalTo('objectId', Parse.User.current().id);
        queryAdmins.first({
            success: function(result) {    // User Object
                var user = result;
                user ? authorized = true : console.log('Shiet, user not Admin');
            }
        });
    },
    error: function(error) {
        console.log("Bruh, can't find the Admin role");
    }
}).then(function() {
    console.log('After test: Auth = ' + authorized);
});
Smallman answered 21/3, 2015 at 17:16 Comment(2)
.. I really like "Shiet, user not admin" :) and of course, helped me a lot!Bekki
if anyone is looking at this in 2018... you need to do this...useMasterKey. I'll post answer below.Ree
O
11

I got a simpler solution, give this a try:

var adminRoleQuery = new Parse.Query(Parse.Role);
adminRoleQuery.equalTo('name', 'admin');
adminRoleQuery.equalTo('users', req.user);

return adminRoleQuery.first().then(function(adminRole) {
  if (!adminRole) {
    throw new Error('Not an admin');
  }
});
Oneself answered 12/9, 2015 at 23:12 Comment(3)
I can verify that this syntax works: equalTo('relation', value) and notEqualTo('relation', value) does indeed match against elements by equality. This should be the correct answer.Tergum
What if you set an ACL on the role with read access for the user then the query should fetch the role if the user has the permission to do so or from another role with read permission on this role, right?Lidialidice
I can't confirm because I haven't tested. But yes, it should work that way!Oneself
R
1

For those of you looking for a Parse Server (2018) answer, see below:

Parse.Cloud.define('authorizedUserTest', function(request, response) {


  if(!request.params.username){
    //response.error('no username');
      response.error(request.params);
  }

  var queryRole = new Parse.Query(Parse.Role);
  queryRole.equalTo('name','Admin');

  queryRole.first({ useMasterKey: true }).then(function(promise){
    var role = promise;
    var relation = new Parse.Relation(role, 'users');
    var admins = relation.query();
    admins.equalTo('username', request.user.get('username'));
    admins.first({ useMasterKey: true }).then(function(user){
      if(user){
        response.success(true)
      }
      else {
        response.success(false)
      }
    }, function(err){
      response.error('User is not an admin')
    })
  }, function(err){
    response.error(err)
  })



});

request.params is equal to a dictionary {"username":inputUsernameHere}.

Feel free to comment if you have questions.

Ree answered 11/5, 2018 at 2:34 Comment(2)
How do you keep you master key secure?Piccolo
Master key is only in the node.js application... not in the client side code. so it's secure as far as i know, but someone else should be consulted before taking this as the answerRee

© 2022 - 2024 — McMap. All rights reserved.