module EM::FTPD::FSD::Base

Base module to include in custom drivers

Constants

COMMANDS

Supported FTP commands.

Public Class Methods

included( klass ) click to toggle source

Extend hooks module to load ‘before’ and ‘after’ class functions

# File lib/em-ftpd-fsd/base.rb, line 42
def self.included( klass )
  klass.extend( EM::FTPD::FSD::Hooks )
end
new( options = {} ) click to toggle source

Initiliaze the driver with basic options @param [Hash] options Options @option options base_path Base directory for FTP server @option options authentication Authentication module to load @example Default options for authentication

{
  plain: {
    user:     "admin",
    password: "root"
  }
}
# File lib/em-ftpd-fsd/base.rb, line 57
def initialize( options = {} )
  opts = {
    base_path: Dir.pwd,
    authentication: {
      plain: {
        user:     "admin",
        password: "root"
      }
    }
  }.merge( options )

  load_auth_module( opts[:authentication] )

  @base_path = opts[:base_path]
end

Public Instance Methods

base_path() click to toggle source

Absolute path to FTP base directory. @return [String] Full path to FTP base folder.

# File lib/em-ftpd-fsd/base.rb, line 75
def base_path
  File.expand_path( @base_path || "" )
end
method_missing( method, *args ) { |ftp_methods( method, args )| ... } click to toggle source

Metaprogrammed redirection to FTP commands defined by FileOperation class. @param [Symbol] method Method called @param [Array] args All arguments received by called method @param [Block] block Block to be yield by called method @raise [NoMethodError] if method is not supported by driver @raise [ArgumentError] if no block is passed to yield value @yield [Object] Return value from file specific operation

# File lib/em-ftpd-fsd/base.rb, line 86
def method_missing( method, *args, &block )
  raise NoMethodError, "#{method}"    unless COMMANDS.include?( method )
  raise ArgumentError, "Block needed" unless block_given?

  yield ftp_methods( method, args )
end
respond_to?( method, include_private = false ) click to toggle source

Return true if obj respond to given method or method correspond to an implemented ftp command. @param [Symbol] method Given method @return [Boolean] Return true if obj respond to given method.

Calls superclass method
# File lib/em-ftpd-fsd/base.rb, line 97
def respond_to?( method, include_private = false )
  super( method, include_private ) || COMMANDS.include?( method )
end

Private Instance Methods

check_file_system_permissions!( path ) click to toggle source
# File lib/em-ftpd-fsd/base.rb, line 129
def check_file_system_permissions!( path )
  unless File.expand_path( path ).include? base_path
    raise SecurityError, "File system path out of FTP folder"
  end
end
file_system_path( ftp_path ) click to toggle source
# File lib/em-ftpd-fsd/base.rb, line 125
def file_system_path( ftp_path )
  "#{base_path}#{ftp_path}"
end
ftp_methods( method, args ) click to toggle source
# File lib/em-ftpd-fsd/base.rb, line 103
def ftp_methods( method, args )
  # We have to map each ftp path to a local file system path to check
  # permissions, but when command is 'put_file' the second argument
  # is an absolute path to temporary that should not be converted
  tmp_file = args.delete_at( 1 ) if method == :put_file
  args = args.map{ |arg| file_system_path( arg ) }

  begin
    # Bypass permissions for second argument if method is put_file
    args.each{ |arg| check_file_system_permissions!( arg ) }
    args.insert( 1, tmp_file ) if method == :put_file

    send( self.class.before_hooks[method], *args ) if self.class.before_hooks[method]
    value = EM::FTPD::FSD::FileOperations.send( method, *args )
    send( self.class.after_hooks[method], *(args << value) ) if self.class.after_hooks[method]

    return value
  rescue Exception
    return COMMANDS[method][:on_error_value]
  end
end
load_auth_module( opts ) click to toggle source
# File lib/em-ftpd-fsd/base.rb, line 135
def load_auth_module( opts )
  auth_mod = EM::FTPD::FSD::Authentication.const_get( opts.keys.first.to_s.capitalize )

  self.class.send( :include, auth_mod )
  configure_authentication( opts.values.first )
end