mirror of
https://github.com/Alfresco/alfresco-content-app.git
synced 2025-05-12 17:04:46 +00:00
[ACA-2199] Upload Version - granular permission (#938)
* canUploadVersion evaluator * change upload version action rule * update docs * simplify condition * unit tests and code fixes
This commit is contained in:
parent
7c38201500
commit
bb5ce29445
@ -129,29 +129,30 @@ The button will be visible only when the linked rule evaluates to `true`.
|
||||
|
||||
## Application Evaluators
|
||||
|
||||
| Key | Description |
|
||||
| ------------------------------- | ------------------------------------------------------------ |
|
||||
| app.selection.canDelete | User has permission to delete selected node(s). |
|
||||
| app.selection.canDownload | User can download selected node(s). |
|
||||
| app.selection.notEmpty | At least one node is selected. |
|
||||
| app.selection.canUnshare | User is able to remove selected node(s) from public sharing. |
|
||||
| app.selection.canAddFavorite | User can add selected node(s) to favorites. |
|
||||
| app.selection.canRemoveFavorite | User can remove selected node(s) from favorites. |
|
||||
| app.selection.first.canUpdate | User has permission to update selected node(s). |
|
||||
| app.selection.file | A single File node is selected. |
|
||||
| app.selection.file.canShare | User is able to share the selected file. |
|
||||
| app.selection.file.isShared | A shared node is selected |
|
||||
| app.selection.file.isLocked | File is locked for editing |
|
||||
| app.selection.library | A single Library node is selected. |
|
||||
| app.selection.isPrivateLibrary | A private Library node is selected. |
|
||||
| app.selection.hasLibraryRole | The selected Library node has a role property. |
|
||||
| app.selection.hasNoLibraryRole | The selected Library node has no role property. |
|
||||
| app.selection.folder | A single Folder node is selected. |
|
||||
| app.selection.folder.canUpdate | User has permissions to update the selected folder. |
|
||||
| app.selection.folder.canUpdate | User has permissions to update the selected folder. |
|
||||
| app.selection.file.canLock | User has permissions to lock file. |
|
||||
| app.selection.file.canUnlock | User has permissions to unlock file. |
|
||||
| repository.isQuickShareEnabled | Whether the quick share repository option is enabled or not. |
|
||||
| Key | Description |
|
||||
| ----------------------------------- | ------------------------------------------------------------ |
|
||||
| app.selection.canDelete | User has permission to delete selected node(s). |
|
||||
| app.selection.canDownload | User can download selected node(s). |
|
||||
| app.selection.notEmpty | At least one node is selected. |
|
||||
| app.selection.canUnshare | User is able to remove selected node(s) from public sharing. |
|
||||
| app.selection.canAddFavorite | User can add selected node(s) to favorites. |
|
||||
| app.selection.canRemoveFavorite | User can remove selected node(s) from favorites. |
|
||||
| app.selection.first.canUpdate | User has permission to update selected node(s). |
|
||||
| app.selection.file | A single File node is selected. |
|
||||
| app.selection.file.canShare | User is able to share the selected file. |
|
||||
| app.selection.file.isShared | A shared node is selected |
|
||||
| app.selection.file.isLocked | File is locked for editing |
|
||||
| app.selection.file.canUploadVersion | User can update file version |
|
||||
| app.selection.library | A single Library node is selected. |
|
||||
| app.selection.isPrivateLibrary | A private Library node is selected. |
|
||||
| app.selection.hasLibraryRole | The selected Library node has a role property. |
|
||||
| app.selection.hasNoLibraryRole | The selected Library node has no role property. |
|
||||
| app.selection.folder | A single Folder node is selected. |
|
||||
| app.selection.folder.canUpdate | User has permissions to update the selected folder. |
|
||||
| app.selection.folder.canUpdate | User has permissions to update the selected folder. |
|
||||
| app.selection.file.canLock | User has permissions to lock file. |
|
||||
| app.selection.file.canUnlock | User has permissions to unlock file. |
|
||||
| repository.isQuickShareEnabled | Whether the quick share repository option is enabled or not. |
|
||||
|
||||
## Navigation Evaluators
|
||||
|
||||
|
@ -123,6 +123,7 @@ export class CoreExtensionsModule {
|
||||
'app.selection.file.canShare': app.canShareFile,
|
||||
'app.selection.file.isShared': app.isShared,
|
||||
'app.selection.file.isLocked': app.hasLockedFiles,
|
||||
'app.selection.file.canUploadVersion': app.canUploadVersion,
|
||||
'app.selection.library': app.hasLibrarySelected,
|
||||
'app.selection.isPrivateLibrary': app.isPrivateLibrary,
|
||||
'app.selection.hasLibraryRole': app.hasLibraryRole,
|
||||
|
316
src/app/extensions/evaluators/app.evaluators.spec.ts
Normal file
316
src/app/extensions/evaluators/app.evaluators.spec.ts
Normal file
@ -0,0 +1,316 @@
|
||||
/*!
|
||||
* @license
|
||||
* Alfresco Example Content Application
|
||||
*
|
||||
* Copyright (C) 2005 - 2018 Alfresco Software Limited
|
||||
*
|
||||
* This file is part of the Alfresco Example Content Application.
|
||||
* If the software was purchased under a paid Alfresco license, the terms of
|
||||
* the paid license agreement will prevail. Otherwise, the software is
|
||||
* provided under the following open source license terms:
|
||||
*
|
||||
* The Alfresco Example Content Application is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Lesser General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* The Alfresco Example Content Application is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with Alfresco. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import * as app from './app.evaluators';
|
||||
|
||||
describe('app.evaluators', () => {
|
||||
describe('isWriteLocked', () => {
|
||||
it('should return [true] if lock type is set', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
file: {
|
||||
entry: {
|
||||
properties: {
|
||||
'cm:lockType': 'WRITE_LOCK'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isWriteLocked(context, null)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if lock type is not set', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
file: {
|
||||
entry: {
|
||||
properties: {}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.isWriteLocked(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if selection not present', () => {
|
||||
const context: any = {};
|
||||
|
||||
expect(app.isWriteLocked(context, null)).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('hasLockedFiles', () => {
|
||||
it('should return [false] if selection not present', () => {
|
||||
const context: any = {};
|
||||
expect(app.hasLockedFiles(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if nodes not present', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
nodes: null
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.hasLockedFiles(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if no files selected', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: false
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
isFile: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.hasLockedFiles(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [true] when one of files is locked', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: true
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: false
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.hasLockedFiles(context, null)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
it('should return [true] when one of files has readonly lock', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: false
|
||||
}
|
||||
},
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: false,
|
||||
properties: {
|
||||
'cm:lockType': 'READ_ONLY_LOCK'
|
||||
}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.hasLockedFiles(context, null)).toBe(true);
|
||||
});
|
||||
|
||||
describe('canUpdateSelectedNode', () => {
|
||||
it('should return [false] if selection not preset', () => {
|
||||
const context: any = {};
|
||||
|
||||
expect(app.canUpdateSelectedNode(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if selection is empty', () => {
|
||||
const context: any = {
|
||||
selection: {
|
||||
isEmpty: true
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUpdateSelectedNode(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if first selection is not a file', () => {
|
||||
const context: any = {
|
||||
permissions: {
|
||||
check: () => false
|
||||
},
|
||||
selection: {
|
||||
isEmpty: false,
|
||||
first: {
|
||||
entry: {
|
||||
isFile: false
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUpdateSelectedNode(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should return [false] if the file is locked', () => {
|
||||
const context: any = {
|
||||
permissions: {
|
||||
check: () => true
|
||||
},
|
||||
selection: {
|
||||
isEmpty: false,
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: true
|
||||
}
|
||||
}
|
||||
],
|
||||
first: {
|
||||
entry: {
|
||||
isFile: true,
|
||||
isLocked: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUpdateSelectedNode(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should evaluate allowable operation for the file', () => {
|
||||
const context: any = {
|
||||
permissions: {
|
||||
check: () => true
|
||||
},
|
||||
selection: {
|
||||
isEmpty: false,
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: true,
|
||||
allowableOperationsOnTarget: []
|
||||
}
|
||||
}
|
||||
],
|
||||
first: {
|
||||
entry: {
|
||||
isFile: true,
|
||||
allowableOperationsOnTarget: []
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUpdateSelectedNode(context, null)).toBe(true);
|
||||
});
|
||||
});
|
||||
|
||||
describe('canUploadVersion', () => {
|
||||
it('should return [true] if user has locked it previously', () => {
|
||||
const context: any = {
|
||||
profile: {
|
||||
id: 'user1'
|
||||
},
|
||||
selection: {
|
||||
file: {
|
||||
entry: {
|
||||
properties: {
|
||||
'cm:lockType': 'WRITE_LOCK',
|
||||
'cm:lockOwner': {
|
||||
id: 'user1'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUploadVersion(context, null)).toBe(true);
|
||||
});
|
||||
|
||||
it('should return [false] if other user has locked it previously', () => {
|
||||
const context: any = {
|
||||
profile: {
|
||||
id: 'user2'
|
||||
},
|
||||
selection: {
|
||||
file: {
|
||||
entry: {
|
||||
properties: {
|
||||
'cm:lockType': 'WRITE_LOCK',
|
||||
'cm:lockOwner': {
|
||||
id: 'user1'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUploadVersion(context, null)).toBe(false);
|
||||
});
|
||||
|
||||
it('should check the [update] operation when no write lock present', () => {
|
||||
let checked = false;
|
||||
const context: any = {
|
||||
permissions: {
|
||||
check: () => (checked = true)
|
||||
},
|
||||
selection: {
|
||||
isEmpty: false,
|
||||
nodes: [
|
||||
{
|
||||
entry: {
|
||||
isFile: true
|
||||
}
|
||||
}
|
||||
],
|
||||
first: {
|
||||
entry: {
|
||||
isFile: true
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
expect(app.canUploadVersion(context, null)).toBe(true);
|
||||
expect(checked).toBe(true);
|
||||
});
|
||||
});
|
||||
});
|
@ -283,17 +283,21 @@ export function hasLockedFiles(
|
||||
context: RuleContext,
|
||||
...args: RuleParameter[]
|
||||
): boolean {
|
||||
return context.selection.nodes.some(node => {
|
||||
if (!node.entry.isFile) {
|
||||
return false;
|
||||
}
|
||||
if (context && context.selection && context.selection.nodes) {
|
||||
return context.selection.nodes.some(node => {
|
||||
if (!node.entry.isFile) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
node.entry.isLocked ||
|
||||
(node.entry.properties &&
|
||||
node.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK')
|
||||
);
|
||||
});
|
||||
return (
|
||||
node.entry.isLocked ||
|
||||
(node.entry.properties &&
|
||||
node.entry.properties['cm:lockType'] === 'READ_ONLY_LOCK')
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
export function isWriteLocked(
|
||||
@ -301,6 +305,8 @@ export function isWriteLocked(
|
||||
...args: RuleParameter[]
|
||||
): boolean {
|
||||
return !!(
|
||||
context &&
|
||||
context.selection &&
|
||||
context.selection.file &&
|
||||
context.selection.file.entry &&
|
||||
context.selection.file.entry.properties &&
|
||||
@ -340,3 +346,12 @@ export function canUnlockFile(
|
||||
isUserWriteLockOwner(context, ...args))
|
||||
);
|
||||
}
|
||||
|
||||
export function canUploadVersion(
|
||||
context: AppRuleContext,
|
||||
...args: RuleParameter[]
|
||||
): boolean {
|
||||
return isWriteLocked(context, ...args)
|
||||
? isUserWriteLockOwner(context, ...args)
|
||||
: canUpdateSelectedNode(context, ...args);
|
||||
}
|
||||
|
@ -662,7 +662,7 @@
|
||||
"click": "UPLOAD_FILE_VERSION"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
"visible": "app.selection.file.canUploadVersion"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -878,7 +878,7 @@
|
||||
"click": "UPLOAD_FILE_VERSION"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
"visible": "app.selection.file.canUploadVersion"
|
||||
}
|
||||
},
|
||||
{
|
||||
@ -1102,7 +1102,7 @@
|
||||
"click": "UPLOAD_FILE_VERSION"
|
||||
},
|
||||
"rules": {
|
||||
"visible": "app.toolbar.versions"
|
||||
"visible": "app.selection.file.canUploadVersion"
|
||||
}
|
||||
},
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user