Rails public/system for user files - ruby-on-rails-3

Both Rails gems DragonFly and Paperclip use public/system folder to store uploaded files.
As far as I know this folder is accessible by everybody - at least the root files, 404.html or others.
How can I protect these uploaded files? Is there any configuration options available?
I need to process transcoded video files which are generated from user uploads and make them available with some permission checks.
Are there any recommendations?

Not sure about dragonfile but you can change the paperclip file upload options.
Could you use Amazon S3 instead?
Add the following to your envrionment:
config.paperclip_defaults = {
:storage => :s3,
:s3_credentials => {
:bucket => ENV['AWS_BUCKET'],
:access_key_id => ENV['AWS_ACCESS_KEY_ID'],
:secret_access_key => ENV['AWS_SECRET_ACCESS_KEY']
}
}
Make sure you've got the s3 gem installed by adding this to your gemfile:
gem 'aws-sdk'
Does that help or do you need to keep them on your server to process??
-- edit --
Apparently heroku recommend using a temp file if you can't use s3. Have a read of this post:
How can I change the upload directory for paperclip on heroku to /tmp?

Related

paperclip with amazon s3 working in development but not working in production (amazon ec2)?

I'm pretty new to rails and seem to be having an issue with the paperclip gem. I installed the gem and it works well in development (localhost:3000) but when I'm running it on the amazon server, for some reason it does not want to attach files, and the app breaks (error 500 page).
i have deployed my code to amazon server, i configured bucket details also, but still it is having problem with production, although it works fine with localhost.
Here is the process i ran... I pushed my file to amazon. This did not seem to help.
Here is the code that I have for paperclip:
user.rb model:
has_attached_file :avatar,
:styles => {
:thumb => "50x50",
:medium => "400x400",
:square => "70x70"
},
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => ":attachment/:id/:style.:extension",
:bucket => "mybucket"
my User form:
<%= form_for(#user, url: "/sessions/#{current_user.id}", :html =>{:method => :put, :class => "form-horizontal", :multipart => true}) do |f| %>
<%= f.file_field :avatar %>
<% end %>
breaks down in production. Any pointers would be greatly appreciated... I just cant seem to figure this out and it's pretty frustrating. Thank you so much for your time and any help! please give a pointer where i am making mistake.
Had same issue with image_magic that was breaking our paperclip functionality in production, but not in development (weird, I know). Yet even after removing imagemagick from our gemfile and Gemfile.lock locally (running bundle install and all that stuff) and then deploying back to production on heroku, the error persisted in production! (weird, I know).
What ended up doing the trick was running:
$ heroku repo:purge_cache -a myAppName
(Taken from: https://github.com/heroku/heroku-repo#purge_cache)
When you deploy your app, Heroku caches some things like your assets and installed gems in order to speed up deployment. Although this is a great feature, it can have side-effects sometimes, and in this case, it seems that something about the imagemagick gem got "stuck" in production's cache, which is why purging solved the issue for us (since after purging, your app will rebuild itself from scratch on your next deployment)

Paperclip Mongoid S3 error

GETTING THIS ERROR WHEN UPLOADING A FILE :
LoadError (no such file to load -- aws-sdk (You may need to install the aws-sdk gem)):
app/controllers/uploaded_files_controller.rb:19:in `create'
I am using Mongo and Paperclip. I can upload files fine without using s3. However, our production server is on Heroku and so I have to use Amazon to store the files.
I've read other Stack Overflow posts about this but none address my specific issue.
I have restarted my server several times. that's not it.
I am indeed requiring the Amazon gem in my Gemfile
I have done a bundle install after putting the amazon gem in ( I know its obvious, but still I had to state this )
I am NOT using ImageMagick. These uploads are simple text file uploads.
I know that my Amazon bucket name and auth stuff is correct because I use this app to connect to other Amazon resources in a different capacity.
Can anyone help with this ? Here is my code:
class UploadedFile
include Mongoid::Document
include Mongoid::Paperclip
require "aws/s3"
has_mongoid_attached_file :file,
:storage => :s3,
:bucket_name => 'my-uploads',
:path => ':attachment/:id/:style.:extension',
:s3_credentials => File.join(Rails.root, 'config', 'amazon_s3.yml')
end
OK, I've found the answer: The gem needs to be updated.
Paperclip now requires Amazon SDK gem instead of the s3 gem.
gem 'aws-s3', :require => "aws/s3"
should be instead
gem 'aws-sdk', :require => "aws-sdk"

How to resolve "Missing Credentials" with Paperclip and s3 storage in rails 3

I have a pretty straightforward model and attachment
has_attached_file :upload,
:storage => :s3,
:bucket => 'bestofbauer',
:s3_credentials => {
:access_key_id => ENV['MyAccessKEY'],
:secret_access_key => ENV['MySecretKey']
}
I have a bucket setup with s3 called bestofbauer.
I know I could refactor the credentials into an initializer but I haven't gotten this to save an attachment yet so I haven't worried about it.
When I run the save for the object and its attachement I get:
RuntimeError in RecommendationsController#create
Missing credentials
I have poured over: Credentials missing when uploading photos with Paperclip and Amazon s3 but that didn't resolve my issue.
I am using the following gems:
gem "paperclip"
gem "sws-sdk"
gem 'aws-s3'
Any other ideas?
You need to set your environment variables. Here's two different ways to do it:
Every time you run rails server or any other command that accesses your S3 account you need to include your keys:
$ MyAccessKEY=ACCESS_KEY MySecretKEY=SECRET_KEY rails server
I'm assuming you're using bash so edit your ~/.bash_rc or ~/.bash_profile to set your environment variables
export MyAccessKEY=ACCESS_KEY
export MySecretKEY=SECRET_KEY
Then open a new terminal window and double-check that they're set
$ echo $MyAccessKey
> ACCESS KEY PRINTS OUT HERE
If you're deploying to Heroku then you'll want to provide your environment variables there as well:
$ heroku config:add MyAccessKEY=ACCESS_KEY MySecretKEY=SECRET_KEY
You can review your Heroku config:
$ heroku config
It will list out all of the config variables you have for that app.
You'll probably want to put your S3 bucket name in an ENV setting as well so you don't mess up your bucket when testing locally.

Troubles setting up Paperclip + AWS S3 for image storing in our Rails3/Heroku App

We have already built a rails app that has several users and an image for each of them. Doing all of the dev work on our localhost, we have working seeds for users & photos...but now that we are trying to use S3 for the image storage, we are running into errors during...always during the "seed" step of the migrations, when doing this:
rake db:migrate:reset
Apologies for the question, but we have have been banging our heads on this for 11 hours, having gone through every related Stack question on the subject. A lot of similar posts had a NoSuchBucket error and other types of issues, but we none of the suggested changes have fixed our issue...maybe it's related to the newest versions of the gems we are using?
We are using Rails 3.0.4, Ruby 1.8.7, Paperclip 2.3.8, aws-s3 0.6.2
We are adding seeds for initial users and a photo for each user using our seeds.rb file in the /migrate/ folder. This always worked fine when storing files and images on local machine (using paperclip, but not S3). We also have tested removing the seeds file and simply creating a new user with the working app and got the same error:
Credentials are not a path, file, or
hash
For the user module, we have tested both the option where we set the following S3 keys through both the (a) yml file and (b) directly in the user model.
access_key_id: 'secret'
secret_access_key: 'secret'
We have tried doing this from our localhost (not yet live on heroku), and we have also tried running this through Heroku.
We have tried seemingly every permutation of the layout of those keys, but the error we most frequently get is this:
can't convert Module into Hash
Googling this error message returns zero results, so we don't know what's happening there. This was the most frustrating part...seemingly every attempt got us back to this error.
We also tried both:
(1) hardcoding the access keys in the user model, both like this:
:access_key_id => ENV['accesskeyid'],
:secret_access_key => ENV['secretaccesskey'],
In this case, we often got this error:
You did not provide both required access keys. Please provide the
access_key_id and the secret_access_key.
Frustrating, because we always had both items listed, tested with and without quotes, changing up the order, etc.
We tried it both (a) with the ENV['accesskeyid'] and (b) without those...with simply
blahblah => 'accesskeyid'.
and (2) putting the keys into the yml file, like this:
has_attached_file :photo,
:storage => :s3,
:s3_credentials => "#{Rails.root}/config/s3.yml",
:path => "/:photo/:filename"
with this in the yml file:
development:
access_key_id: accesskeyid
secret_access_key: secretaccesskey
bucket: ourbucketname
production:
access_key_id: accesskeyid
secret_access_key: secretaccesskey
bucket: ourbucketname
We tried this with single quotes around the keys, and without.
We also tried defining the bucket in the model, rather than in the yml file, and got the same error.
and (3), setting it up this way:
if Rails.env == "production"
S3_CREDENTIALS = { :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'], :bucket => "ourbucket"} else
S3_CREDENTIALS = Rails.root.join("config/s3.yml")
end
has_attached_file :photo,
:storage => :s3,
:styles => { :small => "50x50>", :thumb => "75x75>", :medium =>
"400x400>"},
:path => "/:photo/:filename"
With the same contents in our yml file.
This gave us this error:
credentials are not a file, path, or hash
Naturally, we quadruple-checked that we had the correct access keys (from our AWS account) and tested several different ways of setting up the hash, but never got what we wanted.
Here is the relevant portion of Gemfile:
gem 'aws-s3', :require => 'aws/s3' #For Storing Images on Amazon
gem 'paperclip'
As another attempt, we tried to use the gem right_aws, instead, in the Gemfile, but this resulted in this error:
no such file to load -- aws/s3 (You
may need to install the aws-s3 gem)
Note, we have been doing all of this and hitting all of these errors doing migrations from from localhost, not from the live Heroku app, but couldn't even get past this simple 'seed users' step.
Currently, our bucket is titled media.oururl.com. Is there some issue with having periods in the bucket name?
Going to ask the heroku guys about this, as well, but considering how amazing this community is, I am hoping one of you knows what we're doing wrong her.
MUCH appreciated - and hopefully this helps others who follow behind us.
excellent question. I spent quite some time with a similar issue a while ago
The primary issue is that you need to move the following code into it's own initializer file:
if Rails.env == "production"
S3_CREDENTIALS = { :access_key_id => ENV['S3_KEY'], :secret_access_key => ENV['S3_SECRET'], :bucket => "ourbucket"}
else
S3_CREDENTIALS = Rails.root.join("config/s3.yml")
end
Then, you should add the following line to your model where you have *has_attached_file :photo* The line to add is.
:s3_credentials => S3_CREDENTIALS,
This is what you were missing before.
Also, for when you declare your bucket name, make sure that is for standard us. If you use one of the other locations, you'll have to update the path appropriately.
Hope this helps!

Have Rails 'image_tag' to browse image outside the /public folder?

I am trying to use Paperclip with Heroku. And yes, according to Heroku's Application Constraints. I'll be able to store the uploaded files into /tmp or /.log folder only, which is totally located outside the /public folder.
If we are not going to talk about Amazon S3, how can I access the image in the /tmp directory with image_tag tag.
This is my model of the photo, that using Paperclip
class ObbProductphoto < ActiveRecord::Base
belongs_to :product
has_attached_file :photo, :styles => {:high => '1024x768', :medium => '640x480', :thumb => '100x100'},
:path => "tmp/:id.:extension",
:url => "tmp/:id.:extension"
end
And this is what I got in the browser:
<img src="/images/tmp/24.JPG?1294433924" alt="24" />
It still using the /images folder,
I tried to hack any /.. or ../, couldn't get the solution.
Thank you guys,
Suebphatt
Assuming you can put the files somewhere more permanent than /tmp, storing and accessing uploaded files outside the public directory is possible using the :url and :path parameters, along with a bit of configuration work.
An example extracted from code I wrote recently (it's modified enough that it might not work if you copy it verbatim):
app/models/picture.rb
# Define the attachment
has_attached_file :image,
:styles => {:large => ["700", :jpg],
:thumb => ["100x100>", :gif]},
:url => "/asset/picture/:id/:style/:basename.:extension",
:path => ":base/picture/:id/:style/:basename.:extension"
config/initializers/storage.rb
# Configure common attachment storage
# This approach allows more flexibility in defining, and potentially moving,
# a common storage root for multiple models. If unneeded, just replace
# :base in the :path parameter with the actual path
Paperclip.interpolates :base do |attachment, style|
/path/to/persistent/storage
# A relative path from the Rails.root directory should work as well
end
app/controllers/pictures_controller.rb
# Make the attachment accessible
def asset
instance = Picture.find(params[:id])
params[:style].gsub!(/\.\./, '')
#check permissions before delivering asset?
send_file instance.image.path(params[:style].intern),
:type => instance.image_content_type,
:disposition => 'inline'
end
config/routes.rb
# Add the necessary route
match '/asset/picture/:id/:style/:basename.:extension', :to => 'pictures#asset'
app/views/pictures/show.html.erb
<% # Display the picture %>
<%= image_tag picture.image.url(:large) %>
Note this is all Rails 3 syntax. A handful of changes would be needed to use it in Rails 2.x, but hopefully you get the, um, picture.
As far as I'm aware, you can't - /tmp isn't configured as something that you can serve items out of (it's intended for temporary storage).
Can you access images at the /tmp URLs in your browser? Do they work?