##// END OF EJS Templates
Adds a User-Agent header to Redmine mailhandler requests (#7318)....
Jean-Philippe Lang -
r4605:ced782ecb21c
parent child
Show More
@@ -1,165 +1,168
1 1 #!/usr/bin/env ruby
2 2
3 3 # == Synopsis
4 4 #
5 5 # Reads an email from standard input and forward it to a Redmine server
6 6 # through a HTTP request.
7 7 #
8 8 # == Usage
9 9 #
10 10 # rdm-mailhandler [options] --url=<Redmine URL> --key=<API key>
11 11 #
12 12 # == Arguments
13 13 #
14 14 # -u, --url URL of the Redmine server
15 15 # -k, --key Redmine API key
16 16 #
17 17 # General options:
18 18 # --unknown-user=ACTION how to handle emails from an unknown user
19 19 # ACTION can be one of the following values:
20 20 # ignore: email is ignored (default)
21 21 # accept: accept as anonymous user
22 22 # create: create a user account
23 23 # --no-permission-check disable permission checking when receiving
24 24 # the email
25 25 # -h, --help show this help
26 26 # -v, --verbose show extra information
27 27 # -V, --version show version information and exit
28 28 #
29 29 # Issue attributes control options:
30 30 # -p, --project=PROJECT identifier of the target project
31 31 # -s, --status=STATUS name of the target status
32 32 # -t, --tracker=TRACKER name of the target tracker
33 33 # --category=CATEGORY name of the target category
34 34 # --priority=PRIORITY name of the target priority
35 35 # -o, --allow-override=ATTRS allow email content to override attributes
36 36 # specified by previous options
37 37 # ATTRS is a comma separated list of attributes
38 38 #
39 39 # == Examples
40 40 # No project specified. Emails MUST contain the 'Project' keyword:
41 41 #
42 42 # rdm-mailhandler --url http://redmine.domain.foo --key secret
43 43 #
44 44 # Fixed project and default tracker specified, but emails can override
45 45 # both tracker and priority attributes using keywords:
46 46 #
47 47 # rdm-mailhandler --url https://domain.foo/redmine --key secret \\
48 48 # --project foo \\
49 49 # --tracker bug \\
50 50 # --allow-override tracker,priority
51 51
52 52 require 'net/http'
53 53 require 'net/https'
54 54 require 'uri'
55 55 require 'getoptlong'
56 56 require 'rdoc/usage'
57 57
58 58 module Net
59 59 class HTTPS < HTTP
60 def self.post_form(url, params)
60 def self.post_form(url, params, headers)
61 61 request = Post.new(url.path)
62 62 request.form_data = params
63 63 request.basic_auth url.user, url.password if url.user
64 request.initialize_http_header(headers)
64 65 http = new(url.host, url.port)
65 66 http.use_ssl = (url.scheme == 'https')
66 67 http.start {|h| h.request(request) }
67 68 end
68 69 end
69 70 end
70 71
71 72 class RedmineMailHandler
72 73 VERSION = '0.1'
73 74
74 75 attr_accessor :verbose, :issue_attributes, :allow_override, :unknown_user, :no_permission_check, :url, :key
75 76
76 77 def initialize
77 78 self.issue_attributes = {}
78 79
79 80 opts = GetoptLong.new(
80 81 [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
81 82 [ '--version', '-V', GetoptLong::NO_ARGUMENT ],
82 83 [ '--verbose', '-v', GetoptLong::NO_ARGUMENT ],
83 84 [ '--url', '-u', GetoptLong::REQUIRED_ARGUMENT ],
84 85 [ '--key', '-k', GetoptLong::REQUIRED_ARGUMENT],
85 86 [ '--project', '-p', GetoptLong::REQUIRED_ARGUMENT ],
86 87 [ '--status', '-s', GetoptLong::REQUIRED_ARGUMENT ],
87 88 [ '--tracker', '-t', GetoptLong::REQUIRED_ARGUMENT],
88 89 [ '--category', GetoptLong::REQUIRED_ARGUMENT],
89 90 [ '--priority', GetoptLong::REQUIRED_ARGUMENT],
90 91 [ '--allow-override', '-o', GetoptLong::REQUIRED_ARGUMENT],
91 92 [ '--unknown-user', GetoptLong::REQUIRED_ARGUMENT],
92 93 [ '--no-permission-check', GetoptLong::NO_ARGUMENT]
93 94 )
94 95
95 96 opts.each do |opt, arg|
96 97 case opt
97 98 when '--url'
98 99 self.url = arg.dup
99 100 when '--key'
100 101 self.key = arg.dup
101 102 when '--help'
102 103 usage
103 104 when '--verbose'
104 105 self.verbose = true
105 106 when '--version'
106 107 puts VERSION; exit
107 108 when '--project', '--status', '--tracker', '--category', '--priority'
108 109 self.issue_attributes[opt.gsub(%r{^\-\-}, '')] = arg.dup
109 110 when '--allow-override'
110 111 self.allow_override = arg.dup
111 112 when '--unknown-user'
112 113 self.unknown_user = arg.dup
113 114 when '--no-permission-check'
114 115 self.no_permission_check = '1'
115 116 end
116 117 end
117 118
118 119 RDoc.usage if url.nil?
119 120 end
120 121
121 122 def submit(email)
122 123 uri = url.gsub(%r{/*$}, '') + '/mail_handler'
123 124
125 headers = { 'User-Agent' => "Redmine mail handler/#{VERSION}" }
126
124 127 data = { 'key' => key, 'email' => email,
125 128 'allow_override' => allow_override,
126 129 'unknown_user' => unknown_user,
127 130 'no_permission_check' => no_permission_check}
128 131 issue_attributes.each { |attr, value| data["issue[#{attr}]"] = value }
129 132
130 133 debug "Posting to #{uri}..."
131 response = Net::HTTPS.post_form(URI.parse(uri), data)
134 response = Net::HTTPS.post_form(URI.parse(uri), data, headers)
132 135 debug "Response received: #{response.code}"
133 136
134 137 case response.code.to_i
135 138 when 403
136 139 warn "Request was denied by your Redmine server. " +
137 140 "Make sure that 'WS for incoming emails' is enabled in application settings and that you provided the correct API key."
138 141 return 77
139 142 when 422
140 143 warn "Request was denied by your Redmine server. " +
141 144 "Possible reasons: email is sent from an invalid email address or is missing some information."
142 145 return 77
143 146 when 400..499
144 147 warn "Request was denied by your Redmine server (#{response.code})."
145 148 return 77
146 149 when 500..599
147 150 warn "Failed to contact your Redmine server (#{response.code})."
148 151 return 75
149 152 when 201
150 153 debug "Proccessed successfully"
151 154 return 0
152 155 else
153 156 return 1
154 157 end
155 158 end
156 159
157 160 private
158 161
159 162 def debug(msg)
160 163 puts msg if verbose
161 164 end
162 165 end
163 166
164 167 handler = RedmineMailHandler.new
165 168 exit(handler.submit(STDIN.read))
General Comments 0
You need to be logged in to leave comments. Login now