Search code examples
javasftpapache-commonsapache-commons-vfs

Apache commons sftp - go above user home directory


We have a server which uses the following convention:

/pathA/Users/
/pathB/data/

When users log in they end up at the respective /pathA/Users/user/ dir, but they sometimes need to access /pathB/data/ . I want to write a browser that, using sftp, would let users browse content of the server (I would be happy to find a java tool for that I could just plug into my application, but failed to find anything that matches all my requirements). The problem I have is that apache-commons-vfs accepts a string of form

sftp://user:password@host 

and uses that to log into the user directory and treat that directory as a root. The effect is that I can't step above that dir, calling getParent() on corresponding FileObject returns null. I know it is possible to step above the user home dir using sftp over terminal, so I guess this is a limitation imposed by apache-commons-vfs library. Would anyone happen to know if I can go around that problem so that browsing around the whole server would be possible?


Solution

  • Well, you actually can. check this code!

    public class Test {
    
        public static void main(String[] args) throws Exception {
            FileSystemOptions opts = new FileSystemOptions();
            SftpFileSystemConfigBuilder.getInstance().setStrictHostKeyChecking(opts, "no");
            SftpFileSystemConfigBuilder.getInstance().setUserDirIsRoot(opts, false);
            FileSystemManager fileSystemManager = VFS.getManager();
            FileObject fileObject = fileSystemManager
                    .resolveFile("sftp://user:password@host/",opts);
    
            // foo is under SERVER ROOT not USER's!!!
    
            FileObject temp = fileObject.resolveFile("/foo/faa/frog/");
            FileObject fileObjects[] = temp.getChildren();
    
            try {
                for (FileObject j : fileObjects) {
    
                    System.out.println(j.getName().getBaseName());
                    j.close();
                }
            } finally {
                fileObject.close();
                temp.close();
            }
        }
    }