em-ftpd-memory 0.0.5 → 0.0.6

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: 59b7c1d4a65d038d0a2addbbccbf1697a1f4e6c4
4
- data.tar.gz: 605868d7a3280ff3f5b0ad062acee5f31b8a97cb
3
+ metadata.gz: ff070a000cded7f1c145979f7a4c42285e2c1075
4
+ data.tar.gz: f09bce2a5fdf592df680dd9c76512cfd0423940b
5
5
  SHA512:
6
- metadata.gz: f2d538c602e0060ebcc469f81bb8d33a583b8a825e13ea060583bbb270535e8aec86080757536b48bd096fb90af20c0ee6eadad6e5c84e7c2e1497c4bdb904f7
7
- data.tar.gz: d811d57df20890c04e1687c8a32cd3b0b88680a705fd34d70bd3ee7533b29c23f143d73b221c7c639a7c7876662c17b4a3cd42e7d3f0fcac79cd15227e346a5d
6
+ metadata.gz: 4384dee7ef945d52725be5732013ab356e54a7d1cf07833a971ffee061405864a1dce0e91c453e95f6643f96f7f2e07a9b96574c8edc072d12b6f2841c898914
7
+ data.tar.gz: 4b5da1d0cdbc510f8824043b7322a842df89117c98aabca89613809286e333562714adeacca34a4b505154ad79d6e3c352d4855ed6b80369b0c919ac873139b0
data/README.md CHANGED
@@ -28,20 +28,32 @@ Or install it yourself as:
28
28
  "pwalgo" => "otp",
29
29
 
30
30
  }
31
+ # set up the authentication
31
32
  auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
33
+ # add a test user
32
34
  auth << User.new("test", "test1\ntest2\ntest3\ntest4\ntest5")
35
+ # create the filesystem
33
36
  fs = FileSystem.getFileSystem(options["filesystem_name"])
37
+ # add a pub folder
34
38
  fs.create_dir("/pub", 'root')
39
+ # add a file to the pub folder as root
35
40
  fs.create_file("/pub/helper.rb", "test/helper.rb", 'root')
41
+ # chmod 755 /pub
36
42
  fs.set_permissions("/pub", 'rwxr.xr.x', "root")
43
+ # create /uploads as root
37
44
  fs.create_dir("/uploads", 'root')
45
+ # chmod 777 /uploads
38
46
  fs.set_permissions("/uploads", "rwxrwxrwx", "root")
39
-
47
+ # create /users as root
40
48
  fs.create_dir("/users", 'root')
49
+ # chmod 755 /users
41
50
  fs.set_permissions("/users", "rwxr.xr.x", "root")
51
+ # create a personal directory for hiro, miyako, and pilar, (and add their test user)
42
52
  ["hiro", "miyako", "pilar"].each do |username|
43
53
  fs.create_dir("/users/#{username}", 'root')
54
+ # set the permissions so that no one else can access it
44
55
  fs.set_permissions("/users/#{username}", "rwx......", "root")
56
+ # set the owner to the user
45
57
  fs.set_owner("/users/#{username}", username, 'root')
46
58
  auth << User.new(username, username)
47
59
  end
@@ -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.5"
7
+ spec.version = "0.0.6"
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}
@@ -2,7 +2,7 @@ require 'em-ftpd'
2
2
  require 'digest/md5'
3
3
 
4
4
  module EM::FTPD::Memory
5
- class User < Struct.new(:name, :credential); end
5
+ class User < Struct.new(:name, :algo, :credential); end
6
6
  class InvalidPasswordAlgorithmError < StandardError; end
7
7
  class NoSuchUserError < StandardError; end
8
8
  class InvalidCredentialError < StandardError; end
@@ -12,24 +12,23 @@ module EM::FTPD::Memory
12
12
 
13
13
  class Authenticator
14
14
  @@realms = Hash.new
