[file_column] saves uploading file with wrong rights?


#1

Hello !
How to make file_column plugin saving uploaded documents in the
filesystem
with 660 (-rwrw-----) rights instead of 600 (-rw------- )?

Thank you for your help


#2

Hi Jerome,

On 12/6/05, Jérôme L removed_email_address@domain.invalid wrote:

How to make file_column plugin saving uploaded documents in the filesystem
with 660 (-rwrw-----) rights instead of 600 (-rw------- )?

since I don’t do anything special in the file_column code I believe
the files are saved with the process’ umask. So if you change this to
something more liberal in your environment.rb, you should be able to
get the permissions you want.

Sebastian


#3

skanthak wrote:

since I don’t do anything special in the file_column code I believe
the files are saved with the process’ umask. So if you change this to
something more liberal in your environment.rb, you should be able to
get the permissions you want.

Didn’t work for me. But I fixed it in file_column.rb, see here
http://www.stephensykes.com/blog_perm.html?122

Stephen.


#4

On 12/30/05, Stephen S. removed_email_address@domain.invalid wrote:

skanthak wrote:

since I don’t do anything special in the file_column code I believe
the files are saved with the process’ umask. So if you change this to
something more liberal in your environment.rb, you should be able to
get the permissions you want.

Didn’t work for me. But I fixed it in file_column.rb, see here
http://www.stephensykes.com/blog_perm.html?122

funny, I just found out that my proposed solution doesn’t work at all
and committed a fix to the trunk. You can now control the the
permission files are written with via a :permissions option, it
defaults to 0644. Please give it a try and tell me about any troubles
you’re having with it…

Sebastian


#5

Hi Jerome,

On 1/9/06, Jérôme L removed_email_address@domain.invalid wrote:

On 12/30/05, Sebastian K. removed_email_address@domain.invalid wrote:

funny, I just found out that my proposed solution doesn’t work at all
and committed a fix to the trunk. You can now control the the
permission files are written with via a :permissions option, it
defaults to 0644. Please give it a try and tell me about any troubles
you’re having with it…

Well, I have set :permissions => 0664 and it still saves files as 0644 …

I guess your umask is set to something that prevents files to have
more permissions than 0644. I will include a fix that uses File.chmod
instead, which should not consider the umask. Until I commit this fix
you can work around the problem by setting your process’ umask to 0002
before starting rails.

Sebastian


#6

On 12/30/05, Sebastian K. removed_email_address@domain.invalid wrote:

funny, I just found out that my proposed solution doesn’t work at all
and committed a fix to the trunk. You can now control the the
permission files are written with via a :permissions option, it
defaults to 0644. Please give it a try and tell me about any troubles
you’re having with it…

Well, I have set :permissions => 0664 and it still saves files as 0644


#7

On 1/10/06, Sebastian K. removed_email_address@domain.invalid wrote:

I guess your umask is set to something that prevents files to have
more permissions than 0644. I will include a fix that uses File.chmod
instead, which should not consider the umask. Until I commit this fix
you can work around the problem by setting your process’ umask to 0002
before starting rails.

My FreeBSD current umask is set to 0022.
The problem is indeed solved with File.umask 0002 in environment.rb

Waiting for you fix; thank you very very much Sebastian!


#8

Silly noob question coming here.

I have been having issues using file_column with a dynamic directory
for store_dir to work correctly however I finnaly have a new error
that I think this thread may fix. I am running on OSX in dev right
now and my permissions are coming up as rwxr-xr-x this causes an
error when uploading a file i believe that says that the directory /
rootpath/public/controller/1/tmp/random does not exist. I think this
is a permissions error and have no idea what you mean by setting the
process’ umask to 0002. How does one do this?

Andrew


#9

Well I was wrong. Did some more playing and digging and this issue
seems to be with file_column itself, or I am trying to do something
that i. This call works:

file_column :audio,
:store_dir => :dynamic_dir,
:permission => “0664”

def dynamic_dir
File.join(“episode”,“test”,“audio”)
end

while this does not work:

file_column :audio,
:store_dir => :dynamic_dir,
:permission => “0664”

def dynamic_dir
File.join(“episode”,self.user_id,“audio”)
end

however when I run the second one the directory structure gets built
on the server all the way up to the tmp directory:

/RAILS_ROOT/public/episode/1/audio/tmp/

