reactjssharepointsharepoint-onlinepnp-js

How to tell if a Principal Id is a permission group or a single user?


I'm using pnpJS to list all the users who have permissions on an SPO item:

 var info = await sp.web.lists.getByTitle('MyList').items.getById(theId2).roleAssignments();
    console.log(info, 'info');
var info2 = await sp.web.lists.getByTitle('MyList').roleAssignments.getById(3).groups();
    console.log(info2, 'groups');
    var newArr = info.map(a => a.PrincipalId);
    console.log(newArr, 'newArr');
    const res = newArr.forEach(async el => {
       await sp.web.siteUsers.getById(el).get().then(u => {
        console.log(u.Title);
      });
    });

I'm getting the list of users but if there is a group assigned to the SPO item, it throws an error. I need to deduce what is a group and what is a user so I can stop the foreach from including groups, therefore eliminating the error.

And for newArr log I get:

enter image description here

I know that Principal Id 3 is a group. I want the foreach to ignore any groups it returns. Successfully doing this would stop the error I'm getting. I realise that roleAssigments may be looking for users instead of groups, which would cause the error. But how would I list any groups associated with the item?

Update (working code for anyone else):

const userIds = [];
    const userNames = [];
    const res = newArr.forEach(async el => {
      // console.log(el, 'el');
      try {
        await sp.web.siteUsers.getById(el).get().then(u => {
           console.log(u.Title);
           userNames.push(u.Title);
           userIds.push(el);
         });
       } catch (err) {
         console.error("looks like it wasn't user after all");
       }

     });
   this.setState({
     userIds: userIds,
     userNames: userNames
    },() => {
      console.log(this.state.userIds, 'userIds');
      console.log(this.state.userNames, 'userNames');
    });
 console.log("userIds: ", userIds); // see if you get your "good" ids here
 // vs
 console.log("user and group ids:", newArr);


Solution

  • Looking at the info data and it doesn't seem to provide any differentiators.

    What you could potentially do to deal with this data is to add try / catch blocks and go on with whatever functionality you need, and get a list of actual users as you loop through.

    // Certainly feels hacky but see if it helps

     var info = await sp.web.lists.getByTitle('MyList').items.getById(theId2).roleAssignments();
        var newArr = info.map(a => a.PrincipalId);
        const userIds = []; // store collection of user ids that are not groups
        newArr.forEach(async el => {
          try {
           await sp.web.siteUsers.getById(el).get().then(u => {
              console.log(u.Title);
              userIds.push(el); // OR store actual user you get in response
            });
          } catch (err) {
            console.error("looks like it wasn't user after all", err);
          }
        });
    
    console.log("userIds: ", userIds); // see if you get your "good" ids here
    // vs
    console.log("user and group ids:", newArr);