Skip to content

Commit

Permalink
Adds a simple API and a standalone script that can be used to forward…
Browse files Browse the repository at this point in the history
… emails from a local or remote email server to Redmine (#1110).

git-svn-id: http://redmine.rubyforge.org/svn/trunk@1584 e93f8b46-1217-0410-a6f0-8f06a7374b81
  • Loading branch information
jplang committed Jun 25, 2008
1 parent 4d6f50d commit 25bba80
Show file tree
Hide file tree
Showing 36 changed files with 336 additions and 1 deletion.
44 changes: 44 additions & 0 deletions app/controllers/mail_handler_controller.rb
@@ -0,0 +1,44 @@
# redMine - project management software
# Copyright (C) 2006-2008 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

class MailHandlerController < ActionController::Base
before_filter :check_credential

verify :method => :post,
:only => :index,
:render => { :nothing => true, :status => 405 }

# Submits an incoming email to MailHandler
def index
options = params.dup
email = options.delete(:email)
if MailHandler.receive(email, options)
render :nothing => true, :status => :created
else
render :nothing => true, :status => :unprocessable_entity
end
end

private

def check_credential
User.current = nil
unless Setting.mail_handler_api_enabled? && params[:key] == Setting.mail_handler_api_key
render :nothing => true, :status => 403
end
end
end
19 changes: 19 additions & 0 deletions app/helpers/mail_handler_helper.rb
@@ -0,0 +1,19 @@
# redMine - project management software
# Copyright (C) 2006-2008 Jean-Philippe Lang
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.

module MailHandlerHelper
end
1 change: 1 addition & 0 deletions app/helpers/settings_helper.rb
Expand Up @@ -21,6 +21,7 @@ def administration_settings_tabs
{:name => 'authentication', :partial => 'settings/authentication', :label => :label_authentication},
{:name => 'issues', :partial => 'settings/issues', :label => :label_issue_tracking},
{:name => 'notifications', :partial => 'settings/notifications', :label => l(:field_mail_notification)},
{:name => 'mail_handler', :partial => 'settings/mail_handler', :label => l(:label_incoming_emails)},
{:name => 'repositories', :partial => 'settings/repositories', :label => :label_repository_plural}
]
end
Expand Down
2 changes: 1 addition & 1 deletion app/models/mail_handler.rb
Expand Up @@ -84,7 +84,7 @@ def target_project
# TODO: other ways to specify project:
# * parse the email To field
# * specific project (eg. Setting.mail_handler_target_project)
identifier = if @@handler_options[:project]
identifier = if !@@handler_options[:project].blank?
@@handler_options[:project]
elsif email.plain_text_body =~ %r{^Project:[ \t]*(.+)$}i
$1
Expand Down
18 changes: 18 additions & 0 deletions app/views/settings/_mail_handler.rhtml
@@ -0,0 +1,18 @@
<% form_tag({:action => 'edit', :tab => 'mail_handler'}) do %>

<div class="box tabular settings">
<p><label><%= l(:setting_mail_handler_api_enabled) %></label>
<%= check_box_tag 'settings[mail_handler_api_enabled]', 1, Setting.mail_handler_api_enabled?,
:onclick => "if (this.checked) { Form.Element.enable('settings_mail_handler_api_key'); } else { Form.Element.disable('settings_mail_handler_api_key'); }" %>
<%= hidden_field_tag 'settings[mail_handler_api_enabled]', 0 %></p>

<p><label><%= l(:setting_mail_handler_api_key) %></label>
<%= text_field_tag 'settings[mail_handler_api_key]', Setting.mail_handler_api_key,
:size => 30,
:id => 'settings_mail_handler_api_key',
:disabled => !Setting.mail_handler_api_enabled? %>
<%= link_to_function l(:label_generate_key), "if ($('settings_mail_handler_api_key').disabled == false) { $('settings_mail_handler_api_key').value = randomKey(20) }" %></p>
</div>

<%= submit_tag l(:button_save) %>
<% end %>
4 changes: 4 additions & 0 deletions config/settings.yml
Expand Up @@ -101,6 +101,10 @@ notified_events:
default:
- issue_added
- issue_updated
mail_handler_api_enabled:
default: 0
mail_handler_api_key:
default:
issue_list_default_columns:
serialized: true
default:
Expand Down
79 changes: 79 additions & 0 deletions extra/mail_handler/rdm-mailhandler.rb
@@ -0,0 +1,79 @@
#!/usr/bin/ruby

# rdm-mailhandler
# Reads an email from standard input and forward it to a Redmine server
# Can be used from a remote mail server

require 'net/http'
require 'net/https'
require 'uri'
require 'getoptlong'

class RedmineMailHandler
VERSION = '0.1'

