summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Bugzilla.pm15
-rw-r--r--Bugzilla/Config/GroupSecurity.pm26
-rw-r--r--Bugzilla/DB/Schema.pm12
-rw-r--r--Bugzilla/Product.pm60
-rwxr-xr-xeditproducts.cgi26
-rw-r--r--extensions/BMO/Extension.pm237
-rw-r--r--extensions/BMO/lib/Data.pm24
-rw-r--r--template/en/default/admin/params/groupsecurity.html.tmpl5
8 files changed, 271 insertions, 134 deletions
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 1ab72431a..afdfcefd2 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -57,7 +57,6 @@ use File::Basename;
use File::Spec::Functions;
use Safe;
use Sys::Syslog qw(:DEFAULT);
-use List::Util qw(any);
use JSON::XS qw(decode_json);
use URI;
@@ -863,20 +862,6 @@ sub check_rate_limit {
}
}
-# called from the verify version, component, and group page.
-# if we're making a group invalid, stuff the default group into the cgi param
-# to make it checked by default.
-sub check_default_product_security_group {
- my ($class, $product, $invalid_groups, $optional_group_controls) = @_;
- return unless my $group = $product->default_security_group_obj;
- if (@$invalid_groups) {
- my $cgi = $class->cgi;
- my @groups = $cgi->param('groups');
- push @groups, $group->name unless any { $_ eq $group->name } @groups;
- $cgi->param('groups', @groups);
- }
-}
-
# Private methods
# Per-process cleanup. Note that this is a plain subroutine, not a method,
diff --git a/Bugzilla/Config/GroupSecurity.pm b/Bugzilla/Config/GroupSecurity.pm
index c1d2faac1..68c852fe6 100644
--- a/Bugzilla/Config/GroupSecurity.pm
+++ b/Bugzilla/Config/GroupSecurity.pm
@@ -84,32 +84,6 @@ sub get_param_list {
name => 'strict_isolation',
type => 'b',
default => 0
- },
- {
- name => 'always_filleable_groups',
- type => 'l',
- default => join(", ", qw(
- addons-security
- bugzilla-security
- client-services-security
- consulting
- core-security
- finance
- infra
- infrasec
- l20n-security
- marketing-private
- mozilla-confidential
- mozilla-employee-confidential
- mozilla-foundation-confidential
- mozilla-engagement
- mozilla-messaging-confidential
- partner-confidential
- payments-confidential
- tamarin-security
- websites-security
- webtools-security
- )),
}
);
return @param_list;
diff --git a/Bugzilla/DB/Schema.pm b/Bugzilla/DB/Schema.pm
index 561aa3a4f..3307464db 100644
--- a/Bugzilla/DB/Schema.pm
+++ b/Bugzilla/DB/Schema.pm
@@ -1410,18 +1410,6 @@ use constant ABSTRACT_SCHEMA => {
NOTNULL => 1, DEFAULT => "'---'"},
allows_unconfirmed => {TYPE => 'BOOLEAN', NOTNULL => 1,
DEFAULT => 'TRUE'},
- default_op_sys_id => {TYPE => 'INT2',
- REFERENCES => {TABLE => 'op_sys',
- COLUMN => 'id',
- DELETE => 'SET NULL'}},
- default_platform_id => {TYPE => 'INT2',
- REFERENCES => {TABLE => 'rep_platform',
- COLUMN => 'id',
- DELETE => 'SET NULL'}},
- security_group_id => {TYPE => 'INT3',
- NOTNULL => 1,
- REFERENCES => {TABLE => 'groups',
- COLUMN => 'id'}},
],
INDEXES => [
products_name_idx => {FIELDS => ['name'],
diff --git a/Bugzilla/Product.pm b/Bugzilla/Product.pm
index 3fc4db77f..c4c147a63 100644
--- a/Bugzilla/Product.pm
+++ b/Bugzilla/Product.pm
@@ -47,9 +47,6 @@ use constant DB_COLUMNS => qw(
isactive
defaultmilestone
allows_unconfirmed
- default_platform_id
- default_op_sys_id
- security_group_id
);
use constant UPDATE_COLUMNS => qw(
@@ -58,9 +55,6 @@ use constant UPDATE_COLUMNS => qw(
defaultmilestone
isactive
allows_unconfirmed
- default_platform_id
- default_op_sys_id
- security_group_id
);
use constant VALIDATORS => {
@@ -854,60 +848,6 @@ sub is_active { return $_[0]->{'isactive'}; }
sub default_milestone { return $_[0]->{'defaultmilestone'}; }
sub classification_id { return $_[0]->{'classification_id'}; }
-sub default_security_group {
- my ($self) = @_;
- return $self->default_security_group_obj->name;
-}
-
-sub default_security_group_obj {
- my ($self) = @_;
- my $group_id = $self->{security_group_id};
- if (!$group_id) {
- return Bugzilla::Group->new({ name => Bugzilla->params->{insidergroup}, cache => 1 });
- }
- return Bugzilla::Group->new({ id => $group_id, cache => 1 });
-}
-
-sub default_platform_id { shift->{default_platform_id} }
-sub default_op_sys_id { shift->{default_op_sys_id} }
-
-# you can always file bugs into a product's default security group, as well as
-# into any of the groups in @always_fileable_groups
-sub group_always_settable {
- my ( $self, $group ) = @_;
- my @always_fileable_groups = split(/\s*,\s*/, Bugzilla->params->{always_fileable_groups});
- return $group->name eq $self->default_security_group
- || ( ( any { $_ eq $group->name } @always_fileable_groups ) ? 1 : 0 );
-}
-
-
-sub default_platform {
- my ($self) = @_;
- if (!exists $self->{default_platform}) {
- $self->{default_platform} = $self->default_platform_id
- ? Bugzilla::Field::Choice
- ->type('rep_platform')
- ->new($self->{default_platform_id})
- ->name
- : undef;
- }
- return $self->{default_platform};
-}
-
-sub default_op_sys {
- my ($self) = @_;
- if (!exists $self->{default_op_sys}) {
- $self->{default_op_sys} = $self->default_op_sys_id
- ? Bugzilla::Field::Choice
- ->type('op_sys')
- ->new($self->{default_op_sys_id})
- ->name
- : undef;
- }
- return $self->{default_op_sys};
-}
-
-
###############################
#### Subroutines ######
###############################
diff --git a/editproducts.cgi b/editproducts.cgi
index 618aec547..a989e4bc1 100755
--- a/editproducts.cgi
+++ b/editproducts.cgi
@@ -158,19 +158,15 @@ if ($action eq 'new') {
check_token_data($token, 'add_product');
my %create_params = (
- classification => $classification_name,
- name => $product_name,
- description => scalar $cgi->param('description'),
- version => scalar $cgi->param('version'),
- defaultmilestone => scalar $cgi->param('defaultmilestone'),
- isactive => scalar $cgi->param('is_active'),
- create_series => scalar $cgi->param('createseries'),
- allows_unconfirmed => scalar $cgi->param('allows_unconfirmed'),
- default_platform_id => scalar $cgi->param('default_platform_id'),
- default_op_sys_id => scalar $cgi->param('default_op_sys_id'),
- security_group_id => scalar $cgi->param('security_group_id'),
+ classification => $classification_name,
+ name => $product_name,
+ description => scalar $cgi->param('description'),
+ version => scalar $cgi->param('version'),
+ defaultmilestone => scalar $cgi->param('defaultmilestone'),
+ isactive => scalar $cgi->param('is_active'),
+ create_series => scalar $cgi->param('createseries'),
+ allows_unconfirmed => scalar $cgi->param('allows_unconfirmed'),
);
-
my $product = Bugzilla::Product->create(\%create_params);
delete_token($token);
@@ -283,12 +279,6 @@ if ($action eq 'update') {
default_milestone => scalar $cgi->param('defaultmilestone'),
});
- foreach my $field (qw( default_platform_id default_op_sys_id security_group_id )) {
- my $value = $cgi->param($field);
- detaint_natural($value);
- $product->set($field, $value);
- }
-
my $changes = $product->update();
delete_token($token);
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm
index 817fd1d74..58d4b02cd 100644
--- a/extensions/BMO/Extension.pm
+++ b/extensions/BMO/Extension.pm
@@ -77,6 +77,14 @@ BEGIN {
*Bugzilla::Bug::is_unassigned = \&_bug_is_unassigned;
*Bugzilla::Bug::has_current_patch = \&_bug_has_current_patch;
*Bugzilla::Bug::missing_sec_approval = \&_bug_missing_sec_approval;
+ *Bugzilla::Product::default_security_group = \&_default_security_group;
+ *Bugzilla::Product::default_security_group_obj = \&_default_security_group_obj;
+ *Bugzilla::Product::group_always_settable = \&_group_always_settable;
+ *Bugzilla::Product::default_platform_id = \&_product_default_platform_id;
+ *Bugzilla::Product::default_op_sys_id = \&_product_default_op_sys_id;
+ *Bugzilla::Product::default_platform = \&_product_default_platform;
+ *Bugzilla::Product::default_op_sys = \&_product_default_op_sys;
+ *Bugzilla::check_default_product_security_group = \&_check_default_product_security_group;
*Bugzilla::Attachment::is_bounty_attachment = \&_attachment_is_bounty_attachment;
*Bugzilla::Attachment::bounty_details = \&_attachment_bounty_details;
*Bugzilla::Attachment::external_redirect = \&_attachment_external_redirect;
@@ -813,6 +821,51 @@ sub quicksearch_map {
}
}
+sub object_columns {
+ my ($self, $args) = @_;
+ return unless $args->{class}->isa('Bugzilla::Product');
+ push @{ $args->{columns} }, qw(
+ default_platform_id
+ default_op_sys_id
+ security_group_id
+ );
+}
+
+sub object_update_columns {
+ my ($self, $args) = @_;
+ return unless $args->{object}->isa('Bugzilla::Product');
+ push @{ $args->{columns} }, qw(
+ default_platform_id
+ default_op_sys_id
+ security_group_id
+ );
+}
+
+sub object_before_create {
+ my ($self, $args) = @_;
+ return unless $args->{class}->isa('Bugzilla::Product');
+
+ my $cgi = Bugzilla->cgi;
+ my $params = $args->{params};
+ foreach my $field (qw( default_platform_id default_op_sys_id security_group_id )) {
+ $params->{$field} = $cgi->param($field);
+ }
+}
+
+sub object_end_of_set_all {
+ my ($self, $args) = @_;
+ my $object = $args->{object};
+ return unless $object->isa('Bugzilla::Product');
+
+ my $cgi = Bugzilla->cgi;
+ my $params = $args->{params};
+ foreach my $field (qw( default_platform_id default_op_sys_id security_group_id )) {
+ my $value = $cgi->param($field);
+ detaint_natural($value);
+ $object->set($field, $value);
+ }
+}
+
sub object_end_of_create {
my ($self, $args) = @_;
my $class = $args->{class};
@@ -927,6 +980,33 @@ sub _bug_missing_sec_approval {
return $set == 0;
}
+sub _product_default_platform_id { $_[0]->{default_platform_id} }
+sub _product_default_op_sys_id { $_[0]->{default_op_sys_id} }
+
+sub _product_default_platform {
+ my ($self) = @_;
+ if (!exists $self->{default_platform}) {
+ $self->{default_platform} = $self->default_platform_id
+ ? Bugzilla::Field::Choice
+ ->type('rep_platform')
+ ->new($_[0]->{default_platform_id})
+ ->name
+ : undef;
+ }
+ return $self->{default_platform};
+}
+sub _product_default_op_sys {
+ my ($self) = @_;
+ if (!exists $self->{default_op_sys}) {
+ $self->{default_op_sys} = $self->default_op_sys_id
+ ? Bugzilla::Field::Choice
+ ->type('op_sys')
+ ->new($_[0]->{default_op_sys_id})
+ ->name
+ : undef;
+ }
+ return $self->{default_op_sys};
+}
sub _get_named_query {
my ($sharer_id, $group_id, $definition) = @_;
@@ -1306,6 +1386,34 @@ sub db_schema_abstract_schema {
sub install_update_db {
my $dbh = Bugzilla->dbh;
+ # per-product hw/os defaults
+ my $op_sys_default = _field_value('op_sys', 'Unspecified', 50);
+ $dbh->bz_add_column(
+ 'products',
+ 'default_op_sys_id' => {
+ TYPE => 'INT2',
+ DEFAULT => $op_sys_default->id,
+ REFERENCES => {
+ TABLE => 'op_sys',
+ COLUMN => 'id',
+ DELETE => 'SET NULL',
+ },
+ }
+ );
+ my $platform_default = _field_value('rep_platform', 'Unspecified', 50);
+ $dbh->bz_add_column(
+ 'products',
+ 'default_platform_id' => {
+ TYPE => 'INT2',
+ DEFAULT => $platform_default->id,
+ REFERENCES => {
+ TABLE => 'rep_platform',
+ COLUMN => 'id',
+ DELETE => 'SET NULL',
+ },
+ }
+ );
+
# Migrate old is_active stuff to new patch (is in core in 4.2), The old
# column name was 'is_active', the new one is 'isactive' (no underscore).
if ($dbh->bz_column_info('milestones', 'is_active')) {
@@ -1342,6 +1450,99 @@ sub install_update_db {
buglist => 0,
});
}
+
+ # Add default security group id column
+ if (!$dbh->bz_column_info('products', 'security_group_id')) {
+ $dbh->bz_add_column(
+ 'products',
+ 'security_group_id' => {
+ TYPE => 'INT3',
+ REFERENCES => {
+ TABLE => 'groups',
+ COLUMN => 'id',
+ DELETE => 'SET NULL',
+ },
+ }
+ );
+
+ # if there are no groups, then we're creating a database from scratch
+ # and there's nothing to migrate
+ my ($group_count) = $dbh->selectrow_array("SELECT COUNT(*) FROM groups");
+ if ($group_count) {
+ # Migrate old product_sec_group mappings from the time this change was made
+ my %product_sec_groups = (
+ "addons.mozilla.org" => 'client-services-security',
+ "Air Mozilla" => 'mozilla-employee-confidential',
+ "Android Background Services" => 'cloud-services-security',
+ "Audio/Visual Infrastructure" => 'mozilla-employee-confidential',
+ "AUS" => 'client-services-security',
+ "Bugzilla" => 'bugzilla-security',
+ "bugzilla.mozilla.org" => 'bugzilla-security',
+ "Cloud Services" => 'cloud-services-security',
+ "Community Tools" => 'websites-security',
+ "Data & BI Services Team" => 'metrics-private',
+ "Developer Documentation" => 'websites-security',
+ "Developer Ecosystem" => 'client-services-security',
+ "Finance" => 'finance',
+ "Firefox Friends" => 'mozilla-employee-confidential',
+ "Firefox Health Report" => 'cloud-services-security',
+ "Infrastructure & Operations" => 'mozilla-employee-confidential',
+ "Input" => 'websites-security',
+ "Intellego" => 'intellego-team',
+ "Internet Public Policy" => 'mozilla-employee-confidential',
+ "L20n" => 'l20n-security',
+ "Legal" => 'legal',
+ "Marketing" => 'marketing-private',
+ "Marketplace" => 'client-services-security',
+ "Mozilla Communities" => 'mozilla-communities-security',
+ "Mozilla Corporation" => 'mozilla-employee-confidential',
+ "Mozilla Developer Network" => 'websites-security',
+ "Mozilla Foundation" => 'mozilla-employee-confidential',
+ "Mozilla Foundation Operations" => 'mozilla-foundation-operations',
+ "Mozilla Grants" => 'grants',
+ "mozillaignite" => 'websites-security',
+ "Mozilla Messaging" => 'mozilla-messaging-confidential',
+ "Mozilla Metrics" => 'metrics-private',
+ "mozilla.org" => 'mozilla-employee-confidential',
+ "Mozilla PR" => 'pr-private',
+ "Mozilla QA" => 'mozilla-employee-confidential',
+ "Mozilla Reps" => 'mozilla-reps',
+ "Popcorn" => 'websites-security',
+ "Privacy" => 'privacy',
+ "quality.mozilla.org" => 'websites-security',
+ "Recruiting" => 'hr',
+ "Release Engineering" => 'mozilla-employee-confidential',
+ "Snippets" => 'websites-security',
+ "Socorro" => 'client-services-security',
+ "support.mozillamessaging.com" => 'websites-security',
+ "support.mozilla.org" => 'websites-security',
+ "Talkback" => 'talkback-private',
+ "Tamarin" => 'tamarin-security',
+ "Taskcluster" => 'taskcluster-security',
+ "Testopia" => 'bugzilla-security',
+ "Tree Management" => 'mozilla-employee-confidential',
+ "Web Apps" => 'client-services-security',
+ "Webmaker" => 'websites-security',
+ "Websites" => 'websites-security',
+ "Webtools" => 'webtools-security',
+ "www.mozilla.org" => 'websites-security',
+ );
+ # 1. Set all to core-security by default
+ my $core_sec_group = Bugzilla::Group->new({ name => 'core-security' });
+ $dbh->do("UPDATE products SET security_group_id = ?", undef, $core_sec_group->id);
+ # 2. Update the ones that have explicit security groups
+ foreach my $prod_name (keys %product_sec_groups) {
+ my $group_name = $product_sec_groups{$prod_name};
+ next if $group_name eq 'core-security'; # already done
+ my $group = Bugzilla::Group->new({ name => $group_name, cache => 1 });
+ if (!$group) {
+ warn "Security group $group_name not found. Using core-security instead.\n";
+ next;
+ }
+ $dbh->do("UPDATE products SET security_group_id = ? WHERE name = ?", undef, $group->id, $prod_name);
+ }
+ }
+ }
}
# return the Bugzilla::Field::Choice object for the specified field and value.
@@ -1357,6 +1558,7 @@ sub _field_value {
isactive => 1,
});
}
+
sub _last_closed_date {
my ($self) = @_;
my $dbh = Bugzilla->dbh;
@@ -2365,6 +2567,41 @@ sub query_database {
}
}
+# you can always file bugs into a product's default security group, as well as
+# into any of the groups in @always_fileable_groups
+sub _group_always_settable {
+ my ($self, $group) = @_;
+ return
+ $group->name eq $self->default_security_group
+ || ((grep { $_ eq $group->name } @always_fileable_groups) ? 1 : 0);
+}
+
+sub _default_security_group {
+ return $_[0]->default_security_group_obj->name;
+}
+
+sub _default_security_group_obj {
+ my $group_id = $_[0]->{security_group_id};
+ if (!$group_id) {
+ return Bugzilla::Group->new({ name => Bugzilla->params->{insidergroup}, cache => 1 });
+ }
+ return Bugzilla::Group->new({ id => $group_id, cache => 1 });
+}
+
+# called from the verify version, component, and group page.
+# if we're making a group invalid, stuff the default group into the cgi param
+# to make it checked by default.
+sub _check_default_product_security_group {
+ my ($self, $product, $invalid_groups, $optional_group_controls) = @_;
+ return unless my $group = $product->default_security_group_obj;
+ if (@$invalid_groups) {
+ my $cgi = Bugzilla->cgi;
+ my @groups = $cgi->param('groups');
+ push @groups, $group->name unless grep { $_ eq $group->name } @groups;
+ $cgi->param('groups', @groups);
+ }
+}
+
sub install_filesystem {
my ($self, $args) = @_;
my $files = $args->{files};
diff --git a/extensions/BMO/lib/Data.pm b/extensions/BMO/lib/Data.pm
index 525b4ee04..4df05581c 100644
--- a/extensions/BMO/lib/Data.pm
+++ b/extensions/BMO/lib/Data.pm
@@ -17,6 +17,7 @@ use Tie::IxHash;
our @EXPORT = qw( $cf_visible_in_products
%group_change_notification
$cf_setters
+ @always_fileable_groups
%group_auto_cc
%create_bug_formats
@default_named_queries
@@ -217,6 +218,29 @@ our $cf_setters = {
'cf_rank' => [ 'rank-setters' ],
};
+# Groups in which you can always file a bug, regardless of product or user.
+our @always_fileable_groups = qw(
+ addons-security
+ bugzilla-security
+ client-services-security
+ consulting
+ core-security
+ finance
+ infra
+ infrasec
+ l20n-security
+ marketing-private
+ mozilla-confidential
+ mozilla-employee-confidential
+ mozilla-foundation-confidential
+ mozilla-engagement
+ mozilla-messaging-confidential
+ partner-confidential
+ payments-confidential
+ tamarin-security
+ websites-security
+ webtools-security
+);
# Automatically CC users to bugs filed into configured groups and products
our %group_auto_cc = (
diff --git a/template/en/default/admin/params/groupsecurity.html.tmpl b/template/en/default/admin/params/groupsecurity.html.tmpl
index e20c18421..041af6833 100644
--- a/template/en/default/admin/params/groupsecurity.html.tmpl
+++ b/template/en/default/admin/params/groupsecurity.html.tmpl
@@ -50,14 +50,13 @@
usevisibilitygroups => "Do you wish to restrict visibility of users to members of " _
"specific groups?",
-
+
strict_isolation => "Don't allow users to be assigned to, " _
"be qa-contacts on, " _
"be added to CC list, " _
"or make or remove dependencies " _
"involving any bug that is in a product on which that " _
- "user is forbidden to edit.",
+ "user is forbidden to edit.",
- always_fileablr_grpups => "Groups in which you can always file a bug, regardless of product or user.",
}
%]