but the random directory that file_column is looking for does not.

Is this a bug in file_column? or am i trying to get it to do
something it can’t?

Andrew


#10

On 1/10/06, Andrew F. removed_email_address@domain.invalid wrote:

           :permission => "0664"

Shouldn’t it be an integer and not a string ?


#11

Hi Andrew,

On 1/10/06, Andrew F. removed_email_address@domain.invalid wrote:

while this does not work:

file_column :audio,
:store_dir => :dynamic_dir,
:permission => “0664”

def dynamic_dir
File.join(“episode”,self.user_id,“audio”)
end

could it be that the moment dynamic_dir is called, the user_id
attribute does not have any sensible value (e.g., nil)? file_column
tries to create a temporary directory for the uploaded file as soon as
the file is assigned. If you mass-assign attributes from a hash it
could be that the file is assigned before the user_id attribute?
Just guessing here…

Sebastian


#12

Tried that first and second and figured out that I acctually didn’t
have to put the permissions in at all because it was working
correctly, but having a dynamic directory is causing my issues, if i
make the directory static everything works fine but the dynamic stuff
does not.

Flip


#13

Sebastian I have copied text from a seperate list item for your view.
In essance I believe that I have identified the problem and it is
possible that this is what is going on but the directories are
getting created in both cases but the first case (without overriding
the tmp directory was blowing up). The “1” below in the path is the
user_id directory. The following is the workaround that I found does
work:

After getting my dynamic_dir method to work I was running into the
following error: (Removed the info about the railsroot directory but
the full path was there)

No such file or directory - /{RAILS_ROOT}/public/episode/1/audio/tmp/
1136928177.355831.270

This error came from the following method:

def dynamic_dir
File.join(“episode”,self.user_id,“audio”)
end

The call to file_column looks like this:

file_column :audio,
:permission => 0664,
:store_dir => :dynamic_dir

and here is the full app error trace for those that care:

/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/1.8/fileutils.rb:525:in stat' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/1.8/fileutils.rb:525:instat’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/1.8/fileutils.rb:511:in preserve' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/1.8/fileutils.rb:455:incopy_entry’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/1.8/fileutils.rb:416:in copy_entry' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/1.8/fileutils.rb:584:inmv’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/1.8/fileutils.rb:572:in fu_each_src_dest' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/1.8/fileutils.rb:845:infu_each_src_dest0’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/1.8/fileutils.rb:845:in fu_each_src_dest' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/1.8/fileutils.rb:572:inmv’
#{RAILS_ROOT}/vendor/plugins/trunk/lib/file_column.rb:365:in move_from' #{RAILS_ROOT}/vendor/plugins/trunk/lib/file_column.rb:314:inafter_save’
#{RAILS_ROOT}/vendor/plugins/trunk/lib/file_column.rb:676:in
audio_after_save' #{RAILS_ROOT}/vendor/plugins/trunk/lib/file_column.rb:675:inaudio_after_save’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/callbacks.rb:333:in send' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/callbacks.rb:333:incallback’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/callbacks.rb:330:in each' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/callbacks.rb:330:incallback’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/callbacks.rb:250:in create_or_update' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/base.rb:1226:insave_without_validation’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/validations.rb:698:in save_without_transactions' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:126:insave’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/transactions.rb:126:in transaction' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:91:intransaction’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/
active_record/transactions.rb:118:in transaction' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/activerecord-1.13.2/lib/ active_record/transactions.rb:126:insave’
#{RAILS_ROOT}/app/controllers/episodes_controller.rb:39:in create' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/ action_controller/base.rb:853:insend’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/
action_controller/base.rb:853:in perform_action_without_filters' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/ action_controller/filters.rb:332:inperform_action_without_benchmark’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/
action_controller/benchmarking.rb:69:in perform_action_without_rescue' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/ action_controller/benchmarking.rb:69:inmeasure’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/
action_controller/benchmarking.rb:69:in perform_action_without_rescue' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/ action_controller/rescue.rb:82:inperform_action’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/
action_controller/base.rb:369:in send' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/ action_controller/base.rb:369:inprocess_without_session_management_support’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/actionpack-1.11.2/lib/
action_controller/session_management.rb:116:in process' #{RAILS_ROOT}/app/controllers/application.rb:15:inprocess’
#{RAILS_ROOT}/app/controllers/application.rb:14:in catch' #{RAILS_ROOT}/app/controllers/application.rb:14:inprocess’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/dispatcher.rb:
38:in dispatch' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/ fcgi_handler.rb:141:inprocess_request’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/
fcgi_handler.rb:53:in process!' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/ fcgi_handler.rb:52:ineach_cgi’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:in
each' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/fcgi-0.8.6.1/./fcgi.rb:597:ineach_cgi’
/Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/
Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/
fcgi_handler.rb:52:in process!' /Applications/Locomotive/Bundles/rails-1.0.0-max.bundle/Contents/ Resources/ports/lib/ruby/gems/1.8/gems/rails-1.0.0/lib/ fcgi_handler.rb:22:inprocess!’
/Users/flip/Documents/workspace/SolidPodcast/public/dispatch.fcgi:24

