Read only VirtualFileSystemFactory

229 Views Asked by At

I am trying to create a read only VirtualFileSystemFactory for a custom sftp server using Apache Mina SSHD library. I have searched a lot but it seems that I cant find the solution to this problem. IS there maybe someone who knows how to do this ?

Here is my VirtualFileSystemFactory

VirtualFileSystemFactory virtualFileSystemFactory = new VirtualFileSystemFactory() {
            @Override
            public FileSystem createFileSystem(Session session) throws IOException {
                String username = session.getUsername();
                Path dir = Paths.get("c:\\data\\");
                if (dir == null) {
                    throw new InvalidPathException(username, "Cannot resolve home directory");
                } else {
                    return (new RootedFileSystemProvider()).newFileSystem(dir, Collections.emptyMap());
                }
            }
        };

        // Virtual Factory
        sshd.setFileSystemFactory(virtualFileSystemFactory);
1

There are 1 best solutions below

0
Arash Kahbasi On

I had the same issue. As you can see VirtualFileSystemFactory is creating a RootedFileSystemProvider which contains the file system operations. You can extend both classes to get your customized one.

As I tested the Scp commands and SFTP interface this overridden code can prevent the client from making changes, however, you can change it to your needs.

public class ReadOnlyRootedFileSystemProvider extends RootedFileSystemProvider {

    @Override
    public OutputStream newOutputStream(Path path, OpenOption... options) throws IOException {
        if (Arrays.stream(options).anyMatch(option -> option == StandardOpenOption.CREATE))
            throw new RuntimeException("Writing files is not allowed on this file system");
        return super.newOutputStream(path, options);
    }

    @Override
    public FileChannel newFileChannel(Path path, Set<? extends OpenOption> options, FileAttribute<?>... attrs) throws IOException {
        if (options.contains(StandardOpenOption.CREATE_NEW) || options.contains(StandardOpenOption.WRITE))
            throw new RuntimeException("Writing files is not allowed on this file system");
        return super.newFileChannel(path, options, attrs);
    }

    @Override
    public void delete(Path path) throws IOException {
        throw new RuntimeException("Deleting is not allowed on this file system");
    }

    @Override
    public boolean deleteIfExists(Path path) throws IOException {
        throw new RuntimeException("Deleting is not allowed on this file system");
    } 
}