Add "bypass group" parameter to Checkers

classes
Vitaliy Filippov 2016-01-25 18:19:14 +03:00
parent 98b88de635
commit 4ad3e1d881
6 changed files with 44 additions and 15 deletions

View File

@ -43,6 +43,7 @@ use constant DB_COLUMNS => (
'sql_code', # SQL code for query is cached here
'except_fields', # "Exception" fields - see CF_DENY above.
'triggers', # Triggers (bug changes) (requires CF_FREEZE & !CF_FATAL)
'bypass_group_id', # Group members of which may bypass this check
);
use constant NAME_FIELD => 'message';
use constant ID_FIELD => 'id';
@ -53,16 +54,11 @@ use constant REQUIRED_CREATE_FIELDS => qw(query_id message);
use constant VALIDATORS => {
query_id => \&_check_query_id,
flags => \&_check_flags,
bypass_group_id => \&_check_bypass_group_id,
user_id => \&_check_user_id,
};
use constant UPDATE_COLUMNS => (
'query_id',
'flags',
'message',
'sql_code',
'except_fields',
'triggers',
);
use constant UPDATE_COLUMNS => (grep { $_ ne 'id' && $_ ne 'user_id' } DB_COLUMNS);
# The check works by executing this SQL query with added bugs.bug_id=? condition.
# Rebuild and save SQL code in the DB, from under the superuser
@ -142,6 +138,18 @@ sub _check_query_id
return $q->id;
}
sub _check_user_id
{
my ($invocant, $value, $field) = @_;
return $value ? Bugzilla::User->check({ userid => $_[1] })->id : undef;
}
sub _check_bypass_group_id
{
my ($invocant, $value, $field) = @_;
return $value ? Bugzilla::Group->check({ id => $value })->id : undef;
}
sub _check_flags
{
my ($invocant, $value, $field) = @_;
@ -154,6 +162,7 @@ sub query_id { $_[0]->{query_id} }
sub user_id { $_[0]->{user_id} }
sub message { $_[0]->{message} }
sub sql_code { $_[0]->{sql_code} }
sub bypass_group_id { $_[0]->{bypass_group_id} }
sub flags { $_[0]->{flags} }
# Specific flags from the bitfield
@ -215,8 +224,8 @@ sub user
return $self->{user};
}
sub set_query_id { $_[0]->set('query_id', Bugzilla::Search::Saved->check({ id => $_[1] })->id) }
sub set_user_id { $_[0]->set('user_id', Bugzilla::User->check({ userid => $_[1] })->id) }
sub set_query_id { $_[0]->set('query_id', $_[1]) }
sub set_user_id { $_[0]->set('user_id', $_[1]) }
sub set_flags { $_[0]->set('flags', $_[1]) }
sub set_message { $_[0]->set('message', $_[1]) }
sub set_sql_code { $_[0]->set('sql_code', $_[1]) }

View File

@ -53,11 +53,13 @@ sub check
my $sql = [];
my @bind;
my ($s, $i);
for (values %$all)
for my $checker (values %$all)
{
if (($_->flags & $mask) == $flags)
if (($checker->flags & $mask) == $flags &&
# Do not run checkers which may be bypassed by user based on his permissions
(!$checker->bypass_group_id || !Bugzilla->user->in_group_id($checker->bypass_group_id)))
{
$s = $_->sql_code;
$s = $checker->sql_code;
push @$sql, $s;
push @bind, $bug_id;
}

View File

@ -825,6 +825,7 @@ use constant ABSTRACT_SCHEMA => {
sql_code => {TYPE => 'LONGTEXT'},
except_fields => {TYPE => 'LONGBLOB'},
triggers => {TYPE => 'LONGBLOB'},
bypass_group_id=> {TYPE => 'INT4', REFERENCES => {TABLE => 'groups', COLUMN => 'id', DELETE => 'SET NULL'}},
],
INDEXES => [
checkers_query_id_idx => { FIELDS => ['query_id'] },

View File

@ -864,6 +864,8 @@ WHERE description LIKE \'%[CC:%]%\'');
$dbh->bz_add_column('versions', 'sortkey');
$dbh->bz_add_column('checkers', 'bypass_group_id');
_move_old_defaults($old_params);
################################################################

View File

@ -72,12 +72,14 @@ if ($params->{save})
flags => $flags,
except_fields => $except,
triggers => $triggers,
bypass_group_id => $params->{bypass_group_id},
});
}
else
{
$ch = Bugzilla::Checker->check({ id => $id });
$ch->set_query_id($params->{query_id});
$ch->set('query_id', $params->{query_id});
$ch->set('bypass_group_id', $params->{bypass_group_id});
$ch->set_message($params->{message});
$ch->set_flags($flags);
$ch->set_except_fields($except);
@ -106,6 +108,7 @@ else
{
$vars->{token} = issue_session_token('editcheckers');
$vars->{create} = $params->{create} ? 1 : 0;
$vars->{all_groups} = [ Bugzilla::Group->get_all ];
# Есть специальное поле "longdesc", означающее добавление комментариев
my $f = [ Bugzilla->get_fields ];
@$f = sort { lc $a->description cmp lc $b->description } grep { $_->name !~ /

View File

@ -92,7 +92,7 @@
<option value="[% q.id %]" [% " selected='selected'" IF checker.query_id == q.id %] >[% q.name | html %]</option>
[% END %]
[% IF checker.query_id AND !found %]
<option value="[% checker.query_id %]" selected='selected'>(Чужой) [% checker.query.name | html %]</option>
<option value="[% checker.query_id %]" selected='selected'>([% checker.query.user.login | html %]) [% checker.query.name | html %]</option>
[% END %]
</select></td>
</tr>
@ -128,6 +128,18 @@
<label for="is_fatal">Жёсткий запрет (если нет, то изменения не блокируются, а только даётся предупреждение)</label><br />
</td>
</tr>
<tr><th style="text-align: left" colspan="2">Разрешить следующим пользователям обходить эту проверку:</th></tr>
<tr>
<th>Группа:</th>
<td>
<select name="bypass_group_id" id="bypass_group_id">
<option value="">&mdash; (не разрешать)</option>
[% FOR g = all_groups %]
<option value="[% g.id %]" [% " selected=\"selected\"" IF checker.bypass_group_id == g.id %]>[% g.name | html %]</option>
[% END %]
</select>
</td>
</tr>
<tr><th style="text-align: left" colspan="2">Запреты изменений отдельных полей, действуют только при обновлении багов:</th></tr>
<tr>
<th style="background: #FFE0E0">Запрещать:</th>