[Rt-commit] r18349 - in rt/3.8/branches/html-css-cleanup: . etc lib/RT lib/RT/Interface sbin share/html/Elements/RT__Ticket share/html/NoAuth/css/web2 share/html/Search share/html/Ticket share/html/Widgets
falcone at bestpractical.com
falcone at bestpractical.com
Thu Feb 12 15:38:13 EST 2009
Author: falcone
Date: Thu Feb 12 15:38:12 2009
New Revision: 18349
Added:
rt/3.8/branches/html-css-cleanup/etc/schema.mysql-4.0 (props changed)
- copied unchanged from r17726, /rt/3.8/branches/html-css-cleanup/etc/schema.mysql
rt/3.8/branches/html-css-cleanup/t/validator/
rt/3.8/branches/html-css-cleanup/t/validator/group_members.t
Removed:
rt/3.8/branches/html-css-cleanup/etc/schema.mysql
Modified:
rt/3.8/branches/html-css-cleanup/ (props changed)
rt/3.8/branches/html-css-cleanup/Makefile.in
rt/3.8/branches/html-css-cleanup/etc/RT_Config.pm.in
rt/3.8/branches/html-css-cleanup/lib/RT/Interface/Email.pm
rt/3.8/branches/html-css-cleanup/lib/RT/Principal_Overlay.pm
rt/3.8/branches/html-css-cleanup/lib/RT/Record.pm
rt/3.8/branches/html-css-cleanup/sbin/rt-validator.in
rt/3.8/branches/html-css-cleanup/share/html/Elements/RT__Ticket/ColumnMap
rt/3.8/branches/html-css-cleanup/share/html/NoAuth/css/web2/msie.css
rt/3.8/branches/html-css-cleanup/share/html/Search/Chart.html
rt/3.8/branches/html-css-cleanup/share/html/Ticket/Update.html
rt/3.8/branches/html-css-cleanup/share/html/Widgets/ComboBox
Log:
- Merge //mirror/bps-public/rt/3.8/trunk to //mirror/bps-public/rt/3.8/branches/html-css-cleanup
Modified: rt/3.8/branches/html-css-cleanup/Makefile.in
==============================================================================
--- rt/3.8/branches/html-css-cleanup/Makefile.in (original)
+++ rt/3.8/branches/html-css-cleanup/Makefile.in Thu Feb 12 15:38:12 2009
@@ -167,7 +167,8 @@
rt-server \
rt-test-dependencies \
rt-clean-sessions \
- rt-shredder
+ rt-shredder \
+ rt-validator
ETC_FILES = acl.Informix \
@@ -178,7 +179,7 @@
schema.Informix \
schema.Pg \
schema.Oracle \
- schema.mysql \
+ schema.mysql-4.0 \
schema.mysql-4.1 \
schema.Sybase \
schema.SQLite \
Modified: rt/3.8/branches/html-css-cleanup/etc/RT_Config.pm.in
==============================================================================
--- rt/3.8/branches/html-css-cleanup/etc/RT_Config.pm.in (original)
+++ rt/3.8/branches/html-css-cleanup/etc/RT_Config.pm.in Thu Feb 12 15:38:12 2009
@@ -259,7 +259,10 @@
=item C<$RTAddressRegexp>
C<$RTAddressRegexp> is used to make sure RT doesn't add itself as a ticket CC if
-the setting above is enabled.
+the setting above is enabled. It is important that you set this to a
+regular expression that matches all addresses used by your RT. This lets RT
+avoid sending mail to itself. It will also hide RT addresses from the list of
+"One-time Cc" and Bcc lists on ticket reply.
=cut
@@ -688,14 +691,12 @@
=item C<$LogStackTraces>
-If set to a log level then logging will include stack
-traces for messages with level equal to or greater than
-specified.
-
-NOTICE: Stack traces include parameters that functions or methods
-were called wiht. It is possible for stack trace logging to reveal
-sensitive information such as passwords or ticket content in your
-logs.
+If set to a log level then logging will include stack traces for
+messages with level equal to or greater than specified.
+
+NOTICE: Stack traces include parameters supplied to functions or
+methods. It is possible for stack trace logging to reveal sensitive
+information such as passwords or ticket content in your logs.
=cut
Modified: rt/3.8/branches/html-css-cleanup/lib/RT/Interface/Email.pm
==============================================================================
--- rt/3.8/branches/html-css-cleanup/lib/RT/Interface/Email.pm (original)
+++ rt/3.8/branches/html-css-cleanup/lib/RT/Interface/Email.pm Thu Feb 12 15:38:12 2009
@@ -435,9 +435,8 @@
# duplicate head as we want drop Bcc field
my $head = $args{'Entity'}->head->dup;
- my @recipients = map $_->address, Email::Address->parse(
- map $head->get($_), qw(To Cc Bcc)
- );
+ my @recipients = map $_->address, map
+ Email::Address->parse($head->get($_)), qw(To Cc Bcc);
$head->delete('Bcc');
my $sender = RT->Config->Get('SMTPFrom')
Modified: rt/3.8/branches/html-css-cleanup/lib/RT/Principal_Overlay.pm
==============================================================================
--- rt/3.8/branches/html-css-cleanup/lib/RT/Principal_Overlay.pm (original)
+++ rt/3.8/branches/html-css-cleanup/lib/RT/Principal_Overlay.pm Thu Feb 12 15:38:12 2009
@@ -323,23 +323,13 @@
return (undef);
}
- # If this object is a ticket, we care about ticket roles and queue roles
- if ( UNIVERSAL::isa( $args{'Object'} => 'RT::Ticket' ) ) {
-
-
- # this is a little bit hacky, but basically, now that we've done
- # the ticket roles magic, we load the queue object
- # and ask all the rest of our questions about the queue.
- unshift @{ $args{'EquivObjects'} }, $args{'Object'}->ACLEquivalenceObjects;
-
- }
+ unshift @{ $args{'EquivObjects'} }, $args{'Object'}->ACLEquivalenceObjects;
unshift @{ $args{'EquivObjects'} }, $RT::System
unless $self->can('_IsOverrideGlobalACL')
&& $self->_IsOverrideGlobalACL( $args{'Object'} );
-
# {{{ If we've cached a win or loss for this lookup say so
# Construct a hashkeys to cache decisions:
Modified: rt/3.8/branches/html-css-cleanup/lib/RT/Record.pm
==============================================================================
--- rt/3.8/branches/html-css-cleanup/lib/RT/Record.pm (original)
+++ rt/3.8/branches/html-css-cleanup/lib/RT/Record.pm Thu Feb 12 15:38:12 2009
@@ -1889,15 +1889,9 @@
return $cf;
}
+sub ACLEquivalenceObjects { }
-# }}}
-
-# }}}
-
-# }}}
-
-sub BasicColumns {
-}
+sub BasicColumns { }
sub WikiBase {
return RT->Config->Get('WebPath'). "/index.html?q=";
Modified: rt/3.8/branches/html-css-cleanup/sbin/rt-validator.in
==============================================================================
--- rt/3.8/branches/html-css-cleanup/sbin/rt-validator.in (original)
+++ rt/3.8/branches/html-css-cleanup/sbin/rt-validator.in Thu Feb 12 15:38:12 2009
@@ -130,7 +130,7 @@
RT::Init();
my $dbh = $RT::Handle->dbh;
-my $db_type = $RT::DatabaseType;
+my $db_type = RT->Config->Get('DatabaseType');
my %TYPE = (
'Transactions.Field' => 'text',
@@ -497,10 +497,11 @@
);
# for every CGM where ImmediateParentId != GroupId there should be
- # matching parent record
+ # matching parent record (first level)
check_integrity(
- CachedGroupMembers => ['ImmediateParentId', 'MemberId', 'Via'],
- CachedGroupMembers => ['GroupId', 'MemberId', 'id'],
+ CachedGroupMembers => ['ImmediateParentId', 'MemberId'],
+ CachedGroupMembers => ['GroupId', 'MemberId'],
+ join_condition => 't.Via = t.id',
condition => 's.ImmediateParentId != s.GroupId',
action => sub {
my $id = shift;
@@ -516,8 +517,8 @@
# for every CGM where ImmediateParentId != GroupId there should be
# matching "grand" parent record
check_integrity(
- CachedGroupMembers => ['GroupId', 'ImmediateParentId'],
- CachedGroupMembers => ['GroupId', 'MemberId'],
+ CachedGroupMembers => ['GroupId', 'ImmediateParentId', 'Via'],
+ CachedGroupMembers => ['GroupId', 'MemberId', 'id'],
condition => 's.ImmediateParentId != s.GroupId',
action => sub {
my $id = shift;
@@ -531,25 +532,23 @@
);
# CHECK recursive records:
- # if we have G1 - (M1 == G2) - M2 then we should have G1 - M2 record with
- # Via = CGM2.id and IP = CGM2.G
- # Disabled field should be fixed separatedly
+ # if we have CGM1 (G1,M1,V1,IP1) then for every GM2(G2, M2), where G2 == M1,
+ # we should have CGM3 where G3 = G1, M3 = M2, V3 = ID1, IP3 = M1
{
my $query = <<END;
-SELECT grand.GroupId, parent.MemberId, parent.id AS Via,
- parent.GroupId AS ImmediateParentId, grand.Disabled, parent.Disabled
+SELECT cgm1.GroupId, gm2.MemberId, cgm1.id AS Via,
+ cgm1.MemberId AS ImmediateParentId, cgm1.Disabled
FROM
- CachedGroupMembers grand
- CROSS JOIN CachedGroupMembers parent
- LEFT JOIN CachedGroupMembers grand_child ON (
- grand_child.GroupId = grand.GroupId
- AND grand_child.MemberId = parent.MemberId
- AND grand_child.Via = parent.id
- AND grand_child.ImmediateParentId = parent.GroupId )
-WHERE grand.GroupId != grand.MemberId
-AND parent.GroupId != parent.MemberId
-AND parent.GroupId = grand.MemberId
-AND grand_child.id IS NULL
+ CachedGroupMembers cgm1
+ CROSS JOIN GroupMembers gm2
+ LEFT JOIN CachedGroupMembers cgm3 ON (
+ cgm3.GroupId = cgm1.GroupId
+ AND cgm3.MemberId = gm2.MemberId
+ AND cgm3.Via = cgm1.id
+ AND cgm3.ImmediateParentId = cgm1.MemberId )
+WHERE cgm1.GroupId != cgm1.MemberId
+AND gm2.GroupId = cgm1.MemberId
+AND cgm3.id IS NULL
END
my $action = sub {
@@ -562,12 +561,12 @@
};
my $sth = execute_query( $query );
- while ( my ($g, $m, $via, $ip, $gdis, $pdis) = $sth->fetchrow_array ) {
- print STDERR "Principal #$m is member of #$ip when #$ip is member of #$g,\n";
- print STDERR "but there is no cached GM record that $m is member of #$g.\n";
+ while ( my ($g, $m, $via, $ip, $dis) = $sth->fetchrow_array ) {
+ print STDERR "Principal #$m is member of #$ip when #$ip is member of #$g,";
+ print STDERR " but there is no cached GM record that $m is member of #$g.\n";
$action->(
GroupId => $g, MemberId => $m, Via => $via,
- ImmediateParentId => $ip, Disabled => $gdis || $pdis,
+ ImmediateParentId => $ip, Disabled => $dis,
);
}
}
@@ -650,7 +649,7 @@
);
# type = DelWatcher
check_integrity(
- 'Transactions', 'OldValue' => 'Users', 'id',
+ 'Transactions', 'OldValue' => 'Principals', 'id',
condition => 's.Type = ?',
bind_values => [ 'DelWatcher' ],
action => sub {
@@ -665,7 +664,7 @@
);
# type = AddWatcher
check_integrity(
- 'Transactions', 'NewValue' => 'Users', 'id',
+ 'Transactions', 'NewValue' => 'Principals', 'id',
condition => 's.Type = ?',
bind_values => [ 'AddWatcher' ],
action => sub {
@@ -822,11 +821,10 @@
my $query = <<END;
SELECT m.id, g.id, g.Instance
FROM
- Groups g JOIN $table m
+ Groups g JOIN $table m ON g.id = m.$column
WHERE
g.Domain = ?
AND g.Type = ?
- AND g.id = m.$column
END
my $action = sub {
my ($gid, $uid) = @_;
Modified: rt/3.8/branches/html-css-cleanup/share/html/Elements/RT__Ticket/ColumnMap
==============================================================================
--- rt/3.8/branches/html-css-cleanup/share/html/Elements/RT__Ticket/ColumnMap (original)
+++ rt/3.8/branches/html-css-cleanup/share/html/Elements/RT__Ticket/ColumnMap Thu Feb 12 15:38:12 2009
@@ -113,7 +113,12 @@
return \'<em>', loc('(pending approval)'), \'</em>';
}
else {
- return \'<em>', loc('(pending [quant,_1,other ticket])',$count), \'</em>';
+ my $Query = "DependedOnBy = " . $Ticket->id;
+ $Query .= " AND (" . join(" OR ", map { "Status = '$_'" } RT::Queue->ActiveStatusArray) . ")";
+
+ my $SearchURL = RT->Config->Get('WebPath') . '/Search/Results.html?' . $m->comp('/Elements/QueryString', Query => $Query);
+
+ return \'<a href="',$SearchURL,\'">', loc('(pending [quant,_1,other ticket])',$count), \'</a>';
}
}
else {
Modified: rt/3.8/branches/html-css-cleanup/share/html/NoAuth/css/web2/msie.css
==============================================================================
--- rt/3.8/branches/html-css-cleanup/share/html/NoAuth/css/web2/msie.css (original)
+++ rt/3.8/branches/html-css-cleanup/share/html/NoAuth/css/web2/msie.css Thu Feb 12 15:38:12 2009
@@ -129,6 +129,11 @@
.titlebox .titlebox .titlebox-title .right{
top: 0.25em;
}
+
+.combobox {
+ float: left;
+}
+
.combobox .combo-button {
color: ButtonText;
padding: 0;
Modified: rt/3.8/branches/html-css-cleanup/share/html/Search/Chart.html
==============================================================================
--- rt/3.8/branches/html-css-cleanup/share/html/Search/Chart.html (original)
+++ rt/3.8/branches/html-css-cleanup/share/html/Search/Chart.html Thu Feb 12 15:38:12 2009
@@ -55,7 +55,22 @@
<%init>
$ARGS{SecondaryGroupBy} ||= '';
-my $title = loc( "Search results grouped by [_1]", loc($PrimaryGroupBy) );
+# FIXME: should be factored with RT::Report::Tickets::Label :(
+my $PrimaryGroupByLabel;
+if ( $PrimaryGroupBy =~ /^(?:CF|CustomField)\.{(.*)}$/ ) {
+ my $cf = $1;
+ if ( $cf =~ /\D/ ) {
+ $PrimaryGroupByLabel = loc( "custom field '[_1]'", $cf );
+ } else {
+ my $obj = RT::CustomField->new( $session{'CurrentUser'} );
+ $obj->Load( $cf );
+ $PrimaryGroupByLabel = loc( "custom field '[_1]'", $obj->Name );
+ }
+} else {
+ $PrimaryGroupByLabel = loc( $PrimaryGroupBy );
+}
+
+my $title = loc( "Search results grouped by [_1]", $PrimaryGroupByLabel );
my $saved_search = $m->comp( '/Widgets/SavedSearch:new',
SearchType => 'Chart',
Modified: rt/3.8/branches/html-css-cleanup/share/html/Ticket/Update.html
==============================================================================
--- rt/3.8/branches/html-css-cleanup/share/html/Ticket/Update.html (original)
+++ rt/3.8/branches/html-css-cleanup/share/html/Ticket/Update.html Thu Feb 12 15:38:12 2009
@@ -100,6 +100,7 @@
% if (my $TxnCFs = $TicketObj->TransactionCustomFields) {
% while (my $CF = $TxnCFs->Next()) {
+% next unless $CF->CurrentUserHasRight('ModifyCustomField');
<tr>
<td class="label"><% $CF->Name %>:</td>
<td><& /Elements/EditCustomField, CustomField => $CF, NamePrefix =>
Modified: rt/3.8/branches/html-css-cleanup/share/html/Widgets/ComboBox
==============================================================================
--- rt/3.8/branches/html-css-cleanup/share/html/Widgets/ComboBox (original)
+++ rt/3.8/branches/html-css-cleanup/share/html/Widgets/ComboBox Thu Feb 12 15:38:12 2009
@@ -56,7 +56,7 @@
<option value="<%$value%>"><% $value%></option>
% }
</select>
-</span>
+</div>
<script language="javascript"><!--
ComboBox_InitWith('<% $Name %>');
//--></script>
Added: rt/3.8/branches/html-css-cleanup/t/validator/group_members.t
==============================================================================
--- (empty file)
+++ rt/3.8/branches/html-css-cleanup/t/validator/group_members.t Thu Feb 12 15:38:12 2009
@@ -0,0 +1,179 @@
+#!/usr/bin/perl -w
+
+use strict;
+use warnings;
+
+use Test::More tests => 60;
+use RT::Test;
+
+sub load_or_create_group {
+ my $name = shift;
+ my %args = (@_);
+
+ my $group = RT::Group->new( $RT::SystemUser );
+ $group->LoadUserDefinedGroup( $name );
+ unless ( $group->id ) {
+ my ($id, $msg) = $group->CreateUserDefinedGroup(
+ Name => $name,
+ );
+ die "$msg" unless $id;
+ }
+
+ if ( $args{Members} ) {
+ my $cur = $group->MembersObj;
+ while ( my $entry = $cur->Next ) {
+ my ($status, $msg) = $entry->Delete;
+ die "$msg" unless $status;
+ }
+
+ foreach my $new ( @{ $args{Members} } ) {
+ my ($status, $msg) = $group->AddMember(
+ ref($new)? $new->id : $new,
+ );
+ die "$msg" unless $status;
+ }
+ }
+
+ return $group;
+}
+
+my $validator_path = "$RT::SbinPath/rt-validator";
+sub run_validator {
+ my %args = (check => 1, resolve => 0, force => 1, @_ );
+
+ my $cmd = $validator_path;
+ die "Couldn't find $cmd command" unless -f $cmd;
+
+ while( my ($k,$v) = each %args ) {
+ next unless $v;
+ $cmd .= " --$k '$v'";
+ }
+ $cmd .= ' 2>&1';
+
+ require IPC::Open2;
+ my ($child_out, $child_in);
+ my $pid = IPC::Open2::open2($child_out, $child_in, $cmd);
+ close $child_in;
+
+ my $result = do { local $/; <$child_out> };
+ close $child_out;
+ waitpid $pid, 0;
+
+ DBIx::SearchBuilder::Record::Cachable->FlushCache
+ if $args{'resolve'};
+
+ return ($?, $result);
+}
+
+{
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
+{
+ my $group = load_or_create_group('test', Members => [] );
+ ok $group, "loaded or created a group";
+
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
+# G1 -> G2
+{
+ my $group1 = load_or_create_group( 'test1', Members => [] );
+ ok $group1, "loaded or created a group";
+
+ my $group2 = load_or_create_group( 'test2', Members => [ $group1 ]);
+ ok $group2, "loaded or created a group";
+
+ ok $group2->HasMember( $group1->id ), "has member";
+ ok $group2->HasMemberRecursively( $group1->id ), "has member";
+
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+
+ $RT::Handle->dbh->do("DELETE FROM CachedGroupMembers");
+ DBIx::SearchBuilder::Record::Cachable->FlushCache;
+ ok !$group2->HasMemberRecursively( $group1->id ), "has no member, broken DB";
+
+ ($ecode, $res) = run_validator(resolve => 1);
+
+ ok $group2->HasMember( $group1->id ), "has member";
+ ok $group2->HasMemberRecursively( $group1->id ), "has member";
+
+ ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
+# G1 <- G2 <- G3 <- G4 <- G5
+{
+ my @groups;
+ for (1..5) {
+ my $child = @groups? $groups[-1]: undef;
+
+ my $group = load_or_create_group( 'test'. $_, Members => [ $child? ($child): () ] );
+ ok $group, "loaded or created a group";
+
+ ok $group->HasMember( $child->id ), "has member"
+ if $child;
+ ok $group->HasMemberRecursively( $_->id ), "has member"
+ foreach @groups;
+
+ push @groups, $group;
+ }
+
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+
+ $RT::Handle->dbh->do("DELETE FROM CachedGroupMembers");
+ DBIx::SearchBuilder::Record::Cachable->FlushCache;
+
+ ok !$groups[1]->HasMemberRecursively( $groups[0]->id ), "has no member, broken DB";
+
+ ($ecode, $res) = run_validator(resolve => 1);
+
+ for ( my $i = 1; $i < @groups; $i++ ) {
+ ok $groups[$i]->HasMember( $groups[$i-1]->id ), "has member";
+ ok $groups[$i]->HasMemberRecursively( $groups[$_]->id ), "has member"
+ foreach 0..$i-1;
+ }
+
+ ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
+# G1 <- (G2, G3, G4, G5)
+{
+ my @groups;
+ for (2..5) {
+ my $group = load_or_create_group( 'test'. $_, Members => [] );
+ ok $group, "loaded or created a group";
+ push @groups, $group;
+ }
+
+ my $parent = load_or_create_group( 'test1', Members => \@groups );
+ ok $parent, "loaded or created a group";
+
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
+# G1 <- (G2, G3, G4) <- G5
+{
+ my $gchild = load_or_create_group( 'test5', Members => [] );
+ ok $gchild, "loaded or created a group";
+
+ my @groups;
+ for (2..4) {
+ my $group = load_or_create_group( 'test'. $_, Members => [ $gchild ] );
+ ok $group, "loaded or created a group";
+ push @groups, $group;
+ }
+
+ my $parent = load_or_create_group( 'test1', Members => \@groups );
+ ok $parent, "loaded or created a group";
+
+ my ($ecode, $res) = run_validator();
+ is $res, '', 'empty result';
+}
+
More information about the Rt-commit
mailing list