Skip to content

Commit 8aa8740

Browse files
committed
Add API for restricting operations for sensitive files
This change adds the following API: * org.eclipse.core.resources.IFile.isContentRestricted() * org.eclipse.core.resources.IFile.setContentRestricted(boolean) The goal of this API is to allow Eclipse-based IDEs to restrict certain platform functionality on a per-file basis, for sensitive files. The flags are not persisted, to enable restricted handling these flags must be set for each session. The restrictions will apply to following functionality: * File search * Storing file history Potentially more platform functionality will be restricted. See: #2588
1 parent e02781c commit 8aa8740

File tree

7 files changed

+160
-2
lines changed

7 files changed

+160
-2
lines changed

resources/bundles/org.eclipse.core.resources/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.core.resources; singleton:=true
5-
Bundle-Version: 3.23.300.qualifier
5+
Bundle-Version: 3.24.0.qualifier
66
Bundle-Activator: org.eclipse.core.resources.ResourcesPlugin
77
Bundle-Vendor: %providerName
88
Bundle-Localization: plugin

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/File.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*******************************************************************************
2-
* Copyright (c) 2000, 2015 IBM Corporation and others.
2+
* Copyright (c) 2000, 2026 IBM Corporation and others.
33
*
44
* This program and the accompanying materials
55
* are made available under the terms of the Eclipse Public License 2.0
@@ -61,6 +61,8 @@
6161
*/
6262
public class File extends Resource implements IFile {
6363

64+
private volatile boolean isRestricted;
65+
6466
protected File(IPath path, Workspace container) {
6567
super(path, container);
6668
}
@@ -670,4 +672,13 @@ public String getLineSeparator(boolean checkParent) throws CoreException {
670672
return checkParent ? getProject().getDefaultLineSeparator() : null;
671673
}
672674

675+
@Override
676+
public boolean isContentRestricted() {
677+
return isRestricted;
678+
}
679+
680+
@Override
681+
public void setContentRestricted(boolean restricted) {
682+
isRestricted = restricted;
683+
}
673684
}

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/internal/resources/Workspace.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -271,6 +271,8 @@ public class Workspace extends PlatformObject implements IWorkspace, ICoreConsta
271271
*/
272272
protected IFileModificationValidator validator = null;
273273

274+
private volatile boolean enableRestrictedContent;
275+
274276
/**
275277
* Data structure for holding the multi-part outcome of
276278
* <code>IWorkspace.computeProjectBuildConfigOrder</code>.
@@ -2945,4 +2947,14 @@ private void createMultiple(ConcurrentMap<File, byte[]> filesToCreate, int updat
29452947
subMonitor.done();
29462948
}
29472949
}
2950+
2951+
@Override
2952+
public boolean isRestrictedContentEnabled() {
2953+
return enableRestrictedContent;
2954+
}
2955+
2956+
@Override
2957+
public void setRestrictedContentEnabled(boolean enabled) {
2958+
this.enableRestrictedContent = enabled;
2959+
}
29482960
}

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IFile.java

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@
5353
* @noextend This interface is not intended to be extended by clients.
5454
*/
5555
public interface IFile extends IResource, IEncodedStorage, IAdaptable {
56+
5657
/**
5758
* Character encoding constant (value 0) which identifies
5859
* files that have an unknown character encoding scheme.
@@ -1414,4 +1415,28 @@ public default String readString() throws CoreException {
14141415
public default String getLineSeparator(boolean checkParent) throws CoreException {
14151416
return getProject().getDefaultLineSeparator();
14161417
}
1418+
1419+
/**
1420+
* Returns whether the current file is marked as containing restricted
1421+
* (sensitive) content, where some IDE functionality related to the file content
1422+
* might be limited.
1423+
*
1424+
* @return whether the current file is marked as containing sensitive content.
1425+
* This flag is not persisted and is {@code false} by default.
1426+
* @since 3.24
1427+
*/
1428+
boolean isContentRestricted();
1429+
1430+
/**
1431+
* Marks the current file as containing restricted (sensitive) content. Some IDE
1432+
* functionality related to the file content might be limited as long as the
1433+
* file is marked as restricted. This flag is not persisted and is {@code false}
1434+
* by default.
1435+
*
1436+
* @param restricted <code>true</code> if the file should be a marked
1437+
* restricted, <code>false</code> if the file should be
1438+
* unmarked
1439+
* @since 3.24
1440+
*/
1441+
void setContentRestricted(boolean restricted);
14171442
}

