Merge branch 'ticket/unstable/792-confirmation-emails' into unstable

This commit is contained in:
Eric Davis 2011-12-29 10:28:47 -08:00
commit 00df832126
13 changed files with 212 additions and 14 deletions

View File

@ -69,6 +69,7 @@ class MailHandler < ActionMailer::Base
else
# Default behaviour, emails from unknown users are ignored
logger.info "MailHandler: ignoring email from unknown user [#{sender_email}]" if logger && logger.info
Mailer.deliver_mail_handler_unauthorized_action(user, email.subject.to_s, :to => sender_email) if Setting.mail_handler_confirmation_on_failure
return false
end
end
@ -102,12 +103,15 @@ class MailHandler < ActionMailer::Base
rescue ActiveRecord::RecordInvalid => e
# TODO: send a email to the user
logger.error e.message if logger
Mailer.deliver_mail_handler_missing_information(user, email.subject.to_s, e.message) if Setting.mail_handler_confirmation_on_failure
false
rescue MissingInformation => e
logger.error "MailHandler: missing information from #{user}: #{e.message}" if logger
Mailer.deliver_mail_handler_missing_information(user, email.subject.to_s, e.message) if Setting.mail_handler_confirmation_on_failure
false
rescue UnauthorizedAction => e
logger.error "MailHandler: unauthorized attempt from #{user}" if logger
Mailer.deliver_mail_handler_unauthorized_action(user, email.subject.to_s) if Setting.mail_handler_confirmation_on_failure
false
end
@ -141,6 +145,7 @@ class MailHandler < ActionMailer::Base
issue.save!
add_attachments(issue)
logger.info "MailHandler: issue ##{issue.id} created by #{user}" if logger && logger.info
Mailer.deliver_mail_handler_confirmation(issue, user, issue.subject) if Setting.mail_handler_confirmation_on_success
issue
end
@ -162,6 +167,7 @@ class MailHandler < ActionMailer::Base
add_attachments(issue)
issue.save!
logger.info "MailHandler: issue ##{issue.id} updated by #{user}" if logger && logger.info
Mailer.deliver_mail_handler_confirmation(issue.last_journal, user, email.subject) if Setting.mail_handler_confirmation_on_success
issue.last_journal
end
@ -190,6 +196,7 @@ class MailHandler < ActionMailer::Base
reply.board = message.board
message.children << reply
add_attachments(reply)
Mailer.deliver_mail_handler_confirmation(message, user, reply.subject) if Setting.mail_handler_confirmation_on_success
reply
else
logger.info "MailHandler: ignoring reply from [#{sender_email}] to a locked topic" if logger && logger.info

View File

@ -285,6 +285,44 @@ class Mailer < ActionMailer::Base
render_multipart('register', body)
end
def mail_handler_confirmation(object, user, email_subject)
recipients user.mail
case
when object.is_a?(Issue)
project = object.project.name
url = url_for(:controller => 'issues', :action => 'show', :id => object.id)
when object.is_a?(Journal)
project = object.project.name
url = url_for(:controller => 'issues', :action => 'show', :id => object.issue.id)
when object.class == Message
project = object.project.name
url = url_for(object.event_url)
else
project = ''
url = ''
end
subject "[#{project}] #{l(:label_mail_handler_confirmation, :subject => email_subject)}"
body(:object => object,
:url => url)
render_multipart('mail_handler_confirmation', body)
end
def mail_handler_unauthorized_action(user, email_subject, options={})
recipients options[:to] || user.mail
subject l(:label_mail_handler_failure, :subject => email_subject)
body({})
render_multipart('mail_handler_unauthorized_action', body)
end
def mail_handler_missing_information(user, email_subject, error_message)
recipients user.mail
subject l(:label_mail_handler_failure, :subject => email_subject)
body({:errors => error_message.to_s})
render_multipart('mail_handler_missing_information', body)
end
def test(user)
redmine_headers 'Type' => "Test"
set_language_if_valid(user.language)

View File

@ -0,0 +1,2 @@
<p><%= l(:text_mail_handler_confirmation_successful) %><br />
<%= auto_link(@url) %></p>

View File

@ -0,0 +1,2 @@
<%= l(:text_mail_handler_confirmation_successful) %>
<%= @url %>

View File

@ -0,0 +1,3 @@
<p><%= l(:label_mail_handler_errors_with_submission) %></p>
<p><%= h(@errors) %></p>

View File

@ -0,0 +1,3 @@
<%= l(:label_mail_handler_errors_with_submission) %>
<%= h(@errors) %>

View File

@ -0,0 +1 @@
<%= l(:notice_not_authorized_action) %>

View File

@ -0,0 +1 @@
<%= l(:notice_not_authorized_action) %>

View File

