-------------------------------------------------- FakeFtpServer Filesystems -------------------------------------------------- FakeFtpServer Filesystems ~~~~~~~~~~~~~~~~~~~~~~~~~ <> provides a simulated server file system, including support for file and directory permissions and owner and group authorization based on Unix. This file system can be populated at startup (or thereafter) with directories and files (including arbitrary content) to be retrieved by an FTP client. Any files sent to the server by an FTP client exist within that file system as well, and can be accessed through the file system API, or can even be subsequently retrieved by an FTP client. The filesystem abstraction is accessed through the <<>> interface in the <<>> package. Two implementations of this interface are provided: <<>> and <<>>. They both manage the files and directories in memory, simulating a real file system. You are also free to implement your own <<>> implementation. Note that both <<>> and <<>> are file systems, and do not depend on the operating systems or file systems on which <> is running. In other words, you can configure and run a <> with a <<>> on top of a Unix system, or run a <> with a <<>> on top of a Windows system. See the javadoc for these classes for more information. * WindowsFakeFileSystem ~~~~~~~~~~~~~~~~~~~~~~~ <> is an implementation of the <<>> interface that simulates a Microsoft Windows file system. The rules for file and directory names include: * Filenames are case-insensitive * Either forward slashes (/) or backward slashes (\) are valid path separators (but are normalized to '\') * An absolute path starts with a drive specifier (e.g. 'a:' or 'c:') followed by '\' or '/', or else it starts with "\\" * UnixFakeFileSystem ~~~~~~~~~~~~~~~~~~~~ <> is an implementation of the <<>> interface that simulates a Unix file system. The rules for file and directory names include: * Filenames are case-sensitive * Forward slashes (/) are the only valid path separators * WindowsFakeFileSystem and UnixFakeFileSystem: Common Behavior and Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Both <<>> and <<>> are subclasses of <<>>. They manage the files and directories in memory, simulating a real file system. If the property is set to , then creating a directory or file will automatically create any parent directories (recursively) that do not already exist. If , then creating a directory or file throws an exception if its parent directory does not exist. This value defaults to . The property holds an instance of <>, used by the method to format directory listings in a filesystem-specific manner. This property is initialized by concrete subclasses. * File Permissions, Owners and Groups ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each or entry within a <<>> has associated , and attributes. All of these attributes are optional. If none are specified for a file or directory, then full access by all users is the default. If, however, these values are specified for a filesystem entry, then they affect whether a file can be created, read, written or deleted, and whether a directory can be created, listed or deleted. This approach for access control is conceptually (and somewhat loosely) based on the Unix file system, but don't expect a comprehensive implementation fully matching Unix's capabilities. ** Permissions ~~~~~~~~~~~~~~ The permissions for a file or directory entry in the filesystem are represented by a 9-character string of the form "rwxrwxrwx", consisting of three "rwx" triples. Each triple indicates the READ ("r"), WRITE ("w") and EXECUTE ("x") permissions for a specific set of users. Each position can alternatively contain a "-" to indicate no READ/WRITE/EXECUTE access, depending on its position. The first "rwx" triple indicates the READ, WRITE and EXECUTE permissions for the owner of the file. The second triple indicates the permissions for the group associated with the file. The third triple indicates the permissions for the rest of the world. For example, the permissions string "rwx--xrw-" is interpreted to mean that users have READ/WRITE/EXECUTE access, the group has only EXECUTE, and the world has only READ and WRITE. There are plenty of good tutorials and references for understanding Unix file permissions, including {{{http://www.dartmouth.edu/~rc/help/faq/permissions.html}this one}}. The <<>> class represents and encapsulates the read/write/execute permissions for a file or directory. Its constructor takes a 9-character "rwx" String as described above. The <<>> contains a attribute, so that every file and directory in the file system can be assigned a unique set of permissions from a <<>> object. There is also a <<>> convenience setter that allows setting the permissions directly from a String. ** FileSystem Access Rules ~~~~~~~~~~~~~~~~~~~~~~~~~~~ *** When Are READ, WRITE or EXECUTE Access Required? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ If the are configured for a file or directory within the <<>>, then those permissions affect whether and how that file/directory can be accessed. Here are the rules for applying permissions for file access: *------------------------*-------------------------------------------------------------------* | <> | <> | *------------------------*-------------------------------------------------------------------* | Create a new file | EXECUTE access to the directory and WRITE access to the directory | *------------------------*-------------------------------------------------------------------* | Read a file | EXECUTE access to the directory and READ access to the file | *------------------------*-------------------------------------------------------------------* | Write a file | EXECUTE access to the directory and WRITE access to the file | *------------------------*-------------------------------------------------------------------* | Delete a file | WRITE access to the directory | *------------------------*-------------------------------------------------------------------* | Rename a file | READ access to the FROM file and WRITE access to the directory | *------------------------*-------------------------------------------------------------------* | Create a directory | WRITE and EXECUTE acccess to the parent directory | *------------------------*-------------------------------------------------------------------* | List a directory | READ acccess to the directory/file | *------------------------*-------------------------------------------------------------------* | CD to a directory | EXECUTE acccess to the directory | *------------------------*-------------------------------------------------------------------* | Delete a directory | WRITE acccess to the parent directory | *------------------------*-------------------------------------------------------------------* *** How Do Owner and Group Affect Access? ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Each file and directory in the filesystem (subclass of <<>>) contains and attributes. These attributes are optional. If the is configured for a file/directory, AND the are configured as well, then the <> triple from the are applied if and only if the <<>> for the currently logged in FTP user (client) matches the configured for the file/directory. Similarly, if the is configured for a file/directory, AND the are configured as well, then the <> triple from the are applied if and only if configured for the <<>> for the currently logged in FTP user (client) contain the configured for the file/directory. Otherwise, the <> triple from the are applied. * Example Code ~~~~~~~~~~~~~~ This example illustrates setting the permissions, owner and group for directories and files within the <<>> filesystem. In this case, the filesystem is an instance of <<>>, but the code would be almost exactly the same for <<>> as well. +------------------------------------------------------------------------------ final String USER1 = "joe"; final String USER2 = "mary"; final String GROUP = "dev"; final String CONTENTS = "abcdef 1234567890"; FileSystem fileSystem = new WindowsFakeFileSystem(); DirectoryEntry directoryEntry1 = new DirectoryEntry("c:\\"); directoryEntry1.setPermissions(new Permissions("rwxrwx---")); directoryEntry1.setOwner(USER1); directoryEntry1.setGroup(GROUP); DirectoryEntry directoryEntry2 = new DirectoryEntry("c:\\data"); directoryEntry2.setPermissions(Permissions.ALL); directoryEntry2.setOwner(USER1); directoryEntry2.setGroup(GROUP); FileEntry fileEntry1 = new FileEntry("c:\\data\\file1.txt", CONTENTS); fileEntry1.setPermissionsFromString("rw-rw-rw-"); fileEntry1.setOwner(USER1); fileEntry1.setGroup(GROUP); FileEntry fileEntry2 = new FileEntry("c:\\data\\run.exe"); fileEntry2.setPermissionsFromString("rwxrwx---"); fileEntry2.setOwner(USER2); fileEntry2.setGroup(GROUP); fileSystem.add(directoryEntry1); fileSystem.add(directoryEntry2); fileSystem.add(fileEntry1); fileSystem.add(fileEntry2); FakeFtpServer fakeFtpServer = new FakeFtpServer(); fakeFtpServer.setFileSystem(fileSystem); +------------------------------------------------------------------------------ Things to note about the above example: * The <<>> instance is configured with a <<>> and a "c:\" root directory with a "data" sub-directory containing two files. Permissions and owner/group are specified for both directories and both files. * The permissions for the directories are specified using the "permissions" setter, which takes an instance of the <<>> class. The permissions for both files are specified using the "permissionsFromString" shortcut method. Either way is fine -- use whichever method you prefer on both files and directories. [] When you want to retrieve and/or verify the contents of the <<>> filesystem, you can use the <<>> method, as shown in the following code. +------------------------------------------------------------------------------ DirectoryEntry dirEntry = (DirectoryEntry)fileSystem.getEntry("c:/data"); FileEntry fileEntry = (FileEntry)fileSystem.getEntry("c:/data/file1.txt"); FileEntry newFileEntry = (FileEntry)fileSystem.getEntry("c:/data/new.txt"); InputStream inputStream = newFileEntry.createInputStream(); // read the file contents using inputStream +------------------------------------------------------------------------------ See the javadoc for <<>>, <<>> and <<>> for more information on the methods available. ** Example Using Spring Configuration ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See the {{{./fakeftpserver-getting-started.html#Spring}FakeFtpServer Getting Started - Spring Configuration}} for an example of how to configure a <<>> instance and associated filesystem in the {{{http://www.springframework.org/}Spring Framework}}.