em-ftpd-fsd 0.1.0
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.
- 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
|