15
- def self.getAuthenticatorByRealm(realm, options = {})
15
+ def self.getAuthenticatorByRealm(realm)
16
16
  if @@realms[realm].nil?
17
- @@realms[realm] = Authenticator.new(options)
17
+ @@realms[realm] = Authenticator.new
18
18
  end
19
19
  #puts "returning Authenticator of realm #{realm}"
20
20
  @@realms[realm]
21
21
  end
22
22
 
23
- def initialize(options = {})
23
+ def initialize
24
24
  @users = Hash.new
25
- @pwalgo = options["pwalgo"] || "plain"
26
- @pwalgo = "#{@pwalgo}_authentication".to_sym
27
- unless self.respond_to?(@pwalgo)
28
- raise InvalidPasswordAlgorithmError.new
29
- end
30
25
  end
31
26
 
32
27
  def <<(user)
28
+ unless self.respond_to?("#{user.algo}_authentication".to_sym)
29
+ raise InvalidPasswordAlgorithmError.new
30
+ end
31
+ user.algo = "#{user.algo}_authentication".to_sym
33
32
  @users[user.name] = user
34
33
  end
35
34
 
@@ -41,7 +40,7 @@ module EM::FTPD::Memory
41
40
  if @users[username].nil?
42
41
  raise NoSuchUserError.new
43
42
  end
44
- self.send(@pwalgo, username, credential)
43
+ self.send(@users[username].algo, username, credential)
45
44
  end
46
45
 
47
46
  def plain_authentication(username, credential)
@@ -41,10 +41,8 @@ module EM::FTPD::Memory
41
41
  end
42
42
 
43
43
 
44
- # TODO: support groups
45
-
46
44
  def initialize
47
- @root = MemoryDirectoryItem.new(:name => '/', :owner => 'root', :directory => true, :permissions => "rwxr.xr.x", :contents => Hash.new)
45
+ @root = MemoryDirectoryItem.new(:name => '/', :owner => 'root', :group => 'root', :directory => true, :permissions => "rwxr.xr.x", :contents => Hash.new)
48
46
  end
49
47
 
50
48
  def exist?(path)
@@ -68,13 +66,13 @@ module EM::FTPD::Memory
68
66
  true
69
67
  end
70
68
 
71
- def change_dir(path, user = nil)
69
+ def change_dir(path, user = nil, groups = [])
72
70
  item = get_item(path)
73
- item.directory && use_allowed?(path, :list, user)
71
+ item.directory && use_allowed?(path, :list, user, groups)
74
72
  end
75
73
 
76
- def list_files(path, user = nil)
77
- return [] unless use_allowed?(path, :list, user)
74
+ def list_files(path, user = nil, groups = [])
75
+ return [] unless use_allowed?(path, :list, user, groups)
78
76
  item = get_item(path)
79
77
  if item.directory
80
78
  return item.contents.values
@@ -82,28 +80,28 @@ module EM::FTPD::Memory
82
80
  return []
83
81
  end
84
82
 
85
- def file_size(path, user = nil)
86
- return false unless use_allowed?(path, :size, user)
83
+ def file_size(path, user = nil, groups = [])
84
+ return false unless use_allowed?(path, :size, user, groups)
87
85
  f = get_item(path)
88
86
  return false unless f
89
87
  f.size
90
88
  end
91
89
 
92
- def modified_time(path, user = nil)
93
- return nil unless use_allowed?(path, :time, user)
90
+ def modified_time(path, user = nil, groups = [])
91
+ return nil unless use_allowed?(path, :time, user, groups)
94
92
  f = get_item(path)
95
93
  return nil unless f
96
94
  f.time
97
95
  end
98
96
 
99
- def file_contents(path, user = nil)
100
- return false unless use_allowed?(path, :read, user)
97
+ def file_contents(path, user = nil, groups = [])
98
+ return false unless use_allowed?(path, :read, user, groups)
101
99
  item = get_item(path)
102
100
  item.contents || false
