summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
authorDavid Lawrence <dlawrence@mozilla.com>2011-10-05 00:25:23 +0200
committerDavid Lawrence <dlawrence@mozilla.com>2011-10-05 00:25:23 +0200
commit57584dc4744fea59833ef355f7513690d246c70f (patch)
tree805f2b2941eca17eaf97263165d11d9e676ad9d1 /Bugzilla
parent785580c6c290b93fe25868cfbb5d4e300749de62 (diff)
downloadbugzilla-57584dc4744fea59833ef355f7513690d246c70f.tar.gz
bugzilla-57584dc4744fea59833ef355f7513690d246c70f.tar.xz
more porting work
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/Bug.pm43
-rw-r--r--Bugzilla/BugMail.pm7
-rw-r--r--Bugzilla/Component.pm6
-rw-r--r--Bugzilla/Config/Advanced.pm6
-rw-r--r--Bugzilla/Constants.pm26
-rw-r--r--Bugzilla/Error.pm40
-rw-r--r--Bugzilla/Field.pm167
-rw-r--r--Bugzilla/Group.pm5
-rw-r--r--Bugzilla/Install.pm2
-rw-r--r--Bugzilla/Install/DB.pm28
-rw-r--r--Bugzilla/Install/Filesystem.pm14
-rw-r--r--Bugzilla/Product.pm5
-rw-r--r--Bugzilla/Search.pm3
-rw-r--r--Bugzilla/Search/Quicksearch.pm3
-rw-r--r--Bugzilla/Template.pm13
-rw-r--r--Bugzilla/Token.pm2
-rw-r--r--Bugzilla/User.pm7
-rw-r--r--Bugzilla/WebService/Bug.pm47
-rw-r--r--Bugzilla/WebService/User.pm4
19 files changed, 330 insertions, 98 deletions
diff --git a/Bugzilla/Bug.pm b/Bugzilla/Bug.pm
index 175bcd050..26d2a89f3 100644
--- a/Bugzilla/Bug.pm
+++ b/Bugzilla/Bug.pm
@@ -1628,6 +1628,14 @@ sub _check_groups {
: $params->{product};
my %add_groups;
+ # BMO: Allow extension to add groups before the
+ # real checks are done.
+ Bugzilla::Hook::process('bug_check_groups', {
+ product => $product,
+ group_names => $group_names,
+ add_groups => \%add_groups
+ });
+
# In email or WebServices, when the "groups" item actually
# isn't specified, then just add the default groups.
if (!defined $group_names) {
@@ -1646,7 +1654,12 @@ sub _check_groups {
foreach my $name (@$group_names) {
my $group = Bugzilla::Group->check_no_disclose({ %args, name => $name });
- if (!$product->group_is_settable($group)) {
+ # BMO: Do not check group_is_settable if the group is
+ # already added, such as from the extension hook. group_is_settable
+ # will reject any group the user is not currently in.
+ if (!$add_groups{$group->id}
+ && !$product->group_is_settable($group))
+ {
ThrowUserError('group_restriction_not_allowed', { %args, name => $name });
}
$add_groups{$group->id} = $group;
@@ -1655,7 +1668,7 @@ sub _check_groups {
# Now enforce mandatory groups.
$add_groups{$_->id} = $_ foreach @{ $product->groups_mandatory };
-
+
my @add_groups = values %add_groups;
return \@add_groups;
}
@@ -3244,15 +3257,37 @@ sub depends_on_obj {
return $self->{depends_on_obj};
}
+sub duplicates {
+ my $self = shift;
+ return $self->{duplicates} if exists $self->{duplicates};
+ return [] if $self->{error};
+ $self->{duplicates} = Bugzilla::Bug->new_from_list($self->duplicate_ids);
+ return $self->{duplicates};
+}
+
+sub duplicate_ids {
+ my $self = shift;
+ return $self->{duplicate_ids} if exists $self->{duplicate_ids};
+ return [] if $self->{error};
+
+ my $dbh = Bugzilla->dbh;
+ $self->{duplicate_ids} =
+ $dbh->selectcol_arrayref('SELECT dupe FROM duplicates WHERE dupe_of = ?',
+ undef, $self->id);
+ return $self->{duplicate_ids};
+}
+
sub flag_types {
- my ($self) = @_;
+ my ($self, $params) = @_;
+ $params ||= {};
return $self->{'flag_types'} if exists $self->{'flag_types'};
return [] if $self->{'error'};
my $vars = { target_type => 'bug',
product_id => $self->{product_id},
component_id => $self->{component_id},
- bug_id => $self->bug_id };
+ bug_id => $self->bug_id,
+ %$params };
$self->{'flag_types'} = Bugzilla::Flag->_flag_types($vars);
return $self->{'flag_types'};
diff --git a/Bugzilla/BugMail.pm b/Bugzilla/BugMail.pm
index 55eeeab25..c637c3a66 100644
--- a/Bugzilla/BugMail.pm
+++ b/Bugzilla/BugMail.pm
@@ -267,7 +267,12 @@ sub Send {
}
# Make sure the user isn't in the nomail list, and the dep check passed.
- if ($user->email_enabled && $dep_ok) {
+ # Upstreaming: when we port to 4.2, check the login names of the
+ # user objects in the bugmail_recipients hook instead.
+ if ($user->email_enabled && $dep_ok &&
+ ($user->login !~ /bugs$/) &&
+ ($user->login !~ /\.tld$/))
+ {
# OK, OK, if we must. Email the user.
$sent_mail = sendMail(
{ to => $user,
diff --git a/Bugzilla/Component.pm b/Bugzilla/Component.pm
index dc3cc1b9e..ad5166a0f 100644
--- a/Bugzilla/Component.pm
+++ b/Bugzilla/Component.pm
@@ -371,11 +371,13 @@ sub default_qa_contact {
}
sub flag_types {
- my $self = shift;
+ my ($self, $params) = @_;
+ $params ||= {};
if (!defined $self->{'flag_types'}) {
my $flagtypes = Bugzilla::FlagType::match({ product_id => $self->product_id,
- component_id => $self->id });
+ component_id => $self->id,
+ %$params });
$self->{'flag_types'} = {};
$self->{'flag_types'}->{'bug'} =
diff --git a/Bugzilla/Config/Advanced.pm b/Bugzilla/Config/Advanced.pm
index faab6bbbd..f5653ee86 100644
--- a/Bugzilla/Config/Advanced.pm
+++ b/Bugzilla/Config/Advanced.pm
@@ -62,6 +62,12 @@ use constant get_param_list => (
default => 'off',
checker => \&check_multi
},
+
+ {
+ name => 'disable_bug_updates',
+ type => 'b',
+ default => 0
+ },
);
1;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 5c9fecc57..62836d8cc 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -255,7 +255,8 @@ use constant AUTH_NO_SUCH_USER => 5;
use constant AUTH_LOCKOUT => 6;
# The minimum length a password must have.
-use constant USER_PASSWORD_MIN_LENGTH => 6;
+# BMO uses 8 characters.
+use constant USER_PASSWORD_MIN_LENGTH => 8;
use constant LOGIN_OPTIONAL => 0;
use constant LOGIN_NORMAL => 1;
@@ -424,8 +425,8 @@ use constant MAX_LOGIN_ATTEMPTS => 5;
use constant LOGIN_LOCKOUT_INTERVAL => 30;
# The maximum number of seconds the Strict-Transport-Security header
-# will remain valid. Default is one week.
-use constant MAX_STS_AGE => 604800;
+# will remain valid. BMO uses one month.
+use constant MAX_STS_AGE => 2629744;
# Protocols which are considered as safe.
use constant SAFE_PROTOCOLS => ('afs', 'cid', 'ftp', 'gopher', 'http', 'https',
@@ -438,15 +439,16 @@ use constant LEGAL_CONTENT_TYPES => ('application', 'audio', 'image', 'message',
use constant contenttypes =>
{
- "html"=> "text/html" ,
- "rdf" => "application/rdf+xml" ,
- "atom"=> "application/atom+xml" ,
- "xml" => "application/xml" ,
- "js" => "application/x-javascript" ,
- "json"=> "application/json" ,
- "csv" => "text/csv" ,
- "png" => "image/png" ,
- "ics" => "text/calendar" ,
+ "html" => "text/html" ,
+ "rdf" => "application/rdf+xml" ,
+ "atom" => "application/atom+xml" ,
+ "xml" => "application/xml" ,
+ "dtd" => "application/xml-dtd" ,
+ "js" => "application/x-javascript" ,
+ "json" => "application/json" ,
+ "csv" => "text/csv" ,
+ "png" => "image/png" ,
+ "ics" => "text/calendar" ,
};
# Usage modes. Default USAGE_MODE_BROWSER. Use with Bugzilla->usage_mode.
diff --git a/Bugzilla/Error.pm b/Bugzilla/Error.pm
index 395cc0dc9..17a7a948a 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -26,7 +26,7 @@ package Bugzilla::Error;
use strict;
use base qw(Exporter);
-@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError);
+@Bugzilla::Error::EXPORT = qw(ThrowCodeError ThrowTemplateError ThrowUserError ThrowErrorPage);
use Bugzilla::Constants;
use Bugzilla::WebService::Constants;
@@ -212,6 +212,44 @@ END
exit;
}
+sub ThrowErrorPage {
+ # BMO customisation for bug 659231
+ my ($template_name, $message) = @_;
+
+ my $dbh = Bugzilla->dbh;
+ $dbh->bz_rollback_transaction() if $dbh->bz_in_transaction();
+
+ if (Bugzilla->error_mode == ERROR_MODE_DIE) {
+ die("error: $message");
+ }
+
+ if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT
+ || Bugzilla->error_mode == ERROR_MODE_JSON_RPC)
+ {
+ my $code = ERROR_UNKNOWN_TRANSIENT;
+ if (Bugzilla->error_mode == ERROR_MODE_DIE_SOAP_FAULT) {
+ die SOAP::Fault->faultcode($code)->faultstring($message);
+ } else {
+ my $server = Bugzilla->_json_server;
+ $server->raise_error(code => 100000 + $code,
+ message => $message,
+ id => $server->{_bz_request_id},
+ version => $server->version);
+ die if _in_eval();
+ $server->response($server->error_response_header);
+ }
+ } else {
+ my $cgi = Bugzilla->cgi;
+ my $template = Bugzilla->template;
+ my $vars = {};
+ $vars->{message} = $message;
+ print $cgi->header();
+ $template->process($template_name, $vars)
+ || ThrowTemplateError($template->error());
+ exit;
+ }
+}
+
1;
__END__
diff --git a/Bugzilla/Field.pm b/Bugzilla/Field.pm
index 219172094..e47e92231 100644
--- a/Bugzilla/Field.pm
+++ b/Bugzilla/Field.pm
@@ -78,6 +78,8 @@ use Bugzilla::Constants;
use Bugzilla::Error;
use Bugzilla::Util;
use List::MoreUtils qw(any);
+use Bugzilla::Config qw(SetParam write_params);
+use Bugzilla::Hook;
use Scalar::Util qw(blessed);
@@ -916,53 +918,64 @@ sub remove_from_db {
ThrowUserError('customfield_not_obsolete', {'name' => $self->name });
}
- $dbh->bz_start_transaction();
+ # BMO: disable bug updates during field creation
+ # using an eval as try/finally
+ eval {
+ SetParam('disable_bug_updates', 1);
+ write_params();
- # Check to see if bug activity table has records (should be fast with index)
- my $has_activity = $dbh->selectrow_array("SELECT COUNT(*) FROM bugs_activity
- WHERE fieldid = ?", undef, $self->id);
- if ($has_activity) {
- ThrowUserError('customfield_has_activity', {'name' => $name });
- }
+ $dbh->bz_start_transaction();
+
+ # Check to see if bug activity table has records (should be fast with index)
+ my $has_activity = $dbh->selectrow_array("SELECT COUNT(*) FROM bugs_activity
+ WHERE fieldid = ?", undef, $self->id);
+ if ($has_activity) {
+ ThrowUserError('customfield_has_activity', {'name' => $name });
+ }
- # Check to see if bugs table has records (slow)
- my $bugs_query = "";
+ # Check to see if bugs table has records (slow)
+ my $bugs_query = "";
- if ($self->type == FIELD_TYPE_MULTI_SELECT) {
- $bugs_query = "SELECT COUNT(*) FROM bug_$name";
- }
- else {
- $bugs_query = "SELECT COUNT(*) FROM bugs WHERE $name IS NOT NULL";
- if ($self->type != FIELD_TYPE_BUG_ID && $self->type != FIELD_TYPE_DATETIME) {
- $bugs_query .= " AND $name != ''";
+ if ($self->type == FIELD_TYPE_MULTI_SELECT) {
+ $bugs_query = "SELECT COUNT(*) FROM bug_$name";
}
- # Ignore the default single select value
- if ($self->type == FIELD_TYPE_SINGLE_SELECT) {
- $bugs_query .= " AND $name != '---'";
+ else {
+ $bugs_query = "SELECT COUNT(*) FROM bugs WHERE $name IS NOT NULL";
+ if ($self->type != FIELD_TYPE_BUG_ID && $self->type != FIELD_TYPE_DATETIME) {
+ $bugs_query .= " AND $name != ''";
+ }
+ # Ignore the default single select value
+ if ($self->type == FIELD_TYPE_SINGLE_SELECT) {
+ $bugs_query .= " AND $name != '---'";
+ }
}
- }
- my $has_bugs = $dbh->selectrow_array($bugs_query);
- if ($has_bugs) {
- ThrowUserError('customfield_has_contents', {'name' => $name });
- }
+ my $has_bugs = $dbh->selectrow_array($bugs_query);
+ if ($has_bugs) {
+ ThrowUserError('customfield_has_contents', {'name' => $name });
+ }
- # Once we reach here, we should be OK to delete.
- $dbh->do('DELETE FROM fielddefs WHERE id = ?', undef, $self->id);
+ # Once we reach here, we should be OK to delete.
+ $dbh->do('DELETE FROM fielddefs WHERE id = ?', undef, $self->id);
- my $type = $self->type;
+ my $type = $self->type;
- # the values for multi-select are stored in a seperate table
- if ($type != FIELD_TYPE_MULTI_SELECT) {
- $dbh->bz_drop_column('bugs', $name);
- }
+ # the values for multi-select are stored in a seperate table
+ if ($type != FIELD_TYPE_MULTI_SELECT) {
+ $dbh->bz_drop_column('bugs', $name);
+ }
- if ($self->is_select) {
- # Delete the table that holds the legal values for this field.
- $dbh->bz_drop_field_tables($self);
- }
+ if ($self->is_select) {
+ # Delete the table that holds the legal values for this field.
+ $dbh->bz_drop_field_tables($self);
+ }
- $dbh->bz_commit_transaction()
+ $dbh->bz_commit_transaction();
+ };
+ my $error = "$@";
+ SetParam('disable_bug_updates', 0);
+ write_params();
+ die $error if $error;
}
=pod
@@ -1014,36 +1027,72 @@ sub create {
# the parameter isn't sent to create().
$params->{sortkey} = undef if !exists $params->{sortkey};
$params->{type} ||= 0;
-
- $dbh->bz_start_transaction();
- $class->check_required_create_fields(@_);
- my $field_values = $class->run_create_validators($params);
- my $visibility_values = delete $field_values->{visibility_values};
- my $field = $class->insert_create_data($field_values);
-
- $field->set_visibility_values($visibility_values);
- $field->_update_visibility_values();
-
- $dbh->bz_commit_transaction();
- if ($field->custom) {
- my $name = $field->name;
- my $type = $field->type;
- if (SQL_DEFINITIONS->{$type}) {
- # Create the database column that stores the data for this field.
- $dbh->bz_add_column('bugs', $name, SQL_DEFINITIONS->{$type});
+ # BMO: disable bug updates during field creation
+ # using an eval as try/finally
+ my $field;
+ eval {
+ if ($params->{'custom'}) {
+ SetParam('disable_bug_updates', 1);
+ write_params();
}
- if ($field->is_select) {
- # Create the table that holds the legal values for this field.
- $dbh->bz_add_field_tables($field);
+ # Purpose: if the field is active in the fields list before all of the
+ # data structures are created, anything accessing Bug.pm will crash. So
+ # stash a copy of the intended obsolete value for later and force it
+ # to be obsolete on initial creation.
+ # Upstreaming: https://bugzilla.mozilla.org/show_bug.cgi?id=531243
+ my $original_obsolete;
+ if ($params->{'custom'}) {
+ $original_obsolete = $params->{'obsolete'};
+ $params->{'obsolete'} = 1;
}
- if ($type == FIELD_TYPE_SINGLE_SELECT) {
- # Insert a default value of "---" into the legal values table.
- $dbh->do("INSERT INTO $name (value) VALUES ('---')");
+ $dbh->bz_start_transaction();
+ $class->check_required_create_fields(@_);
+ my $field_values = $class->run_create_validators($params);
+ my $visibility_values = delete $field_values->{visibility_values};
+ my $field = $class->insert_create_data($field_values);
+
+ $field->set_visibility_values($visibility_values);
+ $field->_update_visibility_values();
+
+ $dbh->bz_commit_transaction();
+
+ if ($field->custom) {
+ # Restore the obsolete value that got stashed earlier (in memory)
+ $field->set_obsolete($original_obsolete);
+
+ my $name = $field->name;
+ my $type = $field->type;
+ if (SQL_DEFINITIONS->{$type}) {
+ # Create the database column that stores the data for this field.
+ $dbh->bz_add_column('bugs', $name, SQL_DEFINITIONS->{$type});
+ }
+
+ if ($field->is_select) {
+ # Create the table that holds the legal values for this field.
+ $dbh->bz_add_field_tables($field);
+ }
+
+ if ($type == FIELD_TYPE_SINGLE_SELECT) {
+ # Insert a default value of "---" into the legal values table.
+ $dbh->do("INSERT INTO $name (value) VALUES ('---')");
+ }
+
+ # Safe to write the original 'obsolete' value to the database now
+ $field->update;
}
+ };
+
+ my $error = "$@";
+ if ($params->{'custom'}) {
+ SetParam('disable_bug_updates', 0);
+ write_params();
}
+ die $error if $error;
+
+ Bugzilla::Hook::process("field_end_of_create", { field => $field });
return $field;
}
diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm
index b7532fe09..3f521d0f2 100644
--- a/Bugzilla/Group.pm
+++ b/Bugzilla/Group.pm
@@ -119,9 +119,10 @@ sub _get_members {
}
sub flag_types {
- my $self = shift;
+ my ($self, $params) = @_;
+ $params ||= {};
require Bugzilla::FlagType;
- $self->{flag_types} ||= Bugzilla::FlagType::match({ group => $self->id });
+ $self->{flag_types} ||= Bugzilla::FlagType::match({ group => $self->id, %$params });
return $self->{flag_types};
}
diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm
index ce8fe6bad..60e96766b 100644
--- a/Bugzilla/Install.pm
+++ b/Bugzilla/Install.pm
@@ -93,6 +93,8 @@ sub SETTINGS {
# 2011-06-21 glob@mozilla.com -- Bug 589128
email_format => { options => ['html', 'text_only'],
default => 'html' },
+ # 2011-06-16 glob@mozilla.com -- Bug 663747
+ bugmail_new_prefix => { options => ['on', 'off'], default => 'on' },
}
};
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index 5ce3c7a4e..f30e1503b 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -637,6 +637,9 @@ sub update_table_definitions {
# 2009-05-07 ghendricks@novell.com - Bug 77193
_add_isactive_to_product_fields();
+ # 2009-05-07 ghendricks@novell.com - Bug 77193
+ _add_isactive_to_product_fields();
+
# 2010-10-09 LpSolit@gmail.com - Bug 505165
$dbh->bz_alter_column('flags', 'setter_id', {TYPE => 'INT3', NOTNULL => 1});
@@ -3207,6 +3210,11 @@ sub _populate_bugs_fulltext {
print "Populating bugs_fulltext with $num_bugs entries...";
print " (this can take a long time.)\n";
}
+
+ # As recommended by Monty Widenius for GNOME's upgrade.
+ # mkanat and justdave concur it'll be helpful for bmo, too.
+ $dbh->do('SET SESSION myisam_sort_buffer_size = 3221225472');
+
my $newline = $dbh->quote("\n");
$dbh->do(
qq{$command INTO bugs_fulltext (bug_id, short_desc, comments,
@@ -3602,6 +3610,26 @@ sub _rename_tags_to_tag {
}
}
+sub _add_isactive_to_product_fields {
+ my $dbh = Bugzilla->dbh;
+
+ # If we add the isactive column all values should start off as active
+ if (!$dbh->bz_column_info('components', 'isactive')) {
+ $dbh->bz_add_column('components', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+
+ if (!$dbh->bz_column_info('versions', 'isactive')) {
+ $dbh->bz_add_column('versions', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+
+ if (!$dbh->bz_column_info('milestones', 'isactive')) {
+ $dbh->bz_add_column('milestones', 'isactive',
+ {TYPE => 'BOOLEAN', NOTNULL => 1, DEFAULT => 'TRUE'});
+ }
+}
+
1;
__END__
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index 15106dab9..e6783bbee 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -169,6 +169,7 @@ sub FILESYSTEM {
'contrib/README' => { perms => OWNER_WRITE },
'contrib/*/README' => { perms => OWNER_WRITE },
+ 'contrib/sendunsentbugmail.pl' => { perms => WS_EXECUTE },
'docs/bugzilla.ent' => { perms => OWNER_WRITE },
'docs/makedocs.pl' => { perms => OWNER_EXECUTE },
'docs/style.css' => { perms => WS_SERVE },
@@ -183,8 +184,10 @@ sub FILESYSTEM {
# Directories that we want to set the perms on, but not
# recurse through. These are directories we didn't create
# in checkesetup.pl.
+ #
+ # Purpose of BMO change: unknown.
my %non_recurse_dirs = (
- '.' => DIR_WS_SERVE,
+ '.' => 0755,
docs => DIR_WS_SERVE,
);
@@ -242,10 +245,13 @@ sub FILESYSTEM {
dirs => DIR_WS_SERVE },
"$extensionsdir/*/web" => { files => WS_SERVE,
dirs => DIR_WS_SERVE },
-
+
+ # Purpose: allow webserver to read .bzr so we execute bzr commands
+ # in backticks and look at the result over the web. Used to show
+ # bzr history.
+ '.bzr' => { files => WS_SERVE,
+ dirs => DIR_WS_SERVE },
# Directories only for the owner, not for the webserver.
- '.bzr' => { files => OWNER_WRITE,
- dirs => DIR_OWNER_WRITE },
t => { files => OWNER_WRITE,
dirs => DIR_OWNER_WRITE },
xt => { files => OWNER_WRITE,
diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm
index a0079a033..976804cb0 100644
--- a/Bugzilla/Product.pm
+++ b/Bugzilla/Product.pm
@@ -779,7 +779,8 @@ sub user_has_access {
}
sub flag_types {
- my $self = shift;
+ my ($self, $params) = @_;
+ $params ||= {};
return $self->{'flag_types'} if defined $self->{'flag_types'};
@@ -787,7 +788,7 @@ sub flag_types {
my $cache = Bugzilla->request_cache->{flag_types_per_product} ||= {};
$self->{flag_types} = {};
my $prod_id = $self->id;
- my $flagtypes = Bugzilla::FlagType::match({ product_id => $prod_id });
+ my $flagtypes = Bugzilla::FlagType::match({ product_id => $prod_id, %$params });
foreach my $type ('bug', 'attachment') {
my @flags = grep { $_->target_type eq $type } @$flagtypes;
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index d47e0ae99..a1378e540 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -2786,7 +2786,8 @@ sub _changedby {
sub IsValidQueryType
{
my ($queryType) = @_;
- if (grep { $_ eq $queryType } qw(specific advanced)) {
+ # BMO: Added google query type
+ if (grep { $_ eq $queryType } qw(specific advanced google)) {
return 1;
}
return 0;
diff --git a/Bugzilla/Search/Quicksearch.pm b/Bugzilla/Search/Quicksearch.pm
index 8425a2be2..1d332e5ae 100644
--- a/Bugzilla/Search/Quicksearch.pm
+++ b/Bugzilla/Search/Quicksearch.pm
@@ -492,6 +492,9 @@ sub _default_quicksearch_word {
addChart('short_desc', 'substring', $word, $negate);
addChart('status_whiteboard', 'substring', $word, $negate);
addChart('content', 'matches', _matches_phrase($word), $negate) if $fulltext;
+
+ # BMO Bug 664124 - Include the crash signature (sig:) field in default quicksearches
+ addChart('cf_crash_signature', 'substring', $word, $negate);
}
sub _handle_urls {
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index 527b704b2..433b283b2 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -234,7 +234,8 @@ sub quoteUrls {
~<a href=\"mailto:$2\">$1$2</a>~igx;
# attachment links
- $text =~ s~\b(attachment\s*\#?\s*(\d+)(?:\s+\[details\])?)
+ # BMO: Bug 652332 dkl@mozilla.com 2011-07-20
+ $text =~ s~\b(attachment\s*\#?\s*(\d+)(?:\s+\[diff\])?(?:\s+\[details\])?)
~($things[$count++] = get_attachment_link($2, $1)) &&
("\0\0" . ($count-1) . "\0\0")
~egmxi;
@@ -293,18 +294,20 @@ sub get_attachment_link {
$title = html_quote(clean_text($title));
$link_text =~ s/ \[details\]$//;
+ $link_text =~ s/ \[diff\]$//;
my $linkval = "attachment.cgi?id=$attachid";
- # If the attachment is a patch, try to link to the diff rather
- # than the text, by default.
+ # If the attachment is a patch and patch_viewer feature is
+ # enabled, add link to the diff.
my $patchlink = "";
if ($attachment->ispatch and Bugzilla->feature('patch_viewer')) {
- $patchlink = '&amp;action=diff';
+ $patchlink = qq| <a href="${linkval}&amp;action=diff" title="$title">[diff]</a>|;
}
# Whitespace matters here because these links are in <pre> tags.
return qq|<span class="$className">|
- . qq|<a href="${linkval}${patchlink}" name="attach_${attachid}" title="$title">$link_text</a>|
+ . qq|<a href="${linkval}" name="attach_${attachid}" title="$title">$link_text</a>|
+ . qq|${patchlink}|
. qq| <a href="${linkval}&amp;action=edit" title="$title">[details]</a>|
. qq|</span>|;
}
diff --git a/Bugzilla/Token.pm b/Bugzilla/Token.pm
index 86220aa29..4e32436c0 100644
--- a/Bugzilla/Token.pm
+++ b/Bugzilla/Token.pm
@@ -109,6 +109,8 @@ sub IssueEmailChangeToken {
$vars->{'newemailaddress'} = $new_email . $email_suffix;
$vars->{'expiration_ts'} = ctime($token_ts + MAX_TOKEN_AGE * 86400);
$vars->{'token'} = $token;
+ # For SecureMail extension
+ $vars->{'to_user'} = $user;
$vars->{'emailaddress'} = $old_email . $email_suffix;
my $message;
diff --git a/Bugzilla/User.pm b/Bugzilla/User.pm
index ea186a0fd..8ad84cec7 100644
--- a/Bugzilla/User.pm
+++ b/Bugzilla/User.pm
@@ -50,6 +50,7 @@ use Bugzilla::Product;
use Bugzilla::Classification;
use Bugzilla::Field;
use Bugzilla::Group;
+use Bugzilla::Hook;
use DateTime::TimeZone;
use List::Util qw(max);
@@ -708,8 +709,8 @@ sub bless_groups {
return $self->{'bless_groups'} if defined $self->{'bless_groups'};
return [] unless $self->id;
- if ($self->in_group('editusers')) {
- # Users having editusers permissions may bless all groups.
+ if ($self->in_group('admin')) {
+ # Users having admin permissions may bless all groups.
$self->{'bless_groups'} = [Bugzilla::Group->get_all];
return $self->{'bless_groups'};
}
@@ -2293,7 +2294,7 @@ Determines whether or not a user is in the given group by id.
Returns an arrayref of L<Bugzilla::Group> objects.
The arrayref consists of the groups the user can bless, taking into account
-that having editusers permissions means that you can bless all groups, and
+that having admin permissions means that you can bless all groups, and
that you need to be able to see a group in order to bless it.
=item C<get_products_by_permission($group)>
diff --git a/Bugzilla/WebService/Bug.pm b/Bugzilla/WebService/Bug.pm
index fb2b7b65d..c2083a59f 100644
--- a/Bugzilla/WebService/Bug.pm
+++ b/Bugzilla/WebService/Bug.pm
@@ -439,10 +439,17 @@ sub search {
delete $match_params{'include_fields'};
delete $match_params{'exclude_fields'};
+ my $count_only = delete $match_params{count_only};
+
my $bugs = Bugzilla::Bug->match(\%match_params);
my $visible = Bugzilla->user->visible_bugs($bugs);
- my @hashes = map { $self->_bug_to_hash($_, $params) } @$visible;
- return { bugs => \@hashes };
+ if ($count_only) {
+ return { bug_count => scalar @$visible };
+ }
+ else {
+ my @hashes = map { $self->_bug_to_hash($_, $params) } @$visible;
+ return { bugs => \@hashes };
+ }
}
sub possible_duplicates {
@@ -469,6 +476,12 @@ sub possible_duplicates {
sub update {
my ($self, $params) = validate(@_, 'ids');
+ # BMO: Don't allow updating of bugs if disabled
+ if (Bugzilla->params->{disable_bug_updates}) {
+ ThrowErrorPage('bug/process/updates-disabled.html.tmpl',
+ 'Bug updates are currently disabled.');
+ }
+
my $user = Bugzilla->login(LOGIN_REQUIRED);
my $dbh = Bugzilla->dbh;
@@ -563,6 +576,13 @@ sub update {
sub create {
my ($self, $params) = @_;
+
+ # BMO: Don't allow updating of bugs if disabled
+ if (Bugzilla->params->{disable_bug_updates}) {
+ ThrowErrorPage('bug/process/updates-disabled.html.tmpl',
+ 'Bug updates are currently disabled.');
+ }
+
Bugzilla->login(LOGIN_REQUIRED);
$params = Bugzilla::Bug::map_fields($params);
my $bug = Bugzilla::Bug->create($params);
@@ -625,6 +645,12 @@ sub add_attachment {
my ($self, $params) = validate(@_, 'ids');
my $dbh = Bugzilla->dbh;
+ # BMO: Don't allow updating of bugs if disabled
+ if (Bugzilla->params->{disable_bug_updates}) {
+ ThrowErrorPage('bug/process/updates-disabled.html.tmpl',
+ 'Bug updates are currently disabled.');
+ }
+
Bugzilla->login(LOGIN_REQUIRED);
defined $params->{ids}
|| ThrowCodeError('param_required', { param => 'ids' });
@@ -670,6 +696,12 @@ sub add_attachment {
sub add_comment {
my ($self, $params) = @_;
+ # BMO: Don't allow updating of bugs if disabled
+ if (Bugzilla->params->{disable_bug_updates}) {
+ ThrowErrorPage('bug/process/updates-disabled.html.tmpl',
+ 'Bug updates are currently disabled.');
+ }
+
#The user must login in order add a comment
Bugzilla->login(LOGIN_REQUIRED);
@@ -714,6 +746,12 @@ sub add_comment {
sub update_see_also {
my ($self, $params) = @_;
+ # BMO: Don't allow updating of bugs if disabled
+ if (Bugzilla->params->{disable_bug_updates}) {
+ ThrowErrorPage('bug/process/updates-disabled.html.tmpl',
+ 'Bug updates are currently disabled.');
+ }
+
my $user = Bugzilla->login(LOGIN_REQUIRED);
# Check parameters
@@ -2160,6 +2198,11 @@ C<string> Search the "Status Whiteboard" field on bugs for a substring.
Works the same as the C<summary> field described above, but searches the
Status Whiteboard field.
+=item C<count_only>
+
+C<boolean> If count_only set to true, only a single hash key called C<bug_count>
+will be returned which is the number of bugs that matched the search.
+
=back
=item B<Returns>
diff --git a/Bugzilla/WebService/User.pm b/Bugzilla/WebService/User.pm
index 2d9276cc3..984f41c8a 100644
--- a/Bugzilla/WebService/User.pm
+++ b/Bugzilla/WebService/User.pm
@@ -30,6 +30,7 @@ use Bugzilla::User;
use Bugzilla::Util qw(trim);
use Bugzilla::Token;
use Bugzilla::WebService::Util qw(filter validate);
+use Bugzilla::Hook;
# Don't need auth to login
use constant LOGIN_EXEMPT => {
@@ -235,6 +236,9 @@ sub get {
}} @$in_group;
}
+ Bugzilla::Hook::process('webservice_user_get',
+ { webservice => $self, params => $params, users => \@users });
+
return { users => \@users };
}