@ -5,6 +5,9 @@
<%= setting_text_area :mail_handler_body_delimiters, :rows => 5 %>
<br /><em><%= l(:text_line_separated) %></em>
</p>
<p><%= setting_check_box :mail_handler_confirmation_on_success %></p>
<p><%= setting_check_box :mail_handler_confirmation_on_failure %></p>
</div>
<div class="box tabular settings">

View File

@ -157,6 +157,7 @@ en:
notice_file_not_found: The page you were trying to access doesn't exist or has been removed.
notice_locking_conflict: Data has been updated by another user.
notice_not_authorized: You are not authorized to access this page.
notice_not_authorized_action: You are not authorized to perform this action.
notice_not_authorized_archived_project: The project you're trying to access has been archived.
notice_email_sent: "An email was sent to %{value}"
notice_email_error: "An error occurred while sending mail (%{value})"
@ -368,6 +369,8 @@ en:
setting_commit_logtime_activity_id: Activity for logged time
setting_gantt_items_limit: Maximum number of items displayed on the gantt chart
setting_issue_startdate_is_adddate: Use current date as start date for new issues
setting_mail_handler_confirmation_on_success: "Send confirmation email on successful incoming email"
setting_mail_handler_confirmation_on_failure: "Send confirmation email on failed incoming email"
permission_add_project: Create project
permission_add_subprojects: Create subprojects
@ -818,6 +821,9 @@ en:
label_path_encoding: Path encoding
label_deleted_custom_field: '(deleted custom field)'
label_toc: "Contents"
label_mail_handler_confirmation: "Confirmation of email submission: %{subject}"
label_mail_handler_failure: "Failed email submission: %{subject}"
label_mail_handler_errors_with_submission: "There were errors with your email submission:"
button_login: Login
button_submit: Submit
@ -943,7 +949,8 @@ en:
text_git_repo_example: "a bare and local repository (e.g. /gitrepo, c:\\gitrepo)"
text_display_subprojects: Display subprojects
text_current_project: Current project
text_mail_handler_confirmation_successful: "Your email has been successful added at the following url"
default_role_manager: Manager
default_role_developer: Developer
default_role_reporter: Reporter

View File

@ -178,5 +178,9 @@ default_notification_option:
default: 'only_my_events'
emails_header:
default: ''
mail_handler_confirmation_on_success:
default: 1
mail_handler_confirmation_on_failure:
default: 1
issue_startdate_is_adddate:
default: 1
default: 1

View File

@ -0,0 +1,23 @@
Return-Path: <JSmith@somenet.foo>
Received: from osiris ([127.0.0.1])
by OSIRIS
with hMailServer ; Sun, 22 Jun 2008 12:28:07 +0200
Message-ID: <000501c8d452$a95cd7e0$0a00a8c0@osiris>
From: "John Smith" <JSmith@somenet.foo>
To: <redmine@somenet.foo>
Subject: New ticket on a given project
Date: Sun, 22 Jun 2008 12:28:07 +0200
MIME-Version: 1.0
Content-Type: text/plain;
format=flowed;
charset="iso-8859-1";
reply-type=original
Content-Transfer-Encoding: 7bit
X-Priority: 3
X-MSMail-Priority: Normal
X-Mailer: Microsoft Outlook Express 6.00.2900.2869
X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.2869
Test with missing information
Project: onlinestore

View File

