mirror of
https://github.com/TracksApp/tracks.git
synced 2025-12-16 15:20:13 +01:00
Add Mailgun endpoint for receiving email tasks via Mailgun
This commit is contained in:
parent
daef1c440b
commit
8a2da01d51
8 changed files with 193 additions and 2 deletions
38
app/controllers/mailgun_controller.rb
Normal file
38
app/controllers/mailgun_controller.rb
Normal file
|
|
@ -0,0 +1,38 @@
|
||||||
|
require 'openssl'
|
||||||
|
|
||||||
|
class MailgunController < ApplicationController
|
||||||
|
|
||||||
|
skip_before_filter :login_required, :only => [:mailgun]
|
||||||
|
before_filter :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::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
|
||||||
|
|
@ -27,6 +27,7 @@ class MessageGateway < ActionMailer::Base
|
||||||
todo = todo_builder.construct
|
todo = todo_builder.construct
|
||||||
todo.save!
|
todo.save!
|
||||||
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
|
Rails.logger.info "Saved email as todo for user #{user.login} in context #{context.name}"
|
||||||
|
todo
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
@ -49,10 +50,26 @@ class MessageGateway < ActionMailer::Base
|
||||||
if user.nil?
|
if user.nil?
|
||||||
user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first
|
user = User.where("preferences.sms_email" => address.strip[1.100]).includes(:preference).first
|
||||||
end
|
end
|
||||||
|
if user.present? and !sender_is_in_mailmap?(user,email)
|
||||||
|
Rails.logger.warn "#{email.from[0]} not found in mailmap for #{user.login}"
|
||||||
|
return nil
|
||||||
|
end
|
||||||
Rails.logger.info(!user.nil? ? "Email belongs to #{user.login}" : "User unknown")
|
Rails.logger.info(!user.nil? ? "Email belongs to #{user.login}" : "User unknown")
|
||||||
return user
|
return user
|
||||||
end
|
end
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
|
||||||
def get_user_from_email_address(email)
|
def get_user_from_email_address(email)
|
||||||
SITE_CONFIG['email_dispatch'] == 'single_user' ? get_user_from_env_setting : get_user_from_mail_header(email)
|
SITE_CONFIG['email_dispatch'] == 'single_user' ? get_user_from_env_setting : get_user_from_mail_header(email)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ Tracksapp::Application.routes.draw do
|
||||||
|
|
||||||
root :to => 'todos#index'
|
root :to => 'todos#index'
|
||||||
|
|
||||||
|
post 'mailgun/mime' => 'mailgun#mailgun'
|
||||||
|
|
||||||
post 'login' => 'login#login'
|
post 'login' => 'login#login'
|
||||||
get 'login' => 'login#login'
|
get 'login' => 'login#login'
|
||||||
get 'login/check_expiry' => 'login#check_expiry'
|
get 'login/check_expiry' => 'login#check_expiry'
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,20 @@ open_signups: false
|
||||||
# (see http://docs.cloudmailin.com/validating_the_sender)
|
# (see http://docs.cloudmailin.com/validating_the_sender)
|
||||||
# cloudmailin: asdasd
|
# cloudmailin: asdasd
|
||||||
|
|
||||||
|
# Mailgun api key - used to verify incoming HTTP requests from Mailgun.org
|
||||||
|
# mailgun_api_key: key-abcdef1234567890
|
||||||
|
|
||||||
# change this to reflect the email address of the admin that you want to show
|
# change this to reflect the email address of the admin that you want to show
|
||||||
# on the signup page
|
# on the signup page
|
||||||
admin_email: my.email@domain.com
|
admin_email: my.email@domain.com
|
||||||
|
|
||||||
|
|
||||||
|
# Map of allowed incoming email addresses to real users
|
||||||
|
# Requires email_dispatch == 'to'
|
||||||
|
# This allows you to specify _who_ can send email Todos to your list
|
||||||
|
# The format is your incoming email (as per preferences page) for the key, and
|
||||||
|
# an array-list of acceptable senders for that account
|
||||||
|
#mailmap:
|
||||||
|
# 'user@preferences.from.value':
|
||||||
|
# - 'acceptable1@personal.org'
|
||||||
|
# - 'acceptable2@work.com'
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ class IntegrationsControllerTest < ActionController::TestCase
|
||||||
|
|
||||||
def test_cloudmailin_integration_success
|
def test_cloudmailin_integration_success
|
||||||
SITE_CONFIG['cloudmailin'] = "123456789"
|
SITE_CONFIG['cloudmailin'] = "123456789"
|
||||||
|
SITE_CONFIG['email_dispatch'] = 'from'
|
||||||
post :cloudmailin, {
|
post :cloudmailin, {
|
||||||
"html"=>"",
|
"html"=>"",
|
||||||
"plain"=>"asdasd",
|
"plain"=>"asdasd",
|
||||||
|
|
|
||||||
66
test/controllers/mailgun_controller_test.rb
Normal file
66
test/controllers/mailgun_controller_test.rb
Normal file
|
|
@ -0,0 +1,66 @@
|
||||||
|
require File.expand_path(File.dirname(__FILE__) + '/../test_helper')
|
||||||
|
|
||||||
|
class MailgunControllerTest < ActionController::TestCase
|
||||||
|
|
||||||
|
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
|
||||||
|
SITE_CONFIG['mailgun_api_key'] = "123456789"
|
||||||
|
SITE_CONFIG['email_dispatch'] = 'from'
|
||||||
|
|
||||||
|
post :mailgun, {
|
||||||
|
"timestamp" => "1379539674",
|
||||||
|
"token" => "5km6cwo0e3bfvg78hw4s69znro09xhk1h8u6-s633yasc8hcr5",
|
||||||
|
"signature" => "da92708b8f2c9dcd7ecdc91d52946c01802833e6683e46fc00b3f081920dd5b1",
|
||||||
|
"body-mime" => load_message('mailgun_message1.txt')
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response :success
|
||||||
|
end
|
||||||
|
|
||||||
|
def test_mailgun_creates_todo_with_mailmap
|
||||||
|
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, {
|
||||||
|
"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
|
||||||
|
|
||||||
|
def test_mailgun_signature_fails
|
||||||
|
SITE_CONFIG['mailgun_api_key'] = "invalidkey"
|
||||||
|
SITE_CONFIG['email_dispatch'] = 'from'
|
||||||
|
|
||||||
|
post :mailgun, {
|
||||||
|
"timestamp" => "1379539674",
|
||||||
|
"token" => "5km6cwo0e3bfvg78hw4s69znro09xhk1h8u6-s633yasc8hcr5",
|
||||||
|
"signature" => "da92708b8f2c9dcd7ecdc91d52946c01802833e6683e46fc00b3f081920dd5b1",
|
||||||
|
"body-mime" => load_message('mailgun_message1.txt')
|
||||||
|
}
|
||||||
|
|
||||||
|
assert_response 406
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
27
test/fixtures/mailgun_message1.txt
vendored
Normal file
27
test/fixtures/mailgun_message1.txt
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
Received: by luna.mailgun.net with SMTP mgrt 8745468409521; Wed, 18 Sep 2013\n 20:51:11 +0000
|
||||||
|
X-Envelope-From: <5555555555@tmomail.net>
|
||||||
|
Received: from mail-pa0-f45.google.com (mail-pa0-f45.google.com\n [209.85.220.45]) by mxa.mailgun.org with ESMTP id\n 523a123d.7f3a16482330-in1; Wed, 18 Sep 2013 20:51:09 -0000 (UTC)
|
||||||
|
Received: by mail-pa0-f45.google.com with SMTP id bg4so8745646pad.18 for\n <test@test.mailgun.org>; Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com;\n s=20120113; h=mime-version:date:message-id:subject:from:to:content-type;\n bh=XwBMHRr9XT/f5w7Vzap//yQJ9VoVaVcjEQ5+xjgSoMk=;\n b=IsSDTe2jY8XucXOxviOrGg1upSm5IOddtOsHFpgcyND4F9glSIU+xixRK60/9Dbqae\n BT5On3C+Aoffpj/WUqnp1+hA89JYDbWhzXcJPhkW8FcFnPvAzQ0G/loV7+CafWLubEnp\n T61owZQAQgdkHsrZMf1ChmpghNMJuDLMJvYmiijIId+z7arBocjErhHqwRY4Y6lmFdTo\n s9uGtVJ7Av1g7m8KyGZY6kzh/XPhbr4B0tjIFpyp+bDFH2Nk290RAB/2garNBfQAPhzy\n hIvvbuz5MLFWSnW17eXdymHAEH6oSbRfar8ocxcY5T+hg++nfsegUJ6sPRG1G63qnsj4 dCig==
|
||||||
|
Mime-Version: 1.0
|
||||||
|
X-Received: by 10.68.17.230 with SMTP id r6mr21790845pbd.112.1379537468893;\n Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Received: by 10.70.43.236 with HTTP; Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Date: Wed, 18 Sep 2013 21:51:08 +0100
|
||||||
|
Message-Id: <CAE=3ySAxx8r7dcgaixQjbYS3J4mVG7FdEqAwDAcJ4bkHnDiT5w@mail.gmail.com>
|
||||||
|
Subject: test1
|
||||||
|
From: A User <5555555555@tmomail.net>
|
||||||
|
To: test@test.mailgun.org
|
||||||
|
Content-Type: multipart/alternative; boundary=\"bcaec520ee93c9b26104e6ae9838\"
|
||||||
|
X-Mailgun-Incoming: Yes
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838
|
||||||
|
Content-Type: text/plain; charset=ISO-8859-1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838
|
||||||
|
Content-Type: text/html; charset=ISO-8859-1
|
||||||
|
|
||||||
|
<div dir=\"ltr\"><br></div>
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838--
|
||||||
27
test/fixtures/mailgun_message2.txt
vendored
Normal file
27
test/fixtures/mailgun_message2.txt
vendored
Normal file
|
|
@ -0,0 +1,27 @@
|
||||||
|
Received: by luna.mailgun.net with SMTP mgrt 8745468409521; Wed, 18 Sep 2013\n 20:51:11 +0000
|
||||||
|
X-Envelope-From: <incoming@othermail.com>
|
||||||
|
Received: from mail-pa0-f45.google.com (mail-pa0-f45.google.com\n [209.85.220.45]) by mxa.mailgun.org with ESMTP id\n 523a123d.7f3a16482330-in1; Wed, 18 Sep 2013 20:51:09 -0000 (UTC)
|
||||||
|
Received: by mail-pa0-f45.google.com with SMTP id bg4so8745646pad.18 for\n <5555555555@tmomail.net>; Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Dkim-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com;\n s=20120113; h=mime-version:date:message-id:subject:from:to:content-type;\n bh=XwBMHRr9XT/f5w7Vzap//yQJ9VoVaVcjEQ5+xjgSoMk=;\n b=IsSDTe2jY8XucXOxviOrGg1upSm5IOddtOsHFpgcyND4F9glSIU+xixRK60/9Dbqae\n BT5On3C+Aoffpj/WUqnp1+hA89JYDbWhzXcJPhkW8FcFnPvAzQ0G/loV7+CafWLubEnp\n T61owZQAQgdkHsrZMf1ChmpghNMJuDLMJvYmiijIId+z7arBocjErhHqwRY4Y6lmFdTo\n s9uGtVJ7Av1g7m8KyGZY6kzh/XPhbr4B0tjIFpyp+bDFH2Nk290RAB/2garNBfQAPhzy\n hIvvbuz5MLFWSnW17eXdymHAEH6oSbRfar8ocxcY5T+hg++nfsegUJ6sPRG1G63qnsj4 dCig==
|
||||||
|
Mime-Version: 1.0
|
||||||
|
X-Received: by 10.68.17.230 with SMTP id r6mr21790845pbd.112.1379537468893;\n Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Received: by 10.70.43.236 with HTTP; Wed, 18 Sep 2013 13:51:08 -0700 (PDT)
|
||||||
|
Date: Wed, 18 Sep 2013 21:51:08 +0100
|
||||||
|
Message-Id: <CAE=3ySAxx8r7dcgaixQjbYS3J4mVG7FdEqAwDAcJ4bkHnDiT5w@mail.gmail.com>
|
||||||
|
Subject: test
|
||||||
|
From: A User <incoming@othermail.com>
|
||||||
|
To: 5555555555@tmomail.net
|
||||||
|
Content-Type: multipart/alternative; boundary=\"bcaec520ee93c9b26104e6ae9838\"
|
||||||
|
X-Mailgun-Incoming: Yes
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838
|
||||||
|
Content-Type: text/plain; charset=ISO-8859-1
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838
|
||||||
|
Content-Type: text/html; charset=ISO-8859-1
|
||||||
|
|
||||||
|
<div dir=\"ltr\"><br></div>
|
||||||
|
|
||||||
|
--bcaec520ee93c9b26104e6ae9838--
|
||||||
Loading…
Add table
Add a link
Reference in a new issue