X-Git-Url: http://git.freeside.biz/gitweb/?p=freeside.git;a=blobdiff_plain;f=rt%2Flib%2FRT%2FSharedSetting.pm;h=4a08d07735ffc882b79c7e64a4acfc0abb2e3b03;hp=6d1dbfeb44bc539526811132140d6e7219cb38ca;hb=9aee669886202be7035e6c6049fc71bc99dd3013;hpb=b5c4237a34aef94976bc343c8d9e138664fc3984 diff --git a/rt/lib/RT/SharedSetting.pm b/rt/lib/RT/SharedSetting.pm index 6d1dbfeb4..4a08d0773 100644 --- a/rt/lib/RT/SharedSetting.pm +++ b/rt/lib/RT/SharedSetting.pm @@ -2,7 +2,7 @@ # # COPYRIGHT: # -# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC +# This software is Copyright (c) 1996-2015 Best Practical Solutions, LLC # # # (Except where explicitly superseded by other copyright notices) @@ -64,9 +64,11 @@ It consists of an ID, a name, and some arbitrary data. package RT::SharedSetting; use strict; use warnings; -use RT::Attribute; use base qw/RT::Base/; +use RT::Attribute; +use Scalar::Util 'blessed'; + =head1 METHODS =head2 new @@ -101,24 +103,28 @@ sub Load { my $object = $self->_GetObject($privacy); if ($object) { - $self->{'Attribute'} = $object->Attributes->WithId($id); + $self->{'Attribute'} = RT::Attribute->new($self->CurrentUser); + $self->{'Attribute'}->Load( $id ); if ($self->{'Attribute'}->Id) { $self->{'Id'} = $self->{'Attribute'}->Id; $self->{'Privacy'} = $privacy; $self->PostLoad(); - return (0, $self->loc("Permission denied")) + return wantarray ? (0, $self->loc("Permission Denied")) : 0 unless $self->CurrentUserCanSee; - return (1, $self->loc("Loaded [_1] [_2]", $self->ObjectName, $self->Name)); + my ($ok, $msg) = $self->PostLoadValidate; + return wantarray ? ($ok, $msg) : $ok if !$ok; + + return wantarray ? (1, $self->loc("Loaded [_1] [_2]", $self->ObjectName, $self->Name)) : 1; } else { $RT::Logger->error("Could not load attribute " . $id . " for object " . $privacy); - return (0, $self->loc("Failed to load [_1] [_2]", $self->ObjectName, $id)) + return wantarray ? (0, $self->loc("Failed to load [_1] [_2]", $self->ObjectName, $id)) : 0; } } else { $RT::Logger->warning("Could not load object $privacy when loading " . $self->ObjectName); - return (0, $self->loc("Could not load object for [_1]", $privacy)); + return wantarray ? (0, $self->loc("Could not load object for [_1]", $privacy)) : 0; } } @@ -138,11 +144,11 @@ sub LoadById { my ($ok, $msg) = $attr->LoadById($id); if (!$ok) { - return (0, $self->loc("Failed to load [_1] [_2]: [_3]", $self->ObjectName, $id, $msg)) + return wantarray ? (0, $self->loc("Failed to load [_1] [_2]: [_3]", $self->ObjectName, $id, $msg)) : 0; } my $privacy = $self->_build_privacy($attr->ObjectType, $attr->ObjectId); - return (0, $self->loc("Bad privacy for attribute [_1]", $id)) + return wantarray ? (0, $self->loc("Bad privacy for attribute [_1]", $id)) : 0 if !$privacy; return $self->Load($privacy, $id); @@ -150,12 +156,24 @@ sub LoadById { =head2 PostLoad -Called after after successful L. +Called after a successful L. =cut sub PostLoad { } +=head2 PostLoadValidate + +Called just before returning success from L; may be used to validate +that the record is correct. This method is expected to return a (ok, msg) +pair. + +=cut + +sub PostLoadValidate { + return 1; +} + =head2 Save Creates a new shared setting. Takes a privacy, a name, and any other arguments. @@ -174,7 +192,7 @@ sub Save { my %args = ( 'Privacy' => 'RT::User-' . $self->CurrentUser->Id, 'Name' => "new " . $self->ObjectName, - @_, + @_, ); my $privacy = $args{'Privacy'}; @@ -184,20 +202,21 @@ sub Save { return (0, $self->loc("Failed to load object for [_1]", $privacy)) unless $object; - return (0, $self->loc("Permission denied")) + return (0, $self->loc("Permission Denied")) unless $self->CurrentUserCanCreate($privacy); my ($att_id, $att_msg) = $self->SaveAttribute($object, \%args); if ($att_id) { - $self->{'Attribute'} = $object->Attributes->WithId($att_id); + $self->{'Attribute'} = RT::Attribute->new($self->CurrentUser); + $self->{'Attribute'}->Load( $att_id ); $self->{'Id'} = $att_id; $self->{'Privacy'} = $privacy; - return ( 1, $self->loc( "Saved [_1] [_2]", $self->ObjectName, $name ) ); + return ( 1, $self->loc( "Saved [_1] [_2]", $self->loc( $self->ObjectName ), $name ) ); } else { $RT::Logger->error($self->ObjectName . " save failure: $att_msg"); - return ( 0, $self->loc("Failed to create [_1] attribute", $self->ObjectName) ); + return ( 0, $self->loc("Failed to create [_1] attribute", $self->loc( $self->ObjectName ) ) ); } } @@ -225,7 +244,7 @@ sub Update { return(0, $self->loc("Could not load [_1] attribute", $self->ObjectName)) unless $self->{'Attribute'}->Id; - return (0, $self->loc("Permission denied")) + return (0, $self->loc("Permission Denied")) unless $self->CurrentUserCanModify; my ($status, $msg) = $self->UpdateAttribute(\%args); @@ -257,11 +276,11 @@ where status is true upon success. sub Delete { my $self = shift; - - return (0, $self->loc("Permission denied")) + return (0, $self->loc("Permission Denied")) unless $self->CurrentUserCanDelete; my ($status, $msg) = $self->{'Attribute'}->Delete; + $self->CurrentUser->ClearAttributes; # force the current user's attribute cache to be cleaned up if ($status) { return (1, $self->loc("Deleted [_1]", $self->ObjectName)); } else { @@ -294,6 +313,9 @@ sub Id { return $self->{'Id'}; } +*id = \&Id; + + =head2 Privacy Returns the principal object to whom this shared setting belongs, in a string @@ -329,7 +351,7 @@ This does not deal with ACLs, this only looks at membership. sub IsVisibleTo { my $self = shift; my $to = shift; - my $privacy = $self->Privacy; + my $privacy = $self->Privacy || ''; # if the privacies are the same, then they can be seen. this handles # a personal setting being visible to that user. @@ -372,6 +394,11 @@ sub _GetObject { my $self = shift; my $privacy = shift; + # short circuit: if they pass the object we want anyway, just return it + if (blessed($privacy) && $privacy->isa('RT::Record')) { + return $privacy; + } + my ($obj_type, $obj_id) = split(/\-/, ($privacy || '')); unless ($obj_type && $obj_id) { @@ -395,7 +422,9 @@ sub _GetObject { return undef; } - if ($obj_type eq 'RT::Group' && !$object->HasMemberRecursively($self->CurrentUser->PrincipalObj)) { + if ( $obj_type eq 'RT::Group' + && !$object->HasMemberRecursively($self->CurrentUser->PrincipalObj) + && !$self->CurrentUser->HasRight( Object => $RT::System, Right => 'SuperUser' ) ) { $RT::Logger->debug("Permission denied, ".$self->CurrentUser->Name. " is not a member of group"); return undef; @@ -450,6 +479,42 @@ sub _build_privacy { : undef; } +=head2 ObjectsForLoading + +Returns a list of objects that can be used to load this shared setting. It +is ACL checked. + +=cut + +sub ObjectsForLoading { + my $self = shift; + return grep { $self->CurrentUserCanSee($_) } $self->_PrivacyObjects; +} + +=head2 ObjectsForCreating + +Returns a list of objects that can be used to create this shared setting. It +is ACL checked. + +=cut + +sub ObjectsForCreating { + my $self = shift; + return grep { $self->CurrentUserCanCreate($_) } $self->_PrivacyObjects; +} + +=head2 ObjectsForModifying + +Returns a list of objects that can be used to modify this shared setting. It +is ACL checked. + +=cut + +sub ObjectsForModifying { + my $self = shift; + return grep { $self->CurrentUserCanModify($_) } $self->_PrivacyObjects; +} + RT::Base->_ImportOverlays(); 1;