Update space security and permissions (#10529)

Signed-off-by: Kristina Fefelova <kristin.fefelova@gmail.com>
This commit is contained in:
Kristina
2026-02-19 22:34:28 +05:00
committed by GitHub
parent 2733a2c1ba
commit f446e036ee
2 changed files with 25 additions and 4 deletions
@@ -37,7 +37,7 @@ import core, {
} from '@hcengineering/core'
import platform, { PlatformError, Severity, Status } from '@hcengineering/platform'
import { type Middleware, type TxMiddlewareResult, type PipelineContext } from '@hcengineering/server-core'
import contact from '@hcengineering/contact'
import { BaseMiddleware } from '@hcengineering/server-core'
/**
@@ -446,10 +446,21 @@ export class SpacePermissionsMiddleware extends BaseMiddleware implements Middle
this.checkSpacePermissions(ctx, cudTx, cudTx.objectSpace)
if (isSpace) {
this.checkSpaceTypePermissions(ctx, cudTx as TxCUD<Space>)
this.checkSpacePermissions(ctx, cudTx, cudTx.objectId as Ref<Space>, true)
}
}
private checkSpaceTypePermissions (ctx: MeasureContext, cudTx: TxCUD<Space>): void {
const account = ctx.contextData.account
const h = this.context.hierarchy
if (account.primarySocialId === core.account.System) return
if (h.isDerived(cudTx.objectClass, contact.class.PersonSpace)) {
this.throwForbidden()
}
}
private checkSpacePermissions (
ctx: MeasureContext,
cudTx: TxCUD<Doc>,
@@ -688,7 +688,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
findResult.lookupMap
)
}
if (!isOwner(account, ctx) && account.role !== AccountRole.DocGuest) {
if (account.role !== AccountRole.DocGuest) {
if (options?.lookup !== undefined) {
for (const object of findResult) {
if (object.$lookup !== undefined) {
@@ -737,19 +737,29 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
if (Object.keys(lookup).length === 0) return
const account = ctx.contextData.account
if (isSystem(account, ctx)) return
const owner = isOwner(account, ctx)
const h = this.context.hierarchy
const allowedSpaces = new Set(this.getAllAllowedSpaces(account, true, showArchived))
for (const key in lookup) {
const val = lookup[key]
if (Array.isArray(val)) {
const arr: AttachedDoc[] = []
for (const value of val) {
if (allowedSpaces.has(value.space)) {
const isSpace = '_class' in value && h.isDerived(value._class, core.class.Space)
const availableForOwner = owner && isSpace
const availableSpace = isSpace && allowedSpaces.has(value._id)
const availableDoc = !isSpace && allowedSpaces.has(value.space)
if (availableForOwner || availableSpace || availableDoc) {
arr.push(value)
}
}
lookup[key] = arr as any
} else if (val !== undefined) {
if (!allowedSpaces.has(val.space)) {
const isSpace = '_class' in val && h.isDerived(val._class, core.class.Space)
const availableForOwner = owner && isSpace
const availableSpace = isSpace && allowedSpaces.has(val._id as Ref<Space>)
const availableDoc = !isSpace && allowedSpaces.has(val.space)
if (!availableForOwner && !availableSpace && !availableDoc) {
// allow attached lookups for guests when collaborator security is enabled
// do not check if collaborator of the doc because it's being checked on the storage (DB) level
// as otherwise there will be no doc here at all