request.cgi: code style
parent
39b4db3462
commit
4a57251940
327
request.cgi
327
request.cgi
|
@ -1,6 +1,4 @@
|
|||
#!/usr/bin/perl -wT
|
||||
# -*- Mode: perl; indent-tabs-mode: nil -*-
|
||||
#
|
||||
# The contents of this file are subject to the Mozilla Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
|
@ -21,11 +19,6 @@
|
|||
# Contributor(s): Myk Melez <myk@mozilla.org>
|
||||
# Frédéric Buclin <LpSolit@gmail.com>
|
||||
|
||||
################################################################################
|
||||
# Script Initialization
|
||||
################################################################################
|
||||
|
||||
# Make it harder for us to do dangerous things in Perl.
|
||||
use strict;
|
||||
|
||||
use lib qw(. lib);
|
||||
|
@ -47,43 +40,39 @@ Bugzilla->switch_to_shadow_db;
|
|||
my $template = Bugzilla->template;
|
||||
my $action = $cgi->param('action') || '';
|
||||
|
||||
################################################################################
|
||||
# Main Body Execution
|
||||
################################################################################
|
||||
|
||||
my $fields;
|
||||
$fields->{'requester'}->{'type'} = 'single';
|
||||
$fields->{requester}->{type} = 'single';
|
||||
# If the user doesn't restrict his search to requests from the wind
|
||||
# (requestee ne '-'), include the requestee for completion.
|
||||
unless (defined $cgi->param('requestee')
|
||||
&& $cgi->param('requestee') eq '-')
|
||||
unless (defined $cgi->param('requestee') && $cgi->param('requestee') eq '-')
|
||||
{
|
||||
$fields->{'requestee'}->{'type'} = 'single';
|
||||
$fields->{requestee}->{type} = 'single';
|
||||
}
|
||||
|
||||
Bugzilla::User::match_field($fields);
|
||||
|
||||
if ($action eq 'queue') {
|
||||
if ($action eq 'queue')
|
||||
{
|
||||
queue();
|
||||
}
|
||||
else {
|
||||
else
|
||||
{
|
||||
my $flagtypes = get_flag_types();
|
||||
my @types = ('all', @$flagtypes);
|
||||
|
||||
my $vars = {};
|
||||
$vars->{'types'} = \@types;
|
||||
$vars->{'requests'} = {};
|
||||
|
||||
$vars->{types} = \@types;
|
||||
$vars->{requests} = {};
|
||||
my %components;
|
||||
foreach my $prod (@{$user->get_selectable_products}) {
|
||||
foreach my $comp (@{$prod->components}) {
|
||||
foreach my $prod (@{$user->get_selectable_products})
|
||||
{
|
||||
foreach my $comp (@{$prod->components})
|
||||
{
|
||||
$components{$comp->name} = 1;
|
||||
}
|
||||
}
|
||||
$vars->{'components'} = [ sort { $a cmp $b } keys %components ];
|
||||
|
||||
$vars->{components} = [ sort { $a cmp $b } keys %components ];
|
||||
$template->process('request/queue.html.tmpl', $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
exit;
|
||||
|
||||
|
@ -91,7 +80,8 @@ exit;
|
|||
# Functions
|
||||
################################################################################
|
||||
|
||||
sub queue {
|
||||
sub queue
|
||||
{
|
||||
my $cgi = Bugzilla->cgi;
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $template = Bugzilla->template;
|
||||
|
@ -102,64 +92,44 @@ sub queue {
|
|||
my $status = validateStatus($cgi->param('status'));
|
||||
my $form_group = validateGroup($cgi->param('group'));
|
||||
|
||||
my $query =
|
||||
# Select columns describing each flag, the bug/attachment on which
|
||||
# it has been set, who set it, and of whom they are requesting it.
|
||||
" SELECT flags.id, flagtypes.name,
|
||||
flags.status,
|
||||
flags.bug_id, bugs.short_desc,
|
||||
products.name, components.name,
|
||||
flags.attach_id, attachments.description,
|
||||
requesters.realname, requesters.login_name,
|
||||
requestees.realname, requestees.login_name,
|
||||
" . $dbh->sql_date_format('flags.modification_date', '%Y.%m.%d %H:%i') .
|
||||
# Use the flags and flagtypes tables for information about the flags,
|
||||
# the bugs and attachments tables for target info, the profiles tables
|
||||
# for setter and requestee info, the products/components tables
|
||||
# so we can display product and component names, and the bug_group_map
|
||||
# table to help us weed out secure bugs to which the user should not have
|
||||
# access.
|
||||
"
|
||||
FROM flags
|
||||
LEFT JOIN attachments
|
||||
ON flags.attach_id = attachments.attach_id
|
||||
INNER JOIN flagtypes
|
||||
ON flags.type_id = flagtypes.id
|
||||
INNER JOIN profiles AS requesters
|
||||
ON flags.setter_id = requesters.userid
|
||||
LEFT JOIN profiles AS requestees
|
||||
ON flags.requestee_id = requestees.userid
|
||||
INNER JOIN bugs
|
||||
ON flags.bug_id = bugs.bug_id
|
||||
INNER JOIN products
|
||||
ON bugs.product_id = products.id
|
||||
INNER JOIN components
|
||||
ON bugs.component_id = components.id
|
||||
LEFT JOIN bug_group_map AS bgmap
|
||||
ON bgmap.bug_id = bugs.bug_id
|
||||
AND bgmap.group_id NOT IN (" .
|
||||
$user->groups_as_string . ")
|
||||
LEFT JOIN cc AS ccmap
|
||||
ON ccmap.who = $userid
|
||||
AND ccmap.bug_id = bugs.bug_id
|
||||
" .
|
||||
my $query = " SELECT flags.id, flagtypes.name, flags.status,".
|
||||
" flags.bug_id, bugs.short_desc, products.name, components.name,".
|
||||
" flags.attach_id, attachments.description, requesters.realname,".
|
||||
" requesters.login_name, requestees.realname, requestees.login_name,".
|
||||
$dbh->sql_date_format('flags.modification_date', '%Y.%m.%d %H:%i').
|
||||
# Use the flags and flagtypes tables for information about the flags,
|
||||
# the bugs and attachments tables for target info, the profiles tables
|
||||
# for setter and requestee info, the products/components tables
|
||||
# so we can display product and component names, and the bug_group_map
|
||||
# table to help us weed out secure bugs to which the user should not have
|
||||
# access.
|
||||
" FROM flags".
|
||||
" LEFT JOIN attachments ON flags.attach_id = attachments.attach_id".
|
||||
" INNER JOIN flagtypes ON flags.type_id = flagtypes.id".
|
||||
" INNER JOIN profiles AS requesters ON flags.setter_id = requesters.userid".
|
||||
" LEFT JOIN profiles AS requestees ON flags.requestee_id = requestees.userid".
|
||||
" INNER JOIN bugs ON flags.bug_id = bugs.bug_id".
|
||||
" INNER JOIN products ON bugs.product_id = products.id".
|
||||
" INNER JOIN components ON bugs.component_id = components.id".
|
||||
" LEFT JOIN bug_group_map AS bgmap ON bgmap.bug_id = bugs.bug_id".
|
||||
" AND bgmap.group_id NOT IN (" . $user->groups_as_string . ")".
|
||||
" LEFT JOIN cc AS ccmap ON ccmap.who = $userid AND ccmap.bug_id = bugs.bug_id".
|
||||
# Weed out bugs the user does not have access to
|
||||
" WHERE (bgmap.group_id IS NULL OR (ccmap.who IS NOT NULL AND cclist_accessible=1)".
|
||||
" OR (bugs.reporter = $userid AND bugs.reporter_accessible=1)".
|
||||
" OR (bugs.assigned_to = $userid) ".
|
||||
(Bugzilla->get_field('qa_contact')->enabled ? " OR (bugs.qa_contact=$userid))" : ")");
|
||||
|
||||
# Weed out bug the user does not have access to
|
||||
" WHERE ((bgmap.group_id IS NULL) OR
|
||||
(ccmap.who IS NOT NULL AND cclist_accessible = 1) OR
|
||||
(bugs.reporter = $userid AND bugs.reporter_accessible = 1) OR
|
||||
(bugs.assigned_to = $userid) " .
|
||||
(Bugzilla->get_field('qa_contact')->enabled ? "OR
|
||||
(bugs.qa_contact = $userid))" : ")");
|
||||
|
||||
unless ($user->is_insider) {
|
||||
$query .= " AND (attachments.attach_id IS NULL
|
||||
OR attachments.isprivate = 0
|
||||
OR attachments.submitter_id = $userid)";
|
||||
unless ($user->is_insider)
|
||||
{
|
||||
$query .= " AND (attachments.attach_id IS NULL".
|
||||
" OR attachments.isprivate=0 OR attachments.submitter_id=$userid)";
|
||||
}
|
||||
|
||||
# Limit query to pending requests.
|
||||
$query .= " AND flags.status = '?' " unless $status;
|
||||
$query .= " AND flags.status = '?'" unless $status;
|
||||
|
||||
# The set of criteria by which we filter records to display in the queue.
|
||||
my @criteria = ();
|
||||
|
@ -170,101 +140,117 @@ sub queue {
|
|||
# need to display a "status" column in the report because the value for that
|
||||
# column will always be the same.
|
||||
my @excluded_columns = ();
|
||||
|
||||
# Filter requests by status: "pending", "granted", "denied", "all"
|
||||
|
||||
# Filter requests by status: "pending", "granted", "denied", "all"
|
||||
# (which means any), or "fulfilled" (which means "granted" or "denied").
|
||||
if ($status) {
|
||||
if ($status eq "+-") {
|
||||
push(@criteria, "flags.status IN ('+', '-')");
|
||||
push(@excluded_columns, 'status') unless $cgi->param('do_union');
|
||||
if ($status)
|
||||
{
|
||||
if ($status eq "+-")
|
||||
{
|
||||
push @criteria, "flags.status IN ('+', '-')";
|
||||
push @excluded_columns, 'status' unless $cgi->param('do_union');
|
||||
}
|
||||
elsif ($status ne "all") {
|
||||
push(@criteria, "flags.status = '$status'");
|
||||
push(@excluded_columns, 'status') unless $cgi->param('do_union');
|
||||
elsif ($status ne "all")
|
||||
{
|
||||
push @criteria, "flags.status = '$status'";
|
||||
push @excluded_columns, 'status' unless $cgi->param('do_union');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# Filter results by exact email address of requester or requestee.
|
||||
if (defined $cgi->param('requester') && $cgi->param('requester') ne "") {
|
||||
if (defined $cgi->param('requester') && $cgi->param('requester') ne "")
|
||||
{
|
||||
my $requester = $dbh->quote($cgi->param('requester'));
|
||||
trick_taint($requester); # Quoted above
|
||||
push(@criteria, $dbh->sql_istrcmp('requesters.login_name', $requester));
|
||||
push(@excluded_columns, 'requester') unless $cgi->param('do_union');
|
||||
}
|
||||
if (defined $cgi->param('requestee') && $cgi->param('requestee') ne "") {
|
||||
if ($cgi->param('requestee') ne "-") {
|
||||
if (defined $cgi->param('requestee') && $cgi->param('requestee') ne "")
|
||||
{
|
||||
if ($cgi->param('requestee') ne "-")
|
||||
{
|
||||
my $requestee = $dbh->quote($cgi->param('requestee'));
|
||||
trick_taint($requestee); # Quoted above
|
||||
push(@criteria, $dbh->sql_istrcmp('requestees.login_name',
|
||||
$requestee));
|
||||
push @criteria, $dbh->sql_istrcmp('requestees.login_name', $requestee);
|
||||
}
|
||||
else { push(@criteria, "flags.requestee_id IS NULL") }
|
||||
push(@excluded_columns, 'requestee') unless $cgi->param('do_union');
|
||||
else
|
||||
{
|
||||
push @criteria, "flags.requestee_id IS NULL";
|
||||
}
|
||||
push @excluded_columns, 'requestee' unless $cgi->param('do_union');
|
||||
}
|
||||
|
||||
|
||||
# Filter results by exact product or component.
|
||||
if (defined $cgi->param('product') && $cgi->param('product') ne "") {
|
||||
if (defined $cgi->param('product') && $cgi->param('product') ne "")
|
||||
{
|
||||
my $product = Bugzilla::Product->check(scalar $cgi->param('product'));
|
||||
push(@criteria, "bugs.product_id = " . $product->id);
|
||||
push(@excluded_columns, 'product') unless $cgi->param('do_union');
|
||||
if (defined $cgi->param('component') && $cgi->param('component') ne "") {
|
||||
my $component = Bugzilla::Component->check({ product => $product,
|
||||
name => scalar $cgi->param('component') });
|
||||
push(@criteria, "bugs.component_id = " . $component->id);
|
||||
push(@excluded_columns, 'component') unless $cgi->param('do_union');
|
||||
push @criteria, "bugs.product_id = " . $product->id;
|
||||
push @excluded_columns, 'product' unless $cgi->param('do_union');
|
||||
if (defined $cgi->param('component') && $cgi->param('component') ne "")
|
||||
{
|
||||
my $component = Bugzilla::Component->check({
|
||||
product => $product, name => scalar $cgi->param('component')
|
||||
});
|
||||
push @criteria, "bugs.component_id = " . $component->id;
|
||||
push @excluded_columns, 'component' unless $cgi->param('do_union');
|
||||
}
|
||||
}
|
||||
|
||||
# Filter results by flag types.
|
||||
my $form_type = $cgi->param('type');
|
||||
if (defined $form_type && !grep($form_type eq $_, ("", "all"))) {
|
||||
if (defined $form_type && !grep($form_type eq $_, ("", "all")))
|
||||
{
|
||||
# Check if any matching types are for attachments. If not, don't show
|
||||
# the attachment column in the report.
|
||||
my $has_attachment_type =
|
||||
Bugzilla::FlagType::count({ 'name' => $form_type,
|
||||
'target_type' => 'attachment' });
|
||||
|
||||
if (!$has_attachment_type) { push(@excluded_columns, 'attachment') }
|
||||
|
||||
my $has_attachment_type = Bugzilla::FlagType::count({
|
||||
name => $form_type, target_type => 'attachment'
|
||||
});
|
||||
if (!$has_attachment_type)
|
||||
{
|
||||
push @excluded_columns, 'attachment';
|
||||
}
|
||||
my $quoted_form_type = $dbh->quote($form_type);
|
||||
trick_taint($quoted_form_type); # Already SQL quoted
|
||||
push(@criteria, "flagtypes.name = " . $quoted_form_type);
|
||||
push(@excluded_columns, 'type') unless $cgi->param('do_union');
|
||||
push @criteria, "flagtypes.name = " . $quoted_form_type;
|
||||
push @excluded_columns, 'type' unless $cgi->param('do_union');
|
||||
}
|
||||
|
||||
# Add the criteria to the query. We do an intersection by default
|
||||
# but do a union if the "do_union" URL parameter (for which there is no UI
|
||||
|
||||
# Add the criteria to the query. We do an intersection by default
|
||||
# but do a union if the "do_union" URL parameter (for which there is no UI
|
||||
# because it's an advanced feature that people won't usually want) is true.
|
||||
my $and_or = $cgi->param('do_union') ? " OR " : " AND ";
|
||||
$query .= " AND (" . join($and_or, @criteria) . ") " if scalar(@criteria);
|
||||
|
||||
$query .= " AND (" . join($and_or, @criteria) . ") " if scalar @criteria;
|
||||
|
||||
# Group the records by flag ID so we don't get multiple rows of data
|
||||
# for each flag. This is only necessary because of the code that
|
||||
# removes flags on bugs the user is unauthorized to access.
|
||||
$query .= ' ' . $dbh->sql_group_by('flags.id',
|
||||
'flagtypes.name, flags.status, flags.bug_id, bugs.short_desc,
|
||||
products.name, components.name, flags.attach_id,
|
||||
attachments.description, requesters.realname,
|
||||
requesters.login_name, requestees.realname,
|
||||
requestees.login_name, flags.modification_date,
|
||||
cclist_accessible, bugs.reporter, bugs.reporter_accessible,
|
||||
bugs.assigned_to');
|
||||
$query .= ' GROUP BY flags.id, flagtypes.name, flags.status, flags.bug_id,'.
|
||||
' bugs.short_desc, products.name, components.name, flags.attach_id,'.
|
||||
' attachments.description, requesters.realname,'.
|
||||
' requesters.login_name, requestees.realname,'.
|
||||
' requestees.login_name, flags.modification_date,'.
|
||||
' cclist_accessible, bugs.reporter, bugs.reporter_accessible,'.
|
||||
' bugs.assigned_to';
|
||||
|
||||
# Group the records, in other words order them by the group column
|
||||
# so the loop in the display template can break them up into separate
|
||||
# tables every time the value in the group column changes.
|
||||
|
||||
$form_group ||= "requestee";
|
||||
if ($form_group eq "requester") {
|
||||
if ($form_group eq "requester")
|
||||
{
|
||||
$query .= " ORDER BY requesters.realname, requesters.login_name";
|
||||
}
|
||||
elsif ($form_group eq "requestee") {
|
||||
elsif ($form_group eq "requestee")
|
||||
{
|
||||
$query .= " ORDER BY requestees.realname, requestees.login_name";
|
||||
}
|
||||
elsif ($form_group eq "category") {
|
||||
elsif ($form_group eq "category")
|
||||
{
|
||||
$query .= " ORDER BY products.name, components.name";
|
||||
}
|
||||
elsif ($form_group eq "type") {
|
||||
elsif ($form_group eq "type")
|
||||
{
|
||||
$query .= " ORDER BY flagtypes.name";
|
||||
}
|
||||
|
||||
|
@ -272,38 +258,39 @@ sub queue {
|
|||
$query .= " , flags.modification_date";
|
||||
|
||||
# Pass the query to the template for use when debugging this script.
|
||||
$vars->{'query'} = $query;
|
||||
$vars->{'debug'} = $cgi->param('debug') ? 1 : 0;
|
||||
|
||||
$vars->{query} = $query;
|
||||
$vars->{debug} = $cgi->param('debug') ? 1 : 0;
|
||||
|
||||
my $results = $dbh->selectall_arrayref($query);
|
||||
my @requests = ();
|
||||
foreach my $result (@$results) {
|
||||
foreach my $result (@$results)
|
||||
{
|
||||
my @data = @$result;
|
||||
my $request = {
|
||||
'id' => $data[0] ,
|
||||
'type' => $data[1] ,
|
||||
'status' => $data[2] ,
|
||||
'bug_id' => $data[3] ,
|
||||
'bug_summary' => $data[4] ,
|
||||
'category' => "$data[5]: $data[6]" ,
|
||||
'attach_id' => $data[7] ,
|
||||
'attach_summary' => $data[8] ,
|
||||
'requester' => ($data[9] ? "$data[9] <$data[10]>" : $data[10]) ,
|
||||
'requestee' => ($data[11] ? "$data[11] <$data[12]>" : $data[12]) ,
|
||||
'created' => $data[13]
|
||||
id => $data[0],
|
||||
type => $data[1],
|
||||
status => $data[2],
|
||||
bug_id => $data[3],
|
||||
bug_summary => $data[4],
|
||||
category => "$data[5]: $data[6]",
|
||||
attach_id => $data[7],
|
||||
attach_summary => $data[8],
|
||||
requester => ($data[9] ? "$data[9] <$data[10]>" : $data[10]),
|
||||
requestee => ($data[11] ? "$data[11] <$data[12]>" : $data[12]),
|
||||
created => $data[13],
|
||||
};
|
||||
push(@requests, $request);
|
||||
push @requests, $request;
|
||||
}
|
||||
|
||||
# Get a list of request type names to use in the filter form.
|
||||
my @types = ("all");
|
||||
my $flagtypes = get_flag_types();
|
||||
push(@types, @$flagtypes);
|
||||
push @types, @$flagtypes;
|
||||
|
||||
$vars->{'excluded_columns'} = \@excluded_columns;
|
||||
$vars->{'group_field'} = $form_group;
|
||||
$vars->{'requests'} = \@requests;
|
||||
$vars->{'types'} = \@types;
|
||||
$vars->{excluded_columns} = \@excluded_columns;
|
||||
$vars->{group_field} = $form_group;
|
||||
$vars->{requests} = \@requests;
|
||||
$vars->{types} = \@types;
|
||||
$vars->{selected_requester} = $cgi->param('requester');
|
||||
$vars->{selected_product} = $cgi->param('product');
|
||||
$vars->{selected_component} = $cgi->param('component');
|
||||
|
@ -312,52 +299,52 @@ sub queue {
|
|||
$vars->{selected_group} = $cgi->param('group');
|
||||
|
||||
my %components;
|
||||
foreach my $prod (@{$user->get_selectable_products}) {
|
||||
foreach my $comp (@{$prod->components}) {
|
||||
foreach my $prod (@{$user->get_selectable_products})
|
||||
{
|
||||
foreach my $comp (@{$prod->components})
|
||||
{
|
||||
$components{$comp->name} = 1;
|
||||
}
|
||||
}
|
||||
$vars->{'components'} = [ sort { $a cmp $b } keys %components ];
|
||||
$vars->{components} = [ sort { $a cmp $b } keys %components ];
|
||||
|
||||
# Generate and return the UI (HTML page) from the appropriate template.
|
||||
$template->process("request/queue.html.tmpl", $vars)
|
||||
|| ThrowTemplateError($template->error());
|
||||
|| ThrowTemplateError($template->error());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Data Validation / Security Authorization
|
||||
################################################################################
|
||||
|
||||
sub validateStatus {
|
||||
sub validateStatus
|
||||
{
|
||||
my $status = shift;
|
||||
return if !defined $status;
|
||||
|
||||
grep($status eq $_, qw(? +- + - all))
|
||||
|| ThrowCodeError("flag_status_invalid",
|
||||
{ status => $status });
|
||||
|| ThrowCodeError("flag_status_invalid", { status => $status });
|
||||
trick_taint($status);
|
||||
return $status;
|
||||
}
|
||||
|
||||
sub validateGroup {
|
||||
sub validateGroup
|
||||
{
|
||||
my $group = shift;
|
||||
return if !defined $group;
|
||||
|
||||
grep($group eq $_, qw(requester requestee category type))
|
||||
|| ThrowCodeError("request_queue_group_invalid",
|
||||
{ group => $group });
|
||||
|| ThrowCodeError("request_queue_group_invalid", { group => $group });
|
||||
trick_taint($group);
|
||||
return $group;
|
||||
}
|
||||
|
||||
# Returns all flag types which have at least one flag of this type.
|
||||
# If a flag type is inactive but still has flags, we want it.
|
||||
sub get_flag_types {
|
||||
sub get_flag_types
|
||||
{
|
||||
my $dbh = Bugzilla->dbh;
|
||||
my $flag_types = $dbh->selectcol_arrayref('SELECT DISTINCT name
|
||||
FROM flagtypes
|
||||
WHERE flagtypes.id IN
|
||||
(SELECT DISTINCT type_id FROM flags)
|
||||
ORDER BY name');
|
||||
my $flag_types = $dbh->selectcol_arrayref(
|
||||
'SELECT DISTINCT name FROM flagtypes'.
|
||||
' WHERE flagtypes.id IN (SELECT DISTINCT type_id FROM flags) ORDER BY name'
|
||||
);
|
||||
return $flag_types;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue