mirror of
https://github.com/hcengineering/platform.git
synced 2025-04-19 14:55:31 +00:00
UBERF-7800: Space improvements (#6250)
Signed-off-by: Andrey Sobolev <haiodo@gmail.com>
This commit is contained in:
parent
8667b7482d
commit
96d80a1651
@ -325,43 +325,6 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
private async getTxTargets (ctx: SessionContext, tx: Tx): Promise<string[] | undefined> {
|
|
||||||
const h = this.storage.hierarchy
|
|
||||||
let targets: string[] | undefined
|
|
||||||
|
|
||||||
if (TxProcessor.isExtendsCUD(tx._class)) {
|
|
||||||
const account = await getUser(this.storage, ctx)
|
|
||||||
if (tx.objectSpace === (account._id as string)) {
|
|
||||||
targets = [account.email, systemAccountEmail]
|
|
||||||
} else if ([...this.systemSpaces, ...this.mainSpaces].includes(tx.objectSpace)) {
|
|
||||||
return
|
|
||||||
} else {
|
|
||||||
const cudTx = tx as TxCUD<Doc>
|
|
||||||
const isSpace = h.isDerived(cudTx.objectClass, core.class.Space)
|
|
||||||
|
|
||||||
if (isSpace) {
|
|
||||||
return undefined
|
|
||||||
}
|
|
||||||
|
|
||||||
const space = this.spacesMap.get(tx.objectSpace)
|
|
||||||
|
|
||||||
if (space !== undefined) {
|
|
||||||
targets = await this.getTargets(space.members)
|
|
||||||
if (!isOwner(account, ctx)) {
|
|
||||||
const allowed = this.getAllAllowedSpaces(account, true)
|
|
||||||
if (allowed === undefined || !allowed.includes(tx.objectSpace)) {
|
|
||||||
throw new PlatformError(new Status(Severity.ERROR, platform.status.Forbidden, {}))
|
|
||||||
}
|
|
||||||
} else if (!targets.includes(account.email)) {
|
|
||||||
targets.push(account.email)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return targets
|
|
||||||
}
|
|
||||||
|
|
||||||
private async processTxSpaceDomain (tx: TxCUD<Doc>): Promise<void> {
|
private async processTxSpaceDomain (tx: TxCUD<Doc>): Promise<void> {
|
||||||
const actualTx = TxProcessor.extractTx(tx)
|
const actualTx = TxProcessor.extractTx(tx)
|
||||||
if (actualTx._class === core.class.TxCreateDoc) {
|
if (actualTx._class === core.class.TxCreateDoc) {
|
||||||
@ -450,15 +413,10 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
return isData ? res : [...res, ...this.publicSpaces]
|
return isData ? res : [...res, ...this.publicSpaces]
|
||||||
}
|
}
|
||||||
|
|
||||||
async loadDomainSpaces (ctx: MeasureContext, domain: Domain): Promise<Set<Ref<Space>>> {
|
|
||||||
const field = this.getKey(domain)
|
|
||||||
return await this.storage.groupBy<Ref<Space>>(ctx, domain, field)
|
|
||||||
}
|
|
||||||
|
|
||||||
async getDomainSpaces (domain: Domain): Promise<Set<Ref<Space>>> {
|
async getDomainSpaces (domain: Domain): Promise<Set<Ref<Space>>> {
|
||||||
let domainSpaces = this._domainSpaces.get(domain)
|
let domainSpaces = this._domainSpaces.get(domain)
|
||||||
if (domainSpaces === undefined) {
|
if (domainSpaces === undefined) {
|
||||||
const p = this.loadDomainSpaces(this.spaceMeasureCtx, domain)
|
const p = this.storage.groupBy<Ref<Space>>(this.spaceMeasureCtx, domain, this.getKey(domain))
|
||||||
this._domainSpaces.set(domain, p)
|
this._domainSpaces.set(domain, p)
|
||||||
domainSpaces = await p
|
domainSpaces = await p
|
||||||
this._domainSpaces.set(domain, domainSpaces)
|
this._domainSpaces.set(domain, domainSpaces)
|
||||||
@ -466,9 +424,17 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
return domainSpaces instanceof Promise ? await domainSpaces : domainSpaces
|
return domainSpaces instanceof Promise ? await domainSpaces : domainSpaces
|
||||||
}
|
}
|
||||||
|
|
||||||
private async filterByDomain (domain: Domain, spaces: Ref<Space>[]): Promise<Ref<Space>[]> {
|
private async filterByDomain (
|
||||||
|
domain: Domain,
|
||||||
|
spaces: Ref<Space>[]
|
||||||
|
): Promise<{ result: Ref<Space>[], allDomainSpaces: boolean, domainSpaces: Set<Ref<Space>> }> {
|
||||||
const domainSpaces = await this.getDomainSpaces(domain)
|
const domainSpaces = await this.getDomainSpaces(domain)
|
||||||
return spaces.filter((p) => domainSpaces.has(p))
|
const result = spaces.filter((p) => domainSpaces.has(p))
|
||||||
|
return {
|
||||||
|
result: spaces.filter((p) => domainSpaces.has(p)),
|
||||||
|
allDomainSpaces: result.length === domainSpaces.size,
|
||||||
|
domainSpaces
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async mergeQuery<T extends Doc>(
|
private async mergeQuery<T extends Doc>(
|
||||||
@ -476,19 +442,33 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
query: ObjQueryType<T['space']>,
|
query: ObjQueryType<T['space']>,
|
||||||
domain: Domain,
|
domain: Domain,
|
||||||
isSpace: boolean
|
isSpace: boolean
|
||||||
): Promise<ObjQueryType<T['space']>> {
|
): Promise<ObjQueryType<T['space']> | undefined> {
|
||||||
const spaces = await this.filterByDomain(domain, this.getAllAllowedSpaces(account, !isSpace))
|
const spaces = await this.filterByDomain(domain, this.getAllAllowedSpaces(account, !isSpace))
|
||||||
if (query == null) {
|
if (query == null) {
|
||||||
return { $in: spaces }
|
if (spaces.allDomainSpaces) {
|
||||||
|
return undefined
|
||||||
|
}
|
||||||
|
return { $in: spaces.result }
|
||||||
}
|
}
|
||||||
if (typeof query === 'string') {
|
if (typeof query === 'string') {
|
||||||
if (!spaces.includes(query)) {
|
if (!spaces.result.includes(query)) {
|
||||||
return { $in: [] }
|
return { $in: [] }
|
||||||
}
|
}
|
||||||
} else if (query.$in != null) {
|
} else if (query.$in != null) {
|
||||||
query.$in = query.$in.filter((p) => spaces.includes(p))
|
query.$in = query.$in.filter((p) => spaces.result.includes(p))
|
||||||
|
if (query.$in.length === spaces.domainSpaces.size) {
|
||||||
|
// all domain spaces
|
||||||
|
delete query.$in
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
query.$in = spaces
|
if (spaces.allDomainSpaces) {
|
||||||
|
delete query.$in
|
||||||
|
} else {
|
||||||
|
query.$in = spaces.result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (Object.keys(query).length === 0) {
|
||||||
|
return undefined
|
||||||
}
|
}
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
@ -515,22 +495,31 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
if (!isOwner(account, ctx) || !isSpace) {
|
if (!isOwner(account, ctx) || !isSpace) {
|
||||||
if (query[field] !== undefined) {
|
if (query[field] !== undefined) {
|
||||||
const res = await this.mergeQuery(account, query[field], domain, isSpace)
|
const res = await this.mergeQuery(account, query[field], domain, isSpace)
|
||||||
|
if (res === undefined) {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-dynamic-delete
|
||||||
|
delete (query as any)[field]
|
||||||
|
} else {
|
||||||
;(newQuery as any)[field] = res
|
;(newQuery as any)[field] = res
|
||||||
if (typeof res === 'object') {
|
if (typeof res === 'object') {
|
||||||
if (Array.isArray(res.$in) && res.$in.length === 1 && Object.keys(res).length === 1) {
|
if (Array.isArray(res.$in) && res.$in.length === 1 && Object.keys(res).length === 1) {
|
||||||
;(newQuery as any)[field] = res.$in[0]
|
;(newQuery as any)[field] = res.$in[0]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const spaces = await this.filterByDomain(domain, this.getAllAllowedSpaces(account, !isSpace))
|
const spaces = await this.filterByDomain(domain, this.getAllAllowedSpaces(account, !isSpace))
|
||||||
if (spaces.length === 1) {
|
if (spaces.allDomainSpaces) {
|
||||||
;(newQuery as any)[field] = spaces[0]
|
// 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]
|
||||||
} else {
|
} else {
|
||||||
;(newQuery as any)[field] = { $in: spaces }
|
;(newQuery as any)[field] = { $in: spaces.result }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const findResult = await this.provideFindAll(ctx, _class, newQuery, options)
|
const findResult = await this.provideFindAll(ctx, _class, newQuery, options)
|
||||||
if (!isOwner(account, ctx) && account.role !== AccountRole.DocGuest) {
|
if (!isOwner(account, ctx) && account.role !== AccountRole.DocGuest) {
|
||||||
if (options?.lookup !== undefined) {
|
if (options?.lookup !== undefined) {
|
||||||
@ -564,7 +553,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar
|
|||||||
}
|
}
|
||||||
passedDomains.add(domain)
|
passedDomains.add(domain)
|
||||||
const spaces = await this.filterByDomain(domain, allSpaces)
|
const spaces = await this.filterByDomain(domain, allSpaces)
|
||||||
for (const space of spaces) {
|
for (const space of spaces.result) {
|
||||||
res.add(space)
|
res.add(space)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user