From 25bba80c9eb112b8ded40d2baf9f202c79d4e2ad Mon Sep 17 00:00:00 2001 From: Jean-Philippe Lang Date: Wed, 25 Jun 2008 19:25:28 +0000 Subject: [PATCH] Adds a simple API and a standalone script that can be used to forward 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 --- app/controllers/mail_handler_controller.rb | 44 +++++++++++ app/helpers/mail_handler_helper.rb | 19 +++++ app/helpers/settings_helper.rb | 1 + app/models/mail_handler.rb | 2 +- app/views/settings/_mail_handler.rhtml | 18 +++++ config/settings.yml | 4 + extra/mail_handler/rdm-mailhandler.rb | 79 +++++++++++++++++++ lang/bg.yml | 4 + lang/cs.yml | 4 + lang/da.yml | 4 + lang/de.yml | 4 + lang/en.yml | 4 + lang/es.yml | 4 + lang/fi.yml | 4 + lang/fr.yml | 4 + lang/he.yml | 4 + lang/hu.yml | 4 + lang/it.yml | 4 + lang/ja.yml | 4 + lang/ko.yml | 4 + lang/lt.yml | 4 + lang/nl.yml | 4 + lang/no.yml | 4 + lang/pl.yml | 4 + lang/pt-br.yml | 4 + lang/pt.yml | 4 + lang/ro.yml | 4 + lang/ru.yml | 4 + lang/sr.yml | 4 + lang/sv.yml | 4 + lang/th.yml | 4 + lang/uk.yml | 4 + lang/zh-tw.yml | 4 + lang/zh.yml | 4 + public/javascripts/application.js | 9 +++ .../mail_handler_controller_test.rb | 53 +++++++++++++ 36 files changed, 336 insertions(+), 1 deletion(-) create mode 100644 app/controllers/mail_handler_controller.rb create mode 100644 app/helpers/mail_handler_helper.rb create mode 100644 app/views/settings/_mail_handler.rhtml create mode 100644 extra/mail_handler/rdm-mailhandler.rb create mode 100644 test/functional/mail_handler_controller_test.rb diff --git a/app/controllers/mail_handler_controller.rb b/app/controllers/mail_handler_controller.rb new file mode 100644 index 000000000..8bcfce630 --- /dev/null +++ b/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 diff --git a/app/helpers/mail_handler_helper.rb b/app/helpers/mail_handler_helper.rb new file mode 100644 index 000000000..a29a6dd5a --- /dev/null +++ b/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 diff --git a/app/helpers/settings_helper.rb b/app/helpers/settings_helper.rb index f4ec5a7a7..d88269f7d 100644 --- a/app/helpers/settings_helper.rb +++ b/app/helpers/settings_helper.rb @@ -21,6 +21,7 @@ module SettingsHelper {: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 diff --git a/app/models/mail_handler.rb b/app/models/mail_handler.rb index 7b85077e1..124f7db74 100644 --- a/app/models/mail_handler.rb +++ b/app/models/mail_handler.rb @@ -84,7 +84,7 @@ class MailHandler < ActionMailer::Base # 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 diff --git a/app/views/settings/_mail_handler.rhtml b/app/views/settings/_mail_handler.rhtml new file mode 100644 index 000000000..830b1ba4a --- /dev/null +++ b/app/views/settings/_mail_handler.rhtml @@ -0,0 +1,18 @@ +<% form_tag({:action => 'edit', :tab => 'mail_handler'}) do %> + +
+

+<%= 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 %>

+ +

+<%= 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) }" %>