103
101
  end
104
102
 
105
- def create_file(path, data, user = "nobody")
106
- return false unless use_allowed?(path, :create, user)
103
+ def create_file(path, data, user = "nobody", groups = [])
104
+ return false unless use_allowed?(path, :create, user, groups)
107
105
  dirname = File.dirname(path)
108
106
  basename = File.basename(path)
109
107
  dir = get_item(dirname)
@@ -123,8 +121,8 @@ module EM::FTPD::Memory
123
121
  end
124
122
  end
125
123
 
126
- def delete_file(path, user = nil)
127
- return false unless use_allowed?(path, :delete, user)
124
+ def delete_file(path, user = nil, groups = [])
125
+ return false unless use_allowed?(path, :delete, user, groups)
128
126
  dirname = File.dirname(path)
129
127
  basename = File.basename(path)
130
128
  dir = get_item(dirname)
@@ -135,10 +133,10 @@ module EM::FTPD::Memory
135
133
  false
136
134
  end
137
135
 
138
- def delete_dir(path, user = nil)
136
+ def delete_dir(path, user = nil, groups = [])
139
137
  dir = get_item(path)
140
138
  if dir and dir.directory and dir.contents.empty?
141
- return false unless use_allowed?(path, :delete, user)
139
+ return false unless use_allowed?(path, :delete, user, groups)
142
140
  dirname = File.dirname(path)
143
141
  basename = File.basename(path)
144
142
  parent = get_item(dirname)
@@ -148,10 +146,10 @@ module EM::FTPD::Memory
148
146
  false
149
147
  end
150
148
 
151
- def create_dir(path, user = "nobody")
149
+ def create_dir(path, user = "nobody", groups = [])
152
150
  dir = get_item(path)
153
151
  if dir.nil?
154
- return false unless use_allowed?(path, :create, user)
152
+ return false unless use_allowed?(path, :create, user, groups)
155
153
  dirname = File.dirname(path)
156
154
  basename = File.basename(path)
157
155
  parent = get_item(dirname)
@@ -163,13 +161,13 @@ module EM::FTPD::Memory
163
161
  return false
164
162
  end
165
163
 
166
- def rename(from, to, user = nil)
164
+ def rename(from, to, user = nil, groups = [])
167
165
  titem = get_item(to)
168
166
  return false if titem
169
167
  fitem = get_item(from)
170
168
  return false unless fitem
171
- return false unless use_allowed?(from, :delete, user)
172
- return false unless use_allowed?(to, :create, user)
169
+ return false unless use_allowed?(from, :delete, user, groups)
170
+ return false unless use_allowed?(to, :create, user, groups)
173
171
 
174
172
  from_dirname = File.dirname(from)
175
173
  from_basename = File.basename(from)
@@ -186,30 +184,38 @@ module EM::FTPD::Memory
186
184
  end
187
185
 
188
186
  def destroy
189
- @root = MemoryDirectoryItem.new(:name => '/', :owner => 'root', :directory => true, :permissions => "rwxr.xr.x", :contents => Hash.new)
187
+ @root = MemoryDirectoryItem.new(:name => '/', :owner => 'root', :group => 'root', :directory => true, :permissions => "rwxr.xr.x", :contents => Hash.new)
190
188
  GC.start
191
189
  end
192
190
 
193
- def set_permissions(path, permissions, user = nil)
191
+ def set_permissions(path, permissions, user = nil, groups = [])
194
192
  item = get_item(path)
195
193
  return false unless item
196
194
  raise InvalidPermissionsError.new if permissions.nil?
197
195
  raise InvalidPermissionsError.new(permissions.to_s) unless permissions.class == String
198
196
  raise InvalidPermissionsError.new(permissions) unless permissions =~ /^[r\.][w\.][x\.][r\.][w\.][x\.][r\.][w\.][x\.]$/
