Skip to content

Protected check on object - #3432

Merged
sebjulliand merged 6 commits into
masterfrom
ProtectedObject
Aug 31, 2026
Merged

Protected check on object#3432
sebjulliand merged 6 commits into
masterfrom
ProtectedObject

Conversation

@buzzia2001

Copy link
Copy Markdown
Member

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

  • have tested my change
  • have created one or more test cases
  • updated relevant documentation
  • Remove any/all console.logs I added
  • have added myself to the contributors' list in CONTRIBUTING.md

@buzzia2001
buzzia2001 requested a review from a team August 29, 2026 17:30
@buzzia2001 buzzia2001 self-assigned this Aug 29, 2026
@buzzia2001 buzzia2001 added the enhancement New feature or request label Aug 29, 2026
@github-actions

github-actions Bot commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

👋 A new build is available for this PR based on 081bd22.

@sebjulliand sebjulliand left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.createSourceFile command should also not be allowed to run on protected targets (filters and library objects)
  • the isProtected() abstract method from ObjectBrowserItem should be pulled up into its super class ObjectItem. Then, DebugItem and EnvironmentItem will define it to always return false, and IFSItem can 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 }.

Comment thread src/webviews/filters/index.ts Outdated
Comment thread src/ui/actions.ts Outdated
Comment on lines +50 to +54
protected: parseFSOptions(uri).readonly || ibmi?.getConfig().readOnlyMode
|| (uri.scheme === `object`
? ibmi?.getContent().isProtectedPath(Tools.parseQSysPath(uri.path).library)
: ibmi?.getContent().isProtectedPath(uri.path))
|| false,

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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: []
  };

Comment thread src/ui/views/objectBrowser.ts Outdated
}),
vscode.commands.registerCommand(`code-for-ibmi.renameQSYS`, async (node?: (ObjectBrowserMemberItem | ObjectBrowserObjectItem)) => {
node = getSelectedItems(node).at(0);
if (node instanceof ObjectBrowserItem && checkProtected(node)) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is enough; all nodes from the object browser extend ObjectBrowserItem that defines isProtected().

Suggested change
if (node instanceof ObjectBrowserItem && checkProtected(node)) {
if (node && checkProtected(node)) {

Comment thread src/ui/views/objectBrowser.ts Outdated
Comment on lines +1564 to +1570
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;
}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

node is always defined and its type will always inherit ObjectBrowserItem that always defines isProtected().

Suggested change
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;
}

@buzzia2001
buzzia2001 requested a review from sebjulliand August 30, 2026 14:58
@buzzia2001

Copy link
Copy Markdown
Member Author

@sebjulliand to you

@sebjulliand sebjulliand left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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:

Image

Keep up the good work! 😄

Comment thread src/ui/views/ifsBrowser.ts Outdated
}

isProtected(): boolean {
return isProtected(this.path);

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since the path protection applies to directories, a file needs to check its parent node protection state.

Suggested change
return isProtected(this.path);
return this.file.type === "directory" ? isProtected(this.path) : this.parent?.isProtected() || false;

@github-actions

Copy link
Copy Markdown
Contributor

👋 A new build is available for this PR based on 679fd31.

@buzzia2001
buzzia2001 requested a review from sebjulliand August 30, 2026 20:54
@buzzia2001

Copy link
Copy Markdown
Member Author

@sebjulliand I hope we've reached the end of this PR hahaha

@sebjulliand sebjulliand left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@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.

@buzzia2001

Copy link
Copy Markdown
Member Author

@sebjulliand to you

@buzzia2001
buzzia2001 requested a review from sebjulliand August 31, 2026 09:01

@sebjulliand sebjulliand left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good job @buzzia2001 , it's fully working!

@sebjulliand
sebjulliand merged commit e10750d into master Aug 31, 2026
3 of 4 checks passed
@sebjulliand
sebjulliand deleted the ProtectedObject branch August 31, 2026 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants