em-ftpd-memory 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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