199
- if use_allowed?(path, :chmod, user)
197
+ if use_allowed?(path, :chmod, user, groups)
200
198
  item.permissions = permissions
201
199
  return true
202
200
  end
203
201
  false
204
202
  end
205
203
 
206
- def set_owner(path, owner, user = nil)
204
+ def set_owner(path, owner, user = nil, groups = [])
207
205
  item = get_item(path)
208
206
  return false unless item and owner and owner.class == String
209
207
  return false unless user and user == "root"
210
208
  item.owner = owner
211
209
  true
212
210
  end
211
+
212
+ def set_group(path, group, user = nil, groups = [])
213
+ item = get_item(path)
214
+ return false unless item and group and group.class == String
215
+ return false unless user and user == "root"
216
+ return false unless groups.index(group)
217
+ item.group = group
218
+ end
213
219
 
214
220
  #private
215
221
 
@@ -224,7 +230,7 @@ module EM::FTPD::Memory
224
230
  cur
225
231
  end
226
232
 
227
- def use_allowed?(path, use, username)
233
+ def use_allowed?(path, use, username, groups = [])
228
234
  return true if username == 'root'
229
235
 
230
236
  dirname = File.dirname(path)
@@ -234,17 +240,17 @@ module EM::FTPD::Memory
234
240
  dirname.split(/\//).each do |dir|
235
241
  next if dir == '/'
236
242
  cwd << dir
237
- return false unless allowed?(cwd, "rx", username)
243
+ return false unless allowed?(cwd, "rx", username, groups)
238
244
  cwd << '/'
239
245
  end
240
246
 
241
247
  case use
242
248
  when :read
243
- return allowed?(path, 'r', username)
249
+ return allowed?(path, 'r', username, groups)
244
250
  when :write
245
- return allowed?(path, 'w', username)
251
+ return allowed?(path, 'w', username, groups)
246
252
  when :list
247
- return allowed?(path, 'rx', username)
253
+ return allowed?(path, 'rx', username, groups)
248
254
  when :size
249
255
  return true # since we've already checked everything
250
256
  when :time
@@ -253,15 +259,15 @@ module EM::FTPD::Memory
253
259
  item = get_item(path)
254
260
  return item.owner == username
255
261
  when :delete
256
- return allowed?(dirname, "rwx", username)
262
+ return allowed?(dirname, "rwx", username, groups)
257
263
  when :create
258
- return allowed?(dirname, "rwx", username)
264
+ return allowed?(dirname, "rwx", username, groups)
259
265
  else
260
266
  return false
261
267
  end
262
268
  end
263
269
 
264
- def allowed?(path, required_permissions, username)
270
+ def allowed?(path, required_permissions, username, groups)
265
271
  item = get_item(path)
266
272
  return false unless item
267
273
  permissions = item.permissions || 'rwxrwxrwx'
@@ -269,6 +275,8 @@ module EM::FTPD::Memory
269
275
  perms = permissions[6,3]
270
276
  elsif item.owner == username
271
277
  perms = permissions[0,3]
278
+ elsif groups.index(item.group)
279
+ perms = permissions[3,3]
272
280
  else
273
281
  perms = permissions[6,3]
274
282
  end
@@ -12,22 +12,15 @@ include EM::FTPD::Memory
12
12
 
13
13
  class TestAuthenticator < Minitest::Test
14
14
  def test_invalid_pwalgo
15
- options = {
16
- "pwalgo" => "nogood",
17
- "authentication_realm" => "invalid"
18
- }
19
15
  assert_raises(InvalidPasswordAlgorithmError) do
20
- Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
16
+ auth = Authenticator.getAuthenticatorByRealm(__method__)
17
+ auth << User.new("test", "nogood", "test")
21
18
  end
22
19
  end
23
20
 
24
21
  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")
22
+ auth = Authenticator.getAuthenticatorByRealm(__method__)
23
+ auth << User.new("test", "plain", "test")
31
24
  assert_raises(NoSuchUserError) do
32
25
  auth.authenticate("jerk", "noway")
33
26
  end
@@ -40,12 +33,8 @@ class TestAuthenticator < Minitest::Test
40
33
  end
41
34
 
42
35
  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")
36
+ auth = Authenticator.getAuthenticatorByRealm(__method__)
37
+ auth << User.new("test", "timed_md5", "test")
49
38
  assert_raises(NoSuchUserError) do
50
39
  auth.authenticate("jerk", "noway")
51
40
  end
@@ -85,12 +74,8 @@ class TestAuthenticator < Minitest::Test
85
74
  end
86
75
 
87
76
  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")
77
+ auth = Authenticator.getAuthenticatorByRealm(__method__)
78
+ auth << User.new("test", "otp", "test1\ntest2\ntest3\ntest4\ntest5")
94
79
  assert_raises(NoSuchUserError) do
95
80
  auth.authenticate("jerk", "noway")
96
81
  end
@@ -14,18 +14,12 @@ include EM::FTPD::Memory
14
14
 
15
15
  class TestFTPDMemory < Minitest::Test
16
16
  def test_example
17
- options = {
18
- "filesystem_name" => "boss",
19
- "authentication_realm" => "georgia",
20
- "pwalgo" => "otp",
21
-
22
- }
23
17
  # set up the authentication
24
- auth = Authenticator.getAuthenticatorByRealm(options["authentication_realm"], options)
18
+ auth = Authenticator.getAuthenticatorByRealm("georgia")
25
19
  # add a test user
26
- auth << User.new("test", "test1\ntest2\ntest3\ntest4\ntest5")
20
+ auth << User.new("test", "otp", "test1\ntest2\ntest3\ntest4\ntest5")
27
21
  # create the filesystem
28
- fs = FileSystem.getFileSystem(options["filesystem_name"])
22
+ fs = FileSystem.getFileSystem("boss")
29
23
  # add a pub folder
30
24
  fs.create_dir("/pub", 'root')
31
25
  # add a file to the pub folder as root
@@ -47,9 +41,13 @@ class TestFTPDMemory < Minitest::Test
47
41
  fs.set_permissions("/users/#{username}", "rwx......", "root")
48
42
  # set the owner to the user
49
43
  fs.set_owner("/users/#{username}", username, 'root')
50
- auth << User.new(username, username)
44
+ auth << User.new(username, "plain", username)
51
45
  end
52
46
 
47
+ options = {
48
+ "filesystem_name" => "boss",
49
+ "authentication_realm" => "georgia"
50
+ }
53
51
  EM.run {
54
52
  EventMachine::start_server("0.0.0.0", 2021, EM::FTPD::Server, EM::FTPD::Memory::Driver, options)
55
53
  EM::Timer.new(0.1) do
@@ -190,6 +190,14 @@ class TestMemoryFilesystem < Minitest::Test
190
190
  refute(fs.set_permissions("/pub/pub2/pub3", "rwx......", "jem"))
191
191
  assert(fs.set_permissions("/pub/pub2", "rwxr.xr.x", "root"))
192
192
  assert(fs.set_permissions("/pub/pub2/pub3", "rwx......", "jem"))
193
+
194
+ assert(fs.create_dir("/group_test", "root"))
195
+ assert(fs.set_group("/group_test", "test", "root", ["test"]))
196
+ assert(fs.set_permissions("/group_test", "rwxr.x...", "root"))
197
+ assert(fs.create_file("/group_test/test", "test/helper.rb", "root"))
198
+ assert_equal(0, fs.list_files("/group_test", "jem", ["nottest"]).length)
199
+ assert_equal(1, fs.list_files("/group_test", "jem", ["test", "other", "punkbands"]).length)
200
+
193
201
  end
194
202
 
195
203
  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.5
4
+ version: 0.0.6
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-20 00:00:00.000000000 Z
11
+ date: 2015-03-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: em-ftpd