Collection update access has different args than different field update access #2681
Replies: 2 comments
-
Hey @DanielKraemer — I think if I am understanding you right, you are looking to prevent a user from updating a document based on what data they are passing into the update operation, or, alternatively, based on the document itself. The collection Field-level access control is fundamentally different - those are meant to be used in cases where the user should be able to update the document itself, but NOT able to update the field in question only. And field hooks are indeed executed after the full document is retrieved from the database, so there, the full The right way to do this is to return a Have you seen this video? In it, I describe how to leverage query constraints within access control to accomplish what you're looking to do. So what I'd do if I were you would be to write an access control function like the following: const Media: CollectionConfig = {
slug: 'media',
access: {
update: ({ req: { user }}) => {
// If there is no user, then no access
if (!user) return false;
// If user has admin role, then give access to all
if (user.roles?.includes('admin')) {
return true
}
// Let's say your Users collection has a `sites` select field
// with hasMany (so it is an array).
// This field shows which sites the user has access to
if (user.sites) {
// Here, we will return a query constraint with the user's sites
// so that the media must be associated with one of the sites
// that the user has access to.
// This will automatically restrict the user from updating media
// unless they have explicit access as defined in their `sites` field
return {
site: {
in: user.sites
}
}
}
// If the user is not an admin,
// and has no site access, they should not be able to update
return false;
}
}
} Note that I do not have the doc yet, and don't need it. This is the pattern that Payload leverages. Does that make sense? As I don't think there is anything we can do on the Payload side to make this easier, I will convert this to a discussion, but happy to keep conversation going there! |
Beta Was this translation helpful? Give feedback.
-
@jmikrut thanks for your reply :D Okay, I wasn't sure about if it is be design 😅 and so I wasn't sure if it is a bug or anything else 🙈 Yes, I saw that tutorial and tried it. But my use case is a bit different. My user could have different roles for all of my sites (e.g. admin for page one and editor for page two). And if an image has a relation to different pages, user should only be able to edit the image if he is admin for ALL of those related pages. So if I'm right in my head, my query constraint should look like this: But how to build that query constraint? |
Beta Was this translation helpful? Give feedback.
Uh oh!
There was an error while loading. Please reload this page.
-
Link to reproduction
/
To Reproduce
try to access document data within the update function on collection level already as the document has loaded successfully
Describe the Bug
I have a system for multi pages.
My user can have different roles for the sites (e.g. "admin" for page1 and "editor" for page2). A media file can be linked to different sites.
The user should only be able to edit/update the media file if he has the role "admin" for all sites linked to the media file.
If I'm on field level and run a function if I want to update, type "FieldAccess" has the property doc, so I can check this as the document has loaded successfully.
If I'm collection level (accessing a document), type "Access" has no property doc. I only can see the documents data when clicking "save" after changing a value.
But I have to check my document directly as the content has loaded.
Still tried it with a mongodb query, but this is not possible.
Here within update the documents data is missing when accessing the document.
const Media: CollectionConfig = { slug: 'media', access: { create: hasCreateAccessToMedia, read: hasBasicReadAccess('sites'), update: hasUpdateAccessToMedia('sites'), delete: hasDeleteAccessToMedia, }, }
on this field level I have the property "doc" and can access the data already as the document has loaded.
{ name: 'author', type: 'relationship', relationTo: 'users', access: { update: isAdminFieldLevel, read: isLocalApiRequest, }, defaultValue: ({ user }) => (user.id), admin: { position: 'sidebar', condition: isSystemAdminFieldLevel, }, label: 'Autor', required: true, },
Payload Version
1.6.28
Beta Was this translation helpful? Give feedback.
All reactions