summaryrefslogtreecommitdiff
path: root/rt/lib/RT/Attribute_Overlay.pm
diff options
context:
space:
mode:
Diffstat (limited to 'rt/lib/RT/Attribute_Overlay.pm')
-rw-r--r--rt/lib/RT/Attribute_Overlay.pm469
1 files changed, 0 insertions, 469 deletions
diff --git a/rt/lib/RT/Attribute_Overlay.pm b/rt/lib/RT/Attribute_Overlay.pm
deleted file mode 100644
index 298f2e1..0000000
--- a/rt/lib/RT/Attribute_Overlay.pm
+++ /dev/null
@@ -1,469 +0,0 @@
-# BEGIN BPS TAGGED BLOCK {{{
-#
-# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2007 Best Practical Solutions, LLC
-# <jesse@bestpractical.com>
-#
-# (Except where explicitly superseded by other copyright notices)
-#
-#
-# LICENSE:
-#
-# This work is made available to you under the terms of Version 2 of
-# the GNU General Public License. A copy of that license should have
-# been provided with this software, but in any event can be snarfed
-# from www.gnu.org.
-#
-# This work is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-# General Public License for more details.
-#
-# 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.
-#
-#
-# CONTRIBUTION SUBMISSION POLICY:
-#
-# (The following paragraph is not intended to limit the rights granted
-# to you to modify and distribute this software under the terms of
-# the GNU General Public License and is only of importance to you if
-# you choose to contribute your changes and enhancements to the
-# community by submitting them to Best Practical Solutions, LLC.)
-#
-# By intentionally submitting any modifications, corrections or
-# derivatives to this work, or any other work intended for use with
-# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-# you are the copyright holder for those contributions and you grant
-# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
-# royalty-free, perpetual, license to use, copy, create derivative
-# works based on those contributions, and sublicense and distribute
-# those contributions and any derivatives thereof.
-#
-# END BPS TAGGED BLOCK }}}
-package RT::Attribute;
-
-use strict;
-no warnings qw(redefine);
-use Storable qw/nfreeze thaw/;
-use MIME::Base64;
-
-
-=head1 NAME
-
- RT::Attribute_Overlay
-
-=head1 Content
-
-=cut
-
-# the acl map is a map of "name of attribute" and "what right the user must have on the associated object to see/edit it
-
-our $ACL_MAP = {
- SavedSearch => { create => 'EditSavedSearches',
- update => 'EditSavedSearches',
- delete => 'EditSavedSearches',
- display => 'ShowSavedSearches' },
-
-};
-
-# There are a number of attributes that users should be able to modify for themselves, such as saved searches
-# we could do this with a different set of "modify" rights, but that gets very hacky very fast. this is even faster and even
-# hackier. we're hardcoding that a different set of rights are needed for attributes on oneself
-our $PERSONAL_ACL_MAP = {
- SavedSearch => { create => 'ModifySelf',
- update => 'ModifySelf',
- delete => 'ModifySelf',
- display => 'allow' },
-
-};
-
-=head2 LookupObjectRight { ObjectType => undef, ObjectId => undef, Name => undef, Right => { create, update, delete, display } }
-
-Returns the right that the user needs to have on this attribute's object to perform the related attribute operation. Returns "allow" if the right is otherwise unspecified.
-
-=cut
-
-sub LookupObjectRight {
- my $self = shift;
- my %args = ( ObjectType => undef,
- ObjectId => undef,
- Right => undef,
- Name => undef,
- @_);
-
- # if it's an attribute on oneself, check the personal acl map
- if (($args{'ObjectType'} eq 'RT::User') && ($args{'ObjectId'} eq $self->CurrentUser->Id)) {
- return('allow') unless ($PERSONAL_ACL_MAP->{$args{'Name'}});
- return('allow') unless ($PERSONAL_ACL_MAP->{$args{'Name'}}->{$args{'Right'}});
- return($PERSONAL_ACL_MAP->{$args{'Name'}}->{$args{'Right'}});
-
- }
- # otherwise check the main ACL map
- else {
- return('allow') unless ($ACL_MAP->{$args{'Name'}});
- return('allow') unless ($ACL_MAP->{$args{'Name'}}->{$args{'Right'}});
- return($ACL_MAP->{$args{'Name'}}->{$args{'Right'}});
- }
-}
-
-
-
-
-=head2 Create PARAMHASH
-
-Create takes a hash of values and creates a row in the database:
-
- varchar(200) 'Name'.
- varchar(255) 'Content'.
- varchar(16) 'ContentType',
- varchar(64) 'ObjectType'.
- int(11) 'ObjectId'.
-
-You may pass a C<Object> instead of C<ObjectType> and C<ObjectId>.
-
-=cut
-
-
-
-
-sub Create {
- my $self = shift;
- my %args = (
- Name => '',
- Description => '',
- Content => '',
- ContentType => '',
- Object => undef,
- @_);
-
- if ($args{Object} and UNIVERSAL::can($args{Object}, 'Id')) {
- $args{ObjectType} = ref($args{Object});
- $args{ObjectId} = $args{Object}->Id;
- } else {
- return(0, $self->loc("Required parameter '[_1]' not specified", 'Object'));
-
- }
-
- # object_right is the right that the user has to have on the object for them to have $right on this attribute
- my $object_right = $self->LookupObjectRight(
- Right => 'create',
- ObjectId => $args{'ObjectId'},
- ObjectType => $args{'ObjectType'},
- Name => $args{'Name'}
- );
- if ($object_right eq 'deny') {
- return (0, $self->loc('Permission Denied'));
- }
- elsif ($object_right eq 'allow') {
- # do nothing, we're ok
- }
- elsif (!$self->CurrentUser->HasRight( Object => $args{Object}, Right => $object_right)) {
- return (0, $self->loc('Permission Denied'));
- }
-
-
- if (ref ($args{'Content'}) ) {
- eval {$args{'Content'} = $self->_SerializeContent($args{'Content'}); };
- if ($@) {
- return(0, $@);
- }
- $args{'ContentType'} = 'storable';
- }
-
-
- $self->SUPER::Create(
- Name => $args{'Name'},
- Content => $args{'Content'},
- ContentType => $args{'ContentType'},
- Description => $args{'Description'},
- ObjectType => $args{'ObjectType'},
- ObjectId => $args{'ObjectId'},
-);
-
-}
-
-
-# {{{ sub LoadByNameAndObject
-
-=head2 LoadByNameAndObject (Object => OBJECT, Name => NAME)
-
-Loads the Attribute named NAME for Object OBJECT.
-
-=cut
-
-sub LoadByNameAndObject {
- my $self = shift;
- my %args = (
- Object => undef,
- Name => undef,
- @_,
- );
-
- return (
- $self->LoadByCols(
- Name => $args{'Name'},
- ObjectType => ref($args{'Object'}),
- ObjectId => $args{'Object'}->Id,
- )
- );
-
-}
-
-# }}}
-
-
-=head2 _DeserializeContent
-
-DeserializeContent returns this Attribute's "Content" as a hashref.
-
-
-=cut
-
-sub _DeserializeContent {
- my $self = shift;
- my $content = shift;
-
- my $hashref;
- eval {$hashref = thaw(decode_base64($content))} ;
- if ($@) {
- $RT::Logger->error("Deserialization of attribute ".$self->Id. " failed");
- }
-
- return($hashref);
-
-}
-
-
-=head2 Content
-
-Returns this attribute's content. If it's a scalar, returns a scalar
-If it's data structure returns a ref to that data structure.
-
-=cut
-
-sub Content {
- my $self = shift;
- # Here we call _Value to get the ACL check.
- my $content = $self->_Value('Content');
- if ($self->__Value('ContentType') eq 'storable') {
- eval {$content = $self->_DeserializeContent($content); };
- if ($@) {
- $RT::Logger->error("Deserialization of content for attribute ".$self->Id. " failed. Attribute was: ".$content);
- }
- }
-
- return($content);
-
-}
-
-sub _SerializeContent {
- my $self = shift;
- my $content = shift;
- return( encode_base64(nfreeze($content)));
-}
-
-
-sub SetContent {
- my $self = shift;
- my $content = shift;
-
- # Call __Value to avoid ACL check.
- if ($self->__Value('ContentType') eq 'storable') {
- # We eval the serialization because it will lose on a coderef.
- eval {$content = $self->_SerializeContent($content); };
- if ($@) {
- $RT::Logger->error("For some reason, content couldn't be frozen");
- return(0, $@);
- }
- }
- return ($self->SUPER::SetContent($content));
-}
-
-=head2 SubValue KEY
-
-Returns the subvalue for $key.
-
-=begin testing
-
-my $user = $RT::SystemUser;
-my ($id, $msg) = $user->AddAttribute(Name => 'SavedSearch', Content => { Query => 'Foo'} );
-ok ($id, $msg);
-my $attr = RT::Attribute->new($RT::SystemUser);
-$attr->Load($id);
-ok($attr->Name eq 'SavedSearch');
-$attr->SetSubValues( Format => 'baz');
-
-my $format = $attr->SubValue('Format');
-is ($format , 'baz');
-
-$attr->SetSubValues( Format => 'bar');
-$format = $attr->SubValue('Format');
-is ($format , 'bar');
-
-$attr->DeleteAllSubValues();
-$format = $attr->SubValue('Format');
-is ($format, undef);
-
-$attr->SetSubValues(Format => 'This is a format');
-
-my $attr2 = RT::Attribute->new($RT::SystemUser);
-$attr2->Load($id);
-is ($attr2->SubValue('Format'), 'This is a format');
-$attr2->Delete;
-my $attr3 = RT::Attribute->new($RT::SystemUser);
-my ($id) = $attr3->Load($id);
-is ($id, 0);
-
-=end testing
-
-=cut
-
-sub SubValue {
- my $self = shift;
- my $key = shift;
- my $values = $self->Content();
- return undef unless ref($values);
- return($values->{$key});
-}
-
-=head2 DeleteSubValue NAME
-
-Deletes the subvalue with the key NAME
-
-=cut
-
-sub DeleteSubValue {
- my $self = shift;
- my $key = shift;
- my %values = $self->Content();
- delete $values{$key};
- $self->SetContent(%values);
-
-
-
-}
-
-
-=head2 DeleteAllSubValues
-
-Deletes all subvalues for this attribute
-
-=cut
-
-
-sub DeleteAllSubValues {
- my $self = shift;
- $self->SetContent({});
-}
-
-=head2 SetSubValues { }
-
-Takes a hash of keys and values and stores them in the content of this attribute.
-
-Each key B<replaces> the existing key with the same name
-
-Returns a tuple of (status, message)
-
-=cut
-
-
-sub SetSubValues {
- my $self = shift;
- my %args = (@_);
- my $values = ($self->Content() || {} );
- foreach my $key (keys %args) {
- $values->{$key} = $args{$key};
- }
-
- $self->SetContent($values);
-
-}
-
-
-sub Object {
- my $self = shift;
- my $object_type = $self->__Value('ObjectType');
- my $object;
- eval { $object = $object_type->new($self->CurrentUser) };
- unless(UNIVERSAL::isa($object, $object_type)) {
- $RT::Logger->error("Attribute ".$self->Id." has a bogus object type - $object_type (".$@.")");
- return(undef);
- }
- $object->Load($self->__Value('ObjectId'));
-
- return($object);
-
-}
-
-
-sub Delete {
- my $self = shift;
- unless ($self->CurrentUserHasRight('delete')) {
- return (0,$self->loc('Permission Denied'));
- }
- return($self->SUPER::Delete(@_));
-}
-
-
-sub _Value {
- my $self = shift;
- unless ($self->CurrentUserHasRight('display')) {
- return (0,$self->loc('Permission Denied'));
- }
-
- return($self->SUPER::_Value(@_));
-
-
-}
-
-
-sub _Set {
- my $self = shift;
- unless ($self->CurrentUserHasRight('modify')) {
-
- return (0,$self->loc('Permission Denied'));
- }
- return($self->SUPER::_Set(@_));
-
-}
-
-
-=head2 CurrentUserHasRight
-
-One of "display" "modify" "delete" or "create" and returns 1 if the user has that right for attributes of this name for this object.Returns undef otherwise.
-
-=cut
-
-sub CurrentUserHasRight {
- my $self = shift;
- my $right = shift;
-
- # object_right is the right that the user has to have on the object for them to have $right on this attribute
- my $object_right = $self->LookupObjectRight(
- Right => $right,
- ObjectId => $self->__Value('ObjectId'),
- ObjectType => $self->__Value('ObjectType'),
- Name => $self->__Value('Name')
- );
-
- return (1) if ($object_right eq 'allow');
- return (0) if ($object_right eq 'deny');
- return(1) if ($self->CurrentUser->HasRight( Object => $self->Object, Right => $object_right));
- return(0);
-
-}
-
-
-=head1 TODO
-
-We should be deserializing the content on load and then enver again, rather than at every access
-
-=cut
-
-
-1;