resources/bundles/org.eclipse.core.resources/src/org/eclipse/core/resources/IWorkspace.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1861,4 +1861,37 @@ public default void write(Map<IFile, byte[]> contentMap, boolean force, boolean
18611861
e.getKey().write(e.getValue(), force, derived, keepHistory, subMon.split(1));
18621862
}
18631863
}
1864+
1865+
/**
1866+
* Returns whether certain IDE functionality should be disabled for restricted
1867+
* (sensitive) files. Examples are file history and search. Default is
1868+
* <code>false</code>.
1869+
* <p>
1870+
* Restricted files are marked with: {@link IFile#setContentRestricted(boolean)}
1871+
* </p>
1872+
*
1873+
* @return <code>true</code> if restricted (sensitive) files handling is enabled
1874+
* by the IDE, <code>false</code> otherwise
1875+
* @see IFile#setContentRestricted(boolean)
1876+
* @see IFile#isContentRestricted()
1877+
* @since 3.24
1878+
*/
1879+
boolean isRestrictedContentEnabled();
1880+
1881+
/**
1882+
* Specifies whether certain IDE functionality should be disabled for restricted
1883+
* (sensitive) files. Examples are file history and search. This flag is not
1884+
* persisted and must be set for every new session that requires file
1885+
* restrictions.
1886+
* <p>
1887+
* Restricted files are marked with: {@link IFile#setContentRestricted(boolean)}
1888+
* </p>
1889+
*
1890+
* @param enabled <code>true</code> to enable restricted (sensitive) files
1891+
* handling, <code>false</code> otherwise
1892+
* @see IFile#setContentRestricted(boolean)
1893+
* @see IFile#isContentRestricted()
1894+
* @since 3.24
1895+
*/
1896+
void setRestrictedContentEnabled(boolean enabled);
18641897
}

resources/tests/org.eclipse.core.tests.resources/src/org/eclipse/core/tests/internal/resources/AllInternalResourcesTests.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
ResourceInfoTest.class, //
3333
WorkspaceConcurrencyTest.class, //
3434
WorkspacePreferencesTest.class, //
35+
RestrictedFileTests.class, //
3536
})
3637
public class AllInternalResourcesTests {
3738
}
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2026 Simeon Andreev and others.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* Simeon Andreev - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.core.tests.internal.resources;
15+
16+
import static org.junit.jupiter.api.Assertions.assertFalse;
17+
import static org.junit.jupiter.api.Assertions.assertTrue;
18+
import static org.junit.jupiter.api.Assertions.fail;
19+
20+
import org.eclipse.core.resources.IFile;
21+
import org.eclipse.core.resources.IProject;
22+
import org.eclipse.core.resources.IResource;
23+
import org.eclipse.core.resources.IWorkspace;
24+
import org.eclipse.core.resources.IWorkspaceRoot;
25+
import org.eclipse.core.resources.ResourcesPlugin;
26+
import org.eclipse.core.runtime.CoreException;
27+
import org.eclipse.core.tests.resources.util.WorkspaceResetExtension;
28+
import org.junit.jupiter.api.Test;
29+
import org.junit.jupiter.api.extension.ExtendWith;
30+
31+
@ExtendWith(WorkspaceResetExtension.class)
32+
public class RestrictedFileTests {
33+
34+
@Test
35+
public void testRestrictedFile() throws Exception {
36+
IWorkspace workspace = ResourcesPlugin.getWorkspace();
37+
IWorkspaceRoot root = workspace.getRoot();
38+
IProject project = root.getProject(RestrictedFileTests.class.getSimpleName());
39+
try {
40+
assertFalse(workspace.isRestrictedContentEnabled(),
41+
"Expected file content to not be restricted by default");
42+
workspace.setRestrictedContentEnabled(true);
43+
44+
project.create(null);
45+
project.open(null);
46+
47+
IFile file1 = project.getFile("test1.txt");
48+
IFile file2 = project.getFile("test2.txt");
49+
50+
try {
51+
file1.isContentRestricted();
52+
fail("Should not work on not existing files");
53+
} catch (CoreException e) {
54+
// expected, file should not exist
55+
}
56+
57+
file1.create("line 1".getBytes(), IResource.FORCE, null);
58+
file2.create("line 1".getBytes(), IResource.FORCE, null);
59+
60+
assertFalse(file1.isContentRestricted(), "Expected file to not be restricted");
61+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
62+
63+
file1.setContentRestricted(true);
64+
assertTrue(file1.isContentRestricted(), "Expected file to be restricted");
65+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
66+
67+
workspace.setRestrictedContentEnabled(false);
68+
69+
assertFalse(file1.isContentRestricted(), "Expected file to not be restricted");
70+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
71+
} finally {
72+
workspace.setRestrictedContentEnabled(false);
73+
project.delete(true, null);
74+
}
75+
}
76+
}

0 commit comments

Comments
 (0)