comparison .svn/pristine/19/196c7c4e4ef7e50cda7944736d264f90424a0cab.svn-base @ 1295:622f24f53b42 redmine-2.3

Update to Redmine SVN revision 11972 on 2.3-stable branch
author Chris Cannam
date Fri, 14 Jun 2013 09:02:21 +0100
parents
children
comparison
equal deleted inserted replaced
1294:3e4c3460b6ca 1295:622f24f53b42
1 #!/usr/bin/env ruby
2
3 require 'net/http'
4 require 'net/https'
5 require 'uri'
6 require 'optparse'
7
8 module Net
9 class HTTPS < HTTP
10 def self.post_form(url, params, headers, options={})
11 request = Post.new(url.path)
12 request.form_data = params
13 request.initialize_http_header(headers)
14 request.basic_auth url.user, url.password if url.user
15 http = new(url.host, url.port)
16 http.use_ssl = (url.scheme == 'https')
17 if options[:no_check_certificate]
18 http.verify_mode = OpenSSL::SSL::VERIFY_NONE
19 end
20 http.start {|h| h.request(request) }
21 end
22 end
23 end
24
25 class RedmineMailHandler
26 VERSION = '0.2.1'
27
28 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key, :no_check_certificate
29
30 def initialize
31 self.issue_attributes = {}
32
33 optparse = OptionParser.new do |opts|
34 opts.banner = "Usage: rdm-mailhandler.rb [options] --url=<Redmine URL> --key=<API key>"
35 opts.separator("")
36 opts.separator("Reads an email from standard input and forward it to a Redmine server through a HTTP request.")
37 opts.separator("")
38 opts.separator("Required arguments:")
39 opts.on("-u", "--url URL", "URL of the Redmine server") {|v| self.url = v}
40 opts.on("-k", "--key KEY", "Redmine API key") {|v| self.key = v}
41 opts.separator("")
42 opts.separator("General options:")
43 opts.on("--unknown-user ACTION", "how to handle emails from an unknown user",
44 "ACTION can be one of the following values:",
45 "* ignore: email is ignored (default)",
46 "* accept: accept as anonymous user",
47 "* create: create a user account") {|v| self.unknown_user = v}
48 opts.on("--no-permission-check", "disable permission checking when receiving",
49 "the email") {self.no_permission_check = '1'}
50 opts.on("--key-file FILE", "path to a file that contains the Redmine",
51 "API key (use this option instead of --key",
52 "if you don't the key to appear in the",
53 "command line)") {|v| read_key_from_file(v)}
54 opts.on("--no-check-certificate", "do not check server certificate") {self.no_check_certificate = true}
55 opts.on("-h", "--help", "show this help") {puts opts; exit 1}
56 opts.on("-v", "--verbose", "show extra information") {self.verbose = true}
57 opts.on("-V", "--version", "show version information and exit") {puts VERSION; exit}
58 opts.separator("")
59 opts.separator("Issue attributes control options:")
60 opts.on("-p", "--project PROJECT", "identifier of the target project") {|v| self.issue_attributes['project'] = v}
61 opts.on("-s", "--status STATUS", "name of the target status") {|v| self.issue_attributes['status'] = v}
62 opts.on("-t", "--tracker TRACKER", "name of the target tracker") {|v| self.issue_attributes['tracker'] = v}
63 opts.on( "--category CATEGORY", "name of the target category") {|v| self.issue_attributes['category'] = v}
64 opts.on( "--priority PRIORITY", "name of the target priority") {|v| self.issue_attributes['priority'] = v}
65 opts.on("-o", "--allow-override ATTRS", "allow email content to override attributes",
66 "specified by previous options",
67 "ATTRS is a comma separated list of attributes") {|v| self.allow_override = v}
68 opts.separator("")
69 opts.separator("Examples:")
70 opts.separator("No project specified. Emails MUST contain the 'Project' keyword:")
71 opts.separator(" rdm-mailhandler.rb --url http://redmine.domain.foo --key secret")
72 opts.separator("")
73 opts.separator("Fixed project and default tracker specified, but emails can override")
74 opts.separator("both tracker and priority attributes using keywords:")
75 opts.separator(" rdm-mailhandler.rb --url https://domain.foo/redmine --key secret \\")
76 opts.separator(" --project foo \\")
77 opts.separator(" --tracker bug \\")
78 opts.separator(" --allow-override tracker,priority")
79
80 opts.summary_width = 27
81 end
82 optparse.parse!
83
84 unless url && key
85 puts "Some arguments are missing. Use `rdm-mailhandler.rb --help` for getting help."
86 exit 1
87 end
88 end
89
90 def submit(email)
91 uri = url.gsub(%r{/*$}, '') + '/mail_handler'
92
93 headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
94
95 data = { 'key' => key, 'email' => email,
96 'allow_override' => allow_override,
97 'unknown_user' => unknown_user,
98 'no_permission_check' => no_permission_check}
99 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
100
101 debug "Posting to #{uri}..."
102 response = Net::HTTPS.post_form(URI.parse(uri), data, headers, :no_check_certificate => no_check_certificate)
103 debug "Response received: #{response.code}"
104
105 case response.code.to_i
106 when 403
107 warn "Request was denied by your Redmine server. " +
108 "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
109 return 77
110 when 422
111 warn "Request was denied by your Redmine server. " +
112 "Possible reasons: email is sent from an invalid email address or is missing some information."
113 return 77
114 when 400..499
115 warn "Request was denied by your Redmine server (#{response.code})."
116 return 77
117 when 500..599
118 warn "Failed to contact your Redmine server (#{response.code})."
119 return 75
120 when 201
121 debug "Proccessed successfully"
122 return 0
123 else
124 return 1
125 end
126 end
127
128 private
129
130 def debug(msg)
131 puts msg if verbose
132 end
133
134 def read_key_from_file(filename)
135 begin
136 self.key = File.read(filename).strip
137 rescue Exception => e
138 $stderr.puts "Unable to read the key from #{filename}:\n#{e.message}"
139 exit 1
140 end
141 end
142 end
143
144 handler = RedmineMailHandler.new
145 exit(handler.submit(STDIN.read))