@ -1,4 +1,4 @@
#-- encoding: UTF-8
#-- encoding: utf-8 -8
#-- copyright
# ChiliProject is a project management system.
#
@ -39,6 +39,8 @@ class MailHandlerTest < ActiveSupport::TestCase
def setup
ActionMailer::Base.deliveries.clear
Setting.notified_events = Redmine::Notifiable.all.collect(&:name)
Setting.mail_handler_confirmation_on_success = true
Setting.mail_handler_confirmation_on_failure = true
end
def test_add_issue
@ -67,6 +69,7 @@ class MailHandlerTest < ActiveSupport::TestCase
assert !issue.description.match(/^Status:/i)
assert !issue.description.match(/^Start Date:/i)
# Email notification should be sent
assert_equal 2, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.subject.include?('New ticket on a given project')
@ -289,7 +292,7 @@ class MailHandlerTest < ActiveSupport::TestCase
# This email contains: 'Project: onlinestore'
issue = submit_email('ticket_on_given_project.eml')
assert issue.is_a?(Issue)
assert_equal 1, ActionMailer::Base.deliveries.size
assert_equal 2, ActionMailer::Base.deliveries.size
end
def test_add_issue_note
@ -301,15 +304,6 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal 'Feature request', journal.issue.tracker.name
end
test "reply to issue update (Journal) by message_id" do
journal = submit_email('ticket_reply_by_message_id.eml')
assert journal.is_a?(IssueJournal), "Email was a #{journal.class}"
assert_equal User.find_by_login('jsmith'), journal.user
assert_equal Issue.find(2), journal.journaled
assert_match /This is reply/, journal.notes
assert_equal 'Feature request', journal.issue.tracker.name
end
def test_add_issue_note_with_attribute_changes
# This email contains: 'Status: Resolved'
journal = submit_email('ticket_reply_with_status.eml')
@ -333,7 +327,7 @@ class MailHandlerTest < ActiveSupport::TestCase
ActionMailer::Base.deliveries.clear
journal = submit_email('ticket_reply.eml')
assert journal.is_a?(Journal)
assert_equal 3, ActionMailer::Base.deliveries.size
assert_equal 1, ActionMailer::Base.deliveries.size
end
def test_add_issue_note_should_not_set_defaults
@ -456,6 +450,116 @@ class MailHandlerTest < ActiveSupport::TestCase
assert_equal issue.subject, 'New ticket on a given project with a very long subject line which exceeds 255 chars and should not be ignored but chopped off. And if the subject line is still not long enough, we just add more text. And more text. Wow, this is really annoying. Especially, if you have nothing to say...'[0,255]
end
context "with an email that performs an unauthorized action" do
should "deliver an email error confirmation for an unknown user" do
ActionMailer::Base.deliveries.clear
issue = submit_email('ticket_by_unknown_user.eml')
assert_equal false, issue
assert_equal 1, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.to.include?('john.doe@somenet.foo')
assert mail.subject.include?('Failed email submission: Ticket by unknown user')
assert mail.body.include?('You are not authorized to perform this action')
end
should "deliver an email error confirmation for a user without permission" do
ActionMailer::Base.deliveries.clear
# Clear memberships for the sending user so they fail permission checks
Project.find(1).update_attributes(:is_public => false)
Member.all(:conditions => {:user_id => 2}).collect(&:destroy)
assert_no_difference('Journal.count') do
assert_equal false, submit_email('ticket_reply.eml')
end
assert_equal 1, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.to.include?('jsmith@somenet.foo')
assert mail.subject.include?('Failed email submission: Re: Add ingredients categories')
assert mail.body.include?('You are not authorized to perform this action')
end
end
context "with an email that is missing required information" do
should "deliver an email error confirmation to the sender for a missing project" do
ActionMailer::Base.deliveries.clear
issue = submit_email('ticket_with_attachment.eml') # No project set
assert_equal false, issue
assert_equal 1, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.to.include?('jsmith@somenet.foo')
assert mail.subject.include?('Failed email submission: Ticket created by email with attachment')
assert mail.body.include?('There were errors with your email submission')
assert mail.body.include?('Unable to determine target project')
end
should "deliver an email error confirmation to the sender for a missing other attributes" do
# Add a required custom field to simulate the error
project = Project.find('onlinestore')
project.issue_custom_fields << IssueCustomField.generate(:name => 'Required Custom Field0', :is_required => true, :trackers => project.trackers)
project.save
ActionMailer::Base.deliveries.clear
issue = submit_email('ticket_on_project_with_missing_information.eml')
assert_equal false, issue
assert_equal 1, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.bcc.include?('jsmith@somenet.foo')
assert mail.subject.include?('Failed email submission: New ticket on a given project')
assert mail.body.include?('There were errors with your email submission')
assert mail.body.include?('Required Custom Field0 can\'t be blank')
end
end
context "#receive_issue" do
should "deliver an email confirmation when configured" do
ActionMailer::Base.deliveries.clear
issue = submit_email('ticket_on_given_project.eml')
assert_equal 2, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.subject.include?('[OnlineStore]'), "Project name missing"
assert mail.subject.include?('Confirmation of email submission: New ticket on a given project'), "Main subject missing"
assert mail.body.include?("/issues/#{issue.reload.id}"), "Link to issue missing"
end
end
context "#receive_issue_reply" do
should "deliver an email confirmation when configured" do
journal = submit_email('ticket_reply.eml')
assert_equal 1, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.subject.include?('[eCookbook]'), "Project name missing"
assert mail.subject.include?('Confirmation of email submission: Re: Add ingredients categories'), "Main subject missing"
assert mail.body.include?("/issues/2"), "Link to issue missing"
end
end
context "#receive_message_reply" do
should "deliver an email confirmation when configured" do
ActionMailer::Base.deliveries.clear
m = submit_email('message_reply.eml')
assert_equal 3, ActionMailer::Base.deliveries.size
mail = ActionMailer::Base.deliveries.last
assert_not_nil mail
assert mail.subject.include?('[eCookbook]'), "Project name missing"
assert mail.subject.include?('Confirmation of email submission: Reply via email'), "Main subject missing"
assert mail.body.include?("/boards/1/topics/1"), "Link to message missing"
end
end
private
def submit_email(filename, options={})