Like what we’re doing? Star us on GitHub!

Access Control for a collection when authenticated against specific collection only

ryanlanciaux
last year
1 1

My apologies about this question, as it may be something that's clearly answered in the docs.

I have two user collections: admins and users, Both of the user collections have lists of users with the intent of different responsibilities. admins should be able to edit everything through the admin panel whereas users will basically have a profile they can edit, and that's it.

I'd like to make it so admins could see the list of all other admins, where standard users shouldn't have this functionality. I see in the docs for Access Control it says:

Declaring who should have access to what documents is no more complex than writing a simple JavaScript function that either returns a boolean or a query constraint to restrict which documents users can interact with.

Based on this, I think a query constraint is what I need, however, I get a little lost regarding how to specify a query that says "show me this collection ONLY if I'm in an admin list." As it stands today, I can see the admins collection whether I'm logged in as a standard user or an admin, instead of admin only.

One other thing I tried is to perform a payload.query inside the access control function, but that seemed to cause errors due to the async / promises. Any thoughts on how to achieve this would be greatly appreciated!

  • denolfe
    Payload Team
    last year

    Hey @ryanlanciaux, thanks for the question. You were definitely on the right track. We could probably explain this more and add examples of this in the documentation. Here is an example of doing what you describe:

    You can see from the code that if the user is in the admins collection it will return true, indicating access to all. However, if the user is in the users collection, a query constraint is returned that will return only documents with that user's id.

    const userAccess = ({ req: { user } }) => {
      if (user) {
        if (user.collection === 'admins') {
          return true;
        }
    
        if (user.collection === 'users') {
          return {
            id: {
              equals: user.id,
            },
          };
        }
      }
    
      return false;
    };
    
    export { userAccess };

    If you put that code in a separate file, then import it - you'd use it in your collection like this:

    access: {
        admin: () => true, // Allow access to admin panel
        read: userAccess,
        update: userAccess,
      },

    You may also consider having a similar function for create and delete as well.

    Hopefully, this helps. Let me know if there are any issues running that code đź‘Ť

    1 reply
  • ryanlanciaux
    last year

    Thanks a ton! This works perfectly for me.

Open the post
Continue the discussion in GitHub
Can't find what you're looking for?
Get help straight from the Payload team with an Enterprise License.Learn More