##// END OF EJS Templates
Makes project selection by subaddress optional (#20732)....
Jean-Philippe Lang -
r14308:3795c22730f4
parent child
Show More
@@ -65,7 +65,7 class MailHandler < ActionMailer::Base
65 %w(project status tracker category priority).each do |option|
65 %w(project status tracker category priority).each do |option|
66 options[:issue][option.to_sym] = env[option] if env[option]
66 options[:issue][option.to_sym] = env[option] if env[option]
67 end
67 end
68 %w(allow_override unknown_user no_permission_check no_account_notice default_group).each do |option|
68 %w(allow_override unknown_user no_permission_check no_account_notice default_group project_from_subaddress).each do |option|
69 options[option.to_sym] = env[option] if env[option]
69 options[option.to_sym] = env[option] if env[option]
70 end
70 end
71 if env['private']
71 if env['private']
@@ -365,11 +365,15 class MailHandler < ActionMailer::Base
365 end
365 end
366
366
367 def get_project_from_receiver_addresses
367 def get_project_from_receiver_addresses
368 local, domain = handler_options[:project_from_subaddress].to_s.split("@")
369 return nil unless local && domain
370 local = Regexp.escape(local)
371
368 [:to, :cc, :bcc].each do |field|
372 [:to, :cc, :bcc].each do |field|
369 header = @email[field]
373 header = @email[field]
370 next if header.blank? || header.field.blank? || !header.field.respond_to?(:addrs)
374 next if header.blank? || header.field.blank? || !header.field.respond_to?(:addrs)
371 header.field.addrs.each do |addr|
375 header.field.addrs.each do |addr|
372 if addr.local.to_s =~ /\+([^+]+)\z/
376 if addr.domain.to_s.casecmp(domain)==0 && addr.local.to_s =~ /\A#{local}\+([^+]+)\z/
373 if project = Project.find_by_identifier($1)
377 if project = Project.find_by_identifier($1)
374 return project
378 return project
375 end
379 end
@@ -45,7 +45,7 class RedmineMailHandler
45 VERSION = '0.2.3'
45 VERSION = '0.2.3'
46
46
47 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :default_group, :no_permission_check,
47 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :default_group, :no_permission_check,
48 :url, :key, :no_check_certificate, :certificate_bundle, :no_account_notice, :no_notification
48 :url, :key, :no_check_certificate, :certificate_bundle, :no_account_notice, :no_notification, :project_from_subaddress
49
49
50 def initialize
50 def initialize
51 self.issue_attributes = {}
51 self.issue_attributes = {}
@@ -86,6 +86,8 class RedmineMailHandler
86 "user") { |v| self.no_notification = '1'}
86 "user") { |v| self.no_notification = '1'}
87 opts.separator("")
87 opts.separator("")
88 opts.separator("Issue attributes control options:")
88 opts.separator("Issue attributes control options:")
89 opts.on( "--project-from-subaddress ADDR", "select project from subadress of ADDR found",
90 "in To, Cc, Bcc headers") {|v| self.project_from_subaddress['project'] = v}
89 opts.on("-p", "--project PROJECT", "identifier of the target project") {|v| self.issue_attributes['project'] = v}
91 opts.on("-p", "--project PROJECT", "identifier of the target project") {|v| self.issue_attributes['project'] = v}
90 opts.on("-s", "--status STATUS", "name of the target status") {|v| self.issue_attributes['status'] = v}
92 opts.on("-s", "--status STATUS", "name of the target status") {|v| self.issue_attributes['status'] = v}
91 opts.on("-t", "--tracker TRACKER", "name of the target tracker") {|v| self.issue_attributes['tracker'] = v}
93 opts.on("-t", "--tracker TRACKER", "name of the target tracker") {|v| self.issue_attributes['tracker'] = v}
@@ -104,7 +106,6 Overrides:
104 * project, tracker, status, priority, category, assigned_to, fixed_version,
106 * project, tracker, status, priority, category, assigned_to, fixed_version,
105 start_date, due_date, estimated_hours, done_ratio
107 start_date, due_date, estimated_hours, done_ratio
106 * custom fields names with underscores instead of spaces (case insensitive)
108 * custom fields names with underscores instead of spaces (case insensitive)
107
108 Example: --allow_override=project,priority,my_custom_field
109 Example: --allow_override=project,priority,my_custom_field
109
110
110 If the --project option is not set, project is overridable by default for
111 If the --project option is not set, project is overridable by default for
@@ -113,15 +114,24 Overrides:
113 You can use --allow_override=all to allow all attributes to be overridable.
114 You can use --allow_override=all to allow all attributes to be overridable.
114
115
115 Examples:
116 Examples:
116 No project specified, emails MUST contain the 'Project' keyword:
117 No project specified, emails MUST contain the 'Project' keyword, otherwise
117 rdm-mailhandler.rb --url http://redmine.domain.foo --key secret
118 they will be dropped (not recommanded):
119
120 rdm-mailhandler.rb --url http://redmine.domain.foo --key secret
118
121
119 Fixed project and default tracker specified, but emails can override
122 Fixed project and default tracker specified, but emails can override
120 both tracker and priority attributes using keywords:
123 both tracker and priority attributes using keywords:
121 rdm-mailhandler.rb --url https://domain.foo/redmine --key secret \\
124
122 --project foo \\
125 rdm-mailhandler.rb --url https://domain.foo/redmine --key secret \\
123 --tracker bug \\
126 --project myproject \\
124 --allow-override tracker,priority
127 --tracker bug \\
128 --allow-override tracker,priority
129
130 Project selected by subaddress of redmine@example.net. Sending the email
131 to redmine+myproject@example.net will add the issue to myproject:
132
133 rdm-mailhandler.rb --url http://redmine.domain.foo --key secret \\
134 --project-from-subaddress redmine@example.net
125 END_DESC
135 END_DESC
126
136
127 opts.summary_width = 27
137 opts.summary_width = 27
@@ -145,7 +155,8 END_DESC
145 'default_group' => default_group,
155 'default_group' => default_group,
146 'no_account_notice' => no_account_notice,
156 'no_account_notice' => no_account_notice,
147 'no_notification' => no_notification,
157 'no_notification' => no_notification,
148 'no_permission_check' => no_permission_check}
158 'no_permission_check' => no_permission_check,
159 'project_from_subaddress' => project_from_subaddress}
149 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
160 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
150
161
151 debug "Posting to #{uri}..."
162 debug "Posting to #{uri}..."
@@ -107,7 +107,8 class MailHandlerTest < ActiveSupport::TestCase
107 # This email has redmine+onlinestore@somenet.foo as 'To' header
107 # This email has redmine+onlinestore@somenet.foo as 'To' header
108 issue = submit_email(
108 issue = submit_email(
109 'ticket_on_project_given_by_to_header.eml',
109 'ticket_on_project_given_by_to_header.eml',
110 :issue => {:tracker => 'Support request'}
110 :issue => {:tracker => 'Support request'},
111 :project_from_subaddress => 'redmine@somenet.foo'
111 )
112 )
112 assert issue.is_a?(Issue)
113 assert issue.is_a?(Issue)
113 assert !issue.new_record?
114 assert !issue.new_record?
General Comments 0
You need to be logged in to leave comments. Login now