1 -------------------------------------------------- 2 FakeFtpServer Filesystems 3 -------------------------------------------------- 4 5 FakeFtpServer Filesystems 6 ~~~~~~~~~~~~~~~~~~~~~~~~~ 7 8 <<FakeFtpServer>> provides a simulated server file system, including support for file and directory permissions 9 and owner and group authorization based on Unix. This file system can be populated at startup (or thereafter) with 10 directories and files (including arbitrary content) to be retrieved by an FTP client. Any files sent to the server 11 by an FTP client exist within that file system as well, and can be accessed through the file system API, or 12 can even be subsequently retrieved by an FTP client. 13 14 The filesystem abstraction is accessed through the <<<FileSystem>>> interface in the 15 <<<org.mockftpserver.fake.filesystem>>> package. Two implementations of this interface are provided: 16 <<<WindowsFakeFileSystem>>> and <<<UnixFakeFileSystem>>>. They both manage the files and directories in memory, 17 simulating a real file system. You are also free to implement your own <<<FileSystem>>> implementation. 18 19 Note that both <<<WindowsFakeFileSystem>>> and <<<UnixFakeFileSystem>>> are <virtual> file systems, and do 20 not depend on the <real> operating systems or file systems on which <<FakeFtpServer>> is running. In other 21 words, you can configure and run a <<FakeFtpServer>> with a <<<WindowsFakeFileSystem>>> on top of a <real> 22 Unix system, or run a <<FakeFtpServer>> with a <<<UnixFakeFileSystem>>> on top of a <real> Windows system. 23 24 See the javadoc for these classes for more information. 25 26 27 * WindowsFakeFileSystem 28 ~~~~~~~~~~~~~~~~~~~~~~~ 29 30 <<WindowsFakeFileSystem>> is an implementation of the <<<FileSystem>>> interface that simulates a Microsoft 31 Windows file system. The rules for file and directory names include: 32 33 * Filenames are case-insensitive 34 35 * Either forward slashes (/) or backward slashes (\) are valid path separators (but are normalized to '\') 36 37 * An absolute path starts with a drive specifier (e.g. 'a:' or 'c:') followed by '\' or '/', 38 or else it starts with "\\"</li> 39 40 41 * UnixFakeFileSystem 42 ~~~~~~~~~~~~~~~~~~~~ 43 44 <<UnixFakeFileSystem>> is an implementation of the <<<FileSystem>>> interface that simulates a Unix 45 file system. The rules for file and directory names include: 46 47 * Filenames are case-sensitive 48 49 * Forward slashes (/) are the only valid path separators 50 51 52 * WindowsFakeFileSystem and UnixFakeFileSystem: Common Behavior and Configuration 53 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 54 55 Both <<<WindowsFakeFileSystem>>> and <<<UnixFakeFileSystem>>> are subclasses of <<<AbstractFakeFileSystem>>>. They 56 manage the files and directories in memory, simulating a real file system. 57 58 If the <createParentDirectoriesAutomatically> property is set to <true>, 59 then creating a directory or file will automatically create any parent directories (recursively) 60 that do not already exist. If <false>, then creating a directory or file throws an 61 exception if its parent directory does not exist. This value defaults to <true>. 62 63 The <directoryListingFormatter> property holds an instance of <<DirectoryListingFormatter>>, 64 used by the <formatDirectoryListing> method to format directory listings in a 65 filesystem-specific manner. This property is initialized by concrete subclasses. 66 67 68 * File Permissions, Owners and Groups 69 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 70 71 Each <file> or <directory> entry within a <<<FileSystem>>> has associated <owner>, <group> and <permissions> 72 attributes. All of these attributes are optional. If none are specified for a file or directory, then full 73 access by all users is the default. 74 75 If, however, these values are specified for a filesystem entry, then they affect whether a file can be created, 76 read, written or deleted, and whether a directory can be created, listed or deleted. 77 78 This approach for access control is conceptually (and somewhat loosely) based on the Unix file system, but 79 don't expect a comprehensive implementation fully matching Unix's capabilities. 80 81 82 ** Permissions 83 ~~~~~~~~~~~~~~ 84 85 The permissions for a file or directory entry in the filesystem are represented by a 9-character string of 86 the form "rwxrwxrwx", consisting of three "rwx" triples. Each triple indicates the READ ("r"), WRITE ("w") and 87 EXECUTE ("x") permissions for a specific set of users. Each position can alternatively contain a "-" to 88 indicate no READ/WRITE/EXECUTE access, depending on its position. 89 90 The first "rwx" triple indicates the READ, WRITE and EXECUTE permissions for the owner of the file. The 91 second triple indicates the permissions for the group associated with the file. The third triple 92 indicates the permissions for the rest of the world. 93 94 For example, the permissions string "rwx--xrw-" is interpreted to mean that users have READ/WRITE/EXECUTE access, 95 the group has only EXECUTE, and the world has only READ and WRITE. 96 97 There are plenty of good tutorials and references for understanding Unix file permissions, including 98 {{{http://www.dartmouth.edu/~rc/help/faq/permissions.html}this one}}. 99 100 The <<<Permissions>>> class represents and encapsulates the read/write/execute permissions for a file or 101 directory. Its constructor takes a 9-character "rwx" String as described above. 102 103 The <<<AbstractFileSystemEntry>>> contains a <permissions> attribute, so that every file and directory in the 104 file system can be assigned a unique set of permissions from a <<<Permissions>>> object. There is also a 105 <<<setPermissionsFromString()>>> convenience setter that allows setting the permissions directly from a String. 106 107 108 ** FileSystem Access Rules 109 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ 110 111 *** When Are READ, WRITE or EXECUTE Access Required? 112 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 113 114 If the <permissions> are configured for a file or directory within the <<<FileSystem>>>, then 115 those permissions affect whether and how that file/directory can be accessed. 116 Here are the rules for applying permissions for file access: 117 118 *------------------------*-------------------------------------------------------------------* 119 | <<Operation>> | <<Required Permissions>> | 120 *------------------------*-------------------------------------------------------------------* 121 | Create a new file | EXECUTE access to the directory and WRITE access to the directory | 122 *------------------------*-------------------------------------------------------------------* 123 | Read a file | EXECUTE access to the directory and READ access to the file | 124 *------------------------*-------------------------------------------------------------------* 125 | Write a file | EXECUTE access to the directory and WRITE access to the file | 126 *------------------------*-------------------------------------------------------------------* 127 | Delete a file | WRITE access to the directory | 128 *------------------------*-------------------------------------------------------------------* 129 | Rename a file | READ access to the FROM file and WRITE access to the directory | 130 *------------------------*-------------------------------------------------------------------* 131 | Create a directory | WRITE and EXECUTE acccess to the parent directory | 132 *------------------------*-------------------------------------------------------------------* 133 | List a directory | READ acccess to the directory/file | 134 *------------------------*-------------------------------------------------------------------* 135 | CD to a directory | EXECUTE acccess to the directory | 136 *------------------------*-------------------------------------------------------------------* 137 | Delete a directory | WRITE acccess to the parent directory | 138 *------------------------*-------------------------------------------------------------------* 139 140 *** How Do Owner and Group Affect Access? 141 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 142 143 Each file and directory in the filesystem (subclass of <<<AbstractFileSystemEntry>>>) contains <owner> 144 and <group> attributes. These attributes are optional. 145 146 If the <owner> is configured for a file/directory, AND the <permissions> are configured as well, 147 then the <<owner>> triple from the <permissions> are applied if and only if the <<<UserAccount>>> for the 148 currently logged in FTP user (client) matches the <owner> configured for the file/directory. 149 150 Similarly, if the <group> is configured for a file/directory, AND the <permissions> are configured as well, 151 then the <<group>> triple from the <permissions> are applied if and only if <groups> configured for the 152 <<<UserAccount>>> for the currently logged in FTP user (client) contain the <group> configured for the file/directory. 153 154 Otherwise, the <<world>> triple from the <permissions> are applied. 155 156 * Example Code 157 ~~~~~~~~~~~~~~ 158 159 This example illustrates setting the permissions, owner and group for directories and files within the 160 <<<FakeFtpServer>>> filesystem. In this case, the filesystem is an instance of <<<WindowsFakeFileSystem>>>, 161 but the code would be almost exactly the same for <<<UnixFakeFileSystem>>> as well. 162 163 +------------------------------------------------------------------------------ 164 final String USER1 = "joe"; 165 final String USER2 = "mary"; 166 final String GROUP = "dev"; 167 final String CONTENTS = "abcdef 1234567890"; 168 169 FileSystem fileSystem = new WindowsFakeFileSystem(); 170 DirectoryEntry directoryEntry1 = new DirectoryEntry("c:\\"); 171 directoryEntry1.setPermissions(new Permissions("rwxrwx---")); 172 directoryEntry1.setOwner(USER1); 173 directoryEntry1.setGroup(GROUP); 174 175 DirectoryEntry directoryEntry2 = new DirectoryEntry("c:\\data"); 176 directoryEntry2.setPermissions(Permissions.ALL); 177 directoryEntry2.setOwner(USER1); 178 directoryEntry2.setGroup(GROUP); 179 180 FileEntry fileEntry1 = new FileEntry("c:\\data\\file1.txt", CONTENTS); 181 fileEntry1.setPermissionsFromString("rw-rw-rw-"); 182 fileEntry1.setOwner(USER1); 183 fileEntry1.setGroup(GROUP); 184 185 FileEntry fileEntry2 = new FileEntry("c:\\data\\run.exe"); 186 fileEntry2.setPermissionsFromString("rwxrwx---"); 187 fileEntry2.setOwner(USER2); 188 fileEntry2.setGroup(GROUP); 189 190 fileSystem.add(directoryEntry1); 191 fileSystem.add(directoryEntry2); 192 fileSystem.add(fileEntry1); 193 fileSystem.add(fileEntry2); 194 195 FakeFtpServer fakeFtpServer = new FakeFtpServer(); 196 fakeFtpServer.setFileSystem(fileSystem); 197 +------------------------------------------------------------------------------ 198 199 Things to note about the above example: 200 201 * The <<<FakeFtpServer>>> instance is configured with a <<<WindowsFakeFileSystem>>> and a "c:\" root 202 directory with a "data" sub-directory containing two files. Permissions and owner/group are specified for 203 both directories and both files. 204 205 * The permissions for the directories are specified using the "permissions" setter, which takes an 206 instance of the <<<Permissions>>> class. The permissions for both files are specified using the 207 "permissionsFromString" shortcut method. Either way is fine -- use whichever method you prefer on 208 both files and directories. 209 210 [] 211 212 When you want to retrieve and/or verify the contents of the <<<FakeFtpServer>>> filesystem, you can use 213 the <<<FileSystem#getEntry(String path)>>> method, as shown in the following code. 214 215 +------------------------------------------------------------------------------ 216 DirectoryEntry dirEntry = (DirectoryEntry)fileSystem.getEntry("c:/data"); 217 218 FileEntry fileEntry = (FileEntry)fileSystem.getEntry("c:/data/file1.txt"); 219 220 FileEntry newFileEntry = (FileEntry)fileSystem.getEntry("c:/data/new.txt"); 221 InputStream inputStream = newFileEntry.createInputStream(); 222 // read the file contents using inputStream 223 +------------------------------------------------------------------------------ 224 225 See the javadoc for <<<FileSystem>>>, <<<FileEntry>>> and <<<DirectoryEntry>>> for more information 226 on the methods available. 227 228 229 ** Example Using Spring Configuration 230 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 231 232 See the {{{./fakeftpserver-getting-started.html#Spring}FakeFtpServer Getting Started - Spring Configuration}} 233 for an example of how to configure a <<<FakeFtpServer>>> instance and associated filesystem in the 234 {{{http://www.springframework.org/}Spring Framework}}. 235