em-ftpd-memory 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 935bb1e47a5d580f87e0b150f866074fdf5ac242
4
- data.tar.gz: 976fcbab17763aeddf50197cd3bd36279fa7b7e8
3
+ metadata.gz: 8fd32c31bff6d70f1558c6909462a3edb19d675a
4
+ data.tar.gz: 99a62b6e7e4cdac319b33b813d2d1f26660a8fe7
5
5
  SHA512:
6
- metadata.gz: 8d00f379e4d9b66db5f43aeabc4caa9588cd82ff6ecc93d67eeb06c84c506896b12f736a813652a1da5c741db55978c13aa5b21e158caa60b4b88f4a081ac9be
7
- data.tar.gz: 5aac095867e9ed4ae16224ac3e852763d091d6471ed75dc0e73698d635b7c271c3ec2777055a5f21357033de79453e7004fdeee109f9e40aec0a3f2102679afd
6
+ metadata.gz: 5d2ac6295de54b6b0bc471203b4988b15f66fefa3bdd012a3369811beacd4a2190c5dd1babfd582a26bfed58fd9d5886380aa11de26ab06498f8c2a8bce148cd
7
+ data.tar.gz: 49c64f601a8dc2201e2237fe1847ad22f2168533261970d1f94c10d6139c0642c01a4cf53ee47b8866be9b3ac4b06e1bbd42a9d8ab5ff764e3f66516502253e5
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = "em-ftpd-memory"
7
- spec.version = "0.0.1"
7
+ spec.version = "0.0.2"
8
8
  spec.authors = ["chrislee35"]
9
9
  spec.email = ["rubygems@chrislee.dhs.org"]
10
10
  spec.summary = %q{Memory-based backing store for em-ftpd}
@@ -3,10 +3,12 @@ require 'digest/md5'
3
3
 
4
4
  module EM::FTPD::Memory
5
5
  class User < Struct.new(:name, :credential); end
6
- class InvalidPasswordAlgorithm < StandardError; end
6
+ class InvalidPasswordAlgorithmError < StandardError; end
7
7
  class NoSuchUserError < StandardError; end
8
- class InvalidCredentialdError < StandardError; end
8
+ class InvalidCredentialError < StandardError; end
9
9
  class ExpiredCredentialError < StandardError; end
10
+ class MalformatedCredentialError < StandardError; end
11
+ class NoFurtherCredentialsAvailable < StandardError; end
10
12
 
11
13
  class Authenticator
12
14
  @@realms = Hash.new
@@ -21,6 +23,10 @@ module EM::FTPD::Memory
21
23
  def initialize(options = {})
22
24
  @users = Hash.new
23
25
  @pwalgo = options["pwalgo"] || "plain"
26
+ @pwalgo = "#{@pwalgo}_authentication".to_sym
27
+ unless self.respond_to?(@pwalgo)
28
+ raise InvalidPasswordAlgorithmError.new
29
+ end
24
30
  end
25
31
 
26
32
  def <<(user)
@@ -35,18 +41,12 @@ module EM::FTPD::Memory
35
41
  if @users[username].nil?
36
42
  raise NoSuchUserError.new
37
43
  end
38
- # this prevents someone from setting "delete" as the authentication algorithm
39
- algo = "#{@pwalgo}_authentication".to_sym
40
- if self.respond_to?(algo)
41
- self.send(algo, username, credential)
42
- else
43
- raise InvalidPasswordAlgorithmError.new
44
- end
44
+ self.send(@pwalgo, username, credential)
45
45
  end
46
46
 
47
47
  def plain_authentication(username, credential)
48
48
  if @users[username].credential != credential
49
- raise InvalidCredentialdError.new
49
+ raise InvalidCredentialError.new
50
50
  else
51
51
  return true
52
52
  end
@@ -54,6 +54,9 @@ module EM::FTPD::Memory
54
54
 
55
55
  def timed_md5_authentication(username, credential)
56
56
  seed, time, hash = credential.split(/:/, 3)
