summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Ticket_Overlay.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/Ticket_Overlay.pm')
-rw-r--r--rt/lib/RT/Ticket_Overlay.pm298
1 files changed, 102 insertions, 196 deletions
diff --git a/rt/lib/RT/Ticket_Overlay.pm b/rt/lib/RT/Ticket_Overlay.pm
index 5960f0b63..a294dcafd 100644
--- a/rt/lib/RT/Ticket_Overlay.pm
+++ b/rt/lib/RT/Ticket_Overlay.pm
@@ -2,7 +2,7 @@
#
# COPYRIGHT:
#
-# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2005 Best Practical Solutions, LLC
# <jesse@bestpractical.com>
#
# (Except where explicitly superseded by other copyright notices)
@@ -22,9 +22,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 or visit their web page on the internet at
-# http://www.gnu.org/copyleft/gpl.html.
+# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
#
# CONTRIBUTION SUBMISSION POLICY:
@@ -153,7 +151,6 @@ use RT::Date;
use RT::CustomFields;
use RT::Tickets;
use RT::Transactions;
-use RT::Reminders;
use RT::URI::fsck_com_rt;
use RT::URI;
use MIME::Entity;
@@ -330,20 +327,10 @@ Arguments: ARGS is a hash of named parameters. Valid parameters are:
MIMEObj -- a MIME::Entity object with the content of the initial ticket request.
CustomField-<n> -- a scalar or array of values for the customfield with the id <n>
-Ticket links can be set up during create by passing the link type as a hask key and
-the ticket id to be linked to as a value (or a URI when linking to other objects).
-Multiple links of the same type can be created by passing an array ref. For example:
-
- Parent => 45,
- DependsOn => [ 15, 22 ],
- RefersTo => 'http://www.bestpractical.com',
-
-Supported link types are C<MemberOf>, C<HasMember>, C<RefersTo>, C<ReferredToBy>,
-C<DependsOn> and C<DependedOnBy>. Also, C<Parents> is alias for C<MemberOf> and
-C<Members> and C<Children> are aliases for C<HasMember>.
Returns: TICKETID, Transaction Object, Error Message
+
=begin testing
my $t = RT::Ticket->new($RT::SystemUser);
@@ -476,9 +463,10 @@ sub Create {
#If the status is an inactive status, set the resolved date
if ( $QueueObj->IsInactiveStatus( $args{'Status'} ) && !$args{'Resolved'} )
{
- $RT::Logger->debug( "Got a ". $args{'Status'}
- ." ticket with undefined resolved date. Setting to now."
- );
+ $RT::Logger->debug( "Got a "
+ . $args{'Status'}
+ . "ticket with a resolved of "
+ . $args{'Resolved'} );
$Resolved->SetToNow;
}
@@ -690,20 +678,6 @@ sub Create {
foreach my $link (
ref( $args{$type} ) ? @{ $args{$type} } : ( $args{$type} ) )
{
- # Check rights on the other end of the link if we must
- # then run _AddLink that doesn't check for ACLs
- if ( $RT::StrictLinkACL ) {
- my ($val, $msg, $obj) = $self->__GetTicketFromURI( URI => $link );
- unless ( $val ) {
- push @non_fatal_errors, $msg;
- next;
- }
- if ( $obj && !$obj->CurrentUserHasRight('ModifyTicket') ) {
- push @non_fatal_errors, $self->loc('Linking. Permission denied');
- next;
- }
- }
-
my ( $wval, $wmsg ) = $self->_AddLink(
Type => $LINKTYPEMAP{$type}->{'Type'},
$LINKTYPEMAP{$type}->{'Mode'} => $link,
@@ -1347,10 +1321,7 @@ sub AddWatcher {
# {{{ Check ACLS
#If the watcher we're trying to add is for the current user
- if ( $self->CurrentUser->PrincipalId == ($args{'PrincipalId'} || 0)
- or lc( $self->CurrentUser->UserObj->EmailAddress )
- eq lc( RT::User::CanonicalizeEmailAddress(undef, $args{'Email'}) || '' ) )
- {
+ if ( $self->CurrentUser->PrincipalId eq $args{'PrincipalId'}) {
# If it's an AdminCc and they don't have
# 'WatchAsAdminCc' or 'ModifyTicket', bail
if ( $args{'Type'} eq 'AdminCc' ) {
@@ -1514,7 +1485,7 @@ sub DeleteWatcher {
# {{{ Check ACLS
#If the watcher we're trying to add is for the current user
- if ( $self->CurrentUser->PrincipalId == $principal->id ) {
+ if ( $self->CurrentUser->PrincipalId eq $args{'PrincipalId'} ) {
# If it's an AdminCc and they don't have
# 'WatchAsAdminCc' or 'ModifyTicket', bail
@@ -2125,12 +2096,12 @@ sub SetStarted {
my $time = shift || 0;
unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
- return ( 0, $self->loc("Permission Denied") );
+ return ( 0, self->loc("Permission Denied") );
}
#We create a date object to catch date weirdness
my $time_obj = new RT::Date( $self->CurrentUser() );
- if ( $time ) {
+ if ( $time != 0 ) {
$time_obj->Set( Format => 'ISO', Value => $time );
}
else {
@@ -2423,9 +2394,8 @@ sub _RecordNote {
# If this is from an external source, we need to come up with its
# internal Message-ID now, so all emails sent because of this
# message have a common Message-ID
- unless ( ($args{'MIMEObj'}->head->get('Message-ID') || '')
- =~ /<(rt-.*?-\d+-\d+)\.(\d+-0-0)\@\Q$RT::Organization>/ )
- {
+ unless ($args{'MIMEObj'}->head->get('Message-ID')
+ =~ /<(rt-.*?-\d+-\d+)\.(\d+-0-0)\@$RT::Organization>/) {
$args{'MIMEObj'}->head->set( 'RT-Message-ID',
"<rt-"
. $RT::VERSION . "-"
@@ -2515,29 +2485,11 @@ sub DeleteLink {
@_
);
- unless ( $args{'Target'} || $args{'Base'} ) {
- $RT::Logger->error("Base or Target must be specified\n");
- return ( 0, $self->loc('Either base or target must be specified') );
- }
-
#check acls
- my $right = 0;
- $right++ if $self->CurrentUserHasRight('ModifyTicket');
- if ( !$right && $RT::StrictLinkACL ) {
- return ( 0, $self->loc("Permission Denied") );
- }
+ unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
+ $RT::Logger->debug("No permission to delete links\n");
+ return ( 0, $self->loc('Permission Denied'))
- # If the other URI is an RT::Ticket, we want to make sure the user
- # can modify it too...
- my ($status, $msg, $other_ticket) = $self->__GetTicketFromURI( URI => $args{'Target'} || $args{'Base'} );
- return (0, $msg) unless $status;
- if ( !$other_ticket || $other_ticket->CurrentUserHasRight('ModifyTicket') ) {
- $right++;
- }
- if ( ( !$RT::StrictLinkACL && $right == 0 ) ||
- ( $RT::StrictLinkACL && $right < 2 ) )
- {
- return ( 0, $self->loc("Permission Denied") );
}
my ($val, $Msg) = $self->SUPER::_DeleteLink(%args);
@@ -2605,52 +2557,13 @@ sub AddLink {
Silent => undef,
@_ );
- unless ( $args{'Target'} || $args{'Base'} ) {
- $RT::Logger->error("Base or Target must be specified\n");
- return ( 0, $self->loc('Either base or target must be specified') );
- }
- my $right = 0;
- $right++ if $self->CurrentUserHasRight('ModifyTicket');
- if ( !$right && $RT::StrictLinkACL ) {
- return ( 0, $self->loc("Permission Denied") );
- }
-
- # If the other URI is an RT::Ticket, we want to make sure the user
- # can modify it too...
- my ($status, $msg, $other_ticket) = $self->__GetTicketFromURI( URI => $args{'Target'} || $args{'Base'} );
- return (0, $msg) unless $status;
- if ( !$other_ticket || $other_ticket->CurrentUserHasRight('ModifyTicket') ) {
- $right++;
- }
- if ( ( !$RT::StrictLinkACL && $right == 0 ) ||
- ( $RT::StrictLinkACL && $right < 2 ) )
- {
+ unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
return ( 0, $self->loc("Permission Denied") );
}
- return $self->_AddLink(%args);
-}
-
-sub __GetTicketFromURI {
- my $self = shift;
- my %args = ( URI => '', @_ );
-
- # If the other URI is an RT::Ticket, we want to make sure the user
- # can modify it too...
- my $uri_obj = RT::URI->new( $self->CurrentUser );
- $uri_obj->FromURI( $args{'URI'} );
- unless ( $uri_obj->Resolver && $uri_obj->Scheme ) {
- my $msg = $self->loc( "Couldn't resolve '[_1]' into a URI.", $args{'URI'} );
- $RT::Logger->warning( "$msg\n" );
- return( 0, $msg );
- }
- my $obj = $uri_obj->Resolver->Object;
- unless ( UNIVERSAL::isa($obj, 'RT::Ticket') && $obj->id ) {
- return (1, 'Found not a ticket', undef);
- }
- return (1, 'Found ticket', $obj);
+ $self->_AddLink(%args);
}
=head2 _AddLink
@@ -2667,8 +2580,45 @@ sub _AddLink {
Silent => undef,
@_ );
- my ($val, $msg, $exist) = $self->SUPER::_AddLink(%args);
- return ($val, $msg) if !$val || $exist;
+ # {{{ If the other URI is an RT::Ticket, we want to make sure the user
+ # can modify it too...
+ my $other_ticket_uri = RT::URI->new($self->CurrentUser);
+
+ if ( $args{'Target'} ) {
+ $other_ticket_uri->FromURI( $args{'Target'} );
+
+ }
+ elsif ( $args{'Base'} ) {
+ $other_ticket_uri->FromURI( $args{'Base'} );
+ }
+
+ unless ( $other_ticket_uri->Resolver && $other_ticket_uri->Scheme ) {
+ my $msg = $args{'Target'} ? $self->loc("Couldn't resolve target '[_1]' into a URI.", $args{'Target'})
+ : $self->loc("Couldn't resolve base '[_1]' into a URI.", $args{'Base'});
+ $RT::Logger->warning( "$self $msg\n" );
+
+ return( 0, $msg );
+ }
+
+ if ( $other_ticket_uri->Resolver->Scheme eq 'fsck.com-rt') {
+ my $object = $other_ticket_uri->Resolver->Object;
+
+ if ( UNIVERSAL::isa( $object, 'RT::Ticket' )
+ && $object->id
+ && !$object->CurrentUserHasRight('ModifyTicket') )
+ {
+ return ( 0, $self->loc("Permission Denied") );
+ }
+
+ }
+
+ # }}}
+
+ my ($val, $Msg) = $self->SUPER::_AddLink(%args);
+
+ if (!$val) {
+ return ($val, $Msg);
+ }
my ($direction, $remote_link);
if ( $args{'Target'} ) {
@@ -2681,10 +2631,10 @@ sub _AddLink {
# Don't write the transaction if we're doing this on create
if ( $args{'Silent'} ) {
- return ( $val, $msg );
+ return ( $val, $Msg );
}
else {
- my $remote_uri = RT::URI->new( $self->CurrentUser );
+ my $remote_uri = RT::URI->new( $self->CurrentUser );
$remote_uri->FromURI( $remote_link );
#Write the transaction
@@ -2782,24 +2732,15 @@ sub MergeInto {
return ( 0, $self->loc("Merge failed. Couldn't set EffectiveId") );
}
+ my ( $status_val, $status_msg ) = $self->__Set( Field => 'Status', Value => 'resolved');
- if ( $self->__Value('Status') ne 'resolved' ) {
-
- my ( $status_val, $status_msg )
- = $self->__Set( Field => 'Status', Value => 'resolved' );
-
- unless ($status_val) {
- $RT::Handle->Rollback();
- $RT::Logger->error(
- $self->loc(
- "[_1] couldn't set status to resolved. RT's Database may be inconsistent.",
- $self
- )
- );
- return ( 0, $self->loc("Merge failed. Couldn't set Status") );
- }
+ unless ($status_val) {
+ $RT::Handle->Rollback();
+ $RT::Logger->error( $self->loc("[_1] couldn't set status to resolved. RT's Database may be inconsistent.", $self) );
+ return ( 0, $self->loc("Merge failed. Couldn't set Status") );
}
+
# update all the links that point to that old ticket
my $old_links_to = RT::Links->new($self->CurrentUser);
$old_links_to->Limit(FIELD => 'Target', VALUE => $self->URI);
@@ -2975,8 +2916,6 @@ my $txns = RT::Transactions->new($RT::SystemUser);
$txns->OrderBy(FIELD => 'id', ORDER => 'DESC');
$txns->Limit(FIELD => 'ObjectId', VALUE => '1');
$txns->Limit(FIELD => 'ObjectType', VALUE => 'RT::Ticket');
-$txns->Limit(FIELD => 'Type', OPERATOR => '!=', VALUE => 'EmailRecord');
-
my $steal = $txns->First;
ok($steal->OldValue == $root->Id , "Stolen from root");
ok($steal->NewValue == $RT::SystemUser->Id , "Stolen by the systemuser");
@@ -2990,77 +2929,68 @@ sub SetOwner {
my $NewOwner = shift;
my $Type = shift || "Give";
- $RT::Handle->BeginTransaction();
-
- $self->_SetLastUpdated(); # lock the ticket
- $self->Load( $self->id ); # in case $self changed while waiting for lock
-
- my $OldOwnerObj = $self->OwnerObj;
-
- my $NewOwnerObj = RT::User->new( $self->CurrentUser );
- $NewOwnerObj->Load( $NewOwner );
- unless ( $NewOwnerObj->Id ) {
- $RT::Handle->Rollback();
- return ( 0, $self->loc("That user does not exist") );
- }
-
-
# must have ModifyTicket rights
# or TakeTicket/StealTicket and $NewOwner is self
# see if it's a take
- if ( $OldOwnerObj->Id == $RT::Nobody->Id ) {
+ if ( $self->OwnerObj->Id == $RT::Nobody->Id ) {
unless ( $self->CurrentUserHasRight('ModifyTicket')
|| $self->CurrentUserHasRight('TakeTicket') ) {
- $RT::Handle->Rollback();
return ( 0, $self->loc("Permission Denied") );
}
}
# see if it's a steal
- elsif ( $OldOwnerObj->Id != $RT::Nobody->Id
- && $OldOwnerObj->Id != $self->CurrentUser->id ) {
+ elsif ( $self->OwnerObj->Id != $RT::Nobody->Id
+ && $self->OwnerObj->Id != $self->CurrentUser->id ) {
unless ( $self->CurrentUserHasRight('ModifyTicket')
|| $self->CurrentUserHasRight('StealTicket') ) {
- $RT::Handle->Rollback();
return ( 0, $self->loc("Permission Denied") );
}
}
else {
unless ( $self->CurrentUserHasRight('ModifyTicket') ) {
- $RT::Handle->Rollback();
return ( 0, $self->loc("Permission Denied") );
}
}
+ my $NewOwnerObj = RT::User->new( $self->CurrentUser );
+ my $OldOwnerObj = $self->OwnerObj;
- # If we're not stealing and the ticket has an owner and it's not
- # the current user
- if ( $Type ne 'Steal' and $Type ne 'Force'
- and $OldOwnerObj->Id != $RT::Nobody->Id
- and $OldOwnerObj->Id != $self->CurrentUser->Id )
- {
- $RT::Handle->Rollback();
- return ( 0, $self->loc("You can only take tickets that are unowned") )
- if $NewOwnerObj->id == $self->CurrentUser->id;
- return (
- 0,
- $self->loc("You can only reassign tickets that you own or that are unowned" )
- );
+ $NewOwnerObj->Load($NewOwner);
+ if ( !$NewOwnerObj->Id ) {
+ return ( 0, $self->loc("That user does not exist") );
+ }
+
+ #If thie ticket has an owner and it's not the current user
+
+ if ( ( $Type ne 'Steal' )
+ and ( $Type ne 'Force' )
+ and #If we're not stealing
+ ( $self->OwnerObj->Id != $RT::Nobody->Id ) and #and the owner is set
+ ( $self->CurrentUser->Id ne $self->OwnerObj->Id() )
+ ) { #and it's not us
+ return ( 0,
+ $self->loc(
+"You can only reassign tickets that you own or that are unowned" ) );
}
#If we've specified a new owner and that user can't modify the ticket
- elsif ( !$NewOwnerObj->HasRight( Right => 'OwnTicket', Object => $self ) ) {
- $RT::Handle->Rollback();
+ elsif ( ( $NewOwnerObj->Id )
+ and ( !$NewOwnerObj->HasRight( Right => 'OwnTicket',
+ Object => $self ) )
+ ) {
return ( 0, $self->loc("That user may not own tickets in that queue") );
}
- # If the ticket has an owner and it's the new owner, we don't need
- # To do anything
- elsif ( $NewOwnerObj->Id == $OldOwnerObj->Id ) {
- $RT::Handle->Rollback();
+ #If the ticket has an owner and it's the new owner, we don't need
+ #To do anything
+ elsif ( ( $self->OwnerObj )
+ and ( $NewOwnerObj->Id eq $self->OwnerObj->Id ) ) {
return ( 0, $self->loc("That user already owns that ticket") );
}
+ $RT::Handle->BeginTransaction();
+
# Delete the owner in the owner group, then add a new one
# TODO: is this safe? it's not how we really want the API to work
# for most things, but it's fast.
@@ -3095,6 +3025,8 @@ sub SetOwner {
return ( 0, $self->loc("Could not change owner. ") . $msg );
}
+ $RT::Handle->Commit();
+
($val, $msg) = $self->_NewTransaction(
Type => $Type,
Field => 'Owner',
@@ -3106,14 +3038,9 @@ sub SetOwner {
if ( $val ) {
$msg = $self->loc( "Owner changed from [_1] to [_2]",
$OldOwnerObj->Name, $NewOwnerObj->Name );
- }
- else {
- $RT::Handle->Rollback();
- return ( 0, $msg );
- }
-
- $RT::Handle->Commit();
+ # TODO: make sure the trans committed properly
+ }
return ( $val, $msg );
}
@@ -3458,8 +3385,6 @@ sub DESTROY {
return if $self->{_Destroyed}++;
my $batch = $self->TransactionBatch or return;
- return unless @$batch;
-
require RT::Scrips;
RT::Scrips->new($RT::SystemUser)->Apply(
Stage => 'TransactionBatch',
@@ -3692,26 +3617,6 @@ sub HasRight {
# }}}
-=head2 Reminders
-
-Return the Reminders object for this ticket. (It's an RT::Reminders object.)
-It isn't acutally a searchbuilder collection itself.
-
-=cut
-
-sub Reminders {
- my $self = shift;
-
- unless ($self->{'__reminders'}) {
- $self->{'__reminders'} = RT::Reminders->new($self->CurrentUser);
- $self->{'__reminders'}->Ticket($self->id);
- }
- return $self->{'__reminders'};
-
-}
-
-
-
# {{{ sub Transactions
=head2 Transactions
@@ -3756,7 +3661,7 @@ sub Transactions {
=head2 TransactionCustomFields
- Returns the custom fields that transactions on tickets will have.
+ Returns the custom fields that transactions on tickets will ahve.
=cut
@@ -3791,6 +3696,7 @@ sub CustomFieldValues {
# If we didn't find a valid cfid, give up.
return RT::CustomFieldValues->new($self->CurrentUser);
}
+ $field = $cf->id;
}
return $self->SUPER::CustomFieldValues($field);
}