Meteor-Community-Packages / meteor-roles

Authorization package for Meteor, compatible with built-in accounts packages
http://meteor-community-packages.github.io/meteor-roles/
MIT License
920 stars 164 forks source link

Get a list of users with a scope #388

Open kjrhody opened 5 months ago

kjrhody commented 5 months ago

I see that there is a way to get the users with a specific role, but I'm interested in getting the users with a specific scope.

Say there were a project (Project 1), and the project had different roles. And I had multiple projects on my website (Project 1, Project 2, Project 3). I would like to get everyone associated with Project 1, regardless of their role.

So instead of

Roles.getUsersInRole('user-role')

I guess I'm asking if there's something like

Roles.getUsersInScope('project-name')

This was fairly easy to do in older versions of the package, with a query like this, if a user had been assigned to a project

return Meteor.users.find({"roles.__global_roles__": "project-1"});

But for v3, I didn't see this in the documentation anywhere - is it possible to do this currently?

github-actions[bot] commented 5 months ago

Thank you for submitting this issue!

We, the Members of Meteor Community Packages take every issue seriously. Our goal is to provide long-term lifecycles for packages and keep up with the newest changes in Meteor and the overall NodeJs/JavaScript ecosystem.

However, we contribute to these packages mostly in our free time. Therefore, we can't guarantee your issues to be solved within certain time.

If you think this issue is trivial to solve, don't hesitate to submit a pull request, too! We will accompany you in the process with reviews and hints on how to get development set up.

Please also consider sponsoring the maintainers of the package. If you don't know who is currently maintaining this package, just leave a comment and we'll let you know

jankapunkt commented 5 months ago

Hi @kjrhody there is Roles.getScopesForUser but I wonder why it's not in the docs 🤔

Edit: just rechecked and this is not what you actually need, right?

Edit edit: I think this needs to be implemented or there needs to be a workaround, @StorytellerCZ what do you think?

kjrhody commented 5 months ago

@jankapunkt Thanks for your response! Correct, I'd like to be able to get a list of users who have that scope.

Using the example from your documentation below, I'd like to be able to get a list of all the users, regardless of role, who have real-madrid.com as a scope.

Roles.userIsInRole(joesUserId, 'manage-team', 'real-madrid.com');

ricaragao commented 5 months ago

@kjrhody , you can get the info running this query:

Meteor.roleAssignment.find({scope: 'real-madrid.com'})

StorytellerCZ commented 5 months ago

I see two things here: 1) Get users that have a specific scope, any role 2) Get users that have a specific scope with a specific scope

Am I getting that right?

ricaragao commented 5 months ago

And here has a list with all methods: https://meteor-community-packages.github.io/meteor-roles/classes/Roles.html#api-classes

kjrhody commented 5 months ago

I see two things here:

  1. Get users that have a specific scope, any role
  2. Get users that have a specific scope with a specific scope

Am I getting that right?

@jankapunkt @StorytellerCZ My need is only one thing, I will see if I can clarify. Using the scope as an argument, I would like to be able to get all the users that have that scope. Something like this would be very helpful:

Roles.getUsersInScope('scope-name')

The method posted above by @ricaragao gets all of the records in that collection with that scope, but if a user has two roles within a scope, it will return both of those records. I just really need a list of users. This would be the equivalent to the current method that is available

Roles.getUsersInRole('user-role')

kjrhody commented 5 months ago

@kjrhody , you can get the info running this query:

Meteor.roleAssignment.find({scope: 'real-madrid.com'})

@ricaragao Thanks, I've tried this and it isn't exactly right. For example, if a user had two roles within the same scope, it would return both of those records. I really just need a list of the users within a scope. If you have further code that condenses the list by user that would be helpful, but if there were a method that didn't make me have to loop through all of those records to check whether the user was the same, that would be preferred.

At the moment I'm having to do something like this

    let scopeCursor = Meteor.roleAssignment.find({ 'scope': project_identifier }).fetch();

    let uList = [];
    scopeCursor.forEach(function (scopeRecord){
        let userId = scopeRecord.user._id;
        let u = Meteor.users.findOne({_id: userId});
        uList.push(u);
    })

    return  _.uniq(uList);
copleykj commented 5 months ago

I see two things here:

  1. Get users that have a specific scope, any role
  2. Get users that have a specific scope with a specific scope

Am I getting that right?

@StorytellerCZ

I think 1. covers @kjrhody's use case, but assuming that in 2. you mean "Get users that have a specific scope with a specific scope role" I think that both of these are useful additions.

copleykj commented 5 months ago

@kjrhody to modify @ricaragao's code to fit your your use case you'd just need to use the result to get all the user id's and then run a second lookup to get all the users. The code for this could look something like the following.

const findUsersInScope = async (scope) => {
  const assignments = await Meteor.roleAssignment.find({ scope }).fetchAsync();

  const userIds = assignments.reduce((acc, assignment) => {
    return acc.add(assignment.user._id);
  }, new Set());

  return await Meteor.users.find({ _id: { $in: Array.from(userIds) } }).fetchAsync();
};
ricaragao commented 5 months ago

Thank you @copleykj for the solution! I only gave to @kjrhody the direction, not the solution.

jankapunkt commented 5 months ago

From my end the question remains if this is solved by this workaround (then I would propose a PR to add this to the Readme as example) or if there is the need for a new Method?

copleykj commented 5 months ago

@jankapunkt I think these would be a useful addition to the package, especially due to the fact that the package doesn't define the roleAssignment key on the Meteor object, or provide valid types for the objects returned from the queries for us TypeScript users.