/
patchinfo_controller.rb
392 lines (369 loc) · 13.1 KB
/
patchinfo_controller.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
class Webui::PatchinfoController < Webui::WebuiController
include Webui::WebuiHelper
include Webui::PackageHelper
before_filter :require_all
before_filter :get_binaries, :except => [:show, :delete]
before_filter :require_exists, :except => [:new_patchinfo]
def new_patchinfo
unless Webui::Package.find('patchinfo', :project => @project )
begin
path = "/source/#{CGI.escape(params[:project])}?cmd=createpatchinfo"
frontend.transport.direct_http( URI(path), :method => 'POST')
rescue ActiveXML::Transport::Error => e
flash[:error] = e.summary
redirect_to :controller => 'project', :action => 'show' and return
end
end
@package = find_cached(Webui::Package, 'patchinfo', :project => @project )
@file = find_cached(Webui::Patchinfo, :project => @project, :package => @package )
unless @file
flash[:error] = "Patchinfo not found for #{params[:project]}"
redirect_to :controller => 'package', :action => 'show', :project => @project, :package => @package and return
end
read_patchinfo
@binaries.each do |bin|
if @binarylist.match(bin)
@binarylist.delete(bin)
end
end
end
def updatepatchinfo
path = "/source/#{CGI.escape(params[:project])}/#{CGI.escape(params[:package])}?cmd=updatepatchinfo"
frontend.transport.direct_http( URI(path), :method => 'POST')
Webui::Patchinfo.free_cache(:project=> @project, :package => @package)
redirect_to :action => 'edit_patchinfo', :project => @project, :package => @package
end
def edit_patchinfo
read_patchinfo
@tracker = 'bnc'
@binaries.each do |bin|
if @binarylist.find(bin)
@binarylist.delete(bin)
end
end
end
def show
read_patchinfo
@pkg_names = @project.api_project.packages.pluck(:name)
@pkg_names.delete('patchinfo')
@packager = Webui::Person.find(:login => @packager)
end
def read_patchinfo
@binaries = Array.new
if @file.has_element?('binary')
@file.each_binary do |binaries|
@binaries << binaries.text
end
end
@binary = []
@packager = @file.packager.to_s
@issues = []
if @file.has_element?('issue')
@file.each_issue do |a|
if a.text == ''
# old uploaded patchinfos could have broken tracker-names like "bnc " instead of "bnc". Catch these.
begin
get_issue_sum(a.tracker, a.value(:id))
a.text = @issuesum
rescue ActiveXML::Transport::NotFoundError
a.text = 'PLEASE CHECK THE FORMAT OF THE ISSUE'
end
end
issue = Array.new
issueid = a.value(:id)
issueurl = Webui::IssueTracker.find(:name => a.tracker)
if !issueurl.nil?
issueurl = issueurl.each('/issue-tracker/show-url').first.text
issueurl = issueurl.sub(/@@@/, issueid)
else
issueurl = ''
end
issue << a.tracker
issue << issueid
issue << issueurl
issue << a.text
@issues << issue
end
end
if params[:issue] == nil
params[:issue] = Array.new
params[:issue] << params[:issueid]
end
if params[:issueid] != nil
params[:issue] << params[:issueid]
@issues = params[:issue]
end
@category = @file.category.to_s
@rating = @file.rating.to_s if @file.rating
@description = @summary = @category = nil
@category = @file.category.to_s if @file.has_element? 'category'
@rating = @file.rating.to_s if @file.has_element? 'rating'
@summary = @file.summary.text if @file.has_element? 'summary'
@description = @file.description.text if @file.has_element? 'description'
if @file.has_element?('relogin_needed')
@relogin = true
else
@relogin = false
end
if @file.has_element?('reboot_needed')
@reboot = true
else
@reboot = false
end
if @file.has_element?('zypp_restart_needed')
@zypp_restart_needed = true
else
@zypp_restart_needed = false
end
if @file.has_element?('stopped')
@block = true
@block_reason = @file.stopped.text
end
end
def save
begin
filename = '_patchinfo'
valid_params = true
required_parameters :project, :package
flash[:error] = nil
if !valid_summary? params[:summary]
valid_params = false
flash[:error] = "#{flash[:error]}" + ' || Summary is too short (should have more than 10 signs)'
end
if !valid_description? params[:description]
valid_params = false
flash[:error] = "#{flash[:error]}" + ' || Description is too short (should have more than 50 signs and longer than summary)'
end
if valid_params == true
packager = params[:packager]
binaries = params[:selected_binaries]
relogin = params[:relogin]
reboot = params[:reboot]
zypp_restart_needed = params[:zypp_restart_needed]
if params[:issueid]
issues = Array.new
params[:issueid].each_with_index do |new_issue, index|
issue = Array.new
issue << new_issue
issue << params[:issuetracker][index]
issue << params[:issuesum][index]
issues << issue
end
end
rating = params[:rating]
node = Builder::XmlMarkup.new(:indent=>2)
attrs = {}
attrs[:incident] = @package.project.gsub(/.*:/,'')
xml = node.patchinfo(attrs) do |n|
if binaries
binaries.each do |binary|
if !binary.blank?
node.binary(binary)
end
end
end
node.packager packager
if issues
issues.each do |issue|
node.issue(issue[2], :tracker=>issue[1], :id=>issue[0])
end
end
node.category params[:category]
node.rating rating
node.summary params[:summary]
node.description params[:description].gsub("\r\n", "\n")
if reboot
node.reboot_needed
end
if relogin
node.relogin_needed
end
if zypp_restart_needed
node.zypp_restart_needed
end
if params[:block] == 'true'
node.stopped params[:block_reason]
end
end
begin
frontend.put_file( xml, :project => @project,
:package => @package, :filename => filename)
flash[:notice] = "Successfully edited #{@package}"
rescue Timeout::Error
flash[:error] = 'Timeout when saving file. Please try again.'
end
Webui::Package.free_cache( :all, :project => @project.name )
Webui::Package.free_cache( @package.name, :project => @project )
redirect_to :controller => 'patchinfo', :action => 'show',
:project => @project.name, :package => @package
end
if valid_params == false
@tracker = params[:tracker]
@packager = params[:packager]
@binaries = params[:selected_binaries]
@binarylist = params[:available_binaries]
@issues = Array.new
if params[:issueid]
params[:issueid].each_with_index do |new_issue, index|
issue = Array.new
issue << new_issue
issue << params[:issuetracker][index]
issue << params[:issueurl][index]
issue << params[:issuesum][index]
@issues << issue
end
end
@category = params[:category]
@rating = params[:rating]
@summary = params[:summary]
@description = params[:description]
@relogin = params[:relogin]
@reboot = params[:reboot]
@zypp_restart_needed = params[:zypp_restart_needed]
@block = params[:block]
@block_reason = params[:block_reason]
render :action => 'edit_patchinfo', :project => @project, :package => @package
end
rescue ActiveXML::Transport::ForbiddenError
flash[:error] = 'No permission to edit the patchinfo-file.'
redirect_to :action => 'show', :project => @project.name, :package => @package.name
end
end
def remove
begin
FrontendCompat.new.delete_package :project => @project, :package => @package
flash[:notice] = "'#{@package}' was removed successfully from project '#{@project}'"
Rails.cache.delete('%s_packages_mainpage' % @project)
Rails.cache.delete('%s_problem_packages' % @project)
Webui::Package.free_cache( :all, :project => @project.name )
Webui::Package.free_cache( @package, :project => @project )
Webui::Patchinfo.free_cache(:project=> @project, :package => @package)
rescue ActiveXML::Transport::Error => e
flash[:error] = e.summary
end
redirect_to :controller => 'project', :action => 'show', :project => @project
end
def delete_dialog
render_dialog
end
def valid_summary? name
name != nil and name =~ /^.{10,}$/m
end
def valid_description? name
name != nil and
name.length > params[:summary].length and name =~ /^.{50,}$/m
end
def new_tracker
#new_issues = list of new issues to add
new_issues = params[:issues]
#collection with all informations of the new issues
issue_collection = Array.new
error = String.new
invalid_format = String.new
invalid_tracker = String.new
new_issues.each do |new_issue|
#issue = collecting all informations of an new issue
issue = Array.new
if new_issue.starts_with? 'CVE-'
issue[0] = 'cve'
issue[1] = new_issue
else
issue = new_issue.split('#')
end
if issue.length > 1
begin
issueurl = Webui::IssueTracker.find(:name => issue[0])
if !issueurl.nil?
issueurl = issueurl.each('/issue-tracker/show-url').first.text
issueurl = issueurl.sub(/@@@/, issue[1])
issue << issueurl
get_issue_sum(issue[0], issue[1])
if !@error.nil?
invalid_format += "#{issue[0]} "
next
end
issue << @issuesum
issue_collection << issue
else
invalid_tracker += "#{issue[0]} is not a valid tracker.\n"
end
rescue ActiveXML::Transport::NotFoundError
invalid_format += "#{issue[0]} "
end
else
invalid_format += "#{issue[0]} "
end
end
error += "#{invalid_tracker}"
error += "#{invalid_format}has no valid format. (Correct formats are e.g. bnc#123456, CVE-1234-5678 and the string has to be a comma-separated list)" if !invalid_format.empty?
render :nothing => true, :json => { :error => error, :issues => issue_collection}
end
def get_issue_sum(tracker, issueid)
if !issueid.starts_with? 'CVE-'
bug = tracker + '#' + issueid
else
bug = issueid
end
path = "/issue_trackers/#{CGI.escape(tracker)}"
tracker_result = ActiveXML::Node.new(frontend.transport.direct_http(URI(path), :method => 'GET'))
regexp = '^'
regexp += tracker_result.regex.text
regexp += '$'
regexp = Regexp.new(regexp)
if bug.match(regexp)
begin
path = "/issue_trackers/#{CGI.escape(tracker)}/issues/#{CGI.escape(issueid)}"
result = ActiveXML::Node.new(frontend.transport.direct_http(URI(path), :method => 'GET'))
if result.summary.nil?
path = "/issue_trackers/#{CGI.escape(tracker)}/issues/#{CGI.escape(issueid)}?force_update=1"
result = ActiveXML::Node.new(frontend.transport.direct_http(URI(path), :method => 'GET'))
end
@issuesum = result.summary.text if result.summary
@issuesum = '' if !result.summary
@issuesum.gsub!(/\\|'/) { |c| '' }
# Add no summary if a connection to bugzilla doesn't work e.g. in the testsuite
rescue ActiveXML::Transport::Error
@issuesum = ''
end
else
@error = "#{bug} has no valid format"
end
end
private
def get_binaries
@binarylist = Array.new
@binary_list = Webui::Buildresult.find(:project => params[:project], :view => 'binarylist')
@binary_list.to_hash.elements('result') do |r|
r.elements('binarylist') do |l|
l.elements('binary') do |b|
@binarylist << b['filename'].sub(/-[^-]*-[^-]*.rpm$/, '' )
end
end
end
@binarylist.uniq!
@binarylist.delete('rpmlint.log')
@binarylist.delete('updateinfo.xml')
end
def require_all
required_parameters :project
@project = WebuiProject.find( params[:project] )
unless @project
flash[:error] = "Project not found: #{params[:project]}"
redirect_to :controller => 'project', :action => 'list_public'
return
end
end
def require_exists
unless params[:package].blank?
@package = Webui::Package.find( params[:package], :project => @project )
end
@file = Webui::Patchinfo.find(:project => @project.to_s, :package => @package.to_s)
opt = {:project => @project.name, :package => @package}
opt.store(:patchinfo, @patchinfo.to_s)
@patchinfo = Webui::Patchinfo.find(opt)
unless @file
flash[:error] = "Patchinfo not found for #{params[:project]}"
redirect_to :controller => 'package', :action => 'show', :project => @project, :package => @package and return
end
end
end