57
+ if hash.nil? or hash.length != 32
58
+ raise MalformatedCredentialError.new
59
+ end
57
60
  if (time.to_i - Time.now.to_i).abs > 300
58
61
  raise ExpiredCredentialError.new
59
62
  else
@@ -3,21 +3,30 @@ module EM::FTPD::Memory
3
3
  def initialize(options = {})
4
4
  filesystem_name = options["filesystem_name"] || "default"
5
5
  realm = options["authentication_realm"] || "default"
6
- @fs = FileSystem.getFileSystemByName(filesystem_name)
6
+ @fs = FileSystem.getFileSystem(filesystem_name)
7
7
  @authenticator = Authenticator.getAuthenticatorByRealm(realm, options)
8
+ @authenticated_user = nil
9
+ @server = Kernel.caller[0]
10
+ begin
11
+ $stderr.puts @server
12
+ rescue => e
13
+ $stderr.puts e
14
+ $stderr.puts e.backtrace
15
+ end
8
16
  end
9
17
 
10
18
  def change_dir(path, &block)
11
- yield @fs.is_dir(path)
19
+ yield @fs.change_dir(path, @authenticated_user)
12
20
  end
13
21
 
14
22
  def dir_contents(path, &block)
15
- yield @fs.list_files(path)
23
+ yield @fs.list_files(path, @authenticated_user)
16
24
  end
17
25
 
18
26
  def authenticate(user, pass, &block)
19
27
  begin
20
28
  @authenticator.authenticate(user, pass)
29
+ @authenticated_user = user
21
30
  yield true
22
31
  rescue Exception => e
23
32
  #puts e.backtrace
@@ -26,31 +35,32 @@ module EM::FTPD::Memory
26
35
  end
27
36
 
28
37
  def bytes(path, &block)
29
- yield @fs.file_size(path)
38
+ yield @fs.file_size(path, @authenticated_user)
30
39
  end
31
40
 
32
41
  def get_file(path, &block)
33
- yield @fs.file_contents(path)
42
+ yield @fs.file_contents(path, @authenticated_user)
34
43
  end
35
44
 
36
45
  def put_file(path, data, &block)
37
- yield @fs.create_file(path, data)
46
+ yield @fs.create_file(path, data, @authenticated_user)
38
47
  end
39
48
 
40
49
  def delete_file(path, &block)
41
- yield @fs.remove_file(path)
50
+ yield @fs.delete_file(path, @authenticated_user)
42
51
  end
43
52
 
44
53
  def delete_dir(path, &block)
45
- yield @fs.delete_dir(path)
54
+ yield @fs.delete_dir(path, @authenticated_user)
46
55
  end
47
56
 
48
57
  def rename(from, to, &block)
49
- yield @fs.rename(from, to)
58
+ yield @fs.rename(from, to, @authenticated_user)
50
59
  end
51
60
 
52
61
  def make_dir(path, &block)
53
- yield @fs.create_dir(path)
54
- end
62
+ yield @fs.create_dir(path, @authenticated_user)
63
+ end
64
+
55
65
  end
56
66
  end
@@ -1,7 +1,9 @@
1
1
  module EM::FTPD::Memory
2
+ class InvalidPermissionsError < StandardError; end
3
+
2
4
  class FileSystem
3
5
  @@filesystems = Hash.new
4
- def self.getFileSystemByName(name)
6
+ def self.getFileSystem(name)
5
7
  if @@filesystems[name].nil?
6
8
  @@filesystems[name] = FileSystem.new
7
9
  end
@@ -9,7 +11,21 @@ module EM::FTPD::Memory
9
11
  return @@filesystems[name]
10
12
  end
11
13
 
14
+ def self.destroyFileSystem(name, force = false)
15
+ unless @@filesystems[name].nil?
16
+ if force
17
+ @@filesystems[name].destroy
18
+ @@filesystems.delete(name)
19
+ else
20
+ if @@filesystems[name].list_files("/").empty?
21
+ @@filesystems.delete(name)
22
+ end
23
+ end
24
+ end
25
+ end
26
+
12
27
  def initialize()
28
+ @root_entry = EM::FTPD::DirectoryItem.new(:name => 'root', :directory => true, :size => 0, :permissions => 'rwxrwxrwx', :owner => 'root', :group => 'root')
13
29
  @root = {
14
30
  '/' => Array.new
15
31
  }
@@ -20,39 +36,30 @@ module EM::FTPD::Memory
20
36
  is_dir(path) || is_file(path)
21
37
  end
22
38
 
23
- def list_files(path)
24
- @root[path] || []
39
+ def chdir(path, user = nil)
40
+ is_dir(path) && use_allowed(path, :list, user)
25
41
  end
26
42
 
27
- def file_size(path)
43
+ def list_files(path, user = nil)
44
+ return [] unless use_allowed?(path, :list, user)
45
+ @root[path] || [] # should this return false?
46
+ end
47
+
48
+ def file_size(path, user = nil)
49
+ return false unless use_allowed?(path, :size, user)
28
50
  f = get_file(path)
29
51
  return false unless f
30
52
  f.size
31
53
  end
32
54
 
33
- def file_contents(path)
55
+ def file_contents(path, user = nil)
56
+ return false unless use_allowed?(path, :read, user)
34
57
  # nil || false => false
35
58
  @contents[path] || false
36
59
  end
37
60
 
38
- def get_file(path)
39
- dirname = File.dirname(path)
40
- basename = File.basename(path)
41
- if is_dir(dirname)
42
- return @root[dirname].find {|file| file.directory == false && file.name == basename}
43
- end
44
- nil
45
- end
46
-
47
- def is_file(path)
48
- @contents[path] || false
49
- end
50
-
51
- def is_dir(path)
52
- @root[path] != nil
53
- end
54
-
55
- def create_file(path, data)
61
+ def create_file(path, data, user = "nobody")
62
+ return false unless use_allowed?(path, :create, user)
56
63
  dirname = File.dirname(path)
57
64
  basename = File.basename(path)
58
65
  if is_dir(dirname)
@@ -70,8 +77,9 @@ module EM::FTPD::Memory
70
77
  end
71
78
  end
72
79
 
73
- def remove_file(path)
80
+ def delete_file(path, user = nil)
74
81
  if is_file(path)
82
+ return false unless use_allowed?(path, :delete, user)
75
83
  dirname = File.dirname(path)
76
84
  basename = File.basename(path)
77
85
  @root[dirname].reject! {|file| file.directory == false && file.name == basename}
@@ -81,8 +89,9 @@ module EM::FTPD::Memory
81
89
  false
82
90
  end
83
91
 
84
- def delete_dir(path)
92
+ def delete_dir(path, user = nil)
85
93
  if is_dir(path) && @root[path].empty?
94
+ return false unless use_allowed?(path, :delete, user)
86
95
  @root.delete(path)
87
96
  dirname = File.dirname(path)
88
97
  basename = File.basename(path)
@@ -92,8 +101,9 @@ module EM::FTPD::Memory
92
101
  false
93
102
  end
94
103
 
95
- def create_dir(path)
104
+ def create_dir(path, user = "nobody")
96
105
  if not exist?(path)
106
+ return false unless use_allowed?(path, :create, user)
97
107
  dirname = File.dirname(path)
98
108
  basename = File.basename(path)
99
109
  if is_dir(dirname)
@@ -105,9 +115,11 @@ module EM::FTPD::Memory
105
115
  return false
106
116
  end
107
117
 
108
- def rename(from, to)
118
+ def rename(from, to, user = nil)
109
119
  return false if exist?(to)
110
120
  return false unless exist?(from)
121
+ return false unless use_allowed?(from, :delete, user)
122
+ return false unless use_allowed?(to, :create, user)
111
123
 
112
124
  from_dirname = File.dirname(from)
113
125
  from_basename = File.basename(from)
@@ -117,7 +129,8 @@ module EM::FTPD::Memory
117
129
  if from_dirname == to_dirname
118
130
  @root[from_dirname].find {|file| file.name == from_basename}.name = to_basename
119
131
  else
120
- entry = @root[from_dirname].reject! {|file| file.name == from_basename}
132
+ entry = @root[from_dirname].find {|file| file.name == from_basename}
133
+ @root[from_dirname] -= [entry]
121
134
  entry.name = to_basename
122
135
  @root[to_dirname] << entry
123
136
  end
@@ -133,6 +146,119 @@ module EM::FTPD::Memory
133
146
  end
134
147
  return true
135
148
  end
149
+
150
+ def destroy
151
+ @root.each_key do |d|
152
+ @root.delete(d)
153
+ end
154
+ @contents.each_key do |f|
155
+ @contents.delete(f)
156
+ end
157
+ GC.start
158
+ end
159
+
160
+ def set_permissions(path, permissions, user = nil)
161
+ return false unless exist?(path)
162
+ raise InvalidPermissionsError.new if permissions.nil?
163
+ raise InvalidPermissionsError.new(permissions.to_s) unless permissions.class == String
164
+ raise InvalidPermissionsError.new(permissions) unless permissions =~ /^[r\.][w\.][x\.][r\.][w\.][x\.][r\.][w\.][x\.]$/
165
+ entry = get_entry(path)
166
+ return false unless entry
167
+ return false unless user and (entry.owner == user or user == "root")
168
+ entry.permissions = permissions
169
+ true
170
+ end
171
+
172
+ def set_owner(path, owner, user = nil)
173
+ return false unless exist?(path) and owner and owner.class == String
174
+ entry = get_entry(path)
175
+ return false unless user and user == "root"
176
+ return false unless entry
177
+ entry.owner = owner
178
+ true
179
+ end
180
+
181
+ #private
182
+
183
+ def get_entry(path)
184
+ return @root_entry if path == '/'
185
+ dirname = File.dirname(path)
186
+ basename = File.basename(path)
187
+ if is_dir(dirname)
188
+ return @root[dirname].find {|entry| entry.name == basename}
189
+ end
190
+ nil
191
+ end
192
+
193
+ def get_file(path)
194
+ dirname = File.dirname(path)
195
+ basename = File.basename(path)
196
+ if is_dir(dirname)
197
+ return @root[dirname].find {|file| file.directory == false && file.name == basename}
198
+ end
199
+ nil
200
+ end
201
+
202
+ def is_file(path)
203
+ @contents[path] || false
204
+ end
205
+
206
+ def is_dir(path)
207
+ @root[path] != nil
208
+ end
209
+
210
+ def use_allowed?(path, use, username)
211
+ return true if username == 'root'
212
+
213
+ dirname = File.dirname(path)
214
+ basename = File.basename(path)
215
+ # to do anything, you must be able to rx into the directory containing the entry
216
+ cwd = '/'
217
+ dirname.split(/\//).each do |dir|
218
+ next if dir == '/'
219
+ cwd << dir
220
+ return false unless allowed?(cwd, "rx", username)
221
+ cwd << '/'
222
+ end
223
+
224
+ case use
225
+ when :read
226
+ return allowed?(path, 'r', username)
227
+ when :write
228
+ return allowed?(path, 'w', username)
229
+ when :list
230
+ return allowed?(path, 'rx', username)
231
+ when :size
232
+ return true # since we've already checked everything
233
+ when :delete
234
+ return allowed?(dirname, "rwx", username)
235
+ when :create
236
+ return allowed?(dirname, "rwx", username)
237
+ else
238
+ return false
239
+ end
240
+ end
241
+
242
+ def allowed?(path, required_permissions, username)
243
+ entry = get_entry(path)
244
+ permissions = entry.permissions || 'rwxrwxrwx'
245
+ return false unless entry
246
+ if username.nil?
247
+ perms = permissions[6,3]
248
+ elsif entry.owner == username
249
+ perms = permissions[0,3]
250
+ else
251
+ perms = permissions[6,3]
252
+ end
253
+
254
+ return true if perms == "rwx"
255
+ required_permissions.each_char do |c|
256
+ if perms.index(c).nil?
257
+ return false
258
+ end
259
+ end
260
+ return true
261
+ end
136
262
 
137
263
  end
138
264
  end
@@ -0,0 +1,115 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'helper'
10
+ require 'digest/md5'
11
+ include EM::FTPD::Memory
12
+
13
+ class TestAuthenticator < Minitest::Test
14
+ def test_invalid_pwalgo
15
+ options = {
16
+ "pwalgo" => "nogood",
17
+ "authentication_realm" => "invalid"
18
+ }
19
+ assert_raises(InvalidPasswordAlgorithmError) do
20
+ Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
21
+ end
22
+ end
23
+
24
+ def test_plain_login
25
+ options = {
26
+ "pwalgo" => "plain",
27
+ "authentication_realm" => "plain"
28
+ }
29
+ auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
30
+ auth << User.new("test", "test")
31
+ assert_raises(NoSuchUserError) do
32
+ auth.authenticate("jerk", "noway")
33
+ end
34
+
35
+ assert_raises(InvalidCredentialError) do
36
+ auth.authenticate("test", "noway")
37
+ end
38
+
39
+ assert(auth.authenticate("test", "test"))
40
+ end
41
+
42
+ def test_time_based_login
43
+ options = {
44
+ "pwalgo" => "timed_md5",
45
+ "authentication_realm" => "time_based"
46
+ }
47
+ auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
48
+ auth << User.new("test", "test")
49
+ assert_raises(NoSuchUserError) do
50
+ auth.authenticate("jerk", "noway")
51
+ end
52
+
53
+ assert_raises(MalformatedCredentialError) do
54
+ auth.authenticate("test", "noway")
55
+ end
56
+
57
+ assert_raises(MalformatedCredentialError) do
58
+ auth.authenticate("test", "test")
59
+ end
60
+
61
+ time = Time.now.to_i - 1200
62
+ seed = "this is a random seed"
63
+ expired_hash = Digest::MD5.hexdigest("#{seed}:#{time}:test")
64
+ expired_cred = "#{seed}:#{time}:#{expired_hash}"
65
+
66
+ assert_raises(ExpiredCredentialError) do
67
+ auth.authenticate("test", expired_cred)
68
+ end
69
+
70
+ time = Time.now.to_i
71
+ seed = "this is a random seed"
72
+ invalid_hash = Digest::MD5.hexdigest("#{seed}:#{time}:wrong")
73
+ invalid_cred = "#{seed}:#{time}:#{expired_hash}"
74
+
75
+ assert_raises(InvalidCredentialError) do
76
+ auth.authenticate("test", invalid_cred)
77
+ end
78
+
79
+ time = Time.now.to_i
80
+ seed = "this is a random seed"
81
+ valid_hash = Digest::MD5.hexdigest("#{seed}:#{time}:test")
82
+ valid_cred = "#{seed}:#{time}:#{valid_hash}"
83
+
84
+ assert(auth.authenticate("test", valid_cred))
85
+ end
86
+
87
+ def test_otp_login
88
+ options = {
89
+ "pwalgo" => "otp",
90
+ "authentication_realm" => "otp"
91
+ }
92
+ auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
93
+ auth << User.new("test", "test1\ntest2\ntest3\ntest4\ntest5")
94
+ assert_raises(NoSuchUserError) do
95
+ auth.authenticate("jerk", "noway")
96
+ end
97
+
98
+ assert_raises(InvalidCredentialError) do
99
+ auth.authenticate("test", "wrong")
100
+ end
101
+
102
+ 1.upto(4) do |i|
103
+ assert(auth.authenticate("test","test#{i}"))
104
+
105
+ assert_raises(InvalidCredentialError) do
106
+ auth.authenticate("test", "test#{i}")
107
+ end
108
+ end
109
+
110
+ assert(auth.authenticate("test","test5"))
111
+ assert_raises(NoFurtherCredentialsAvailable) do
112
+ auth.authenticate("test", "test5")
113
+ end
114
+ end
115
+ end
@@ -9,6 +9,8 @@ end
9
9
  require_relative 'helper'
10
10
  require 'eventmachine'
11
11
  require 'em-ftpd'
12
+ require 'digest/md5'
13
+ include EM::FTPD::Memory
12
14
 
13
15
  class TestFTPDMemory < Minitest::Test
14
16
  def test_example
@@ -18,9 +20,9 @@ class TestFTPDMemory < Minitest::Test
18
20
  "pwalgo" => "otp",
19
21
 
20
22
  }
