diff --git a/app/controllers/integrations_controller.rb b/app/controllers/integrations_controller.rb
index bb47497b2..fd5b42382 100644
--- a/app/controllers/integrations_controller.rb
+++ b/app/controllers/integrations_controller.rb
@@ -1,8 +1,7 @@
class IntegrationsController < ApplicationController
require 'mail'
- skip_before_action :login_required, :only => [:cloudmailin, :search_plugin]
- skip_before_action :verify_authenticity_token, only: [:cloudmailin]
+ skip_before_action :login_required, :only => [:search_plugin]
def index
@page_title = 'TRACKS::Integrations'
@@ -21,31 +20,8 @@ def search_plugin
.pack('m').gsub(/\n/, '')
end
- def cloudmailin
- if !verify_cloudmailin_signature
- render :body => "Message signature verification failed.", :status => 403
- return false
- end
-
- if process_message(params[:message])
- render :body => 'success', :status => 200
- else
- render :body => "No user found or other error", :status => 404
- end
- end
-
private
- def process_message(message)
- MessageGateway.receive(Mail.new(message))
- end
-
- def verify_cloudmailin_signature
- provided = request.request_parameters.delete(:signature)
- signature = Digest::MD5.hexdigest(flatten_params(request.request_parameters).sort.map { |k, v| v }.join + SITE_CONFIG['cloudmailin'])
- return provided == signature
- end
-
def flatten_params(params, title = nil, result = {})
params.each do |key, value|
if value.is_a? Hash
diff --git a/app/controllers/mailgun_controller.rb b/app/controllers/mailgun_controller.rb
deleted file mode 100644
index d3eac0917..000000000
--- a/app/controllers/mailgun_controller.rb
+++ /dev/null
@@ -1,36 +0,0 @@
-require 'openssl'
-
-class MailgunController < ApplicationController
- skip_before_action :login_required, :only => [:mailgun]
- before_action :verify, :only => [:mailgun]
- protect_from_forgery with: :null_session
-
- def mailgun
- unless params.include? 'body-mime'
- Rails.logger.info "Cannot process Mailgun request, no body-mime sent"
- render_failure "Unacceptable body-mime", 406
- return
- end
-
- todo = MessageGateway.receive(params['body-mime'])
- if todo
- render :xml => todo.to_xml(*todo_xml_params)
- else
- render_failure "Todo not saved", 406
- end
- end
-
- private
-
- def verify
- unless params['signature'] == OpenSSL::HMAC.hexdigest(
- OpenSSL::Digest.new('sha256'),
- SITE_CONFIG['mailgun_api_key'],
- '%s%s' % [params['timestamp'], params['token']]
- )
- Rails.logger.info "Cannot verify Mailgun signature"
- render_failure "Access denied", 406
- return
- end
- end
-end
diff --git a/app/models/message_gateway.rb b/app/models/message_gateway.rb
deleted file mode 100644
index 2a125cd79..000000000
--- a/app/models/message_gateway.rb
+++ /dev/null
@@ -1,141 +0,0 @@
-class MessageGateway < ActionMailer::Base
- def receive(email)
- user = get_receiving_user_from_email_address(email)
- return false if user.nil?
- return false unless check_sender_is_in_mailmap(user, email)
-
- context = user.prefs.sms_context
- todo_params = get_todo_params(email)
-
- todo_builder = TodoFromRichMessage.new(user, context.id, todo_params[:description], todo_params[:notes])
- todo = todo_builder.construct
-
- if todo.save!
- Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
-
- if attach_email_to_todo(todo, email)
- Rails.logger.info "Saved email as attachment to todo for user #{user.login} in context #{context.name}"
- end
- end
- todo
- end
-
- private
-
- def attach_email_to_todo(todo, email)
- attachment = todo.attachments.build
-
- # create temp file
- tmp = Tempfile.new(['attachment', '.eml'], universal_newline: true)
- tmp.write email.raw_source.gsub(/\r/, "")
-
- # 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!
-
- # enable write permissions on group, since MessageGateway could be run under different
- # user than Tracks (i.e. apache versus mail)
- dir = File.open(File.dirname(attachment.file.path))
- dir.chmod(0770)
-
- # delete temp file
- tmp.unlink
- end
-
- def get_todo_params(email)
- params = {}
-
- 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
- end
-
- 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)
- end
-
- def get_receiving_user_from_env_setting
- Rails.logger.info "All received email goes to #{ENV['TRACKS_MAIL_RECEIVER']}"
- user = User.where(:login => ENV['TRACKS_MAIL_RECEIVER']).first
- Rails.logger.info "WARNING: Unknown user set for TRACKS_MAIL_RECEIVER (#{ENV['TRACKS_MAIL_RECEIVER']})" if user.nil?
- return user
- end
-
- 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)
- Rails.logger.info "Looking for user with email #{address}"
- user = User.where("preferences.sms_email" => address.strip).includes(:preference).first
- user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first if user.nil?
- return user
- end
-
- def check_sender_is_in_mailmap(user, email)
- if user.present? && !sender_is_in_mailmap?(user, email)
- Rails.logger.warn "#{email.from[0]} not found in mailmap for #{user.login}"
- return false
- end
- return true
- end
-
- def sender_is_in_mailmap?(user, email)
- if (SITE_CONFIG['mailmap'].is_a? Hash) && 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
-
- def get_text_or_nil(text)
- return text ? text.strip : nil
- end
-
- def get_decoded_text_or_nil(text)
- return text ? text.decoded.strip : nil
- end
-
- def get_first_text_plain_part(email)
- # get all parts from multipart/alternative attachments
- parts = get_all_parts(email.parts)
-
- # remove all parts that are not text/plain
- parts.reject { |part| !part.content_type.start_with?("text/plain") }
-
- return parts.count > 0 ? parts[0].decoded.strip : ""
- end
-
- 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
- end
-end
diff --git a/app/views/integrations/index.html.erb b/app/views/integrations/index.html.erb
index 5de4fbf91..a8db5c152 100644
--- a/app/views/integrations/index.html.erb
+++ b/app/views/integrations/index.html.erb
@@ -4,8 +4,6 @@
<%= I18n.t 'integrations.contents_header' %>
<%= raw I18n.t 'integrations.add_your_own', tell_us_link: link_to(I18n.t('integrations.tell_us_link_text'), 'https://github.com/TracksApp/tracks/issues') %>
@@ -19,41 +17,6 @@<%= raw I18n.t 'integrations.cron_2', feeds_link: link_to(I18n.t('integrations.feeds_link_text'), feeds_path) %>
- -<%= I18n.t 'integrations.message_gateway.description' %>
-/PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'" %>
<%= I18n.t 'integrations.message_gateway.rich_api_tip' %>
-<%= raw I18n.t 'integrations.message_gateway.configuration', site_yml: 'site.yml', to_name: 'to:', from_name: 'from:' %>
-<%= raw I18n.t 'integrations.message_gateway.one_user_configuration', single_user_value: 'single_user', code: "
TRACKS_MAIL_RECEIVER=" + current_user.login + " /PATH/TO/TRACKS/bin/rails r -e production 'MessageGateway.receive(STDIN.read)'" %> - - -
<%= raw I18n.t 'integrations.mailgun.description', mailgun_link: link_to('Mailgun', 'http://www.mailgun.com/') %>
-<%= I18n.t 'integrations.mailgun.conditions' %>
--mailmap: - tracks@user.mailgun.org: - - me@myhome.example.net - - mr.user@work.example.com -' %>
<%= I18n.t 'integrations.mailgun.gateway_instructions' %>
-<%= I18n.t 'integrations.email_rich.description' %>
diff --git a/test/controllers/integrations_controller_test.rb b/test/controllers/integrations_controller_test.rb index d01c0e06a..bfbcd42d3 100644 --- a/test/controllers/integrations_controller_test.rb +++ b/test/controllers/integrations_controller_test.rb @@ -13,65 +13,4 @@ def test_page_load assert_response :success end - def test_cloudmailin_integration_success - stub_site_config do - SITE_CONFIG['cloudmailin'] = "123456789" - SITE_CONFIG['email_dispatch'] = 'from' - post :cloudmailin, params: { - "html"=>"", - "plain"=>"asdasd", - "x_to_header"=>"[\"81496ecea21032d35a7a@cloudmailin.net\"]", - "disposable"=>"", - "from"=>"5555555555@tmomail.net", - "signature"=>"e85e908fb893394762047c21e54ce248", - "to"=>"<123123@cloudmailin.net>", - "subject"=>"asd", - "x_cc_header"=>"", - "message"=>"Received: from VMBX103.ihostexchange.net ([192.168.3.3]) by\r\n HUB103.ihostexchange.net ([66.46.182.53]) with mapi; Wed, 5 Oct 2011 17:12:44\r\n -0400\r\nFrom: SMS User <5555555555@tmomail.net>\r\nTo: Tracks <123123@cloudmailin.net>\r\nDate: Wed, 5 Oct 2011 17:12:43 -0400\r\nSubject: asd\r\nThread-Topic: asd\r\nThread-Index: AcyDo4aig2wghvcsTAOkleWqi4t/FQ==\r\nMessage-ID: <7D7CB176-7559-4997-A301-8DF9726264C7@tmomail.net>\r\nAccept-Language: de-DE, en-US\r\nContent-Language: en-US\r\nX-MS-Has-Attach:\r\nX-MS-TNEF-Correlator:\r\nacceptlanguage: de-DE, en-US\r\nContent-Type: text/plain; charset=\"us-ascii\"\r\nContent-Transfer-Encoding: quoted-printable\r\nMIME-Version: 1.0\r\n\r\nasdasd\r\n" - } - - assert_response :success - end - end - - def test_cloudmailin_integration_invalid_signature - stub_site_config do - SITE_CONFIG['cloudmailin'] = "12345678901234567890" - post :cloudmailin, params: { - "html"=>"", - "plain"=>"asdasd", - "x_to_header"=>"[\"81496ecea21032d35a7a@cloudmailin.net\"]", - "disposable"=>"", - "from"=>"5555555555@tmomail.net", - "signature"=>"e85e908fb893394762047c21e54ce248", - "to"=>"<123123@cloudmailin.net>", - "subject"=>"asd", - "x_cc_header"=>"", - "message"=>"Received: from VMBX103.ihostexchange.net ([192.168.3.3]) by\r\n HUB103.ihostexchange.net ([66.46.182.53]) with mapi; Wed, 5 Oct 2011 17:12:44\r\n -0400\r\nFrom: SMS User <5555555555@tmomail.net>\r\nTo: Tracks <123123@cloudmailin.net>\r\nDate: Wed, 5 Oct 2011 17:12:43 -0400\r\nSubject: asd\r\nThread-Topic: asd\r\nThread-Index: AcyDo4aig2wghvcsTAOkleWqi4t/FQ==\r\nMessage-ID: <7D7CB176-7559-4997-A301-8DF9726264C7@tmomail.net>\r\nAccept-Language: de-DE, en-US\r\nContent-Language: en-US\r\nX-MS-Has-Attach:\r\nX-MS-TNEF-Correlator:\r\nacceptlanguage: de-DE, en-US\r\nContent-Type: text/plain; charset=\"us-ascii\"\r\nContent-Transfer-Encoding: quoted-printable\r\nMIME-Version: 1.0\r\n\r\nasdasd\r\n" - } - - assert_response 403 - end - end - - def test_cloudmailin_integration_unknown_address - stub_site_config do - SITE_CONFIG['cloudmailin'] = "123456789" - post :cloudmailin, params: { - "html"=>"", - "plain"=>"asdasd", - "x_to_header"=>"[\"81496ecea21032d35a7a@cloudmailin.net\"]", - "disposable"=>"", - "from"=>"444444444444@tmomail.net", - "signature"=>"6d2df0e807bfa9b77d24c31dce6d4515", - "to"=>"<123123@cloudmailin.net>", - "subject"=>"asd", - "x_cc_header"=>"", - "message"=>"Received: from VMBX103.ihostexchange.net ([192.168.3.3]) by\r\n HUB103.ihostexchange.net ([66.46.182.53]) with mapi; Wed, 5 Oct 2011 17:12:44\r\n -0400\r\nFrom: SMS User <444444444444@tmomail.net>\r\nTo: Tracks <123123@cloudmailin.net>\r\nDate: Wed, 5 Oct 2011 17:12:43 -0400\r\nSubject: asd\r\nThread-Topic: asd\r\nThread-Index: AcyDo4aig2wghvcsTAOkleWqi4t/FQ==\r\nMessage-ID: <7D7CB176-7559-4997-A301-8DF9726264C7@tmomail.net>\r\nAccept-Language: de-DE, en-US\r\nContent-Language: en-US\r\nX-MS-Has-Attach:\r\nX-MS-TNEF-Correlator:\r\nacceptlanguage: de-DE, en-US\r\nContent-Type: text/plain; charset=\"us-ascii\"\r\nContent-Transfer-Encoding: quoted-printable\r\nMIME-Version: 1.0\r\n\r\nasdasd\r\n" - } - - assert_response 404 - end - end - end diff --git a/test/controllers/mailgun_controller_test.rb b/test/controllers/mailgun_controller_test.rb deleted file mode 100644 index 0b1300e2e..000000000 --- a/test/controllers/mailgun_controller_test.rb +++ /dev/null @@ -1,74 +0,0 @@ -require 'test_helper' -require 'support/stub_site_config_helper' - -class MailgunControllerTest < ActionController::TestCase - include StubSiteConfigHelper - - def setup - @user = users(:sms_user) - @inbox = contexts(:inbox) - end - - def load_message(filename) - File.read(File.join(Rails.root, 'test', 'fixtures', filename)) - end - - def test_mailgun_signature_verifies - stub_site_config do - SITE_CONFIG['mailgun_api_key'] = "123456789" - SITE_CONFIG['email_dispatch'] = 'from' - - post :mailgun, params: { - "timestamp" => "1379539674", - "token" => "5km6cwo0e3bfvg78hw4s69znro09xhk1h8u6-s633yasc8hcr5", - "signature" => "da92708b8f2c9dcd7ecdc91d52946c01802833e6683e46fc00b3f081920dd5b1", - "body-mime" => load_message('mailgun_message1.txt') - } - - assert_response :success - end - end - - def test_mailgun_creates_todo_with_mailmap - stub_site_config do - SITE_CONFIG['mailgun_api_key'] = "123456789" - SITE_CONFIG['email_dispatch'] = 'to' - SITE_CONFIG['mailmap'] = { - '5555555555@tmomail.net' => ['incoming@othermail.com', 'notused@foo.org'] - } - - todo_count = Todo.count - post :mailgun, params: { - "timestamp" => "1379539674", - "token" => "5km6cwo0e3bfvg78hw4s69znro09xhk1h8u6-s633yasc8hcr5", - "signature" => "da92708b8f2c9dcd7ecdc91d52946c01802833e6683e46fc00b3f081920dd5b1", - "body-mime" => load_message('mailgun_message2.txt') - } - - assert_response :success - - assert_equal(todo_count+1, Todo.count) - message_todo = Todo.where(:description => "test").first - assert_not_nil(message_todo) - assert_equal(@inbox, message_todo.context) - assert_equal(@user, message_todo.user) - end - end - - def test_mailgun_signature_fails - stub_site_config do - SITE_CONFIG['mailgun_api_key'] = "invalidkey" - SITE_CONFIG['email_dispatch'] = 'from' - - post :mailgun, params: { - "timestamp" => "1379539674", - "token" => "5km6cwo0e3bfvg78hw4s69znro09xhk1h8u6-s633yasc8hcr5", - "signature" => "da92708b8f2c9dcd7ecdc91d52946c01802833e6683e46fc00b3f081920dd5b1", - "body-mime" => load_message('mailgun_message1.txt') - } - - assert_response 406 - end - end - -end diff --git a/test/controllers/message_gateway_test.rb b/test/controllers/message_gateway_test.rb deleted file mode 100644 index 6bb3eab95..000000000 --- a/test/controllers/message_gateway_test.rb +++ /dev/null @@ -1,103 +0,0 @@ -require 'test_helper' - -class MessageGatewayTest < ActiveSupport::TestCase - - def setup - @user = users(:sms_user) - @inbox = contexts(:inbox) - end - - def load_message(filename) - MessageGateway.receive(File.read(File.join(Rails.root, 'test', 'fixtures', filename))) - end - - def test_sms_with_no_subject - todo_count = Todo.count - - load_message('sample_sms.txt') - # assert some stuff about it being created - assert_equal(todo_count+1, Todo.count) - - message_todo = Todo.where(:description => "message_content").first - assert_not_nil(message_todo) - - assert_equal(@inbox, message_todo.context) - assert_equal(@user, message_todo.user) - end - - def test_mms_with_subject - todo_count = Todo.count - - load_message('sample_mms.txt') - - # assert some stuff about it being created - assert_equal(todo_count+1, Todo.count) - - message_todo = Todo.where(:description => "This is the subject").first - assert_not_nil(message_todo) - - assert_equal(@inbox, message_todo.context) - assert_equal(@user, message_todo.user) - assert_equal("This is the message body", message_todo.notes) - end - - def test_email_with_winmail_dat - todo_count = Todo.count - - load_message('email_with_winmail.txt') - - # assert some stuff about it being created - assert_equal(todo_count+1, Todo.count) - end - - def test_email_with_multipart_attachments - todo_count = Todo.count - - load_message('email_with_multipart.txt') - - # assert some stuff about it being created - assert_equal(todo_count+1, Todo.count) - end - - def test_no_user - todo_count = Todo.count - badmessage = File.read(File.join(Rails.root, 'test', 'fixtures', 'sample_sms.txt')) - badmessage.gsub!("5555555555", "notauser") - MessageGateway.receive(badmessage) - assert_equal(todo_count, Todo.count) - end - - def test_direct_to_context - message = File.read(File.join(Rails.root, 'test', 'fixtures', 'sample_sms.txt')) - - valid_context_msg = message.gsub('message_content', 'this is a task @ anothercontext') - invalid_context_msg = message.gsub('message_content', 'this is also a task @ notacontext') - - MessageGateway.receive(valid_context_msg) - valid_context_todo = Todo.where(:description => "this is a task").first - assert_not_nil(valid_context_todo) - assert_equal(contexts(:anothercontext), valid_context_todo.context) - - MessageGateway.receive(invalid_context_msg) - invalid_context_todo = Todo.where(:description => 'this is also a task').first - assert_not_nil(invalid_context_todo) - assert_equal(@inbox, invalid_context_todo.context) - end - - def test_receiving_email_adds_attachment - attachment_count = Attachment.count - - load_message('sample_mms.txt') - - message_todo = Todo.where(:description => "This is the subject").first - assert_not_nil(message_todo) - - assert_equal attachment_count+1, Attachment.count - assert_equal 1,message_todo.attachments.count - - orig = File.read(File.join(Rails.root, 'test', 'fixtures', 'sample_mms.txt')) - attachment = File.read(message_todo.attachments.first.file.path) - - assert_equal orig, attachment - end -end