From accb6dc8d05941c90b334f26ce79b1fba8f49343 Mon Sep 17 00:00:00 2001 From: Denis Bykhov Date: Sat, 10 Jan 2026 15:22:51 +0500 Subject: [PATCH 1/2] Add type/tag permissions Signed-off-by: Denis Bykhov --- common/scripts/version.txt | 2 +- models/card/src/migration.ts | 160 ++++++++++++++++ models/card/src/plugin.ts | 24 +-- .../settings/ProperitiesSection.svelte | 44 +---- plugins/card-resources/src/plugin.ts | 22 ++- plugins/card-resources/src/utils.ts | 180 +++++++++++++++++- 6 files changed, 366 insertions(+), 66 deletions(-) diff --git a/common/scripts/version.txt b/common/scripts/version.txt index 1786157c5c8..191a501d751 100644 --- a/common/scripts/version.txt +++ b/common/scripts/version.txt @@ -1 +1 @@ -"0.7.340" +"0.7.343" diff --git a/models/card/src/migration.ts b/models/card/src/migration.ts index 1eb8cab1d7a..29c32a4b25c 100644 --- a/models/card/src/migration.ts +++ b/models/card/src/migration.ts @@ -17,6 +17,8 @@ import cardPlugin, { cardId, DOMAIN_CARD, type Card, type Role } from '@hcengine import core, { DOMAIN_MODEL, TxOperations, + type Class, + type ClassPermission, type Client, type Data, type Doc, @@ -121,11 +123,169 @@ export const cardOperation: MigrateOperation = { state: 'version-for-versionable-types', mode: 'upgrade', func: addVersionForVersionableTypes + }, + { + state: 'migrate-restricted-permissions', + mode: 'upgrade', + func: migrateRestrictedPermissions } ]) } } +async function migrateRestrictedPermissions (_client: MigrationUpgradeClient): Promise { + const client = new TxOperations(_client, core.account.System) + const hierarchy = client.getHierarchy() + const desc = hierarchy.getDescendants(card.class.Card) + const permissions = await client.findAll(core.class.ClassPermission, { objectClass: { $in: desc } }) + const restrictedTargets = new Set>>() + for (const perm of permissions) { + if (perm.targetClass !== undefined) { + restrictedTargets.add(perm.targetClass) + } + } + + const targets = await client.findAll(card.class.MasterTag, { _id: { $in: [...restrictedTargets] } }) + + for (const masterTag of targets) { + const isMixin = hierarchy.isMixin(masterTag._id) + const objectClass = hierarchy.getBaseClass(masterTag._id) + if (isMixin) { + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxMixin, + txMatch: { + mixin: masterTag._id + }, + scope: 'space', + forbid: false, + label: card.string.AddTagPermission, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_create_allowed` as Ref + ) + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxMixin, + txMatch: { + mixin: masterTag._id + }, + scope: 'space', + forbid: true, + label: card.string.ForbidAddTagPermission, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_create_forbidden` as Ref + ) + const key = `operations.$unset.${masterTag._id}` + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxUpdateDoc, + txMatch: { + [key]: { + $exists: true + } + }, + scope: 'space', + forbid: false, + label: card.string.RemoveTag, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_remove_allowed` as Ref + ) + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxUpdateDoc, + txMatch: { + [key]: { $exists: true } + }, + scope: 'space', + forbid: true, + label: card.string.ForbidRemoveTag, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_remove_forbidden` as Ref + ) + } else { + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxCreateDoc, + scope: 'space', + forbid: false, + label: card.string.CreateCardPermission, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_create_allowed` as Ref + ) + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxCreateDoc, + scope: 'space', + forbid: true, + label: card.string.ForbidCreateCardPermission, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_create_forbidden` as Ref + ) + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxRemoveDoc, + scope: 'space', + forbid: false, + label: card.string.RemoveCard, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_remove_allowed` as Ref + ) + await client.createDoc( + core.class.ClassPermission, + core.space.Model, + { + objectClass, + txClass: core.class.TxRemoveDoc, + txMatch: { + objectClass: masterTag._id + }, + scope: 'space', + forbid: true, + label: card.string.ForbidRemoveCard, + description: masterTag.label, + targetClass: masterTag._id + }, + `${masterTag._id}_remove_forbidden` as Ref + ) + } + } +} + async function addVersionForVersionableTypes (client: MigrationUpgradeClient): Promise { const txOp = new TxOperations(client, core.account.System) const versionableTypes = await client.findAll(card.class.MasterTag, {}) diff --git a/models/card/src/plugin.ts b/models/card/src/plugin.ts index d701f4674ad..c6b90350cad 100644 --- a/models/card/src/plugin.ts +++ b/models/card/src/plugin.ts @@ -17,7 +17,7 @@ import { type Card, cardId } from '@hcengineering/card' import card from '@hcengineering/card-resources/src/plugin' import type { Client, Doc, Ref } from '@hcengineering/core' import {} from '@hcengineering/core' -import { type IntlString, mergeIds, type Resource } from '@hcengineering/platform' +import { mergeIds, type Resource } from '@hcengineering/platform' import { type TagCategory } from '@hcengineering/tags' import { type Location, type ResolvedLocation } from '@hcengineering/ui/src/types' import { type Action, type ActionCategory, type ViewAction } from '@hcengineering/view' @@ -39,28 +39,6 @@ export default mergeIds(cardId, card, { PublicLink: '' as Ref>, Duplicate: '' as Ref }, - string: { - CreateCardPersmissionDescription: '' as IntlString, - UpdateCardPersmissionDescription: '' as IntlString, - RemoveCardPersmissionDescription: '' as IntlString, - AddTagPersmissionDescription: '' as IntlString, - RemoveTagPersmissionDescription: '' as IntlString, - RemoveCard: '' as IntlString, - UpdateCard: '' as IntlString, - CreateCardPermission: '' as IntlString, - AddTagPermission: '' as IntlString, - RemoveTag: '' as IntlString, - ForbidCreateCardPersmissionDescription: '' as IntlString, - ForbidUpdateCardPersmissionDescription: '' as IntlString, - ForbidRemoveCardPersmissionDescription: '' as IntlString, - ForbidAddTagPersmissionDescription: '' as IntlString, - ForbidRemoveTagPersmissionDescription: '' as IntlString, - ForbidRemoveCard: '' as IntlString, - ForbidUpdateCard: '' as IntlString, - ForbidCreateCardPermission: '' as IntlString, - ForbidAddTagPermission: '' as IntlString, - ForbidRemoveTag: '' as IntlString - }, category: { Card: '' as Ref, Labels: '' as Ref diff --git a/plugins/card-resources/src/components/settings/ProperitiesSection.svelte b/plugins/card-resources/src/components/settings/ProperitiesSection.svelte index 49db15d6346..d8af6d34e99 100644 --- a/plugins/card-resources/src/components/settings/ProperitiesSection.svelte +++ b/plugins/card-resources/src/components/settings/ProperitiesSection.svelte @@ -14,13 +14,13 @@ -->