mirror of
https://github.com/hcengineering/platform.git
synced 2026-08-17 18:05:42 +02:00
Add type/tag permissions (#10384)
Signed-off-by: Denis Bykhov <bykhov.denis@gmail.com>
This commit is contained in:
@@ -1 +1 @@
|
||||
"0.7.340"
|
||||
"0.7.343"
|
||||
|
||||
@@ -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<void> {
|
||||
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<Ref<Class<Doc>>>()
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
} 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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async function addVersionForVersionableTypes (client: MigrationUpgradeClient): Promise<void> {
|
||||
const txOp = new TxOperations(client, core.account.System)
|
||||
const versionableTypes = await client.findAll(card.class.MasterTag, {})
|
||||
|
||||
@@ -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<Action<Doc, any>>,
|
||||
Duplicate: '' as Ref<Action>
|
||||
},
|
||||
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<ActionCategory>,
|
||||
Labels: '' as Ref<TagCategory>
|
||||
|
||||
@@ -14,18 +14,17 @@
|
||||
-->
|
||||
<script lang="ts">
|
||||
import { MasterTag } from '@hcengineering/card'
|
||||
import { ClassPermission, Ref } from '@hcengineering/core'
|
||||
import { getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import { ClassAttributes } from '@hcengineering/setting-resources'
|
||||
import setting from '@hcengineering/setting-resources/src/plugin'
|
||||
import { ButtonIcon, showPopup } from '@hcengineering/ui'
|
||||
import card from '../../plugin'
|
||||
import { getClient, MessageBox } from '@hcengineering/presentation'
|
||||
import core, { ClassPermission, Ref } from '@hcengineering/core'
|
||||
import view from '@hcengineering/view'
|
||||
import { createTypePermissions } from '../../utils'
|
||||
|
||||
export let masterTag: MasterTag
|
||||
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
|
||||
let isRestricted: boolean =
|
||||
client.getModel().findObject(getPermissionRef(false)) !== undefined ||
|
||||
@@ -43,43 +42,7 @@
|
||||
message: setting.string.RestrictedAttributeWarning,
|
||||
action: async () => {
|
||||
isRestricted = true
|
||||
const isMixin = hierarchy.isMixin(masterTag._id)
|
||||
const objectClass = hierarchy.getBaseClass(masterTag._id)
|
||||
const txClass = isMixin ? core.class.TxMixin : core.class.TxUpdateDoc
|
||||
await client.createDoc(
|
||||
core.class.ClassPermission,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass,
|
||||
txClass,
|
||||
txMatch: {
|
||||
[isMixin ? 'mixin' : 'objectClass']: masterTag._id
|
||||
},
|
||||
scope: 'space',
|
||||
forbid: false,
|
||||
label: view.string.AllowAttributeChanges,
|
||||
description: masterTag.label,
|
||||
targetClass: masterTag._id
|
||||
},
|
||||
getPermissionRef(false)
|
||||
)
|
||||
await client.createDoc(
|
||||
core.class.ClassPermission,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass,
|
||||
txClass,
|
||||
txMatch: {
|
||||
[isMixin ? 'mixin' : 'objectClass']: masterTag._id
|
||||
},
|
||||
scope: 'space',
|
||||
forbid: true,
|
||||
label: view.string.ForbidAttributeChanges,
|
||||
description: masterTag.label,
|
||||
targetClass: masterTag._id
|
||||
},
|
||||
getPermissionRef(true)
|
||||
)
|
||||
await createTypePermissions(masterTag)
|
||||
}
|
||||
},
|
||||
'top',
|
||||
|
||||
@@ -135,6 +135,26 @@ export default mergeIds(cardId, card, {
|
||||
EnableVersioning: '' as IntlString,
|
||||
EnableVersioningConfirm: '' as IntlString,
|
||||
NewVersionConfirmation: '' as IntlString,
|
||||
RelationCopyDescr: '' as IntlString
|
||||
RelationCopyDescr: '' as IntlString,
|
||||
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
|
||||
}
|
||||
})
|
||||
|
||||
@@ -13,10 +13,11 @@
|
||||
|
||||
import { type AccountClient, getClient as getAccountClientRaw } from '@hcengineering/account-client'
|
||||
import { Analytics } from '@hcengineering/analytics'
|
||||
import { type Card, CardEvents, cardId, type CardSpace, type MasterTag } from '@hcengineering/card'
|
||||
import { type Card, CardEvents, cardId, type CardSpace, type MasterTag, type Tag } from '@hcengineering/card'
|
||||
import core, {
|
||||
AccountRole,
|
||||
type Class,
|
||||
type ClassPermission,
|
||||
type Client,
|
||||
type Data,
|
||||
type Doc,
|
||||
@@ -97,6 +98,183 @@ export async function deleteMasterTag (tag: MasterTag | undefined, onDelete?: ()
|
||||
}
|
||||
}
|
||||
|
||||
export async function createTypePermissions (masterTag: MasterTag | Tag): Promise<void> {
|
||||
const client = getClient()
|
||||
const hierarchy = client.getHierarchy()
|
||||
const isMixin = hierarchy.isMixin(masterTag._id)
|
||||
const objectClass = hierarchy.getBaseClass(masterTag._id)
|
||||
const txClass = isMixin ? core.class.TxMixin : core.class.TxUpdateDoc
|
||||
|
||||
await client.createDoc(
|
||||
core.class.ClassPermission,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass,
|
||||
txClass,
|
||||
txMatch: {
|
||||
[isMixin ? 'mixin' : 'objectClass']: masterTag._id
|
||||
},
|
||||
scope: 'space',
|
||||
forbid: false,
|
||||
label: view.string.AllowAttributeChanges,
|
||||
description: masterTag.label,
|
||||
targetClass: masterTag._id
|
||||
},
|
||||
`${masterTag._id}_allowed` as Ref<ClassPermission>
|
||||
)
|
||||
await client.createDoc(
|
||||
core.class.ClassPermission,
|
||||
core.space.Model,
|
||||
{
|
||||
objectClass,
|
||||
txClass,
|
||||
txMatch: {
|
||||
[isMixin ? 'mixin' : 'objectClass']: masterTag._id
|
||||
},
|
||||
scope: 'space',
|
||||
forbid: true,
|
||||
label: view.string.ForbidAttributeChanges,
|
||||
description: masterTag.label,
|
||||
targetClass: masterTag._id
|
||||
},
|
||||
`${masterTag._id}_forbidden` as Ref<ClassPermission>
|
||||
)
|
||||
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
} 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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
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<ClassPermission>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function cloneCard (
|
||||
origin: Card,
|
||||
overrideProps: Record<string, any>,
|
||||
|
||||
Reference in New Issue
Block a user