2014-07-03 23:24:29 +02:00
|
|
|
require 'tempfile'
|
|
|
|
|
2008-09-20 19:15:12 -07:00
|
|
|
class MessageGateway < ActionMailer::Base
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2008-06-04 18:16:06 -07:00
|
|
|
def receive(email)
|
2013-09-22 17:34:58 +02:00
|
|
|
user = get_receiving_user_from_email_address(email)
|
2012-07-12 13:14:21 +02:00
|
|
|
return false if user.nil?
|
2013-09-22 17:34:58 +02:00
|
|
|
return false unless check_sender_is_in_mailmap(user, email)
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2008-06-04 18:16:06 -07:00
|
|
|
context = user.prefs.sms_context
|
2013-09-22 17:34:58 +02:00
|
|
|
todo_params = get_todo_params(email)
|
2008-06-04 18:16:06 -07:00
|
|
|
|
2013-09-22 17:34:58 +02:00
|
|
|
todo_builder = TodoFromRichMessage.new(user, context.id, todo_params[:description], todo_params[:notes])
|
2013-07-18 16:35:51 -05:00
|
|
|
todo = todo_builder.construct
|
2014-07-03 23:24:29 +02:00
|
|
|
|
|
|
|
saved = todo.save!
|
|
|
|
|
|
|
|
if saved
|
|
|
|
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
|
|
|
|
|
2014-07-17 12:56:22 +02:00
|
|
|
saved = attach_email_to_todo(todo, email)
|
2014-07-17 12:56:22 +02:00
|
|
|
|
|
|
|
if saved
|
2014-07-03 23:24:29 +02:00
|
|
|
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2013-09-15 21:17:05 +01:00
|
|
|
todo
|
2008-06-04 18:16:06 -07:00
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2012-04-24 20:47:07 +02:00
|
|
|
private
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2014-07-17 12:56:22 +02:00
|
|
|
def attach_email_to_todo(todo, email)
|
|
|
|
attachment = todo.attachments.build
|
|
|
|
|
|
|
|
# create temp file
|
2014-07-17 12:56:22 +02:00
|
|
|
tmp = Tempfile.new(['attachment', '.eml'], universal_newline: true)
|
|
|
|
tmp.write email.raw_source
|
2014-07-17 12:56:22 +02:00
|
|
|
|
|
|
|
# add temp file to attachment. paperclip will copy the file to the right location
|
|
|
|
Rails.logger.info "Saved received email to #{tmp.path}"
|
|
|
|
attachment.file = tmp
|
|
|
|
tmp.close
|
|
|
|
saved = attachment.save!
|
|
|
|
|
|
|
|
# delete temp file
|
|
|
|
tmp.unlink
|
|
|
|
end
|
|
|
|
|
2013-09-22 17:34:58 +02:00
|
|
|
def get_todo_params(email)
|
|
|
|
params = {}
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2013-09-22 17:34:58 +02:00
|
|
|
if email.multipart?
|
|
|
|
params[:description] = get_text_or_nil(email.subject)
|
|
|
|
params[:notes] = get_first_text_plain_part(email)
|
|
|
|
else
|
|
|
|
if email.subject.blank?
|
|
|
|
params[:description] = get_decoded_text_or_nil(email.body)
|
|
|
|
params[:notes] = nil
|
|
|
|
else
|
|
|
|
params[:description] = get_text_or_nil(email.subject)
|
|
|
|
params[:notes] = get_decoded_text_or_nil(email.body)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
params
|
2014-08-14 21:05:05 -05:00
|
|
|
end
|
2013-09-22 17:34:58 +02:00
|
|
|
|
|
|
|
def get_receiving_user_from_email_address(email)
|
|
|
|
SITE_CONFIG['email_dispatch'] == 'single_user' ? get_receiving_user_from_env_setting : get_receiving_user_from_mail_header(email)
|
2014-08-14 21:05:05 -05:00
|
|
|
end
|
2013-09-22 17:34:58 +02:00
|
|
|
|
|
|
|
def get_receiving_user_from_env_setting
|
2012-07-18 11:42:26 +02:00
|
|
|
Rails.logger.info "All received email goes to #{ENV['TRACKS_MAIL_RECEIVER']}"
|
2013-04-29 09:38:34 +02:00
|
|
|
user = User.where(:login => ENV['TRACKS_MAIL_RECEIVER']).first
|
2012-07-18 11:42:26 +02:00
|
|
|
Rails.logger.info "WARNING: Unknown user set for TRACKS_MAIL_RECEIVER (#{ENV['TRACKS_MAIL_RECEIVER']})" if user.nil?
|
|
|
|
return user
|
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2013-09-22 17:34:58 +02:00
|
|
|
def get_receiving_user_from_mail_header(email)
|
|
|
|
user = get_receiving_user_from_sms_email( get_address(email) )
|
|
|
|
Rails.logger.info(user.nil? ? "User unknown": "Email belongs to #{user.login}")
|
|
|
|
return user
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_address(email)
|
|
|
|
return SITE_CONFIG['email_dispatch'] == 'to' ? email.to[0] : email.from[0]
|
|
|
|
end
|
|
|
|
|
|
|
|
def get_receiving_user_from_sms_email(address)
|
2012-07-18 11:42:26 +02:00
|
|
|
Rails.logger.info "Looking for user with email #{address}"
|
|
|
|
user = User.where("preferences.sms_email" => address.strip).includes(:preference).first
|
2013-09-22 17:34:58 +02:00
|
|
|
user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first if user.nil?
|
|
|
|
return user
|
2014-08-14 21:05:05 -05:00
|
|
|
end
|
2013-09-22 17:34:58 +02:00
|
|
|
|
|
|
|
def check_sender_is_in_mailmap(user, email)
|
2013-09-15 21:17:05 +01:00
|
|
|
if user.present? and !sender_is_in_mailmap?(user,email)
|
|
|
|
Rails.logger.warn "#{email.from[0]} not found in mailmap for #{user.login}"
|
2013-09-22 17:34:58 +02:00
|
|
|
return false
|
2013-09-15 21:17:05 +01:00
|
|
|
end
|
2013-09-22 17:34:58 +02:00
|
|
|
return true
|
2014-08-14 21:05:05 -05:00
|
|
|
end
|
2013-09-15 21:17:05 +01:00
|
|
|
|
|
|
|
def sender_is_in_mailmap?(user,email)
|
|
|
|
if SITE_CONFIG['mailmap'].is_a? Hash and SITE_CONFIG['email_dispatch'] == 'to'
|
|
|
|
# Look for the sender in the map of allowed senders
|
|
|
|
SITE_CONFIG['mailmap'][user.preference.sms_email].include? email.from[0]
|
|
|
|
else
|
|
|
|
# We can't check the map if it's not defined, or if the lookup is the
|
|
|
|
# wrong way round, so just allow it
|
|
|
|
true
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
2012-04-24 20:47:07 +02:00
|
|
|
def get_text_or_nil(text)
|
2013-10-13 22:11:55 +01:00
|
|
|
return text ? text.strip : nil
|
2012-04-24 20:47:07 +02:00
|
|
|
end
|
|
|
|
|
|
|
|
def get_decoded_text_or_nil(text)
|
2013-10-13 22:11:55 +01:00
|
|
|
return text ? text.decoded.strip : nil
|
2012-04-24 20:47:07 +02:00
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2012-04-24 20:47:07 +02:00
|
|
|
def get_first_text_plain_part(email)
|
2012-08-24 23:47:27 +02:00
|
|
|
# get all parts from multipart/alternative attachments
|
|
|
|
parts = get_all_parts(email.parts)
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2012-08-24 23:47:27 +02:00
|
|
|
# remove all parts that are not text/plain
|
|
|
|
parts.reject{|part| !part.content_type.start_with?("text/plain") }
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2013-10-13 22:11:55 +01:00
|
|
|
return parts.count > 0 ? parts[0].decoded.strip : ""
|
2012-08-24 23:47:27 +02:00
|
|
|
end
|
2014-08-14 21:05:05 -05:00
|
|
|
|
2012-08-24 23:47:27 +02:00
|
|
|
def get_all_parts(parts)
|
|
|
|
# return a flattened array of parts. If a multipart attachment is found, recurse over its parts
|
|
|
|
all_parts = parts.inject([]) do |set, elem|
|
|
|
|
if elem.content_type.start_with?("multipart/alternative")
|
|
|
|
# recurse to handle multiparts in this multipart
|
|
|
|
set += get_all_parts(elem.parts)
|
|
|
|
else
|
|
|
|
set << elem
|
|
|
|
end
|
|
|
|
end
|
2012-04-24 20:47:07 +02:00
|
|
|
end
|
2008-06-04 18:16:06 -07:00
|
|
|
end
|