class ElFinderS3::Connector
Represents ElFinder connector on Rails side.
Constants
- DEFAULT_OPTIONS
Default options for instances. @see initialize
- VALID_COMMANDS
Valid commands to run. @see
run
Attributes
adapter[R]
Public Class Methods
logger()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 65 def logger @logger ||= Logger.new(STDOUT) end
logger=(val)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 69 def logger=(val) @logger = val end
new(options)
click to toggle source
Initializes new instance. @param [Hash] options Instance options. :url and :server options are required. @option options [String] :url Entry point of ElFinder router. @option options [String] :server A hash containing the :host, :username, :password, and, optionally, :port to connect to @see DEFAULT_OPTIONS
# File lib/el_finder_s3/connector.rb, line 42 def initialize(options) @options = DEFAULT_OPTIONS.merge(options) raise(ArgumentError, 'Missing required :url option') unless @options.key?(:url) raise(ArgumentError, 'Missing required :server option') unless @options.key?(:server) raise(ArgumentError, 'Mime Handler is invalid') unless mime_handler.respond_to?(:for) raise(ArgumentError, 'Image Handler is invalid') unless image_handler.nil? || ([:size, :resize, :thumbnail].all? { |m| image_handler.respond_to?(m) }) raise(ArgumentError, 'Missing required :region option') unless @options[:server].key?(:region) raise(ArgumentError, 'Missing required :access_key_id option') unless @options[:server].key?(:access_key_id) raise(ArgumentError, 'Missing required :secret_access_key option') unless @options[:server].key?(:secret_access_key) raise(ArgumentError, 'Missing required :bucket_name option') unless @options[:server].key?(:bucket_name) @options[:url] = 'https://' + @options[:server][:bucket] + '.s3.amazonaws.com' unless @options.key?(:url) @headers = {} @response = {} end
Public Instance Methods
from_hash(hash)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 133 def from_hash(hash) # restore missing '=' len = hash.length % 4 hash += '==' if len == 1 or len == 2 hash += '=' if len == 3 decoded_hash = Base64.urlsafe_decode64(hash) decoded_hash = decoded_hash.respond_to?(:force_encoding) ? decoded_hash.force_encoding('utf-8') : decoded_hash pathname = @root + decoded_hash rescue ArgumentError => e if e.message != 'invalid base64' raise end nil end
options=(value = {})
click to toggle source
@!attribute [w] options Options setter. @param value [Hash] Options to be merged with instance ones. @return [Hash] Updated options.
# File lib/el_finder_s3/connector.rb, line 155 def options=(value = {}) value.each_pair do |k, v| @options[k.to_sym] = v end @options end
run(params)
click to toggle source
Runs request-response cycle. @param [Hash] params Request parameters. :cmd option is required. @option params [String] :cmd Command to be performed. @see VALID_COMMANDS
# File lib/el_finder_s3/connector.rb, line 78 def run(params) @adapter = ElFinderS3::Adapter.new(@options[:server], @options[:cache_connector]) @root = ElFinderS3::Pathname.new(adapter) begin @params = params.dup @headers = {} @response = {} @response[:errorData] = {} if VALID_COMMANDS.include?(@params[:cmd]) if @options[:thumbs] @thumb_directory = @root + @options[:thumbs_directory] @thumb_directory.mkdir unless @thumb_directory.exist? raise(RuntimeError, "Unable to create thumbs directory") unless @thumb_directory.directory? end @current = @params[:current] ? from_hash(@params[:current]) : nil @target = (@params[:target] and !@params[:target].empty?) ? from_hash(@params[:target]) : nil if params[:targets] @targets = @params[:targets].map { |t| from_hash(t) } end begin send("_#{@params[:cmd]}") rescue Exception => exception puts exception.message puts exception.backtrace.inspect @response[:error] = 'Access Denied' end else invalid_request end @response.delete(:errorData) if @response[:errorData].empty? return @headers, @response ensure adapter.close end end
to_hash(pathname)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 125 def to_hash(pathname) # note that '=' are removed Base64.urlsafe_encode64(pathname.path.to_s).chomp.tr("=\n", "") end
Protected Instance Methods
_archive()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 462 def _archive command_not_implemented end
_duplicate()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 410 def _duplicate command_not_implemented end
_extract()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 455 def _extract command_not_implemented end
_file()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 428 def _file if perms_for(@target)[:read] == true @response[:file_data] = @target.read @response[:mime_type] = mime_handler.for(@target) @response[:disposition] = 'attachment' @response[:filename] = @target.basename.to_s else @response[:error] = 'Access Denied' end end
_get()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 417 def _get if perms_for(@target)[:read] == true @response[:content] = @target.read else @response[:error] = 'Access Denied' end end
_ls()
click to toggle source
of open
# File lib/el_finder_s3/connector.rb, line 217 def _ls if @target.directory? files = @target.files.reject { |child| perms_for(child)[:hidden] } @response[:list] = files.map { |e| e.basename.to_s }.compact else @response[:error] = "Directory does not exist" end end
_mkdir()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 242 def _mkdir if perms_for(@target)[:write] == false @response[:error] = 'Access Denied' return end unless valid_name?(@params[:name]) @response[:error] = 'Unable to create folder' return end dir = @target + @params[:name] if !dir.exist? && dir.mkdir @params[:tree] = true @response[:added] = [to_hash(dir)] _open(@target) else @response[:error] = "Unable to create folder" end end
_mkfile()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 265 def _mkfile if perms_for(@target)[:write] == false @response[:error] = 'Access Denied' return end unless valid_name?(@params[:name]) @response[:error] = 'Unable to create file' return end file = @target + @params[:name] file.type = :file if !file.exist? && file.touch @response[:select] = [to_hash(file)] _open(@target) else @response[:error] = "Unable to create file" end end
_open(target = nil)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 168 def _open(target = nil) target ||= @target if target.nil? _open(@root) return end if perms_for(target)[:read] == false @response[:error] = 'Access Denied' return end if target.file? command_not_implemented elsif target.directory? @response[:cwd] = cwd_for(target) @response[:cdc] = target.children. reject { |child| perms_for(child)[:hidden] }. sort_by { |e| e.basename.to_s.downcase }.map { |e| cdc_for(e) }.compact if @params[:tree] @response[:tree] = { :name => @options[:home], :hash => to_hash(@root), :dirs => tree_for(@root), }.merge(perms_for(@root)) end if @params[:init] @response[:disabled] = @options[:disabled_commands] @response[:params] = { :dotFiles => @options[:allow_dot_files], :uplMaxSize => @options[:upload_max_size], :archives => @options[:archivers].keys, :extract => @options[:extractors].keys, :url => @options[:url] } end else @response[:error] = "Directory does not exist" _open(@root) if File.directory?(@root) end end
_paste()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 356 def _paste if perms_for(from_hash(@params[:dst]))[:write] == false @response[:error] = 'Access Denied' return end added_list = [] removed_list = [] @targets.to_a.each do |src| if perms_for(src)[:read] == false || (@params[:cut].to_i > 0 && perms_for(src)[:locked] == true) @response[:error] ||= 'Some files were not moved.' @response[:errorData][src.basename.to_s] = "Access Denied" return else dst = from_hash(@params[:dst]) + src.basename if dst.exist? @response[:error] ||= 'The target file already exists' @response[:errorData][src.basename.to_s] = "already exists in '#{dst.dirname}'" else if @params[:cut].to_i > 0 adapter.move(src, dst) added_list.push cdc_for(dst) removed_list.push to_hash(src) else command_not_implemented return end end end end @response[:added] = added_list unless added_list.empty? @response[:removed] = removed_list unless removed_list.empty? end
_ping()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 349 def _ping @headers['Connection'] = 'Close' end
_put()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 442 def _put perms = perms_for(@target) if perms[:read] == true && perms[:write] == true @target.write @params[:content] @response[:changed] = [cdc_for(@target)] else @response[:error] = 'Access Denied' end end
_rename()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 288 def _rename unless valid_name?(@params[:name]) @response[:error] = "Unable to rename #{@target.ftype}" return end to = @target.dirname + @params[:name] perms_for_target = perms_for(@target) if perms_for_target[:locked] == true @response[:error] = 'Access Denied' return end perms_for_current = perms_for(@target) if perms_for_current[:write] == false @response[:error] = 'Access Denied' return end if to.exist? @response[:error] = "Unable to rename #{@target.ftype}. '#{to.basename}' already exists" else to = @target.rename(to) if to @response[:added] = [cdc_for(to)] @response[:removed] = [to_hash(@target)] else @response[:error] = "Unable to rename #{@target.ftype}" end end end
_resize()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 495 def _resize command_not_implemented end
_rm()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 395 def _rm if @targets.empty? @response[:error] = "No files were selected for removal" else removed_list = [] @targets.to_a.each do |target| removed_list.concat remove_target(target) end @response[:removed] = removed_list unless removed_list.empty? end end
_tmb()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 469 def _tmb if image_handler.nil? command_not_implemented else @response[:current] = to_hash(@current) @response[:images] = {} idx = 0 @current.children.select { |e| mime_handler.for(e) =~ /image/ }.each do |img| if (idx >= @options[:thumbs_at_once]) @response[:tmb] = true break end thumbnail = thumbnail_for(img) unless thumbnail.exist? && thumbnail.file? imgSourcePath = @options[:url] + '/' + img.path.to_s image_handler.thumbnail(imgSourcePath, thumbnail, :width => @options[:thumbs_size].to_i, :height => @options[:thumbs_size].to_i) @response[:images][to_hash(img)] = @options[:url] + '/' + thumbnail.path.to_s idx += 1 end end end end
_tree()
click to toggle source
of open
# File lib/el_finder_s3/connector.rb, line 230 def _tree if @target.directory? @response[:tree] = tree_for(@target).map { |e| cdc_for(e) }.compact else @response[:error] = "Directory does not exist" end end
_upload()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 324 def _upload if perms_for(@current)[:write] == false @response[:error] = 'Access Denied' return end select = [] @params[:upload].to_a.each do |io| name = @options[:original_filename_method].call(io) unless valid_name?(name) @response[:error] = 'Unable to create file' return end dst = @current + name dst.write(io) select << to_hash(dst) end @response[:select] = select unless select.empty? _open(@current) end
Private Instance Methods
cdc_for(pathname)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 577 def cdc_for(pathname) return nil if @options[:thumbs] && pathname.to_s == @thumb_directory.to_s response = { :name => pathname.basename.to_s, :hash => to_hash(pathname), :date => pathname.mtime.to_s } response.merge! perms_for(pathname) if pathname.directory? response.merge!( :size => 0, :mime => 'directory' ) elsif pathname.file? response.merge!( :size => pathname.size, :mime => mime_handler.for(pathname), :url => (@options[:url] + '/' + pathname.path.to_s) ) if pathname.readable? && response[:mime] =~ /image/ && !image_handler.nil? response.merge!( :resize => true, :dim => image_handler.size(pathname) ) if @options[:thumbs] if (thumbnail = thumbnail_for(pathname)).exist? response.merge!(:tmb => (@options[:url] + '/' + thumbnail.path.to_s)) else @response[:tmb] = true end end end end if pathname.symlink? response.merge!( :link => to_hash(@root + pathname.readlink), # hash of file to which point link :linkTo => (@root + pathname.readlink).relative_to(pathname.dirname.path).to_s, # relative path to :parent => to_hash((@root + pathname.readlink).dirname) # hash of directory in which is linked file ) end return response end
command_not_implemented()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 694 def command_not_implemented @response[:error] = "Command '#{@params[:cmd]}' not implemented" end
cwd_for(pathname)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 566 def cwd_for(pathname) { :name => pathname.basename.to_s, :hash => to_hash(pathname), :mime => 'directory', :rel => pathname.is_root? ? @options[:home] : (@options[:home] + '/' + pathname.path.to_s), :size => 0, :date => pathname.mtime.to_s, }.merge(perms_for(pathname)) end
image_handler()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 562 def image_handler @options[:image_handler] end
invalid_request()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 687 def invalid_request @response[:error] = "Invalid command '#{@params[:cmd]}'" end
mime_handler()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 557 def mime_handler @options[:mime_handler] end
perms_for(pathname, options = {})
click to toggle source
# File lib/el_finder_s3/connector.rb, line 643 def perms_for(pathname, options = {}) # skip = [options[:skip]].flatten response = {} response[:read] = pathname.readable? response[:read] &&= specific_perm_for(pathname, :read) response[:read] &&= @options[:default_perms][:read] response[:write] = pathname.writable? response[:write] &&= specific_perm_for(pathname, :write) response[:write] &&= @options[:default_perms][:write] response[:locked] = pathname.is_root? response[:locked] &&= specific_perm_for(pathname, :locked) response[:locked] &&= @options[:default_perms][:locked] response[:hidden] = false response[:hidden] ||= specific_perm_for(pathname, :hidden) response[:hidden] ||= @options[:default_perms][:hidden] response end
remove_target(target)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 530 def remove_target(target) removed = [] if target.directory? target.children.each do |child| removed.concat remove_target(child) end end if perms_for(target)[:locked] == true @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Access Denied" else begin removed.push to_hash(target) target.unlink if @options[:thumbs] && (thumbnail = thumbnail_for(target)).file? removed.push to_hash(thumbnail) thumbnail.unlink end rescue Exception => ex @response[:error] ||= 'Some files/directories were unable to be removed' @response[:errorData][target.basename.to_s] = "Remove failed" end end removed end
specific_perm_for(pathname, perm)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 669 def specific_perm_for(pathname, perm) pathname = pathname.path if pathname.is_a?(ElFinderS3::Pathname) matches = @options[:perms].select { |k, v| pathname.to_s.send((k.is_a?(String) ? :== : :match), k) } if perm == :hidden matches.one? { |e| e.last[perm] } else matches.none? { |e| e.last[perm] == false } end end
thumbnail_for(pathname)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 523 def thumbnail_for(pathname) result = @thumb_directory + "#{to_hash(pathname)}.png" result.type = :file result end
tree_for(root)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 626 def tree_for(root) root.child_directories(@options[:tree_sub_folders]). reject { |child| (@options[:thumbs] && child.to_s == @thumb_directory.to_s) || perms_for(child)[:hidden] }. sort_by { |e| e.basename.to_s.downcase }. map { |child| {:name => child.basename.to_s, :hash => to_hash(child), :dirs => tree_for(child), }.merge(perms_for(child)) } end
upload_max_size_in_bytes()
click to toggle source
# File lib/el_finder_s3/connector.rb, line 505 def upload_max_size_in_bytes bytes = @options[:upload_max_size] if bytes.is_a?(String) && bytes.strip =~ /(\d+)([KMG]?)/ bytes = $1.to_i unit = $2 case unit when 'K' bytes *= 1024 when 'M' bytes *= 1024 * 1024 when 'G' bytes *= 1024 * 1024 * 1024 end end bytes.to_i end
valid_name?(name)
click to toggle source
# File lib/el_finder_s3/connector.rb, line 682 def valid_name?(name) @options[:name_validator].call(name) end