em-ftpd-fsd 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.simplecov +3 -0
- data/COPYING +674 -0
- data/Gemfile +12 -0
- data/README.md +21 -0
- data/Rakefile +34 -0
- data/VERSION +1 -0
- data/em-ftpd-fsd.gemspec +71 -0
- data/lib/em-ftpd-fsd.rb +23 -0
- data/lib/em-ftpd-fsd/authentication/plain.rb +46 -0
- data/lib/em-ftpd-fsd/base.rb +144 -0
- data/lib/em-ftpd-fsd/directory_item.rb +52 -0
- data/lib/em-ftpd-fsd/file_operations.rb +98 -0
- data/lib/em-ftpd-fsd/hooks.rb +69 -0
- data/spec/base_spec.rb +18 -0
- data/spec/file_operations/authentication_spec.rb +35 -0
- data/spec/file_operations/bytes_spec.rb +33 -0
- data/spec/file_operations/change_dir_spec.rb +31 -0
- data/spec/file_operations/delete_dir_spec.rb +45 -0
- data/spec/file_operations/delete_file_spec.rb +45 -0
- data/spec/file_operations/dir_contents_spec.rb +45 -0
- data/spec/file_operations/get_file_spec.rb +31 -0
- data/spec/file_operations/make_dir_spec.rb +47 -0
- data/spec/file_operations/put_file_spec.rb +56 -0
- data/spec/file_operations/rename_spec.rb +76 -0
- data/spec/hooks_spec.rb +37 -0
- data/spec/spec_helper.rb +43 -0
- data/spec/support/files_helper.rb +36 -0
- metadata +110 -0
@@ -0,0 +1,69 @@
|
|
1
|
+
# This file is part of em-ftpd-fsd.
|
2
|
+
#
|
3
|
+
# em-ftpd-fsd is free software: you can redistribute it and/or modify
|
4
|
+
# it under the terms of the GNU General Public License as published by
|
5
|
+
# the Free Software Foundation, either version 3 of the License, or
|
6
|
+
# (at your option) any later version.
|
7
|
+
#
|
8
|
+
# em-ftpd-fsd is distributed in the hope that it will be useful,
|
9
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
+
# GNU General Public License for more details.
|
12
|
+
#
|
13
|
+
# You should have received a copy of the GNU General Public License
|
14
|
+
# along with em-ftpd-fsd. If not, see <http://www.gnu.org/licenses/>.
|
15
|
+
|
16
|
+
module EM
|
17
|
+
module FTPD
|
18
|
+
module FSD
|
19
|
+
|
20
|
+
# Add callbacks methods to base class.
|
21
|
+
# @example Usage
|
22
|
+
# class BasicDriver
|
23
|
+
# include EM::FTPD::FSD::Base
|
24
|
+
#
|
25
|
+
# before :put_file, :some_method
|
26
|
+
# after :delete_file, :some_other_method
|
27
|
+
#
|
28
|
+
# def some_method( path, tmp_path )
|
29
|
+
# ...
|
30
|
+
# end
|
31
|
+
#
|
32
|
+
# def some_other_method( path, value )
|
33
|
+
# ...
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
module Hooks
|
37
|
+
|
38
|
+
# Set a method to be called before FTP command is executed
|
39
|
+
# That method will be invoked with same arguments that FTP command
|
40
|
+
# @param [Symbol] command FTP command to be hooked
|
41
|
+
# @param [Symbol] method Method to be called before FTP command
|
42
|
+
def before( command, method )
|
43
|
+
before_hooks[command] = method
|
44
|
+
end
|
45
|
+
|
46
|
+
# Set a method to be called after FTP command is executed
|
47
|
+
# That method will be invoked with same arguments that FTP command and
|
48
|
+
# an extra parameter containig the value yielded by the FTP command
|
49
|
+
# @param [Symbol] command FTP command to be hooked
|
50
|
+
# @param [Symbol] method Method to be called after FTP command
|
51
|
+
def after( command, method )
|
52
|
+
after_hooks[command] = method
|
53
|
+
end
|
54
|
+
|
55
|
+
# Defined hooks to be executed before FTP commands
|
56
|
+
# @return [Array] List of methods to be called before FTP commands
|
57
|
+
def before_hooks
|
58
|
+
@before_hooks ||= {}
|
59
|
+
end
|
60
|
+
|
61
|
+
# Defined hooks to be executed after FTP commands
|
62
|
+
# @return [Array] List of methods to be called after FTP commands
|
63
|
+
def after_hooks
|
64
|
+
@after_hooks ||= {}
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
data/spec/base_spec.rb
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
describe "included methods" do
|
5
|
+
subject{ BasicDriver.new( DriverConfig ) }
|
6
|
+
|
7
|
+
it{ should respond_to( :authenticate ) }
|
8
|
+
it{ should respond_to( :dir_contents ) }
|
9
|
+
it{ should respond_to( :delete_file ) }
|
10
|
+
it{ should respond_to( :change_dir ) }
|
11
|
+
it{ should respond_to( :delete_dir ) }
|
12
|
+
it{ should respond_to( :make_dir ) }
|
13
|
+
it{ should respond_to( :get_file ) }
|
14
|
+
it{ should respond_to( :put_file ) }
|
15
|
+
it{ should respond_to( :rename ) }
|
16
|
+
it{ should respond_to( :bytes ) }
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
|
7
|
+
# The driver has been configured in spec_helper using
|
8
|
+
# user admin
|
9
|
+
# password root
|
10
|
+
describe "#authenticate" do
|
11
|
+
context "when user and password are correct" do
|
12
|
+
it "yield true" do
|
13
|
+
expect{ |b| driver.authenticate( "admin", "root", &b ) }.to yield_with_args( true )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when user is not correct" do
|
18
|
+
it "yield false" do
|
19
|
+
expect{ |b| driver.authenticate( "root", "root", &b ) }.to yield_with_args( false )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when password is not correct" do
|
24
|
+
it "yield false" do
|
25
|
+
expect{ |b| driver.authenticate( "admin", "admin", &b ) }.to yield_with_args( false )
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when neither user nor password are correct" do
|
30
|
+
it "yield false" do
|
31
|
+
expect{ |b| driver.authenticate( "god", "1234", &b ) }.to yield_with_args( false )
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#bytes" do
|
7
|
+
context "when the file exist" do
|
8
|
+
it "yields the size of the specified file" do
|
9
|
+
ensure_file_exist( "/test_file" )
|
10
|
+
|
11
|
+
expect do |b|
|
12
|
+
driver.bytes( "/test_file", &b )
|
13
|
+
end.to yield_with_args( File.size( FTPRoot + "/test_file" ) )
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "when the file does not exist" do
|
18
|
+
it "yields nil" do
|
19
|
+
ensure_file_does_not_exist( "/test_file" )
|
20
|
+
|
21
|
+
expect{ |b| driver.bytes( "/test_file", &b ) }.to yield_with_args( nil )
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "when the file is out of ftp folder" do
|
26
|
+
it "yields nil" do
|
27
|
+
ensure_file_exist( "/../out_of_ftp_file" )
|
28
|
+
|
29
|
+
expect{ |b| driver.bytes( "/../out_of_ftp_file", &b ) }.to yield_with_args( nil )
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#change_dir" do
|
7
|
+
context "when the directory exist" do
|
8
|
+
it "yields true" do
|
9
|
+
ensure_dir_exist( "/test_dir" )
|
10
|
+
|
11
|
+
expect{ |b| driver.change_dir( "/test_dir", &b ) }.to yield_with_args( true )
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when the directory does not exists" do
|
16
|
+
it "yields false" do
|
17
|
+
ensure_dir_does_not_exist( "/test_dir" )
|
18
|
+
|
19
|
+
expect{ |b| driver.change_dir( "/test_dir", &b ) }.to yield_with_args( false )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the directory is out of ftp folder" do
|
24
|
+
it "yields false" do
|
25
|
+
ensure_dir_exist( "/../out_of_ftp_dir" )
|
26
|
+
|
27
|
+
expect{ |b| driver.change_dir( "/../out_of_ftp_dir", &b ) }.to yield_with_args( false )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#delete_dir" do
|
7
|
+
context "when directory exist" do
|
8
|
+
before do
|
9
|
+
ensure_dir_exist( "/test_dir" )
|
10
|
+
end
|
11
|
+
|
12
|
+
it "yields true" do
|
13
|
+
expect{ |b| driver.delete_dir( "/test_dir", &b ) }.to yield_with_args( true )
|
14
|
+
end
|
15
|
+
|
16
|
+
it "deletes the directory" do
|
17
|
+
driver.delete_dir( "/test_dir"){ |value| }
|
18
|
+
File.directory?( FTPRoot + "/test_dir" ).should be_false
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when the directory does not exists" do
|
23
|
+
it "yields false" do
|
24
|
+
ensure_dir_does_not_exist( "/test_dir" )
|
25
|
+
|
26
|
+
expect{ |b| driver.delete_dir( "/test_dir", &b ) }.to yield_with_args( false )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when the directory is out of ftp folder" do
|
31
|
+
before do
|
32
|
+
ensure_dir_exist( "/../out_of_ftp_dir" )
|
33
|
+
end
|
34
|
+
|
35
|
+
it "yields false" do
|
36
|
+
expect{ |b| driver.delete_dir( "/../out_of_ftp_dir", &b ) }.to yield_with_args( false )
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not delete the directory" do
|
40
|
+
driver.delete_dir( "/../out_of_ftp_dir"){ |value| }
|
41
|
+
File.directory?( FTPRoot + "/../out_of_ftp_dir" ).should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#delete_file" do
|
7
|
+
|
8
|
+
context "when the file exist" do
|
9
|
+
before do
|
10
|
+
ensure_file_exist( "/test_file" )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "yields true" do
|
14
|
+
expect{ |b| driver.delete_file( "/test_file", &b ) }.to yield_with_args( true )
|
15
|
+
end
|
16
|
+
|
17
|
+
it "deletes the file" do
|
18
|
+
driver.delete_file( "/test_file"){ |value| }
|
19
|
+
File.exist?( FTPRoot + "/test_file" ).should be_false
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the file does not exists" do
|
24
|
+
it "yields false" do
|
25
|
+
ensure_file_does_not_exist( "/test_file" )
|
26
|
+
expect{ |b| driver.delete_file( "/test_file", &b ) }.to yield_with_args( false )
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
context "when the file is out of ftp folder" do
|
31
|
+
before do
|
32
|
+
ensure_file_exist( "/../out_of_ftp_file" )
|
33
|
+
end
|
34
|
+
|
35
|
+
it "yields false" do
|
36
|
+
expect{ |b| driver.delete_file( "/../out_of_ftp_file", &b ) }.to yield_with_args( false )
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not delete the file" do
|
40
|
+
driver.delete_file( "/test_file"){ |value| }
|
41
|
+
File.exist?( FTPRoot + "/../out_of_ftp_file" ).should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#dir_contents" do
|
7
|
+
context "when path route to existing resource" do
|
8
|
+
before do
|
9
|
+
ensure_dir_exist( "/test_dir" )
|
10
|
+
ensure_file_exist( "/test_dir/test_file2" )
|
11
|
+
ensure_file_exist( "/test_dir/test_file1" )
|
12
|
+
end
|
13
|
+
|
14
|
+
context "when resource is a directory" do
|
15
|
+
it "yields an array of DirectoryItem's" do
|
16
|
+
expect do |b|
|
17
|
+
driver.dir_contents( "/test_dir", &b )
|
18
|
+
end.to yield_with_args( Array )
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
context "when resource is a file" do
|
23
|
+
it "yields nil" do
|
24
|
+
expect{ |b| driver.dir_contents( "/test_dir/test_file1", &b ) }.to yield_with_args( nil )
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
context "when the directory does not exist" do
|
30
|
+
it "yields nil" do
|
31
|
+
ensure_dir_does_not_exist( "/test_dir" )
|
32
|
+
|
33
|
+
expect{ |b| driver.dir_contents( "/test_dir", &b ) }.to yield_with_args( nil )
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
context "when directory is out of ftp folder" do
|
38
|
+
it "yields nil" do
|
39
|
+
ensure_dir_exist( "/../out_of_ftp_dir" )
|
40
|
+
|
41
|
+
expect{ |b| driver.dir_contents( "/out_of_ftp_dir", &b ) }.to yield_with_args( nil )
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
describe EM::FTPD::FSD::Base do
|
2
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
3
|
+
|
4
|
+
describe "#get_file" do
|
5
|
+
context "when file exist" do
|
6
|
+
it "yields a string with the file data to send to the client" do
|
7
|
+
ensure_file_exist( "/test_file" )
|
8
|
+
|
9
|
+
expect{ |b| driver.get_file( "/test_file", &b ) }.to yield_with_args(
|
10
|
+
File.read( FTPRoot + "/test_file" )
|
11
|
+
)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "when file does not exist" do
|
16
|
+
it "yields nil" do
|
17
|
+
ensure_file_does_not_exist( "/test_file" )
|
18
|
+
|
19
|
+
expect{ |b| driver.get_file( "/test_file", &b ) }.to yield_with_args( nil )
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when file is out of ftp folder" do
|
24
|
+
it "yields nil" do
|
25
|
+
ensure_file_exist( "/../out_of_ftp_file" )
|
26
|
+
|
27
|
+
expect{ |b| driver.get_file( "/../out_of_ftp_file", &b ) }.to yield_with_args( nil )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#make_dir" do
|
7
|
+
|
8
|
+
context "when directory does not exist" do
|
9
|
+
before do
|
10
|
+
ensure_dir_does_not_exist( "/test_dir" )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "yields true" do
|
14
|
+
expect{ |b| driver.make_dir( "/test_dir", &b ) }.to yield_with_args( true )
|
15
|
+
end
|
16
|
+
|
17
|
+
it "creates the directory" do
|
18
|
+
driver.make_dir( "/test_dir"){ |value| }
|
19
|
+
File.directory?( FTPRoot + "/test_dir" ).should be_true
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
context "when the directory exists" do
|
24
|
+
it "yields false" do
|
25
|
+
ensure_dir_exist( "/test_dir" )
|
26
|
+
|
27
|
+
expect{ |b| driver.make_dir( "/test_dir", &b ) }.to yield_with_args( false )
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "when the directory is out of ftp folder" do
|
32
|
+
before do
|
33
|
+
ensure_dir_does_not_exist( "/../out_of_ftp_dir" )
|
34
|
+
end
|
35
|
+
it "yields false" do
|
36
|
+
expect{ |b| driver.make_dir( "/../out_of_ftp_dir", &b ) }.to yield_with_args( false )
|
37
|
+
end
|
38
|
+
|
39
|
+
it "does not create the directory" do
|
40
|
+
driver.make_dir( "/../out_of_ftp_dir" ){ |value| }
|
41
|
+
File.directory?( FTPRoot + "/../out_of_ftp_dir" ).should be_false
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
|
46
|
+
end
|
47
|
+
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe EM::FTPD::FSD::Base do
|
4
|
+
let( :driver ){ BasicDriver.new( DriverConfig ) }
|
5
|
+
|
6
|
+
describe "#put_file" do
|
7
|
+
context "when the destination file does not exist" do
|
8
|
+
before do
|
9
|
+
ensure_file_does_not_exist( "/new_file" )
|
10
|
+
ensure_file_exist( "/tmp_file" )
|
11
|
+
end
|
12
|
+
|
13
|
+
it "yields an integer indicating the number of bytes received" do
|
14
|
+
file_size = File.size( FTPRoot + "/tmp_file" )
|
15
|
+
|
16
|
+
expect{ |b| driver.put_file( "/new_file", FTPRoot + "/tmp_file", &b ) }.to yield_with_args( file_size )
|
17
|
+
end
|
18
|
+
|
19
|
+
it "creates a new file in destination path" do
|
20
|
+
driver.put_file( "/new_file", FTPRoot + "/tmp_file" ){ |value| }
|
21
|
+
|
22
|
+
File.exist?( FTPRoot + "/new_file" ).should be_true
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
context "when the destination file already exist" do
|
27
|
+
before do
|
28
|
+
ensure_file_exist( "/new_file" )
|
29
|
+
ensure_file_exist( "/tmp_file" )
|
30
|
+
end
|
31
|
+
|
32
|
+
it "yields an integer indicating the number of bytes received" do
|
33
|
+
file_size = File.size( FTPRoot + "/tmp_file" )
|
34
|
+
|
35
|
+
expect{ |b| driver.put_file( "/tmp_file", FTPRoot + "/new_file", &b ) }.to yield_with_args( file_size )
|
36
|
+
end
|
37
|
+
|
38
|
+
it "creates a new file in destination path" do
|
39
|
+
driver.put_file( "/new_file", "/tmp_file" ){ |value| }
|
40
|
+
|
41
|
+
File.exist?( FTPRoot + "/new_file" ).should be_true
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
context "when destination path is out of ftp folder" do
|
46
|
+
before do
|
47
|
+
ensure_file_exist( "/../out_of_ftp_file" )
|
48
|
+
ensure_file_exist( "/tmp_file" )
|
49
|
+
end
|
50
|
+
|
51
|
+
it "yields nil" do
|
52
|
+
expect{ |b| driver.put_file( "/new_file", "/../out_of_ftp_file", &b ) }.to yield_with_args( false )
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|