Protected check on object - #3432
Conversation
|
👋 A new build is available for this PR based on 081bd22. |
sebjulliand
left a comment
There was a problem hiding this comment.
@buzzia2001 overall it's OK, but there are a couple of things to change.
And I guess think you can push the logic a bit further:
- the
code-for-ibmi.createSourceFilecommand should also not be allowed to run on protected targets (filters and library objects) - the
isProtected()abstract method fromObjectBrowserItemshould be pulled up into its super classObjectItem. Then,DebugItemandEnvironmentItemwill define it to always returnfalse, andIFSItemcan benefit from it and return an actual value, based on the actual protection status of the IFS item. Thi seems to be a cleaner approach and avoid type checks like{ isProtected()?: boolean }.
| protected: parseFSOptions(uri).readonly || ibmi?.getConfig().readOnlyMode | ||
| || (uri.scheme === `object` | ||
| ? ibmi?.getContent().isProtectedPath(Tools.parseQSysPath(uri.path).library) | ||
| : ibmi?.getContent().isProtectedPath(uri.path)) | ||
| || false, |
There was a problem hiding this comment.
The whole function should be like this to take into account library objects:
const extension = uri.path.substring(uri.path.lastIndexOf(`.`) + 1).toUpperCase();
let path = uri.path;
if (uri.scheme === `object`) {
const qsysPath = Tools.parseQSysPath(path);
path = (extension === 'LIB' ? qsysPath.name.split('.')[0] : qsysPath.library);
}
return {
uri,
extension,
fragment: uri.fragment.toUpperCase(),
protected: ibmi?.getConfig().readOnlyMode ||
parseFSOptions(uri).readonly ||
ibmi?.getContent().isProtectedPath(path) ||
false,
workspaceFolder: workspaceFolder || vscode.workspace.getWorkspaceFolder(uri),
executionOK: false,
hasRun: false,
processed: false,
output: []
};| }), | ||
| vscode.commands.registerCommand(`code-for-ibmi.renameQSYS`, async (node?: (ObjectBrowserMemberItem | ObjectBrowserObjectItem)) => { | ||
| node = getSelectedItems(node).at(0); | ||
| if (node instanceof ObjectBrowserItem && checkProtected(node)) { |
There was a problem hiding this comment.
This is enough; all nodes from the object browser extend ObjectBrowserItem that defines isProtected().
| if (node instanceof ObjectBrowserItem && checkProtected(node)) { | |
| if (node && checkProtected(node)) { |
| function checkProtected(node: { isProtected?: () => boolean, toString(): string }): boolean { | ||
| if (node?.isProtected?.()) { | ||
| vscode.window.showWarningMessage(vscode.l10n.t(`{0} is in a protected filter or library and cannot be modified.`, node.toString())); | ||
| return true; | ||
| } | ||
| return false; | ||
| } |
There was a problem hiding this comment.
node is always defined and its type will always inherit ObjectBrowserItem that always defines isProtected().
| function checkProtected(node: { isProtected?: () => boolean, toString(): string }): boolean { | |
| if (node?.isProtected?.()) { | |
| vscode.window.showWarningMessage(vscode.l10n.t(`{0} is in a protected filter or library and cannot be modified.`, node.toString())); | |
| return true; | |
| } | |
| return false; | |
| } | |
| function checkProtected(node: ObjectBrowserItem): boolean { | |
| if (node.isProtected()) { | |
| vscode.window.showWarningMessage(vscode.l10n.t(`{0} is in a protected filter or library and cannot be modified.`, node.toString())); | |
| return true; | |
| } | |
| return false; | |
| } |
|
@sebjulliand to you |
sebjulliand
left a comment
There was a problem hiding this comment.
We're almost there @buzzia2001!
Now that we have the protected state accross the IFS browser, actions that cannot run on protected IFS files should be hidden.
These four specifically:
Keep up the good work! 😄
| } | ||
|
|
||
| isProtected(): boolean { | ||
| return isProtected(this.path); |
There was a problem hiding this comment.
Since the path protection applies to directories, a file needs to check its parent node protection state.
| return isProtected(this.path); | |
| return this.file.type === "directory" ? isProtected(this.path) : this.parent?.isProtected() || false; |
|
👋 A new build is available for this PR based on 679fd31. |
|
@sebjulliand I hope we've reached the end of this PR hahaha |
sebjulliand
left a comment
There was a problem hiding this comment.
@buzzia2001 it's all good!
Just one thing I noticed, not directly related to this PR but worth fixing while we're at it: the IFS paths isProtected check is case sensitive, which is only valid for /QOpensys paths. The rest of the IFS FS is case insensitive.
So here is an enhancement for the isProtectedPath() function in IBMIContent.ts on line 1058:
isProtectedPath(path: string) {
if (path[0] === '/') { //IFS path
//QOpensys FS is case sensistive
const flag = /^\/QOpenSys/i.test(path) ? '' : 'i';
return this.config.protectedPaths.some(p => new RegExp(escapeStringRegexp(p), flag).test(path));
}
else { //QSYS path
const qsysObject = Tools.parseQSysPath(path);
return this.config.protectedPaths.includes(this.ibmi.upperCaseName(qsysObject.library));
}
}With this, we make the check case insensitive unless the protected path is in QOpenSys.
|
@sebjulliand to you |
sebjulliand
left a comment
There was a problem hiding this comment.
Good job @buzzia2001 , it's fully working!
Changes
This PR adds a check on “protected” filters for objects as well
How to test this PR
Create a “protected” filter; when you click on an object, there should be no options to rename, move, or delete objects.
The actions to be performed must also be flagged to run in a protected environment.
Checklist
console.logs I added