diff options
author | Byron Jones <glob@mozilla.com> | 2014-07-08 10:40:14 +0200 |
---|---|---|
committer | Byron Jones <glob@mozilla.com> | 2014-07-08 10:40:14 +0200 |
commit | 2f3b5dd7df3e131af6aef3cd5ccf7e8523c1780e (patch) | |
tree | e71ea56398621e038df3c27cc5b87accf7a04968 /extensions/BugmailFilter/lib | |
parent | d74129306d8d5a903af6fe3957046feb36affdd1 (diff) | |
download | bugzilla-2f3b5dd7df3e131af6aef3cd5ccf7e8523c1780e.tar.gz bugzilla-2f3b5dd7df3e131af6aef3cd5ccf7e8523c1780e.tar.xz |
Bug 990980: create an extension for server-side filtering of bugmail
Diffstat (limited to 'extensions/BugmailFilter/lib')
-rw-r--r-- | extensions/BugmailFilter/lib/Constants.pm | 113 | ||||
-rw-r--r-- | extensions/BugmailFilter/lib/FakeField.pm | 57 | ||||
-rw-r--r-- | extensions/BugmailFilter/lib/Filter.pm | 169 |
3 files changed, 339 insertions, 0 deletions
diff --git a/extensions/BugmailFilter/lib/Constants.pm b/extensions/BugmailFilter/lib/Constants.pm new file mode 100644 index 000000000..98b5793af --- /dev/null +++ b/extensions/BugmailFilter/lib/Constants.pm @@ -0,0 +1,113 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugmailFilter::Constants; +use strict; + +use base qw(Exporter); + +our @EXPORT = qw( + FAKE_FIELD_NAMES + IGNORE_FIELDS + FIELD_DESCRIPTION_OVERRIDE + FILTER_RELATIONSHIPS +); + +use Bugzilla::Constants; + +# these are field names which are inserted into X-Bugzilla-Changed-Field-Names +# header but are not real fields + +use constant FAKE_FIELD_NAMES => [ + { + name => 'comment.created', + description => 'Comment created', + }, + { + name => 'attachment.created', + description => 'Attachment created', + }, +]; + +# these fields don't make any sense to filter on + +use constant IGNORE_FIELDS => qw( + attach_data.thedata + attachments.submitter + comment_tag + days_elapsed + delta_ts + everconfirmed + longdesc + longdescs.count + owner_idle_time + reporter + reporter_accessible + tag +); + +# override the description of some fields + +use constant FIELD_DESCRIPTION_OVERRIDE => { + bug_id => 'Bug Created', +}; + +# relationship / int mappings +# _should_drop() also needs updating when this const is changed + +use constant FILTER_RELATIONSHIPS => [ + { + name => 'Assignee', + value => 1, + }, + { + name => 'Not Assignee', + value => 2, + }, + { + name => 'Reporter', + value => 3, + }, + { + name => 'Not Reporter', + value => 4, + }, + { + name => 'QA Contact', + value => 5, + }, + { + name => 'Not QA Contact', + value => 6, + }, + { + name => "CC'ed", + value => 7, + }, + { + name => "Not CC'ed", + value => 8, + }, + { + name => 'Watching', + value => 9, + }, + { + name => 'Not Watching', + value => 10, + }, + { + name => 'Mentoring', + value => 11, + }, + { + name => 'Not Mentoring', + value => 12, + }, +]; + +1; diff --git a/extensions/BugmailFilter/lib/FakeField.pm b/extensions/BugmailFilter/lib/FakeField.pm new file mode 100644 index 000000000..88e4ac1ca --- /dev/null +++ b/extensions/BugmailFilter/lib/FakeField.pm @@ -0,0 +1,57 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugmailFilter::FakeField; + +use strict; +use warnings; + +use Bugzilla::Extension::BugmailFilter::Constants; + +# object + +sub new { + my ($class, $params) = @_; + return bless($params, $class); +} + +sub name { $_[0]->{name} } +sub description { $_[0]->{description} } + +# static methods + +sub fake_fields { + my $cache = Bugzilla->request_cache->{bugmail_filter}; + if (!$cache->{fake_fields}) { + my @fields; + foreach my $rh (@{ FAKE_FIELD_NAMES() }) { + push @fields, Bugzilla::Extension::BugmailFilter::FakeField->new($rh); + } + $cache->{fake_fields} = \@fields; + } + return $cache->{fake_fields}; +} + +sub tracking_flag_fields { + my $cache = Bugzilla->request_cache->{bugmail_filter}; + if (!$cache->{tracking_flag_fields}) { + require Bugzilla::Extension::TrackingFlags::Constants; + my @fields; + my $tracking_types = Bugzilla::Extension::TrackingFlags::Constants::FLAG_TYPES(); + foreach my $tracking_type (@$tracking_types) { + push @fields, Bugzilla::Extension::BugmailFilter::FakeField->new({ + name => 'tracking.' . $tracking_type->{name}, + description => $tracking_type->{description}, + sortkey => $tracking_type->{sortkey}, + }); + } + $cache->{tracking_flag_fields} = \@fields; + } + return $cache->{tracking_flag_fields}; +} + +1; diff --git a/extensions/BugmailFilter/lib/Filter.pm b/extensions/BugmailFilter/lib/Filter.pm new file mode 100644 index 000000000..9a0d0f89a --- /dev/null +++ b/extensions/BugmailFilter/lib/Filter.pm @@ -0,0 +1,169 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +# +# This Source Code Form is "Incompatible With Secondary Licenses", as +# defined by the Mozilla Public License, v. 2.0. + +package Bugzilla::Extension::BugmailFilter::Filter; + +use base qw(Bugzilla::Object); + +use strict; +use warnings; + +use Bugzilla::Component; +use Bugzilla::Error; +use Bugzilla::Extension::BugmailFilter::Constants; +use Bugzilla::Extension::BugmailFilter::FakeField; +use Bugzilla::Field; +use Bugzilla::Product; +use Bugzilla::User; + +use constant DB_TABLE => 'bugmail_filters'; + +use constant DB_COLUMNS => qw( + id + user_id + product_id + component_id + field_name + relationship + action +); + +use constant LIST_ORDER => 'id'; + +use constant UPDATE_COLUMNS => (); + +use constant VALIDATORS => { + user_id => \&_check_user, + field_name => \&_check_field_name, + action => \&Bugzilla::Object::check_boolean, +}; +use constant VALIDATOR_DEPENDENCIES => { + component_id => [ 'product_id' ], +}; + +use constant AUDIT_CREATES => 0; +use constant AUDIT_UPDATES => 0; +use constant AUDIT_REMOVES => 0; +use constant USE_MEMCACHED => 0; + +# getters + +sub user { + my ($self) = @_; + return Bugzilla::User->new({ id => $self->{user_id}, cache => 1 }); +} + +sub product { + my ($self) = @_; + return $self->{product_id} + ? Bugzilla::Product->new({ id => $self->{product_id}, cache => 1 }) + : undef; +} + +sub product_name { + my ($self) = @_; + return $self->{product_name} //= $self->{product_id} ? $self->product->name : ''; +} + +sub component { + my ($self) = @_; + return $self->{component_id} + ? Bugzilla::Component->new({ id => $self->{component_id}, cache => 1 }) + : undef; +} + +sub component_name { + my ($self) = @_; + return $self->{component_name} //= $self->{component_id} ? $self->component->name : ''; +} + +sub field_name { + return $_[0]->{field_name} //= ''; +} + +sub field { + my ($self) = @_; + return unless $self->{field_name}; + if (!$self->{field}) { + foreach my $field ( + @{ Bugzilla::Extension::BugmailFilter::FakeField->fake_fields() }, + @{ Bugzilla::Extension::BugmailFilter::FakeField->tracking_flag_fields() }, + ) { + if ($field->{name} eq $self->{field_name}) { + return $self->{field} = $field; + } + } + $self->{field} = Bugzilla::Field->new({ name => $self->{field_name}, cache => 1 }); + } + return $self->{field}; +} + +sub relationship { + return $_[0]->{relationship}; +} + +sub relationship_name { + my ($self) = @_; + foreach my $rel (@{ FILTER_RELATIONSHIPS() }) { + return $rel->{name} + if $rel->{value} == $self->{relationship}; + } + return '?'; +} + +sub is_exclude { + return $_[0]->{action} == 1; +} + +sub is_include { + return $_[0]->{action} == 0; +} + +# validators + +sub _check_user { + my ($class, $user) = @_; + $user || ThrowCodeError('param_required', { param => 'user' }); +} + +sub _check_field_name { + my ($class, $field_name) = @_; + return undef unless $field_name; + foreach my $rh (@{ FAKE_FIELD_NAMES() }) { + return $field_name if $rh->{name} eq $field_name; + } + return $field_name + if $field_name =~ /^tracking\./; + Bugzilla::Field->check({ name => $field_name, cache => 1}); + return $field_name; +} + +# methods + +sub matches { + my ($self, $args) = @_; + + if ($self->{field_name} && $self->{field_name} ne $args->{field_name}) { + return 0; + } + + if ($self->{product_id} && $self->{product_id} != $args->{product_id}) { + return 0; + } + + if ($self->{component_id} && $self->{component_id} != $args->{component_id}) { + return 0; + } + + if ($self->{relationship} && !$args->{rel_map}->[$self->{relationship}]) { + return 0; + } + + return 1; +} + +1; |