Permission
Univer provides the ability to control permissions, which can typically be used to restrict users' operations on workbooks, worksheets, and selections. When a user performs an operation without permission, the code execution can be terminated and the user can be prompted for missing permissions. For example, you can set protection in a selected area to determine whether other collaborators can use editing, reading, copying, filtering, and more within that protected area.
Basic example
workbook permission
Currently, the overall permissions of a workbook are modified directly through the API. We provide the Facade API. You can set the edit permissions of a workbook by calling this API.
import { FUniver } from "@univerjs/facade";
const univerAPI = FUniver.newAPI(univer);
Then you can use Univer by calling the univerAPI
method and set the entire workbook to be uneditable:
univerAPI.getActiveWorkbook().setEditable(false);
The essence is to control the switch of permissions by setting the value of the permission point. The command corresponding to the permission point will read the value of the point before execution. If the permission value is false, the execution of the command will be terminated.
Worksheet permission code example
The permissions for worksheets and selections are set in command mode.
const accessor = univer.__getInjector();
const commandService = accessor.get(ICommandService);
// import { getSheetCommandTarget } from '@univerjs/sheets';
const target = getSheetCommandTarget(univerInstanceService);
if (!target) {
return;
}
const { unitId, subUnitId } = target;
commandService.executeCommand(AddWorksheetProtectionMutation.id, {
unitId,
subUnitId,
rule: {
permissionId: "2sxcza1",
name: "sheet",
unitType: 2,
unitId,
subUnitId,
},
});
This demo is to add protection to the worksheet. permissionId
is a randomly generated unique ID for storing permissions. You need to generate it yourself. unitType
is the type of the worksheet. You can use the UnitObject
enumeration in the warehouse to replace the magic number above. unitId
is the id of the workbook, and subUnitId
is the id of the worksheet.
To delete, you can use DeleteWorksheetProtectionMutation
, the parameters are unitId
and subUnitId
.
DeleteWorksheetProtectionMutationParams {
unitId: string;
subUnitId: string;
}
Custom selection permission code example
const accessor = univer.__getInjector();
const commandService = accessor.get(ICommandService);
const sheetSelectionManagerService = accessor.get(SheetsSelectionsService);
// import { getSheetCommandTarget } from '@univerjs/sheets';
const target = getSheetCommandTarget(univerInstanceService);
if (!target) {
return;
}
const { unitId, subUnitId } = target;
const ranges = sheetSelectionManagerService.getCurrentSelections().map(selection => selection.range);
commandService.executeCommand(AddRangeProtectionMutation.id, {
unitId,
subUnitId,
rules: [{
permissionId: "3xtfxG1",
name: "sheet1",
unitType: 3,
unitId,
subUnitId,
ranges,
id: 'rule1'
}],
});
This demo adds permission protection to a custom selection. The parameters here are the same as above, with the addition of a ranges
parameter, which is the area you selected, and an id
parameter, which is the unique id used to identify this rule and is used to delete this rule.
In typical workflows, the creator of a permissioned area will have the highest level of access, which means they can always edit the area they created. To implement a scenario where no one, including the creator, can edit the area, you can add the following code to the demo provided above.
const permissionService = accessor.get(IPermissionService);
// The third parameter of RangeProtectionPermissionEditPoint is the permissionId generated above. Setting it to false indicates that editing is not allowed.
permissionService.updatePermissionPoint(new RangeProtectionPermissionEditPoint(unitId, subUnitId, "3xtfxG1").id, false);
To delete, you can use DeleteRangeProtectionMutation
, the parameters are unitId
and subUnitId
and the ruleIds
you want to delete in batches.
DeleteRangeProtectionMutationParams {
unitId: string;
subUnitId: string;
ruleIds: string[];
}
Extended usage
Here we take WorkbookEditablePermission
as an example and add permission verification in your own plug-in. Other points are similar.
import { WorkbookEditablePermission } from '@univerjs/sheets';
import { IPermissionService } from '@univerjs/core';
class YourService {
constructor(@IPermissionService private _permissionService: IPermissionService) {
}
setWorkbookNotEditable() {
this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, false);
}
setWorkbookEditable() {
this._permissionService.updatePermissionPoint(new WorkbookEditablePermission('unitId').id, true);
}
}
You can also extend and modify other permission points to achieve permission control for different functions. For a specific list of points, please refer to the bottom of the article.
How to extend the permission point
import { IPermissionService, IPermissionPoint } from '@univerjs/core';
export class CustomPermissionPoint implements IPermissionPoint {
type = UnitObject.Unkonwn; // your type
subType = UnitAction.View; // your subType
status = PermissionStatus.INIT;
value = true; // Initial values
id: string;
constructor(unitId: string, subUnitId: string, customId: string) {
// The id attribute needs to be guaranteed to be unique throughout `IPermissionService`.
this.id = `${unitId}.${subUnitId}.${customId}`;
}
}
class YourService {
constructor(@IPermissionService private _permissionService: IPermissionService) {
this._init()
}
_init() {
this._permissionService.addPermissionPoint(new CustomPermissionPoint('unitId','subUnitId','my-id'));
}
}
// How to use it elsewhere
class ConsumeService {
constructor(@IPermissionService private _permissionService: IPermissionService) {
}
doSomething() {
const point = this._permissionService.getPermissionPoint(new CustomPermissionPoint('unitId','subUnitId','my-id').id);
console.log(point.value);
}
bindEvent() {
// This will get an RX object, allowing you to listen for changes to the current permissions and make a list of changes
const pount$ = this._permissionService.getPermissionPoint$(new CustomPermissionPoint('unitId','subUnitId','my-id').id);
console.log(pount$);
}
}
Integration of Third-Party Authorization Service
The logic for determining permissions is typically handled by an external service, which involves a communication process. In the frontend SDK implementation, we use the AuthzIoLocalService (opens in a new tab) to handle this logic.
In a production environment, we need to replace this implementation with a backend service. The frontend needs to implement the corresponding request functions based on the IAuthzIoService (opens in a new tab) interface for runtime replacement.
Here's how you can replace it:
import { IAuthzIoService, Injector, Univer } from '@univerjs/core';
class YourAuthzService implements IAuthzIoService { }
export class YourPlugin extends Plugin {
override onStarting(injector: Injector): void {
injector.add([IAuthzIoService, { useClass: YourAuthzService }]);
}
}
// By setting the override option to [[IAuthzIoService, null]], you can instruct Univer not to register the built-in IAuthzIoService.
// This way, Univer will use the service provided by YourAuthzService as the implementation of the authorization service.
const univer = new Univer({
override: [[IAuthzIoService, null]],
});
univer.registerPlugin(YourPlugin);
List of permission point bits
To access the specific code related to permission point at the given URL, you can refer to the code (opens in a new tab).
In the case where the permission control of the workbook intersects with the worksheet/range, all permissions must be set to true in order to use them.
Workbook Permissions
Permission | Description |
---|---|
WorkbookEditablePermission | Whether or not editing is allowed. |
WorkbookPrintPermission | Whether or not printing is allowed. |
WorkbookCommentPermission | Whether or not commenting is allowed. |
WorkbookViewPermission | Whether or not viewing is allowed. |
WorkbookCopyPermission | Whether or not copying is allowed. |
WorkbookExportPermission | Whether or not exporting is allowed. |
WorkbookManageCollaboratorPermission | Whether or not managing collaborators is allowed. |
Worksheet Permissions
Permission | Description |
---|---|
WorksheetCopyPermission | Whether or not copying is allowed. |
WorksheetDeleteColumnPermission | Whether or not delete columns is allowed. |
WorksheetDeleteRowPermission | Whether or not delete row is allowed. |
WorksheetFilterPermission | Whether or not sort is allowed. |
WorksheetInsertColumnPermission | Whether or not insert columns is allowed. |
WorksheetInsertHyperlinkPermission | Whether or not use hyperlinks is allowed. |
WorksheetInsertRowPermission | Whether or not insert row is allowed. |
WorksheetPivotTablePermission | Whether or not use pivot tables is allowed. |
WorksheetSetCellStylePermission | Whether or not set cell style is allowed. |
WorksheetSetCellValuePermission | Whether or not set cell value is allowed. |
WorksheetSetColumnStylePermission | Whether or not set column style is allowed. |
WorksheetSetRowStylePermission | Whether or not set row style is allowed. |
WorksheetSortPermission | Whether or not use sort is allowed. |
WorksheetViewPermission | Whether or not viewing is allowed. |
WorksheetEditPermission | Whether or not editing is allowed. |
Range Permissions
Permission | Description |
---|---|
RangeProtectionPermissionViewPoint | Whether or not view the contents of a protected area. |
RangeProtectionPermissionEditPoint | Whether or not edit the contents of a protected area. |