[Rt-commit] r7253 - in rt/branches/3.6-RELEASE: .
jesse at bestpractical.com
jesse at bestpractical.com
Thu Mar 15 17:24:47 EDT 2007
Author: jesse
Date: Thu Mar 15 17:24:46 2007
New Revision: 7253
Modified:
rt/branches/3.6-RELEASE/ (props changed)
rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm
Log:
r53457 at 124: jesse | 2007-03-15 17:18:44 -0400
RT-Ticket: 8186
RT-Status: resolved
RT-Update: correspond
* Patch for a possible race condition in the "SetOwner" routine that could be triggered when two users tried to take a ticket at the same time. Thanks to Todd Chapman!
Modified: rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm
==============================================================================
--- rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm (original)
+++ rt/branches/3.6-RELEASE/lib/RT/Ticket_Overlay.pm Thu Mar 15 17:24:46 2007
@@ -2979,14 +2979,28 @@
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 ) {
unless ( $self->CurrentUserHasRight('ModifyTicket')
|| $self->CurrentUserHasRight('TakeTicket') ) {
+ $RT::Handle->Rollback();
return ( 0, $self->loc("Permission Denied") );
}
}
@@ -2997,27 +3011,24 @@
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 );
- $NewOwnerObj->Load( $NewOwner );
- unless ( $NewOwnerObj->Id ) {
- return ( 0, $self->loc("That user does not exist") );
- }
-
- # If we're not stealing and the ticket has an owner and it's not
+ # 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 (
@@ -3028,17 +3039,17 @@
#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();
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();
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.
@@ -3073,8 +3084,6 @@
return ( 0, $self->loc("Could not change owner. ") . $msg );
}
- $RT::Handle->Commit();
-
($val, $msg) = $self->_NewTransaction(
Type => $Type,
Field => 'Owner',
@@ -3086,9 +3095,14 @@
if ( $val ) {
$msg = $self->loc( "Owner changed from [_1] to [_2]",
$OldOwnerObj->Name, $NewOwnerObj->Name );
-
- # TODO: make sure the trans committed properly
}
+ else {
+ $RT::Handle->Rollback();
+ return ( 0, $msg );
+ }
+
+ $RT::Handle->Commit();
+
return ( $val, $msg );
}
More information about the Rt-commit
mailing list