From 8e840c7d3c949af8e2a8a3f1126883bc3b54ed28 Mon Sep 17 00:00:00 2001 From: Andrey Sobolev <haiodo@users.noreply.github.com> Date: Sun, 13 Oct 2024 23:59:38 +0700 Subject: [PATCH] UBERF-8455: Fix admin users (#6909) Signed-off-by: Andrey Sobolev <haiodo@gmail.com> --- models/tracker/src/viewlets.ts | 8 +++++- .../projects/ProjectPresenter.svelte | 13 ++++++++-- .../src/components/navigator/NavLink.svelte | 3 ++- .../src/components/Navigator.svelte | 16 +++++++----- server/middleware/src/spaceSecurity.ts | 25 ++++++------------- server/middleware/src/utils.ts | 4 +-- 6 files changed, 40 insertions(+), 29 deletions(-) diff --git a/models/tracker/src/viewlets.ts b/models/tracker/src/viewlets.ts index ac55bde0ee..ee25b63197 100644 --- a/models/tracker/src/viewlets.ts +++ b/models/tracker/src/viewlets.ts @@ -528,7 +528,13 @@ export function defineViewlets (builder: Builder): void { hiddenKeys: ['identifier', 'name', 'description'] }, config: [ - '', + { + key: '', + presenter: tracker.component.ProjectPresenter, + props: { + openIssues: true + } + }, 'members', { key: 'defaultAssignee', diff --git a/plugins/tracker-resources/src/components/projects/ProjectPresenter.svelte b/plugins/tracker-resources/src/components/projects/ProjectPresenter.svelte index a68ced6268..b694ea84ec 100644 --- a/plugins/tracker-resources/src/components/projects/ProjectPresenter.svelte +++ b/plugins/tracker-resources/src/components/projects/ProjectPresenter.svelte @@ -13,7 +13,7 @@ // limitations under the License. --> <script lang="ts"> - import presentation from '@hcengineering/presentation' + import presentation, { isAdminUser } from '@hcengineering/presentation' import { Project } from '@hcengineering/tracker' import { Icon, @@ -24,12 +24,15 @@ themeStore } from '@hcengineering/ui' import view from '@hcengineering/view' + import { NavLink } from '@hcengineering/view-resources' import tracker from '../../plugin' + import { getCurrentAccount } from '@hcengineering/core' export let value: Project | undefined export let inline: boolean = false export let accent: boolean = false export let colorInherit: boolean = false + export let openIssues: boolean </script> {#if value} @@ -49,7 +52,13 @@ /> </div> <span class="label no-underline nowrap" class:fs-bold={accent}> - {value.name} + {#if openIssues && (isAdminUser() || value.members.includes(getCurrentAccount()._id))} + <NavLink space={value._id} special={'issues'} noUnderline={false}> + {value.name} + </NavLink> + {:else} + {value.name} + {/if} {#if value.archived} <Label label={presentation.string.Archived} /> {/if} diff --git a/plugins/view-resources/src/components/navigator/NavLink.svelte b/plugins/view-resources/src/components/navigator/NavLink.svelte index 62f047a630..39fd9864a7 100644 --- a/plugins/view-resources/src/components/navigator/NavLink.svelte +++ b/plugins/view-resources/src/components/navigator/NavLink.svelte @@ -22,6 +22,7 @@ export let disabled = false export let shrink: number | undefined = undefined export let restoreLastLocation = false + export let noUnderline = true $: loc = createLocation($location, app, space, special) @@ -76,7 +77,7 @@ {#if disabled} <slot /> {:else} - <a class="noUnderline noBold" style:flex-shrink={shrink} {href} on:click={clickHandler}> + <a class:noUnderline class="noBold" style:flex-shrink={shrink} {href} on:click={clickHandler}> <slot /> </a> {/if} diff --git a/plugins/workbench-resources/src/components/Navigator.svelte b/plugins/workbench-resources/src/components/Navigator.svelte index 8536d5aeb7..10b72261af 100644 --- a/plugins/workbench-resources/src/components/Navigator.svelte +++ b/plugins/workbench-resources/src/components/Navigator.svelte @@ -16,7 +16,7 @@ import core, { Doc, Ref, SortingOrder, Space, getCurrentAccount, hasAccountRole } from '@hcengineering/core' import { getResource } from '@hcengineering/platform' import preference, { SpacePreference } from '@hcengineering/preference' - import { createQuery, getClient } from '@hcengineering/presentation' + import { createQuery, getClient, isAdminUser } from '@hcengineering/presentation' import { Scroller, NavItem } from '@hcengineering/ui' import { NavLink } from '@hcengineering/view-resources' import type { Application, NavigatorModel, SpecialNavModel } from '@hcengineering/workbench' @@ -40,6 +40,8 @@ let starred: Space[] = [] let shownSpaces: Space[] = [] + const adminUser = isAdminUser() + $: if (model) { const classes = Array.from(new Set(getSpecialSpaceClass(model).flatMap((c) => hierarchy.getDescendants(c)))).filter( (it) => !hierarchy.isMixin(it) @@ -47,10 +49,12 @@ if (classes.length > 0) { query.query( classes.length === 1 ? classes[0] : core.class.Space, - { - ...(classes.length === 1 ? {} : { _class: { $in: classes } }), - members: getCurrentAccount()._id - }, + !adminUser + ? { + ...(classes.length === 1 ? {} : { _class: { $in: classes } }), + members: getCurrentAccount()._id + } + : { ...(classes.length === 1 ? {} : { _class: { $in: classes } }) }, (result) => { spaces = result }, @@ -187,7 +191,7 @@ /> {/if} - {#each model.spaces as m, i (m.label)} + {#each model.spaces as m (m.label)} <SpacesNav spaces={shownSpaces.filter((it) => hierarchy.isDerived(it._class, m.spaceClass))} {currentSpace} diff --git a/server/middleware/src/spaceSecurity.ts b/server/middleware/src/spaceSecurity.ts index 04e447e047..a7e76eeba1 100644 --- a/server/middleware/src/spaceSecurity.ts +++ b/server/middleware/src/spaceSecurity.ts @@ -503,17 +503,14 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar const isSpace = this.context.hierarchy.isDerived(_class, core.class.Space) const field = this.getKey(domain) - if ( - ctx.contextData.admin === true && - this.context.hierarchy.isDerived(_class, core.class.Space) && - (newQuery as DocumentQuery<Space>).members !== undefined - ) { - delete (newQuery as any).members - } - let clientFilterSpaces: Set<Ref<Space>> | undefined - if (!this.skipFindCheck && !isSystem(account) && account.role !== AccountRole.DocGuest && domain !== DOMAIN_MODEL) { + if ( + !this.skipFindCheck && + !isSystem(account, ctx) && + account.role !== AccountRole.DocGuest && + domain !== DOMAIN_MODEL + ) { if (!isOwner(account, ctx) || !isSpace) { if (query[field] !== undefined) { const res = await this.mergeQuery(ctx, account, query[field], domain, isSpace) @@ -566,12 +563,6 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar } } } - if (ctx.contextData.admin === true && this.context.hierarchy.isDerived(_class, core.class.Space)) { - // We need to add amin to all spaces. - for (const d of findResult) { - ;(d as unknown as Space).members = [...((d as unknown as Space).members ?? []), ctx.contextData.account._id] - } - } return findResult } @@ -583,7 +574,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar await this.init(ctx) const newQuery = { ...query } const account = ctx.contextData.account - if (!isSystem(account)) { + if (!isSystem(account, ctx)) { const allSpaces = this.getAllAllowedSpaces(account, true) if (query.classes !== undefined) { const res = new Set<Ref<Space>>() @@ -610,7 +601,7 @@ export class SpaceSecurityMiddleware extends BaseMiddleware implements Middlewar async isUnavailable (ctx: MeasureContext<SessionData>, space: Ref<Space>): Promise<boolean> { const account = ctx.contextData.account - if (isSystem(account)) return false + if (isSystem(account, ctx)) return false return !this.getAllAllowedSpaces(account, true).includes(space) } diff --git a/server/middleware/src/utils.ts b/server/middleware/src/utils.ts index 95e188f5de..1ab7e9a17f 100644 --- a/server/middleware/src/utils.ts +++ b/server/middleware/src/utils.ts @@ -19,6 +19,6 @@ export function isOwner (account: Account, ctx: MeasureContext<SessionData>): bo return account.role === AccountRole.Owner || account._id === core.account.System || ctx.contextData.admin === true } -export function isSystem (account: Account): boolean { - return account._id === core.account.System || account._id.startsWith('system:') +export function isSystem (account: Account, ctx: MeasureContext<SessionData>): boolean { + return account._id === core.account.System || ctx.contextData.admin === true }