PDF corrupted on Outlook with AVG anti-virus software installed - ruby-on-rails

we are having the problem of sending PDF attachment using ActionMailer.
The PDF file was combined from 2 PDF files using combine_pdf gem.
A normal PDF file with our logo.
A docx converted PDF using http://convertapi.com
The combined PDF file is stored on AWS S3. What we did is just attach it using open-uri
require 'open-uri'
class ApplicationMailer < ActionMailer::Base
def employer_notification application_id
#application = JobApplication.find_by_id application_id
return unless #application
attachments[#application.cv_name] = {
mime_type: 'application/pdf',
content: open(#application.cv_url(900)).read
}
mail(
from: "#{#application.fullname}<test#myapp.com>",
to: #application.job.employer_emails(", "),
reply_to: #application.email,
subject: "Application for #{#application.job.title}"
)
end
end
We used Mandrill to send out the emails over the internet and something strangely happened. Some PDF could be viewed properly, some contained font errors and the converted PDF part went blank.
But if we turned off AVG anti-virus, it worked perfectly.
Does anyone have the same problem before? May I know how a PDF file is considered malicious?
Thanks in advance.

Related

Rails 5.0.1 - ActionMailer with MailGun, setting 'noname' for filename when directly attaching base64 string

I have read the entire official guide here and about 5 questions on SO that describe this problem for Rails 3 and Rails 4.
This question is for Rails 5, but he is using an actual file, not an encoded string.
This is my mailer code (and yes I have both views setup). The email comes through perfectly fine, with the attached PDF.
def pdf_quote(proposal)
#proposal = proposal
email_with_name = %("#{#proposal.first_name} #{#proposal.last_name}" <#{#proposal.email}>)
filename = "QD-#{#proposal.qd_number}_#{#proposal.last_name}.pdf"
attachments[filename] = {
mime_type: 'application/pdf',
encoding: 'Base64',
content: #proposal.pdf_base64
}
mail(
to: email_with_name,
from: 'Floorbook UK <email address>',
subject: 'Your Personal Flooring Quote is attached',
sent_on: Time.now
)
end
In gmail the attachment is called 'noname' and in Postbox it is called 'pb_mime_attachment.pdf'
How can I get ActionMailer to use the filename I provide?
Note that I am using MailGun (mailgun-ruby gem 1.1.4) to send the email, so it could be the gem at fault here.
It turned out to be a bug with 3rd party mailgun-ruby gem.
I raised a bug with them, here are the details:
https://github.com/mailgun/mailgun-ruby/issues/82
It is fixed (I tested it) in version 1.1.5.

Rails or my SMTP client Gmail, does not allow large CSV file attachments

I'm trying to have ActionMailer deliver a CSV I generated as so :
#csv= CSV.generate(force_quotes: true) do |csv|
::CourseExportGenerator.load_template csv, sections, standard, registration
end
#filename = "my_sweet_filename.csv"
EnterpriseMailer.send_report(#csv, #filename).deliver
Then my EnterpriseMailer.rb file looks like so :
def send_report report, filename
attachments["#{filename}"] = {data: report, encoding: 'base64'}
mail to: 'trip#triptrip.com', subject: "Your large CSV file!"
end
The email gets delivered with the right subject, but none of my actual content ( which is just some simple placeholder text). The file attached is titled "noname" and when it's opened it reads :
This is a multi-part message in MIME format...
----
I know the file it's delivering is roughly 2 to 3 megabytes and have over 8,000 lines.
Does anyone know how I can send simply deliver a large CSV file within an email attachment? Maybe I'm writing the syntax incorrectly?
The answer is that I had to create this file within the Mailer itself. Not sure why that works, but it does.
My enterprise_mailer.rb looks like this :
attachments["#{#filename}"] = CSV.generate(force_quotes: true) do |csv|
::ExportGenerator.load_template csv, sections, standard, registration
end
mail to: 'trip#triptrip.com', subject: "My totally awesome subject line"

Rails not sending (ical) attachments in emails

I'm trying to send an email with an ical attachment, I'm running rails v.3.2.13 and using the icalendar gem (to generate the ical string) see. (In development mode in case that might be a problem).
The relevant mailer code looks like this:
def mailme
ical = Icalendar::Calendar.new
...
attachments["meetings.ics"] = { mime_type: "text/calendar", content: ical.to_ical }
mail(from: email, to: recipient, ...)
end
there is also template file with the same name (mailme.html.erb)
The problem is the mail (html) is send without the attachment.
As usual any help would be much appreciated.
Thank you.
I've gotten them working with something like below:
mail.attachments['meeting.ics'] = { mime_type: 'application/ics',
content: ical.to_ical }
mail(from: email, to: recipient, ...)
So it's possible you need to call it on #attachments on the mail object instead of calling it on the current context. I'm not sure if your mime type needs to be application/ics, but that's worked fine for me in my systems.
In case someone else stumbles upon this.
If you are using delayed_job check out https://github.com/collectiveidea/delayed_job/wiki/Common-problems#wiki-Sending_emails_with_attachments
To fix this, remember to add this line to your mailer:
content_type "multipart/mixed"

Uploading a file to Facebook using Koala on Ruby on Rails

I followed the following blogpost to figure out how to create Facebook events remotely using my app. I've been having problems loading the images from my app, however, because I do not have images stored locally on my app, they are stored in AWS.
#graph = Koala::Facebook::GraphAPI.new(#token)
picture = Koala::UploadableIO.new(#event.photo.url(:small))
params = {
:picture => picture,
:name => 'Event name',
:description => 'Event descriptio
:start_time => datetime,
}
is the following code I am currently using to send pictures to Facebook when Facebook events are created on my app. The problem is, however, that Rails is throwing the error: No such file or directory - http://s3.amazonaws.com/ColumbiaEventsApp/photos/21/small.jpeg?1312521889.
Does anybody who's more experienced with Rails development know if there is a way for me to treat a URL like a path to a file? The UploadableIO class expects a path to a file, and I'm struggling to figure out if there's a way in Ruby to treat URL's like filepaths. The way that photos stored on the app can be loaded to Facebook is as follows:
picture = Koala::UploadableIO.new(File.open("PATH TO YOUR EVENT IMAGE"))
if that helps.
I appreciate any new insights into this issue.
Ok so I played around and figured out how to post pictures.
Basically what I did was use the 'open-uri' library to convert the image links into file objects, which can then be passed to UploadableIO and sent to Facebook. This is the code that worked:
require 'open-uri'
OpenURI::Buffer.send :remove_const, 'StringMax' if OpenURI::Buffer.const_defined?('StringMax')
OpenURI::Buffer.const_set 'StringMax', 0
picture = Koala::UploadableIO.new(open(#event.photo.url(:small)).path, 'image')
params = {
picture: picture,
name: #event.name,
description: #event.description,
location: #event.location,
start_time: datetime
}
#graph.put_object('me', 'events', params )
The OpenURI constant StringMax needed to be changed because the image files I was using were small enough that the files were being processed as Strings rather than File Objects.
Hope this helps anyone trying to fix this!
With Koala 1.2.1 it's a very elegant solution. Here is sample code for creating an album and uploading to it from a remote, AWS link (btw this took about 30 lines in PHP w/ the PHP SDK!
#foo = Foo.find(params[:foo_id])
albuminfo = #graph.put_object('me','albums', :name=>#foo.title)
album_id = albuminfo["id"]
#graph.put_picture(#foo.remote_image_path,{}, album_id)
Facebook recently released an update that lets you post pictures using publicly accessible URLs (http://developers.facebook.com/blog/post/526/). The Koala library you're using supports that (https://github.com/arsduo/koala/blob/master/lib/koala/graph_api.rb#L102), so you should be able to post the pictures you're hosting on S3 without having to use OpenURI::Buffer.
For Facebook Ad Images, you unfortunately currently cannot do it by URL, thus:
require 'open-uri'
img_data = open(my_post.image.url :medium).read
img = graph.put_connections('act_X', 'adimages', bytes: Base64.encode64(img_data))

Using Send_File to a Remote Source (Ruby on Rails)

In my app, I have a requirement that is stumping me.
I have a file stored in S3, and when a user clicks on a link in my app, I log in the DB they've clicked the link, decrease their 'download credit' allowance by one and then I want to prompt the file for download.
I don't simply want to redirect the user to the file because it's stored in S3 and I don't want them to have the link of the source file (so that I can maintain integrity and access)
It looks like send_file() wont work with a remote source file, anyone recommend a gem or suitable code which will do this?
You would need to stream the file content to the user while reading it from the S3 bucket/object.
If you use the AWS::S3 library something like this may work:
send_file_headers!( :length=>S3Object.about(<s3 object>, <s3 bucket>)["content-length"], :filename=><the filename> )
render :status => 200, :text => Proc.new { |response, output|
S3Object.stream(<s3 object>, <s3 bucket>) do |chunk|
output.write chunk
end
}
This code is mostly copied form the send_file code which by itself works only for local files or file-like objects
N.B. I would anyhow advise against serving the file from the rails process itself. If possible/acceptable for your use case I'd use an authenticated GET to serve the private data from the bucket.
Using an authenticated GET you can keep the bucket and its objects private, while allowing temporary permission to read a specific object content by crafting a URL that includes an authentication signature token. The user is simply redirected to the authenticated URL, and the token can be made valid for just a few minutes.
Using the above mentioned AWS::S3 you can obtain an authenticated GET url in this way:
time_of_exipry = Time.now + 2.minutes
S3Object.url_for(<s3 object>, <s3 bucket>,
:expires => time_of_exipry)
Full image download method using temp file (tested rails 3.2):
def download
#image = Image.find(params[:image_id])
open(#image.url) {|img|
tmpfile = Tempfile.new("download.jpg")
File.open(tmpfile.path, 'wb') do |f|
f.write img.read
end
send_file tmpfile.path, :filename => "great-image.jpg"
}
end
You can read the file from S3 and write it locally to a non-public directory, then use X-Sendfile (apache) or X-Accel-Redirect (nginx) to serve the content.
For nginx you would include something like the following in your config:
location /private {
internal;
alias /path/to/private/directory/;
}
Then in your rails controller, you do the following:
response.headers['Content-Type'] = your_content_type
response.headers['Content-Disposition'] = "attachment; filename=#{your_file_name}"
response.headers['Cache-Control'] = "private"
response.headers['X-Accel-Redirect'] = path_to_your_file
render :nothing=>true
A good writeup of the process is here

Resources