21
- auth = EM::FTPD::Memory::Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
22
- auth << EM::FTPD::Memory::User.new("test", "test1\ntest2\ntest3\ntest4\ntest5")
23
- fs = EM::FTPD::Memory::FileSystem.getFileSystemByName(options["filesystem_name"])
23
+ auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
24
+ auth << User.new("test", "test1\ntest2\ntest3\ntest4\ntest5")
25
+ fs = FileSystem.getFileSystem(options["filesystem_name"])
24
26
  fs.create_dir("/pub")
25
27
  fs.create_file("/pub/helper.rb", "test/helper.rb")
26
28
 
@@ -31,38 +33,5 @@ class TestFTPDMemory < Minitest::Test
31
33
  end
32
34
  }
33
35
  end
34
-
35
- def test_plain_login
36
- end
37
-
38
- def test_time_based_login
39
- end
40
-
41
- def test_otp_login
42
- end
43
-
44
- def test_file_creation
45
- end
46
-
47
- def test_file_deletion
48
- end
49
-
50
- def test_create_directory
51
- end
52
-
53
- def test_delete_directory
54
- end
55
-
56
- def test_file_rename
57
- end
58
-
59
- def test_file_move_between_directories
60
- end
61
-
62
- def test_chmod_file
63
- end
64
-
65
- def test_chmod_directory
66
- end
67
-
36
+
68
37
  end
