Accessing a file with normal Ruby IO fails. Security issue of what?

Hi,

I'm developing a small Rails 2.2.0 app. I have a slightly modified
scaffold-generated file,
PayrollSys\app\controllers\cvs_items_controller.rb, as follows:

class CvsItemsController < ApplicationController
  # GET /cvs_items
  # GET /cvs_items.xml
  require 'find' # Added

  def index
    logger.info "==> index in cvs_items_controller.rb"
    # @cvs_items = CvsItem.find(:all)
    @cvs_items = get_csv_filenames_attributes() # Replacement

  [snip]

protected
  def reload
    logger.info "==> Reload in cvs_items_controller.rb -- RLM "
  end

  def get_csv_filenames_attributes # Brand new method
    csv_data_dir = "../../public/data/csv"
    values = []
    Find.find(csv_data_dir) do |item|
      next unless File.file?(item)
      values << item
    end
    values
  end
end

Using a logger, I have confirmed that no filenames have been returned
by File.find and that the values array remains zero length.

However, the exact same method (without the "def" and its closing
"end"), when added to a brother file in the same directory, correctly
lists the two .csv files in the
PayrollSys\public\data\csv directory (when a puts is prepended to the
closing "values" symbol).

Is there some security method that precludes accessing the files?
Would the tableless plugin be relevant, though I do want ActiveRecord
to access the application database(s).

Thanks in Advance,
Richard

RichardOnRails wrote:

Hi,

I'm developing a small Rails 2.2.0 app. I have a slightly modified
scaffold-generated file,
PayrollSys\app\controllers\cvs_items_controller.rb, as follows:

class CvsItemsController < ApplicationController
  # GET /cvs_items
  # GET /cvs_items.xml
  require 'find' # Added

  def index
    logger.info "==> index in cvs_items_controller.rb"
    # @cvs_items = CvsItem.find(:all)
    @cvs_items = get_csv_filenames_attributes() # Replacement

  [snip]

protected
  def reload
    logger.info "==> Reload in cvs_items_controller.rb -- RLM "
  end

  def get_csv_filenames_attributes
    csv_data_dir = "../../public/data/csv"

do you mean "../../../public/data/csv"?
or you have a public dir under the app dir?

yes it is strange but you need to go 1 dir more back...

    values = []
    Find.find(csv_data_dir) do |item|
      next unless File.file?(item)
      values << item
    end
    values
  end
end

Using a logger, I have confirmed that no filenames have been returned
by File.find and that the values array remains zero length.

probably you are looking in the wrong dir

However, the exact same method (without the "def" and its closing
"end"), when added to a brother file in the same directory, correctly
lists the two .csv files in the
PayrollSys\public\data\csv directory (when a puts is prepended to the
closing "values" symbol).

Is there some security method that precludes accessing the files?
Would the tableless plugin be relevant, though I do want ActiveRecord
to access the application database(s).

Thanks in Advance,
Richard

try this:

  protected
    def reload
      logger.info "==> Reload in cvs_items_controller.rb -- RLM "
    end

    def get_csv_filenames_attributes
      csv_data_dir = File.expand_path(File.dirname(__FILE__) +
"../../../public/data/csv/")
      logger.info "==> csv_data_dir: #{csv_data_dir}" #print the dir so
you can check if it is correct
      values = []
      Find.find(csv_data_dir) do |item|
        logger.info "==> item in csv_data_dir: #{item}"
        next unless File.file?(item)
        values << item
      end
      values
    end

Hope this help

Duilio Ruggiero

Duilio Ruggiero wrote:

RichardOnRails wrote:

Hi,

I'm developing a small Rails 2.2.0 app. I have a slightly modified
scaffold-generated file,
PayrollSys\app\controllers\cvs_items_controller.rb, as follows:

class CvsItemsController < ApplicationController
  # GET /cvs_items
  # GET /cvs_items.xml
  require 'find' # Added

  def index
    logger.info "==> index in cvs_items_controller.rb"
    # @cvs_items = CvsItem.find(:all)
    @cvs_items = get_csv_filenames_attributes() # Replacement

  [snip]

protected
  def reload
    logger.info "==> Reload in cvs_items_controller.rb -- RLM "
  end

  def get_csv_filenames_attributes
    csv_data_dir = "../../public/data/csv"

do you mean "../../../public/data/csv"?
or you have a public dir under the app dir?

yes it is strange but you need to go 1 dir more back...

no, my error
is relative to the dir where you start rails

if you use
ruby script/server
and
csv_data_dir = "public/data/csv"
it works

    values = []
    Find.find(csv_data_dir) do |item|
      next unless File.file?(item)
      values << item
    end
    values
  end
end

Using a logger, I have confirmed that no filenames have been returned
by File.find and that the values array remains zero length.

probably you are looking in the wrong dir

However, the exact same method (without the "def" and its closing
"end"), when added to a brother file in the same directory, correctly
lists the two .csv files in the
PayrollSys\public\data\csv directory (when a puts is prepended to the
closing "values" symbol).

Is there some security method that precludes accessing the files?
Would the tableless plugin be relevant, though I do want ActiveRecord
to access the application database(s).

Thanks in Advance,
Richard

try this:

  protected
    def reload
      logger.info "==> Reload in cvs_items_controller.rb -- RLM "
    end

    def get_csv_filenames_attributes
      csv_data_dir = File.expand_path(File.dirname(__FILE__) +
"../../../public/data/csv/")
      logger.info "==> csv_data_dir: #{csv_data_dir}" #print the dir so
you can check if it is correct
      values = []
      Find.find(csv_data_dir) do |item|
        logger.info "==> item in csv_data_dir: #{item}"
        next unless File.file?(item)
        values << item
      end
      values
    end

Hope this help

Duilio Ruggiero

Errata corrige

  protected
    def reload
      logger.info "==> Reload in cvs_items_controller.rb -- RLM "
    end

    def get_csv_filenames_attributes
      csv_data_dir = File.expand_path(File.dirname(__FILE__) +
                                   "/../../public/data/csv/")
      values = []
      logger.info "==> csv_data_dir: #{csv_data_dir}"
      Find.find(csv_data_dir) do |item|
        next unless File.file?(item)
        logger.info "==> file in csv_data_dir: #{item}"
        values << item
      end
      values
    end

I hope this is correct :wink:

Duilio Ruggiero

PS: I'm sorry for my English

Richard,

What you want is:

csv_data_dir = RAILS_ROOT + "/public/data/csv"

Rick

Hi Duilio,

Thanks for your responses. I'll try them out today. I have a slight
digression: in the process of removing my debugging code I managed to
mess a few things up, which I'll have to fix first. I'll post back
with the outcome.

PS: I'm sorry for my English

No apology necessary. It's not the form of your expression that
matters, it's the content of your message (with apologies to Martin
Luther King's memory.)

Best wishes,
Richard

Hi Rick,

csv_data_dir = RAILS_ROOT + "/public/data/csv"

Now that looks like REAL Ruby-on-Rails programming.

Many thanks.

I'll post back on success/failure later today or tomorrow.

Best wishes,
Richard

Hey Rick,

RAILS_ROOT was the key. I never would have dreamed that up by
myself, despite my handsome collection of Rails books :slight_smile:

Thanks and Best Wishes,
Richard