+
+ +<%= submit_tag l(:button_save) %> +<% end %> diff --git a/config/settings.yml b/config/settings.yml index 616665f23..78a366f35 100644 --- a/config/settings.yml +++ b/config/settings.yml @@ -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: diff --git a/extra/mail_handler/rdm-mailhandler.rb b/extra/mail_handler/rdm-mailhandler.rb new file mode 100644 index 000000000..585afefef --- /dev/null +++ b/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= --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) diff --git a/lang/bg.yml b/lang/bg.yml index 48226c79a..1339d9a83 100644 --- a/lang/bg.yml +++ b/lang/bg.yml @@ -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 diff --git a/lang/cs.yml b/lang/cs.yml index de460ba3a..00d0642de 100644 --- a/lang/cs.yml +++ b/lang/cs.yml @@ -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 diff --git a/lang/da.yml b/lang/da.yml index 6919cdfcb..b8546ab20 100644 --- a/lang/da.yml +++ b/lang/da.yml @@ -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 diff --git a/lang/de.yml b/lang/de.yml index 290acd916..6bc7919f9 100644 --- a/lang/de.yml +++ b/lang/de.yml @@ -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 diff --git a/lang/en.yml b/lang/en.yml index ffbd10622..7ab73f051 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -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 @@ -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 diff --git a/lang/es.yml b/lang/es.yml index b027f48e3..2615d8f61 100644 --- a/lang/es.yml +++ b/lang/es.yml @@ -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 diff --git a/lang/fi.yml b/lang/fi.yml index e1d188dcc..51b0c04a0 100644 --- a/lang/fi.yml +++ b/lang/fi.yml @@ -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 diff --git a/lang/fr.yml b/lang/fr.yml index eaae51765..1fd86dd07 100644 --- a/lang/fr.yml +++ b/lang/fr.yml @@ -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é @@ -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 diff --git a/lang/he.yml b/lang/he.yml index 5f14ee16e..7455fc395 100644 --- a/lang/he.yml +++ b/lang/he.yml @@ -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 diff --git a/lang/hu.yml b/lang/hu.yml index c46d0e26c..ba904ed45 100644 --- a/lang/hu.yml +++ b/lang/hu.yml @@ -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 diff --git a/lang/it.yml b/lang/it.yml index 8aec9ef0e..867c73f9a 100644 --- a/lang/it.yml +++ b/lang/it.yml @@ -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 diff --git a/lang/ja.yml b/lang/ja.yml index c48579dda..aa4320c3a 100644 --- a/lang/ja.yml +++ b/lang/ja.yml @@ -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 diff --git a/lang/ko.yml b/lang/ko.yml index f2339556f..f945537a9 100644 --- a/lang/ko.yml +++ b/lang/ko.yml @@ -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 diff --git a/lang/lt.yml b/lang/lt.yml index 61533b3ab..355f473c8 100644 --- a/lang/lt.yml +++ b/lang/lt.yml @@ -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 diff --git a/lang/nl.yml b/lang/nl.yml index 109d444f1..89b8a5736 100644 --- a/lang/nl.yml +++ b/lang/nl.yml @@ -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 diff --git a/lang/no.yml b/lang/no.yml index 4e47c75a2..5e4bdcca3 100644 --- a/lang/no.yml +++ b/lang/no.yml @@ -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 diff --git a/lang/pl.yml b/lang/pl.yml index 97378b5b1..0b0f87b6f 100644 --- a/lang/pl.yml +++ b/lang/pl.yml @@ -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 diff --git a/lang/pt-br.yml b/lang/pt-br.yml index 67822499e..e2036afde 100644 --- a/lang/pt-br.yml +++ b/lang/pt-br.yml @@ -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 diff --git a/lang/pt.yml b/lang/pt.yml index a91eea01b..543743cab 100644 --- a/lang/pt.yml +++ b/lang/pt.yml @@ -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 diff --git a/lang/ro.yml b/lang/ro.yml index aafc61916..16c2ea104 100644 --- a/lang/ro.yml +++ b/lang/ro.yml @@ -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 diff --git a/lang/ru.yml b/lang/ru.yml index e04377781..f68505be5 100644 --- a/lang/ru.yml +++ b/lang/ru.yml @@ -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 diff --git a/lang/sr.yml b/lang/sr.yml index ec01774bc..83bfdf43c 100644 --- a/lang/sr.yml +++ b/lang/sr.yml @@ -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 diff --git a/lang/sv.yml b/lang/sv.yml index e28943d9b..375970f3e 100644 --- a/lang/sv.yml +++ b/lang/sv.yml @@ -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 diff --git a/lang/th.yml b/lang/th.yml index 6c84dba70..acbf146cf 100644 --- a/lang/th.yml +++ b/lang/th.yml @@ -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 diff --git a/lang/uk.yml b/lang/uk.yml index 365ced150..d70916b1e 100644 --- a/lang/uk.yml +++ b/lang/uk.yml @@ -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 diff --git a/lang/zh-tw.yml b/lang/zh-tw.yml index c7b473548..462633575 100644 --- a/lang/zh-tw.yml +++ b/lang/zh-tw.yml @@ -627,3 +627,7 @@ enumeration_doc_categories: 文件分類 enumeration_activities: 活動 (時間追蹤) 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 diff --git a/lang/zh.yml b/lang/zh.yml index 981e8102d..9f81d42fa 100644 --- a/lang/zh.yml +++ b/lang/zh.yml @@ -627,3 +627,7 @@ enumeration_doc_categories: 文档类别 enumeration_activities: 活动(时间跟踪) 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 diff --git a/public/javascripts/application.js b/public/javascripts/application.js index a8b6c0e46..4e5b67e55 100644 --- a/public/javascripts/application.js +++ b/public/javascripts/application.js @@ -107,6 +107,15 @@ function scmEntryLoaded(id) { Element.removeClassName(id, 'loading'); } +function randomKey(size) { + var chars = new Array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z'); + var key = ''; + for (i = 0; i < size; i++) { + key += chars[Math.floor(Math.random() * chars.length)]; + } + return key; +} + /* shows and hides ajax indicator */ Ajax.Responders.register({ onCreate: function(){ diff --git a/test/functional/mail_handler_controller_test.rb b/test/functional/mail_handler_controller_test.rb new file mode 100644 index 000000000..6c5af23f0 --- /dev/null +++ b/test/functional/mail_handler_controller_test.rb @@ -0,0 +1,53 @@ +# 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. + +require File.dirname(__FILE__) + '/../test_helper' +require 'mail_handler_controller' + +# Re-raise errors caught by the controller. +class MailHandlerController; def rescue_action(e) raise e end; end + +class MailHandlerControllerTest < Test::Unit::TestCase + fixtures :users, :projects, :enabled_modules, :roles, :members, :issues, :issue_statuses, :trackers, :enumerations + + FIXTURES_PATH = File.dirname(__FILE__) + '/../fixtures/mail_handler' + + def setup + @controller = MailHandlerController.new + @request = ActionController::TestRequest.new + @response = ActionController::TestResponse.new + User.current = nil + end + + def test_should_create_issue + # Enable API and set a key + Setting.mail_handler_api_enabled = 1 + Setting.mail_handler_api_key = 'secret' + + post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml')) + assert_response 201 + end + + def test_should_not_allow + # Disable API + Setting.mail_handler_api_enabled = 0 + Setting.mail_handler_api_key = 'secret' + + post :index, :key => 'secret', :email => IO.read(File.join(FIXTURES_PATH, 'ticket_on_given_project.eml')) + assert_response 403 + end +end