@@ -0,0 +1,182 @@
1
+ unless Kernel.respond_to?(:require_relative)
2
+ module Kernel
3
+ def require_relative(path)
4
+ require File.join(File.dirname(caller[0]), path.to_str)
5
+ end
6
+ end
7
+ end
8
+
9
+ require_relative 'helper'
10
+
11
+ include EM::FTPD::Memory
12
+
13
+ class TestMemoryFilesystem < Minitest::Test
14
+ def test_filesystem_instance_retrieval
15
+ fs = FileSystem.getFileSystem(__method__)
16
+ fs2 = FileSystem.getFileSystem(__method__)
17
+ assert(fs.equal?(fs2))
18
+ FileSystem.destroyFileSystem(__method__)
19
+ fs2 = FileSystem.getFileSystem(__method__)
20
+ refute(fs.equal?(fs2))
21
+ FileSystem.destroyFileSystem(__method__)
22
+ end
23
+
24
+ def test_file_creation
25
+ fs = FileSystem.getFileSystem(__method__)
26
+ fs.create_file("/helper.rb", "test/helper.rb")
27
+ assert(fs.exist?("/helper.rb"))
28
+ refute(fs.is_dir("/helper.rb"))
29
+ assert(fs.is_file("/helper.rb"))
30
+ assert_equal(169, fs.file_size("/helper.rb"))
31
+ FileSystem.destroyFileSystem(__method__)
32
+ end
33
+
34
+ def test_file_deletion
35
+ fs = FileSystem.getFileSystem(__method__)
36
+ fs.create_file("/helper.rb", "test/helper.rb")
37
+ assert(fs.exist?("/helper.rb"))
38
+ refute(fs.is_dir("/helper.rb"))
39
+ assert(fs.is_file("/helper.rb"))
40
+ assert_equal(169, fs.file_size("/helper.rb"))
41
+ fs.delete_file("/helper.rb")
42
+ refute(fs.exist?("/helper.rb"))
43
+ FileSystem.destroyFileSystem(__method__)
44
+ end
45
+
46
+ def test_create_directory
47
+ fs = FileSystem.getFileSystem(__method__)
48
+ fs.create_dir("/pub")
49
+ assert(fs.exist?("/pub"))
50
+ assert(fs.is_dir("/pub"))
51
+ refute(fs.is_file("/pub"))
52
+
53
+ fs.create_file("/pub/helper.rb", "test/helper.rb")
54
+ assert(fs.exist?("/pub/helper.rb"))
55
+ assert_equal(169, fs.file_size("/pub/helper.rb"))
56
+ fs.delete_file("/pub/helper.rb")
57
+ refute(fs.exist?("/pub/helper.rb"))
58
+ FileSystem.destroyFileSystem(__method__)
59
+ end
60
+
61
+ def test_delete_directory
62
+ fs = FileSystem.getFileSystem(__method__)
63
+ fs.create_dir("/pub")
64
+ assert(fs.exist?("/pub"))
65
+ assert(fs.is_dir("/pub"))
66
+ refute(fs.is_file("/pub"))
67
+
68
+ fs.create_file("/pub/helper.rb", "test/helper.rb")
69
+ assert(fs.exist?("/pub/helper.rb"))
70
+ assert_equal(169, fs.file_size("/pub/helper.rb"))
71
+ refute(fs.delete_dir("/pub"))
72
+ fs.delete_file("/pub/helper.rb")
73
+ refute(fs.exist?("/pub/helper.rb"))
74
+ assert(fs.delete_dir("/pub"))
75
+ refute(fs.exist?("/pub"))
76
+ FileSystem.destroyFileSystem(__method__)
77
+ end
78
+
79
+ def test_file_rename
80
+ fs = FileSystem.getFileSystem(__method__)
81
+ fs.create_dir("/pub")
82
+ assert(fs.exist?("/pub"))
83
+ assert(fs.is_dir("/pub"))
84
+ refute(fs.is_file("/pub"))
85
+
86
+ fs.create_file("/pub/helper.rb", "test/helper.rb")
87
+ assert(fs.exist?("/pub/helper.rb"))
88
+ assert_equal(169, fs.file_size("/pub/helper.rb"))
89
+ fs.rename("/pub/helper.rb", "/pub/helper.txt")
90
+ refute(fs.exist?("/pub/helper.rb"))
91
+ assert(fs.exist?("/pub/helper.txt"))
92
+ assert_equal(169, fs.file_size("/pub/helper.txt"))
93
+
94
+ FileSystem.destroyFileSystem(__method__)
95
+ end
96
+
97
+ def test_file_move_between_directories
98
+ fs = FileSystem.getFileSystem(__method__)
99
+ fs.create_dir("/pub")
100
+ assert(fs.exist?("/pub"))
101
+ assert(fs.is_dir("/pub"))
102
+ refute(fs.is_file("/pub"))
103
+ fs.create_dir("/pub2")
104
+ assert(fs.exist?("/pub2"))
105
+ assert(fs.is_dir("/pub2"))
106
+ refute(fs.is_file("/pub2"))
107
+
108
+ fs.create_file("/pub/helper.rb", "test/helper.rb")
109
+ assert(fs.exist?("/pub/helper.rb"))
110
+ assert_equal(169, fs.file_size("/pub/helper.rb"))
111
+ fs.rename("/pub/helper.rb", "/pub2/helper.txt")
112
+ refute(fs.exist?("/pub/helper.rb"))
113
+ assert(fs.exist?("/pub2/helper.txt"))
114
+ assert_equal(169, fs.file_size("/pub2/helper.txt"))
115
+
116
+ FileSystem.destroyFileSystem(__method__)
117
+ end
118
+
119
+ def test_rename_directory
120
+ fs = FileSystem.getFileSystem(__method__)
121
+ fs.create_dir("/pub")
122
+ assert(fs.exist?("/pub"))
123
+ assert(fs.is_dir("/pub"))
124
+ refute(fs.is_file("/pub"))
125
+ fs.create_dir("/pub2")
126
+ assert(fs.exist?("/pub2"))
127
+ assert(fs.is_dir("/pub2"))
128
+ refute(fs.is_file("/pub2"))
129
+ fs.create_file("/pub3", "test/helper.rb")
130
+ assert(fs.exist?("/pub3"))
131
+ refute(fs.is_dir("/pub3"))
132
+ assert(fs.is_file("/pub3"))
133
+ assert_equal(169, fs.file_size("/pub3"))
134
+
135
+ refute(fs.rename("/pub", "/pub2"))
136
+ refute(fs.rename("/pub", "/pub3"))
137
+ assert(fs.delete_file("/pub3"))
138
+ assert(fs.rename("/pub", "/pub3"))
139
+
140
+ FileSystem.destroyFileSystem(__method__)
141
+ end
142
+
143
+ def test_file_permissions
144
+ fs = FileSystem.getFileSystem(__method__)
145
+ assert_raises(InvalidPermissionsError) do
146
+ fs.set_permissions("/", "rwx", "root")
147
+ end
148
+
149
+ refute(fs.set_permissions("/", "rwxr.xr.x", "nobody"))
150
+ assert(fs.set_permissions("/", "rwxr.xr.x", "root"))
151
+ refute(fs.create_dir("/pub"))
152
+ refute(fs.exist?("/pub"))
153
+ assert(fs.create_dir("/pub", "root"))
154
+ assert(fs.exist?("/pub"))
155
+ assert(fs.create_file("/pub/helper.rb", "test/helper.rb"))
156
+ assert(fs.exist?("/pub/helper.rb"))
157
+ assert(fs.delete_file("/pub/helper.rb"))
158
+ refute(fs.exist?("/pub/helper.rb"))
159
+ assert(fs.set_permissions("/pub", 'rwxr.xr.x', "root"))
160
+ refute(fs.create_file("/pub/helper.rb", "test/helper.rb"))
161
+ refute(fs.exist?("/pub/helper.rb"))
162
+ assert(fs.create_dir("/pub/pub2","root"))
163
+ assert(fs.create_dir("/pub/pub2/pub3","root"))
164
+ assert(fs.create_dir("/pub/pub2/pub3/pub4","root"))
165
+ assert(fs.set_permissions("/pub/pub2/pub3", "rwx......", "root"))
166
+ assert_equal(0, fs.list_files("/pub/pub2/pub3").length)
167
+ assert_equal(1, fs.list_files("/pub/pub2/pub3", "root").length)
168
+ refute(fs.create_file("/pub/pub2/pub3/pub4/helper.rb", "test/helper.rb"))
169
+ assert(fs.create_file("/pub/pub2/pub3/pub4/helper.rb", "test/helper.rb", "root"))
170
+ refute(fs.file_size("/pub/pub2/pub3/pub4/helper.rb"))
171
+ assert_equal(169, fs.file_size("/pub/pub2/pub3/pub4/helper.rb", "root"))
172
+
173
+
174
+ assert_equal(0, fs.list_files("/pub/pub2/pub3", "charlie").length)
175
+ refute(fs.file_size("/pub/pub2/pub3/pub4/helper.rb", "charlie"))
176
+ assert(fs.set_owner("/pub/pub2/pub3", "charlie", "root"))
177
+ assert_equal(1, fs.list_files("/pub/pub2/pub3", "charlie").length)
178
+ assert_equal(169, fs.file_size("/pub/pub2/pub3/pub4/helper.rb", "charlie"))
179
+
180
+ end
181
+
182
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: em-ftpd-memory
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - chrislee35
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-03-14 00:00:00.000000000 Z
11
+ date: 2015-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-ftpd
@@ -98,7 +98,9 @@ files:
98
98
  - lib/em/ftpd/memory/driver.rb
99
99
  - lib/em/ftpd/memory/filesystem.rb
100
100
  - test/helper.rb
101
+ - test/test_authenticator.rb
101
102
  - test/test_ftpd-memory.rb
103
+ - test/test_memory_filesystem.rb
102
104
  homepage: https://github.com/chrislee35/em-ftpd-memory
103
105
  licenses:
104
106
  - MIT
@@ -125,4 +127,6 @@ specification_version: 4
125
127
  summary: Memory-based backing store for em-ftpd
126
128
  test_files:
127
129
  - test/helper.rb
130
+ - test/test_authenticator.rb
128
131
  - test/test_ftpd-memory.rb
132
+ - test/test_memory_filesystem.rb