Skip to content

Commit 5002953

Browse files
authored
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**
1 parent c80b6e9 commit 5002953

File tree

2 files changed

+16
-6
lines changed

2 files changed

+16
-6
lines changed

examples/multi-tenant/src/collections/Pages/access/superAdminOrTenantAdmin.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@ export const superAdminOrTenantAdminAccess: Access = ({ req }) => {
1414
return true
1515
}
1616

17-
return {
18-
tenant: {
19-
in: getUserTenantIDs(req.user, 'tenant-admin'),
20-
},
17+
const adminTenantAccessIDs = getUserTenantIDs(req.user, 'tenant-admin')
18+
const requestedTenant = req?.data?.tenant
19+
20+
if (requestedTenant && adminTenantAccessIDs.includes(requestedTenant)) {
21+
return true
2122
}
23+
24+
return false
2225
}

examples/multi-tenant/src/collections/Users/access/create.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import type { Access } from 'payload'
22

3-
import type { User } from '../../../payload-types'
3+
import type { Tenant, User } from '../../../payload-types'
44

55
import { isSuperAdmin } from '../../../access/isSuperAdmin'
66
import { getUserTenantIDs } from '../../../utilities/getUserTenantIDs'
@@ -16,7 +16,14 @@ export const createAccess: Access<User> = ({ req }) => {
1616

1717
const adminTenantAccessIDs = getUserTenantIDs(req.user, 'tenant-admin')
1818

19-
if (adminTenantAccessIDs.length) {
19+
const requestedTenants: Tenant['id'][] =
20+
req.data?.tenants?.map((t: { tenant: Tenant['id'] }) => t.tenant) ?? []
21+
22+
const hasAccessToAllRequestedTenants = requestedTenants.every((tenantID) =>
23+
adminTenantAccessIDs.includes(tenantID),
24+
)
25+
26+
if (hasAccessToAllRequestedTenants) {
2027
return true
2128
}
2229

0 commit comments

Comments
 (0)