fix(examples): checks requested tenant matches user tenant permissions (#13012)

### What

This PR updates the `create` access control functions in the
`multi-tenant` example to ensure that any `tenant` specified in a create
request matches a tenant the user has admin access to.

### Why

Previously, while the admin panel UI restricted the tenant selection, it
was still possible to bypass this by making a request directly to the
API with a different `tenant`. This allowed users to create documents
under tenants they shouldn't have access to.

### How

The `access` functions on the `users` and `pages` collections now
explicitly check whether the tenant(s) in the request are included in
the user's tenant permissions. If not, access is denied by returning
`false`.

**Fixes: CMS2-Q225-03**
This commit is contained in:
Jessica Rynkar
2025-07-02 14:30:47 +01:00
committed by GitHub
parent c80b6e92c4
commit 50029532aa
2 changed files with 16 additions and 6 deletions

View File

@@ -14,9 +14,12 @@ export const superAdminOrTenantAdminAccess: Access = ({ req }) => {
return true return true
} }
return { const adminTenantAccessIDs = getUserTenantIDs(req.user, 'tenant-admin')
tenant: { const requestedTenant = req?.data?.tenant
in: getUserTenantIDs(req.user, 'tenant-admin'),
}, if (requestedTenant && adminTenantAccessIDs.includes(requestedTenant)) {
return true
} }
return false
} }

View File

@@ -1,6 +1,6 @@
import type { Access } from 'payload' import type { Access } from 'payload'
import type { User } from '../../../payload-types' import type { Tenant, User } from '../../../payload-types'
import { isSuperAdmin } from '../../../access/isSuperAdmin' import { isSuperAdmin } from '../../../access/isSuperAdmin'
import { getUserTenantIDs } from '../../../utilities/getUserTenantIDs' import { getUserTenantIDs } from '../../../utilities/getUserTenantIDs'
@@ -16,7 +16,14 @@ export const createAccess: Access<User> = ({ req }) => {
const adminTenantAccessIDs = getUserTenantIDs(req.user, 'tenant-admin') const adminTenantAccessIDs = getUserTenantIDs(req.user, 'tenant-admin')
if (adminTenantAccessIDs.length) { const requestedTenants: Tenant['id'][] =
req.data?.tenants?.map((t: { tenant: Tenant['id'] }) => t.tenant) ?? []
const hasAccessToAllRequestedTenants = requestedTenants.every((tenantID) =>
adminTenantAccessIDs.includes(tenantID),
)
if (hasAccessToAllRequestedTenants) {
return true return true
} }