Now on to the workaround. I figured that there was something going on
with the temp_dir settings and decided to test it out by defining the
temp directory myself. The new file_column call looks like this:

file_column :audio,
:permission => 0664,
:store_dir => :dynamic_dir,
:tmp_base_dir => “/episode/tmp”

The permission really doesnt matter. What does is the tmp_base_dir.
As the stack shows something is going on when creating the temp
directory as file_column blows up when trying to implement the
after_save_method found at line 675 of the trunk version. It blows up
because the temp directory is never created, since it is never
created the file is never saved and therefore can’t be moved to the
permanent directory.

By over riding the tmp directory settings I am able to upload files
that are stored where i want them to be stored with the added layer
of by user.

Like I said I will try to carve some time out to look into this more
and come up with a patch to submit for file_column but until than or
if someone else figures out why this acts the way it does and you
need to have a dynamic directory than this is the workaround to the
issue.

Thanks for all the lists help again I know that I have had several
questions with some great responses on this list. I wish all
communities were this helpful.

Andrew


#14

Jérôme L wrote:

On 12/30/05, Sebastian K. removed_email_address@domain.invalid wrote:

funny, I just found out that my proposed solution doesn’t work at all
and committed a fix to the trunk. You can now control the the
permission files are written with via a :permissions option, it
defaults to 0644. Please give it a try and tell me about any troubles
you’re having with it…

Well, I have set :permissions => 0664 and it still saves files as 0644

I have been struggling with permission issues on images I’ve been
uploading, some images upload find and the correct permissions are set
0644 others are uploaded fine but the permissions are not set correctly
0600. The incorrect permissions were alway applied to the same images
and after some lengthy investigation into this issue it turns out that
file_columns fix_file_extension is the cause of the issue.

The following code snippet is located in file_column.rb
TempUploadedFile#store_upload

  # stored uploaded file into local_file_path
  # If it was a Tempfile object, the temporary file will be
  # cleaned up automatically, so we do not have to care for this
  if file.respond_to?(:local_path) and file.local_path and 

File.exists?(file.local_path)
FileUtils.copy_file(file.local_path, local_file_path)
elsif file.respond_to?(:read)
File.open(local_file_path, “wb”) { |f| f.write(file.read) }
else
raise ArgumentError.new(“Do not know how to handle
#{file.inspect}”)
end
File.chmod(options[:permissions], local_file_path)

After the file is created the File.chmod changes the file permission to
the value supplied (defaults to 0644) this all works correctly and is
the reason some of my images have the correct permissions.

The following code snippet appears after the above code in
file_column.rb and is responsible for fixing incorrect file extensions
on the uploaded files.

  if options[:fix_file_extensions]
    # try to determine correct file extension and fix
    # if necessary
    content_type = get_content_type((file.content_type.chomp if 

file.content_type))
if content_type and options[:mime_extensions][content_type]
@filename =
correct_extension(@filename,options[:mime_extensions][content_type])
end

    new_local_file_path = File.join(tmp_base_dir,@tmp_dir,@filename)
    File.rename(local_file_path, new_local_file_path) unless 

new_local_file_path == local_file_path
local_file_path = new_local_file_path
end

If the file extension is ‘fixed’ by the above code the file gets saved a
second time and it’s this saving of the file that was causing some of my
images to have incorrect permissions.

Add the following line after the :fix_file_extensions if statement and
the permissions of ‘fixed’ files will also be set correctly.

 File.chmod(options[:permissions], local_file_path)

Pin