diff options
-rw-r--r-- | Bugzilla.pm | 15 | ||||
-rw-r--r-- | Bugzilla/Config/GroupSecurity.pm | 26 | ||||
-rw-r--r-- | Bugzilla/DB/Schema.pm | 12 | ||||
-rw-r--r-- | Bugzilla/Product.pm | 60 | ||||
-rwxr-xr-x | editproducts.cgi | 26 | ||||
-rw-r--r-- | extensions/BMO/Extension.pm | 237 | ||||
-rw-r--r-- | extensions/BMO/lib/Data.pm | 24 | ||||
-rw-r--r-- | template/en/default/admin/params/groupsecurity.html.tmpl | 5 |
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.", } %] |