errno::eacces: permission denied # rb_sysopen when uploading jpg - ruby

I am developing rails app and I have problem when I try to upload photo to a server, error message is shown. In log file I have error: "Errno::EACCES (Permission denied # rb_sysopen - /photo.jpg". Issue occurred on line "File.open(...)"
My upload method:
def upload_photo
logger.info(params.to_s)
logger.info(params[:file].to_s)
photo = params[:file]
filename = photo.instance_variable_get(:#headers).to_s.match(/filename="(.*)"/).captures[0]
File.open("#{PHOTO_DIR}/#{photo.original_filename}",'wb') do |file|
file.write(photo.read)
end
respond_to do |format|
format.html {
render :text => 'File uploaded.'
}
end
end
Perimissions on the folder where photos would be stored is "drw-rw-rw-", owner is my user, group is also my user.
I tried to fix this by reclaiming ownership using chown -R user:user /path/to/photos but it didn't work.
How can I resolve this?

Problem was with PHOTO_DIR constant because it is setted as env variable in constants.rb file.
PHOTO_DIR = ENV['PHOTO']
When I changed env variable with the full path to the dir, everything works as expected.
PHOTO_DIR = '/path/to/jpg_files/'
It looks like env variable is not loaded in ~/.bashrc file but I tried echo $PHOTO and path to the photos is printed.

Related

Rspec: do a mkdir and then and then pass screenshots to the new directory

I've created an rspec test where I've created a directory inside of an it block and am also taking screenshots of the various states of the test.
It's a form entry I'm testing so the it block looks like this:
...
it "confirm that a user can successfully sign up" do
timestamp = Time.now.to_i
dir = Dir.mkdir("dir_#{timestamp}")
driver = Selenium::WebDriver.for :firefox
driver.navigate.to "go/to/url"
username_field = driver.find_element(id: "user_username")
username_field.send_keys("user #{timestamp}")
driver.save_screenshot("./#{dir}/screen_username.png")
...
end
So if timestamp is 1234, then I'm assuming a directory named dir_1234 will be created and it will, at some point, put an image inside of it named screen_username.png inside of it. But when I run rspec, I get the following error:
Failure/Error: driver.save_screenshot("./#{dir}/screen_username.png")
Errno::ENOENT:
No such file or directory # rb_sysopen - ./0/screen_username.png
...
Any ideas? Thanks in advance.
Dir::mkdir always returns 0
dir = Dir.mkdir("dir_#{timestamp}") # => 0
That's your problem
You can save path to some variable
dir_path = File.join(__dir__, "dir_#{timestamp}")
Dir.mkdir(dir_path)
# your code
driver.save_screenshot(File.join(dir_path, "screen_username.png"))

Passing jpg file directly on from backend server

I'm uploading an image file from my app via JSON to my ruby backend hosted by Heroku. It is then supposed to be passed to stripe via their gem via a path to my uploaded image. Is it possible to just pass it the tempfile? The stripe docs say to do:
Stripe::FileUpload.create(
:purpose => 'dispute_evidence',
:file => File.new('/path/to/a/file.jpg')
)
my backend post looks like:
post '/account/id' do
tempfile = params[:file][:tempfile]
filename = params[:file][:filename]
path = "#{tempfile.path}/#{filename}"
p path --> "/tmp/RackMultipart20170112-4-fgtv2n/photoID.jpg"
begin
file = Stripe::FileUpload.create({
:purpose => params[:purpose],
:file => File.new(path)
},
{
:stripe_account => params[:stripe_account]
}
)
rescue Stripe::StripeError => e
status 402
return "Error saving verification id to account: #{e.message}"
end
status 200
return file.to_json
end
but when running i get:
Errno::ENOENT - No such file or directory # rb_sysopen - /tmp/RackMultipart20170112-4-1qmr03y/photoID.jpg:
i cant figure out what im doing wrong. can any one help or suggest a better option?
You are mistaking tempfile for a directory. tempfile is actually your temporary file, so pass it instead of path (that you don't need any more).

Error while rewriting from temp file

I'm writing to a file from a temp file, when I try to read the file that has been written from the temp file, it seems to be adding an extra character to the directory called tmp. (file is passed in through optparse)
Source:
require 'tempfile'
PATH = Dir.pwd
def format_file
puts 'Writing to temporary file..'
if File.exists?(OPTIONS[:file])
file = Tempfile.new('file')
IO.read(OPTIONS[:file]).each_line do |s|
File.open(file, 'a+') { |format| format.puts(s) unless s.chomp.empty? }
end
IO.read(file).each_line do |file|
File.open("#{PATH}/tmp/#sites.txt", 'a+') { |line| line.puts(file) }
end
puts "File: #{OPTIONS[:file]}, has been formatted and saved as #sites.txt in the tmp directory."
else
puts <<-_END_
Woah now my friend! I know you're eager to get those vulns;
But file: #{OPTIONS[:file]} doesn't exist or in this directory at least!
What I'm gonna need you to do is go move that file over here.
It's okay, you're forgiven, I'll wait until you return..
_END_
end
end
Example:
ruby whitewidow.rb -f sites.txt
[12:40:43 INFO]Formatting file
[12:40:43 INFO]Writing to temporary file..
[12:40:43 INFO]File: tmp/sites.txt, has been formatted and saved as #sites.txt in the tmp directory.
[12:40:43 INFO]Let's check out this file real quick like..
whitewidow.rb:224:in `read': No such file or directory # rb_sysopen - C:/Users/Justin/MyScripts/RubySQL/whitewidow/#tmp/#sites.txt (Errno::ENOENT)
#<= Correct path but the '#' in tmp shouldn't be there..
What it does is format the file to remove any empty lines within it (this program doesn't like empty lines) from there it should write to a temp file, rewrite from the temp file back to the original directory (whitewidow/tmp/) and delete the temp file (I know how to do this part).
It seems to me like while rewriting back to the original directory it's adding a # to the directory name (#tmp is actually tmp) is there a reason that it's adding this?
I fixed it, for some reason the program was adding a # to the path, so I gsubed out the # and it works.

In Ruby, how can I update the avatar / background image file.jpg in a folder?

My image files are in a folder titled "avis" and each jpeg file inside has a title of "IMG_36754.JPG". The numbers are kind of random. My problem is that I can't get the client to update the avatar or the background image.
client = Twitter::REST::Client.new do |config|
config.consumer_key = "xxxxx"
config.consumer_secret = "xxxxx"
config.access_token = "xxxxx"
config.access_token_secret = "xxxxx"
end
When I try the code below, I get an error that reads " No such file or directory # rb_sysopen - IMG_7394.JPG (Errno::ENOENT)"
file5 = File.open(Dir.entries("avis").sample)
puts client.update_profile_image(file5)
When I use this code below, I get an error "No such file or directory # rb_sysopen - avi (Errno::ENOENT)"
avis = Dir.entries("avis")
avi = avis.sample.to_s
file = File.read("avi","r")
puts client.update_profile_image(file)
I tried to make it so that it can get the image file from the folder and then have the update profile method use the image string to update, however it doesn't seem to work. please help, thanks.

Sinatra list of image files works on localhost but not on the test server

The code below gets a list of images from the public/images directory, creates an array of hashes and converts it to JSON then returns to the caller.
The code works perfectly on the local host - I get the list of image names as needed.
I then uploaded the code to my VPS and ran it on the same environment, running on thin, and nothing is returned at all. No matter what I change, either the path or method for getting filenames, like using glob instead of just Dir, nothing works that I tried.
Here is the code in the route I call from the client-side JavaScript using Ajax:
# get all images
get '/debug/posts/images/' do
puts '>> debug > posts > images > get'
all_images = Array.new
# build substitute prefix path
uri = URI(request.url)
prefix ='http://' + uri.host
if request.port
prefix += ':' + request.port.to_s
end
prefix += '/content/'
begin
content_type :json
# get list of images
pics = Dir['public/images/*']
pics.map { |pic|
# build hash for use with tinyMCE
pic.split('/')
pic_hash = {:title => File.basename(pic).to_s, :value => prefix + File.basename(pic).to_s}
all_images.push(pic_hash)
}
# convert to json
pic_json = JSON.generate(all_images)
body(pic_json)
rescue Sequel::Error => e
puts e.message
status(400).to_json
end
end
I get an array of values back running on the localhost:
[ {title: "bear-love.jpg"value: "/content/bear-love.jpg"}, {title: "bear-love2.jpg"value: "/content/bear-love2.jpg"}...]
I get an empty array from the VPS:
[]
Check that the server is being run as a user who has permission to read and execute public/images
verify that public/images exists
verify that public/images is where you think it is.
Turns out that it's easier to get the current path on the server and simply get a list of the image filenames I needed that way and just add my prefix path for use from the browser.

Resources