Skip to content

Commit 8fbeb32

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 8fbeb32

File tree

5 files changed

+127
-2
lines changed

5 files changed

+127
-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: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@
4141
import org.eclipse.core.resources.IProjectDescription;
4242
import org.eclipse.core.resources.IResource;
4343
import org.eclipse.core.resources.IResourceStatus;
44+
import org.eclipse.core.resources.ResourcesPlugin;
4445
import org.eclipse.core.runtime.Assert;
4546
import org.eclipse.core.runtime.CoreException;
4647
import org.eclipse.core.runtime.IPath;
@@ -61,6 +62,12 @@
6162
*/
6263
public class File extends Resource implements IFile {
6364

65+
/**
66+
* Session property used to mark a file as containing restricted content
67+
*/
68+
private static final QualifiedName RESTRICTED_CONTENT =
69+
new QualifiedName(ResourcesPlugin.PI_RESOURCES, "restrictedContent"); //$NON-NLS-1$
70+
6471
protected File(IPath path, Workspace container) {
6572
super(path, container);
6673
}
@@ -670,4 +677,14 @@ public String getLineSeparator(boolean checkParent) throws CoreException {
670677
return checkParent ? getProject().getDefaultLineSeparator() : null;
671678
}
672679

680+
@Override
681+
public boolean isContentRestricted() throws CoreException {
682+
Object sessionProperty = getSessionProperty(RESTRICTED_CONTENT);
683+
return Boolean.TRUE.equals(sessionProperty);
684+
}
685+
686+
@Override
687+
public void setContentRestricted(boolean restricted) throws CoreException {
688+
setSessionProperty(RESTRICTED_CONTENT, restricted ? Boolean.TRUE : null);
689+
}
673690
}

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

Lines changed: 37 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
@@ -21,7 +21,9 @@
2121
import java.io.Reader;
2222
import java.net.URI;
2323
import java.util.Objects;
24+
import org.eclipse.core.internal.resources.ResourceException;
2425
import org.eclipse.core.internal.utils.FileUtil;
26+
import org.eclipse.core.internal.utils.Messages;
2527
import org.eclipse.core.runtime.CoreException;
2628
import org.eclipse.core.runtime.IAdaptable;
2729
import org.eclipse.core.runtime.IPath;
@@ -32,6 +34,7 @@
3234
import org.eclipse.core.runtime.Status;
3335
import org.eclipse.core.runtime.content.IContentDescription;
3436
import org.eclipse.core.runtime.content.IContentTypeManager;
37+
import org.eclipse.osgi.util.NLS;
3538

3639
/**
3740
* Files are leaf resources which contain data.
@@ -1414,4 +1417,37 @@ public default String readString() throws CoreException {
14141417
public default String getLineSeparator(boolean checkParent) throws CoreException {
14151418
return getProject().getDefaultLineSeparator();
14161419
}
1420+
1421+
/**
1422+
* Returns whether the current file is marked as containing restricted
1423+
* (sensitive) content, where some IDE functionality related to the file content
1424+
* might be limited. The file must exist.
1425+
*
1426+
* @return whether the current file is marked as containing sensitive content.
1427+
* This flag is not persisted and is {@code false} by default
1428+
* @throws CoreException if the file doesn't exist or if this method fails
1429+
* @since 3.24
1430+
*/
1431+
default boolean isContentRestricted() throws CoreException {
1432+
if (!exists()) {
1433+
String message = NLS.bind(Messages.resources_mustExist, getFullPath());
1434+
throw new ResourceException(IResourceStatus.RESOURCE_NOT_FOUND, getFullPath(), message, null);
1435+
}
1436+
return false;
1437+
}
1438+
1439+
/**
1440+
* Marks the current file as containing restricted (sensitive) content. Some IDE
1441+
* functionality related to the file content might be limited as long as the
1442+
* file is marked as restricted. The file must exist. This flag is not persisted
1443+
* and is {@code false} by default.
1444+
*
1445+
* @param restricted <code>true</code> if the file should be marked restricted,
1446+
* <code>false</code> if the file should be unmarked
1447+
* @throws CoreException if the file doesn't exist or if this method fails
1448+
* @since 3.24
1449+
*/
1450+
default void setContentRestricted(boolean restricted) throws CoreException {
1451+
throw new CoreException(Status.error("Not implemented")); //$NON-NLS-1$
1452+
}
14171453
}

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: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
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+
project.create(null);
41+
project.open(null);
42+
43+
IFile file1 = project.getFile("test1.txt");
44+
IFile file2 = project.getFile("test2.txt");
45+
46+
try {
47+
file1.isContentRestricted();
48+
fail("Should not work on not existing files");
49+
} catch (CoreException e) {
50+
// expected, file should not exist
51+
}
52+
53+
file1.create("line 1".getBytes(), IResource.FORCE, null);
54+
file2.create("line 1".getBytes(), IResource.FORCE, null);
55+
56+
assertFalse(file1.isContentRestricted(), "Expected file to not be restricted");
57+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
58+
59+
file1.setContentRestricted(true);
60+
assertTrue(file1.isContentRestricted(), "Expected file to be restricted");
61+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
62+
63+
file1 = project.getFile("test1.txt");
64+
file2 = project.getFile("test2.txt");
65+
assertTrue(file1.isContentRestricted(), "Expected file to be restricted");
66+
assertFalse(file2.isContentRestricted(), "Expected file to not be restricted");
67+
} finally {
68+
project.delete(true, null);
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)