The File class can set a file for reading, writing, and executing. To get it by user, you need to use NIO.
The Files class and NIO uses PosixFilePermissions, which sets permissions by file and by three groups: User, owner, and Group. On Windows, Administrators will be in a group, as well as System.
To move it we need our own SecurityManager. When moving files, NIO uses the write permission. So our SecurityManager has to modify the write permission. See my code below as an example.
p.s. although the FileSystemsProvider is WindowsFileSystemProvider, this is returned by FileSystemProviders.getProvider (or the method similar). Its possible that the rt.jar is different for each OS downloaded on, but if you're on Windows you can assume this is correct.
PathRestrictor.java
package Testers;
import java.io.IOException;
import java.net.URI;
import java.nio.channels.SeekableByteChannel;
import java.nio.file.AccessMode;
import java.nio.file.CopyOption;
import java.nio.file.DirectoryStream;
import java.nio.file.DirectoryStream.Filter;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
import java.nio.file.OpenOption;
import java.nio.file.Path;
import java.nio.file.attribute.BasicFileAttributes;
import java.nio.file.attribute.FileAttribute;
import java.nio.file.attribute.FileAttributeView;
import java.nio.file.attribute.PosixFilePermission;
import java.nio.file.spi.FileSystemProvider;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import sun.nio.fs.WindowsFileSystemProvider;
public class PathRestrictor extends FileSystemProvider{
boolean canRead;
boolean canWrite;
boolean canMove; //This is the tricky one
boolean canOpen;
private Path path;
WindowsFileSystemProvider provider = new WindowsFileSystemProvider();
public PathRestrictor(Path p){
path = p;
canRead = true;
canWrite = true;
canOpen = true;
}
public void setExecuteable(boolean executable){
canOpen = executable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setReadable(boolean readable){
canRead = readable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setWriteable(boolean writeable){
canWrite = writeable;
try {
Files.setPosixFilePermissions(path, getPerms());
} catch (IOException e) {
e.printStackTrace();
}
}
public void setMoveable(boolean moveable){
canMove = moveable;
MovementSecurityManager manager = new MovementSecurityManager();
if(!moveable)manager.unMoveablePaths.add(path.toString());
else manager.unMoveablePaths.remove(path.toString());
System.setSecurityManager(manager);
}
private Set<PosixFilePermission> getPerms() {
Set<PosixFilePermission> perms = new HashSet<PosixFilePermission>();
perms.add(PosixFilePermission.GROUP_EXECUTE);
perms.add(PosixFilePermission.GROUP_READ);
perms.add(PosixFilePermission.GROUP_WRITE);
if(canRead){
perms.add(PosixFilePermission.OTHERS_READ);
perms.add(PosixFilePermission.OWNER_READ);
}
if(canWrite){
perms.add(PosixFilePermission.OTHERS_WRITE);
perms.add(PosixFilePermission.OWNER_WRITE);
}
if(canOpen){
perms.add(PosixFilePermission.OTHERS_EXECUTE);
perms.add(PosixFilePermission.OWNER_EXECUTE);
}
return perms;
}
@Override
public void checkAccess(Path path, AccessMode... modes) throws IOException {
provider.checkAccess(path, modes);
}
@Override
public void copy(Path source, Path target, CopyOption... options)
throws IOException {
// TODO Auto-generated method stub
provider.copy(source, target, options);
}
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs)
throws IOException {
provider.createDirectory(dir, attrs);
}
@Override
public void delete(Path path) throws IOException {
provider.delete(path);
}
@Override
public <V extends FileAttributeView> V getFileAttributeView(Path path,
java.lang.Class<V> type, LinkOption... options) {
return provider.getFileAttributeView(path, type, options);
}
@Override
public FileStore getFileStore(Path path) throws IOException {
return provider.getFileStore(path);
}
@Override
public FileSystem getFileSystem(URI uri) {
return provider.getFileSystem(uri);
}
@Override
public Path getPath(URI uri) {
return provider.getPath(uri);
}
@Override
public String getScheme() {
return provider.getScheme();
}
@Override
public boolean isHidden(Path path) throws IOException {
return provider.isHidden(path);
}
@Override
public boolean isSameFile(Path path, Path path2) throws IOException {
return path.toString().equals(path2.toString());
}
@Override
public void move(Path source, Path target, CopyOption... options)
throws IOException {
MovementSecurityManager manager = new MovementSecurityManager();
manager.isMoving = true;
System.setSecurityManager(manager);
provider.move(source, target, options);
}
@Override
public SeekableByteChannel newByteChannel(Path path,
Set<? extends OpenOption> options, FileAttribute<?>... attrs)
throws IOException {
return provider.newByteChannel(path, options, attrs);
}
@Override
public DirectoryStream<Path> newDirectoryStream(Path dir,
Filter<? super Path> filter) throws IOException {
return provider.newDirectoryStream(dir, filter);
}
@Override
public FileSystem newFileSystem(URI uri, Map<String, ?> env)
throws IOException {
return provider.newFileSystem(uri, env);
}
@Override
public <A extends BasicFileAttributes> A readAttributes(Path path,
java.lang.Class<A> type, LinkOption... options) throws IOException {
return provider.readAttributes(path, type, options);
}
@Override
public Map<String, Object> readAttributes(Path path, String attributes,
LinkOption... options) throws IOException {
return provider.readAttributes(path, attributes, options);
}
@Override
public void setAttribute(Path path, String attribute, Object value,
LinkOption... options) throws IOException {
provider.setAttribute(path, attribute, value, options);
}
}
MovementSecurityManager.java
package Testers;
import java.util.HashSet;
import java.util.Set;
public class MovementSecurityManager extends SecurityManager {
public Set<String> unMoveablePaths = new HashSet<String>();
public boolean isMoving = true;
public void checkWrite(String path){
if(unMoveablePaths.contains(path) && isMoving) throw new SecurityException("Cannot move file!");
else super.checkWrite(path);
}
}