attr_accessor :verbose, :project, :url, :key

def initialize
opts = GetoptLong.new(
[ '--help', '-h', GetoptLong::NO_ARGUMENT ],
[ '--version', '-V', GetoptLong::NO_ARGUMENT ],
[ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
[ '--url', '-u', GetoptLong::REQUIRED_ARGUMENT ],
[ '--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
[ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ]
)

opts.each do |opt, arg|
case opt
when '--url'
self.url = arg.dup
when '--key'
self.key = arg.dup
when '--help'
usage
when '--verbose'
self.verbose = true
when '--version'
puts VERSION; exit
when '--project'
self.project = arg.dup
end
end

usage if url.nil?
end

def submit(email)
uri = url.gsub(%r{/*$}, '') + '/mail_handler'
debug "Posting to #{uri}..."
data = { 'key' => key, 'project' => project, 'email' => email }
response = Net::HTTP.post_form(URI.parse(uri), data)
debug "Response received: #{response.code}"
response.code == 201 ? 0 : 1
end

private

def usage
puts "Usage: rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>"
puts "Reads an email from standard input and forward it to a Redmine server"
puts
puts "Options:"
puts " --help show this help"
puts " --verbose show extra information"
puts " --project identifier of the target project"
puts
puts "Examples:"
puts " rdm-mailhandler --url http://redmine.domain.foo --key secret"
puts " rdm-mailhandler --url https://redmine.domain.foo --key secret --project foo"
exit
end

def debug(msg)
puts msg if verbose
end
end

handler = RedmineMailHandler.new
handler.submit(STDIN.read)
4 changes: 4 additions & 0 deletions lang/bg.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/cs.yml
Expand Up @@ -631,3 +631,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/da.yml
Expand Up @@ -628,3 +628,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/de.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/en.yml
Expand Up @@ -214,6 +214,8 @@ setting_user_format: Users display format
setting_activity_days_default: Days displayed on project activity
setting_display_subprojects_issues: Display subprojects issues on main projects by default
setting_enabled_scm: Enabled SCM
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key

project_module_issue_tracking: Issue tracking
project_module_time_tracking: Time tracking
Expand Down Expand Up @@ -515,6 +517,8 @@ label_preferences: Preferences
label_chronological_order: In chronological order
label_reverse_chronological_order: In reverse chronological order
label_planning: Planning
label_incoming_emails: Incoming emails
label_generate_key: Generate a key

button_login: Login
button_submit: Submit
Expand Down
4 changes: 4 additions & 0 deletions lang/es.yml
Expand Up @@ -629,3 +629,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/fi.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/fr.yml
Expand Up @@ -215,6 +215,8 @@ setting_user_format: Format d'affichage des utilisateurs
setting_activity_days_default: Nombre de jours affichés sur l'activité des projets
setting_display_subprojects_issues: Afficher par défaut les demandes des sous-projets sur les projets principaux
setting_enabled_scm: SCM activés
setting_mail_handler_api_enabled: "Activer le WS pour la réception d'emails"
setting_mail_handler_api_key: Clé de protection de l'API

project_module_issue_tracking: Suivi des demandes
project_module_time_tracking: Suivi du temps passé
Expand Down Expand Up @@ -515,6 +517,8 @@ label_preferences: Préférences
label_chronological_order: Dans l'ordre chronologique
label_reverse_chronological_order: Dans l'ordre chronologique inverse
label_planning: Planning
label_incoming_emails: Emails entrants
label_generate_key: Générer une clé

button_login: Connexion
button_submit: Soumettre
Expand Down
4 changes: 4 additions & 0 deletions lang/he.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/hu.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplikálta
setting_enabled_scm: Forráskódkezelő (SCM) engedélyezése
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/it.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/ja.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/ko.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/lt.yml
Expand Up @@ -628,3 +628,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/nl.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/no.yml
Expand Up @@ -627,3 +627,7 @@ enumeration_doc_categories: Dokument-kategorier
enumeration_activities: Aktiviteter (tidssporing)
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/pl.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/pt-br.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/pt.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/ro.yml
Expand Up @@ -626,3 +626,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/ru.yml
Expand Up @@ -630,3 +630,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/sr.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key
4 changes: 4 additions & 0 deletions lang/sv.yml
Expand Up @@ -627,3 +627,7 @@ label_duplicated_by: duplicated by
setting_enabled_scm: Enabled SCM
text_enumeration_category_reassign_to: 'Reassign them to this value:'
text_enumeration_destroy_question: '%d objects are assigned to this value.'
label_incoming_emails: Incoming emails
label_generate_key: Generate a key
setting_mail_handler_api_enabled: Enable WS for incoming emails
setting_mail_handler_api_key: API key

0 comments on commit 25bba80

Please sign in to comment.