8abc8f4bc9
Created by Github action <!-- This is an auto-generated description by cubic. --> <a href="https://cubic.dev/pr/twentyhq/twenty/pull/23618?utm_source=github" target="_blank" rel="noopener noreferrer" data-no-image-dialog="true"><picture><source media="(prefers-color-scheme: dark)" srcset="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"><source media="(prefers-color-scheme: light)" srcset="https://www.cubic.dev/buttons/review-in-cubic-light.svg"><img alt="Review in cubic" src="https://www.cubic.dev/buttons/review-in-cubic-dark.svg"></picture></a> <!-- End of auto-generated description by cubic. --> Co-authored-by: github-actions <github-actions@twenty.com>
208 lines
9.3 KiB
Plaintext
208 lines
9.3 KiB
Plaintext
---
|
||
title: Ruoli e permessi
|
||
description: Dichiara quali oggetti e campi le funzioni di logica e i componenti front-end della tua app possono leggere e scrivere.
|
||
icon: shield-halved
|
||
---
|
||
|
||
Un **ruolo** è un insieme di permessi: quali oggetti un’app può leggere o scrivere, quali campi può vedere e quali funzionalità a livello di piattaforma può usare. Tutte le funzioni di logica e i componenti front-end di ogni app ereditano i permessi del ruolo contrassegnato con `defineApplicationRole()` (vedi [The default function role](#the-default-function-role) di seguito).
|
||
|
||
```ts src/roles/restricted-company-role.ts
|
||
import {
|
||
defineRole,
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||
SystemPermissionFlag,
|
||
} from 'twenty-sdk/define';
|
||
|
||
export default defineRole({
|
||
universalIdentifier: '2c80f640-2083-4803-bb49-003e38279de6',
|
||
label: 'My new role',
|
||
description: 'A role that can be used in your workspace',
|
||
canReadAllObjectRecords: false,
|
||
canUpdateAllObjectRecords: false,
|
||
canSoftDeleteAllObjectRecords: false,
|
||
canDestroyAllObjectRecords: false,
|
||
canUpdateAllSettings: false,
|
||
canBeAssignedToAgents: false,
|
||
canBeAssignedToUsers: false,
|
||
canBeAssignedToApiKeys: false,
|
||
objectPermissions: [
|
||
{
|
||
objectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||
canReadObjectRecords: true,
|
||
canUpdateObjectRecords: true,
|
||
canSoftDeleteObjectRecords: false,
|
||
canDestroyObjectRecords: false,
|
||
},
|
||
],
|
||
fieldPermissions: [
|
||
{
|
||
objectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||
fieldUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.fields.name
|
||
.universalIdentifier,
|
||
canReadFieldValue: false,
|
||
canUpdateFieldValue: false,
|
||
},
|
||
],
|
||
permissionFlagUniversalIdentifiers: [SystemPermissionFlag.APPLICATIONS],
|
||
});
|
||
```
|
||
|
||
## Sicurezza a livello di riga
|
||
|
||
Le autorizzazioni sugli oggetti e sui campi determinano *quali oggetti e campi* un ruolo può gestire. **I predicati di autorizzazione
|
||
a livello di riga** vanno oltre e determinano *quali record* un ruolo può vedere e su cui può agire — per
|
||
esempio, un ruolo self-service in cui ogni utente esterno vede solo i propri record.
|
||
|
||
Dichiara i predicati con `rowLevelPermissionPredicates` sul ruolo. Come il resto del manifest,
|
||
ogni predicato ha il proprio `universalIdentifier` e fa riferimento a un oggetto e a un campo tramite il loro
|
||
`universalIdentifier`, un `operand` e (facoltativamente) un campo workspaceMember il cui valore viene iniettato
|
||
al momento della query — così puoi esprimere "la relazione di proprietario del record **è** l'attuale membro dello spazio di lavoro":
|
||
|
||
```ts src/roles/partner-role.ts
|
||
import {
|
||
defineRole,
|
||
RowLevelPermissionPredicateOperand,
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||
} from 'twenty-sdk/define';
|
||
|
||
import { ACCOUNT_OWNER_FIELD_UNIVERSAL_IDENTIFIER } from '../fields/account-owner.field';
|
||
|
||
export default defineRole({
|
||
universalIdentifier: 'c3c1dc2e-1a08-4de5-abb7-2139b3d99343',
|
||
label: 'Partner',
|
||
description: 'External partner — sees only its own records',
|
||
canBeAssignedToUsers: true,
|
||
objectPermissions: [
|
||
{
|
||
objectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||
canReadObjectRecords: true,
|
||
canUpdateObjectRecords: true,
|
||
},
|
||
],
|
||
rowLevelPermissionPredicates: [
|
||
{
|
||
universalIdentifier: 'd0f0c1a2-3b4c-4d5e-8f60-111111111111',
|
||
objectUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.company.universalIdentifier,
|
||
fieldUniversalIdentifier: ACCOUNT_OWNER_FIELD_UNIVERSAL_IDENTIFIER,
|
||
operand: RowLevelPermissionPredicateOperand.IS,
|
||
workspaceMemberFieldUniversalIdentifier:
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.workspaceMember.fields.id
|
||
.universalIdentifier,
|
||
},
|
||
],
|
||
});
|
||
```
|
||
|
||
Poiché i predicati vengono distribuiti nel manifest, vengono creati, aggiornati e rimossi insieme al ruolo a ogni installazione e aggiornamento — non è necessario alcun passaggio post-installazione separato per mantenerli sincronizzati.
|
||
|
||
### Combinare i predicati con i gruppi
|
||
|
||
Per impostazione predefinita, i predicati di un ruolo sono combinati con `AND`. Per combinarne alcuni con `OR` (o per annidare la logica), dichiara una voce `rowLevelPermissionPredicateGroups` e collega ogni predicato ad essa tramite `predicateGroupUniversalIdentifier`. Questo ruolo consente a un partner di vedere un'Opportunità di cui **è proprietario**
|
||
o per cui è il **punto di contatto**:
|
||
|
||
```ts src/roles/partner-opportunities-role.ts
|
||
import {
|
||
defineRole,
|
||
RowLevelPermissionPredicateGroupLogicalOperator,
|
||
RowLevelPermissionPredicateOperand,
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS,
|
||
} from 'twenty-sdk/define';
|
||
|
||
const OPPORTUNITY = STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.opportunity;
|
||
const CURRENT_MEMBER =
|
||
STANDARD_OBJECT_UNIVERSAL_IDENTIFIERS.workspaceMember.fields.id
|
||
.universalIdentifier;
|
||
|
||
export default defineRole({
|
||
universalIdentifier: 'b2a1c0d9-8e7f-4a6b-9c5d-222222222222',
|
||
label: 'Partner (opportunities)',
|
||
canBeAssignedToUsers: true,
|
||
objectPermissions: [
|
||
{
|
||
objectUniversalIdentifier: OPPORTUNITY.universalIdentifier,
|
||
canReadObjectRecords: true,
|
||
},
|
||
],
|
||
rowLevelPermissionPredicateGroups: [
|
||
{
|
||
universalIdentifier: 'c3b2a1d0-9f8e-4b7a-8d6c-333333333333',
|
||
objectUniversalIdentifier: OPPORTUNITY.universalIdentifier,
|
||
logicalOperator: RowLevelPermissionPredicateGroupLogicalOperator.OR,
|
||
},
|
||
],
|
||
rowLevelPermissionPredicates: [
|
||
{
|
||
universalIdentifier: 'd4c3b2a1-0e9f-4c8b-9e7d-444444444444',
|
||
objectUniversalIdentifier: OPPORTUNITY.universalIdentifier,
|
||
fieldUniversalIdentifier: OPPORTUNITY.fields.owner.universalIdentifier,
|
||
operand: RowLevelPermissionPredicateOperand.IS,
|
||
workspaceMemberFieldUniversalIdentifier: CURRENT_MEMBER,
|
||
predicateGroupUniversalIdentifier: 'c3b2a1d0-9f8e-4b7a-8d6c-333333333333',
|
||
},
|
||
{
|
||
universalIdentifier: 'e5d4c3b2-1f0e-4d9c-8f8e-555555555555',
|
||
objectUniversalIdentifier: OPPORTUNITY.universalIdentifier,
|
||
fieldUniversalIdentifier:
|
||
OPPORTUNITY.fields.pointOfContact.universalIdentifier,
|
||
operand: RowLevelPermissionPredicateOperand.IS,
|
||
workspaceMemberFieldUniversalIdentifier: CURRENT_MEMBER,
|
||
predicateGroupUniversalIdentifier: 'c3b2a1d0-9f8e-4b7a-8d6c-333333333333',
|
||
},
|
||
],
|
||
});
|
||
```
|
||
|
||
Note:
|
||
|
||
* Assegna a ogni predicato e gruppo un `universalIdentifier` stabile (qualsiasi uuid) — identifica l'entità attraverso gli aggiornamenti e i predicati fanno riferimento ai gruppi tramite esso.
|
||
* I predicati possono fare riferimento a oggetti e campi di proprietà della tua app o degli oggetti standard di Twenty.
|
||
* La sicurezza a livello di riga è applicata per gli spazi di lavoro sui piani che la includono; i predicati vengono comunque sincronizzati sugli altri piani, semplicemente non vengono applicati.
|
||
|
||
## Ruolo funzione predefinito
|
||
|
||
Quando esegui lo scaffolding di una nuova app, la CLI crea un file di ruolo predefinito dichiarato con `defineApplicationRole()`:
|
||
|
||
```ts src/roles/default-role.ts
|
||
import { defineApplicationRole } from 'twenty-sdk/define';
|
||
|
||
export const DEFAULT_ROLE_UNIVERSAL_IDENTIFIER =
|
||
'b648f87b-1d26-4961-b974-0908fd991061';
|
||
|
||
export default defineApplicationRole({
|
||
universalIdentifier: DEFAULT_ROLE_UNIVERSAL_IDENTIFIER,
|
||
label: 'Default function role',
|
||
description: 'Default role for function Twenty client',
|
||
canReadAllObjectRecords: true,
|
||
canUpdateAllObjectRecords: false,
|
||
canSoftDeleteAllObjectRecords: false,
|
||
canDestroyAllObjectRecords: false,
|
||
canUpdateAllSettings: false,
|
||
canBeAssignedToAgents: false,
|
||
canBeAssignedToUsers: false,
|
||
canBeAssignedToApiKeys: false,
|
||
objectPermissions: [],
|
||
fieldPermissions: [],
|
||
permissionFlagUniversalIdentifiers: [],
|
||
});
|
||
```
|
||
|
||
`defineApplicationRole()` è un leggero wrapper attorno a `defineRole()` che contrassegna il ruolo usato come predefinito per la tua applicazione al momento dell’installazione. La convalida è identica a `defineRole`, ma la pipeline di build collega automaticamente il suo `universalIdentifier` al `defaultRoleUniversalIdentifier` del manifest dell’applicazione — quindi non è necessario farvi riferimento in [`defineApplication`](/l/it/developers/extend/apps/config/application).
|
||
|
||
Note:
|
||
|
||
* È consentita esattamente **una** chiamata a `defineApplicationRole(...)` per app — la build del manifest avrà esito negativo se ne trova più di una.
|
||
* Usa `defineRole()` (non `defineApplicationRole()`) per qualsiasi ruolo **aggiuntivo** fornito dalla tua app.
|
||
* L’impostazione esplicita di `defaultRoleUniversalIdentifier` in `defineApplication()` è ancora supportata per retrocompatibilità, ma è deprecata a favore di `defineApplicationRole()`.
|
||
|
||
## Migliori Pratiche
|
||
|
||
* Parti dal ruolo generato dallo scaffold, poi restringilo progressivamente: il ruolo predefinito concede un ampio accesso in lettura, che raramente è ciò che vuoi in produzione.
|
||
* Sostituisci `objectPermissions` e `fieldPermissions` con gli oggetti e i campi di cui le tue funzioni hanno realmente bisogno.
|
||
* `permissionFlagUniversalIdentifiers` controllano l'accesso alle funzionalità a livello di piattaforma. Mantienili al minimo.
|
||
* Vedi un esempio di lavoro: [`examples/hello-world/src/roles/default-role.ts`](https://github.com/twentyhq/twenty/blob/main/packages/twenty-apps/examples/hello-world/src/roles/default-role.ts).
|