mirror of
https://github.com/hcengineering/platform.git
synced 2026-09-23 01:55:00 +02:00
UBERF-8856: Fix space security query and schema update (#7413)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
@@ -40,6 +40,7 @@ import core, {
|
||||
TxUpdateDoc,
|
||||
TxWorkspaceEvent,
|
||||
WorkspaceEvent,
|
||||
clone,
|
||||
generateId,
|
||||
systemAccountEmail,
|
||||
toFindResult,
|
||||
@@ -69,14 +70,14 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
|
||||
wasInit: Promise<void> | boolean = false
|
||||
|
||||
private readonly mainSpaces = [
|
||||
private readonly mainSpaces = new Set([
|
||||
core.space.Configuration,
|
||||
core.space.DerivedTx,
|
||||
core.space.Model,
|
||||
core.space.Space,
|
||||
core.space.Workspace,
|
||||
core.space.Tx
|
||||
]
|
||||
])
|
||||
|
||||
private constructor (
|
||||
private readonly skipFindCheck: boolean,
|
||||
@@ -424,7 +425,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
ctx.contextData.broadcast.targets.spaceSec = (tx) => {
|
||||
const space = this.spacesMap.get(tx.objectSpace)
|
||||
if (space === undefined) return undefined
|
||||
if (this.systemSpaces.has(space._id) || this.mainSpaces.includes(space._id)) return undefined
|
||||
if (this.systemSpaces.has(space._id) || this.mainSpaces.has(space._id)) return undefined
|
||||
|
||||
return space.members.length === 0 ? undefined : this.getTargets(space?.members)
|
||||
}
|
||||
@@ -455,12 +456,12 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
ctx: MeasureContext,
|
||||
domain: Domain,
|
||||
spaces: Ref<Space>[]
|
||||
): Promise<{ result: Ref<Space>[], allDomainSpaces: boolean, domainSpaces: Set<Ref<Space>> }> {
|
||||
): Promise<{ result: Set<Ref<Space>>, allDomainSpaces: boolean, domainSpaces: Set<Ref<Space>> }> {
|
||||
const domainSpaces = await this.getDomainSpaces(ctx, domain)
|
||||
const result = spaces.filter((p) => domainSpaces.has(p))
|
||||
const result = new Set(spaces.filter((p) => domainSpaces.has(p)))
|
||||
return {
|
||||
result: spaces.filter((p) => domainSpaces.has(p)),
|
||||
allDomainSpaces: result.length === domainSpaces.size,
|
||||
result,
|
||||
allDomainSpaces: result.size === domainSpaces.size,
|
||||
domainSpaces
|
||||
}
|
||||
}
|
||||
@@ -477,14 +478,14 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
if (spaces.allDomainSpaces) {
|
||||
return undefined
|
||||
}
|
||||
return { $in: spaces.result }
|
||||
return { $in: Array.from(spaces.result) }
|
||||
}
|
||||
if (typeof query === 'string') {
|
||||
if (!spaces.result.includes(query)) {
|
||||
if (!spaces.result.has(query)) {
|
||||
return { $in: [] }
|
||||
}
|
||||
} else if (query.$in != null) {
|
||||
query.$in = query.$in.filter((p) => spaces.result.includes(p))
|
||||
query.$in = query.$in.filter((p) => spaces.result.has(p))
|
||||
if (query.$in.length === spaces.domainSpaces.size) {
|
||||
// all domain spaces
|
||||
delete query.$in
|
||||
@@ -493,7 +494,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
if (spaces.allDomainSpaces) {
|
||||
delete query.$in
|
||||
} else {
|
||||
query.$in = spaces.result
|
||||
query.$in = Array.from(spaces.result)
|
||||
}
|
||||
}
|
||||
if (Object.keys(query).length === 0) {
|
||||
@@ -515,7 +516,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
await this.init(ctx)
|
||||
|
||||
const domain = this.context.hierarchy.getDomain(_class)
|
||||
const newQuery = { ...query }
|
||||
const newQuery = clone(query)
|
||||
const account = ctx.contextData.account
|
||||
const isSpace = this.context.hierarchy.isDerived(_class, core.class.Space)
|
||||
const field = this.getKey(domain)
|
||||
@@ -528,12 +529,12 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
const res = await this.mergeQuery(ctx, account, query[field], domain, isSpace)
|
||||
if (res === undefined) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete (newQuery as any)[field]
|
||||
delete newQuery[field]
|
||||
} else {
|
||||
;(newQuery as any)[field] = res
|
||||
newQuery[field] = res
|
||||
if (typeof res === 'object') {
|
||||
if (Array.isArray(res.$in) && res.$in.length === 1 && Object.keys(res).length === 1) {
|
||||
;(newQuery as any)[field] = res.$in[0]
|
||||
newQuery[field] = res.$in[0]
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,25 +542,25 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
||||
const spaces = await this.filterByDomain(ctx, domain, this.getAllAllowedSpaces(account, !isSpace))
|
||||
if (spaces.allDomainSpaces) {
|
||||
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||
delete (newQuery as any)[field]
|
||||
} else if (spaces.result.length === 1) {
|
||||
;(newQuery as any)[field] = spaces.result[0]
|
||||
delete newQuery[field]
|
||||
} else if (spaces.result.size === 1) {
|
||||
newQuery[field] = Array.from(spaces.result)[0]
|
||||
if (options !== undefined) {
|
||||
options.allowedSpaces = spaces.result
|
||||
options.allowedSpaces = Array.from(spaces.result)
|
||||
} else {
|
||||
options = { allowedSpaces: spaces.result }
|
||||
options = { allowedSpaces: Array.from(spaces.result) }
|
||||
}
|
||||
} else {
|
||||
// Check if spaces > 85% of all domain spaces, in this case return all and filter on client.
|
||||
if (spaces.result.length / spaces.domainSpaces.size > 0.85 && options?.limit === undefined) {
|
||||
clientFilterSpaces = new Set(spaces.result)
|
||||
if (spaces.result.size / spaces.domainSpaces.size > 0.85 && options?.limit === undefined) {
|
||||
clientFilterSpaces = spaces.result
|
||||
delete newQuery.space
|
||||
} else {
|
||||
;(newQuery as any)[field] = { $in: spaces.result }
|
||||
newQuery[field] = { $in: Array.from(spaces.result) }
|
||||
if (options !== undefined) {
|
||||
options.allowedSpaces = spaces.result
|
||||
options.allowedSpaces = Array.from(spaces.result)
|
||||
} else {
|
||||
options = { allowedSpaces: spaces.result }
|
||||
options = { allowedSpaces: Array.from(spaces.result) }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -625,19 +626,19 @@ 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 allowedSpaces = this.getAllAllowedSpaces(account, true)
|
||||
const allowedSpaces = new Set(this.getAllAllowedSpaces(account, true))
|
||||
for (const key in lookup) {
|
||||
const val = lookup[key]
|
||||
if (Array.isArray(val)) {
|
||||
const arr: AttachedDoc[] = []
|
||||
for (const value of val) {
|
||||
if (allowedSpaces.includes(value.space)) {
|
||||
if (allowedSpaces.has(value.space)) {
|
||||
arr.push(value)
|
||||
}
|
||||
}
|
||||
lookup[key] = arr as any
|
||||
} else if (val !== undefined) {
|
||||
if (!allowedSpaces.includes(val.space)) {
|
||||
if (!allowedSpaces.has(val.space)) {
|
||||
lookup[key] = undefined
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user