rt 4.2.16
[freeside.git] / rt / lib / RT / Dashboard.pm
index 9fb2e60..24764b7 100644 (file)
@@ -2,7 +2,7 @@
 #
 # COPYRIGHT:
 #
-# This software is Copyright (c) 1996-2011 Best Practical Solutions, LLC
+# This software is Copyright (c) 1996-2019 Best Practical Solutions, LLC
 #                                          <sales@bestpractical.com>
 #
 # (Except where explicitly superseded by other copyright notices)
 
 package RT::Dashboard;
 
-use RT::SavedSearch;
-
 use strict;
 use warnings;
+
 use base qw/RT::SharedSetting/;
 
+use RT::SavedSearch;
+
 use RT::System;
-RT::System::AddRights(
-    SubscribeDashboard => 'Subscribe to dashboards', #loc_pair
+'RT::System'->AddRight( Staff   => SubscribeDashboard => 'Subscribe to dashboards'); # loc
 
-    SeeDashboard       => 'View system dashboards', #loc_pair
-    CreateDashboard    => 'Create system dashboards', #loc_pair
-    ModifyDashboard    => 'Modify system dashboards', #loc_pair
-    DeleteDashboard    => 'Delete system dashboards', #loc_pair
+'RT::System'->AddRight( General => SeeDashboard       => 'View system dashboards'); # loc
+'RT::System'->AddRight( Admin   => CreateDashboard    => 'Create system dashboards'); # loc
+'RT::System'->AddRight( Admin   => ModifyDashboard    => 'Modify system dashboards'); # loc
+'RT::System'->AddRight( Admin   => DeleteDashboard    => 'Delete system dashboards'); # loc
 
-    SeeOwnDashboard    => 'View personal dashboards', #loc_pair
-    CreateOwnDashboard => 'Create personal dashboards', #loc_pair
-    ModifyOwnDashboard => 'Modify personal dashboards', #loc_pair
-    DeleteOwnDashboard => 'Delete personal dashboards', #loc_pair
-);
+'RT::System'->AddRight( Staff   => SeeOwnDashboard    => 'View personal dashboards'); # loc
+'RT::System'->AddRight( Staff   => CreateOwnDashboard => 'Create personal dashboards'); # loc
+'RT::System'->AddRight( Staff   => ModifyOwnDashboard => 'Modify personal dashboards'); # loc
+'RT::System'->AddRight( Staff   => DeleteOwnDashboard => 'Delete personal dashboards'); # loc
 
 
 =head2 ObjectName
@@ -95,7 +94,7 @@ An object of this class is called "dashboard"
 
 =cut
 
-sub ObjectName { "dashboard" }
+sub ObjectName { "dashboard" } # loc
 
 sub SaveAttribute {
     my $self   = shift;
@@ -142,6 +141,19 @@ sub UpdateAttribute {
     return ($status, $msg);
 }
 
+=head2 PostLoadValidate
+
+Ensure that the ID corresponds to an actual dashboard object, since it's all
+attributes under the hood.
+
+=cut
+
+sub PostLoadValidate {
+    my $self = shift;
+    return (0, "Invalid object type") unless $self->{'Attribute'}->Name eq 'Dashboard';
+    return 1;
+}
+
 =head2 Panes
 
 Returns a hashref of pane name to portlets
@@ -230,44 +242,23 @@ sub PossibleHiddenSearches {
 }
 
 # _PrivacyObjects: returns a list of objects that can be used to load
-# dashboards from. If the Modify parameter is true, then check modify rights.
-# If the Create parameter is true, then check create rights. Otherwise, check
-# read rights.
+# dashboards from. You probably want to use the wrapper methods like
+# ObjectsForLoading, ObjectsForCreating, etc.
 
 sub _PrivacyObjects {
     my $self = shift;
-    my %args = @_;
 
-    my $CurrentUser = $self->CurrentUser;
     my @objects;
 
-    my $prefix = $args{Modify} ? "Modify"
-               : $args{Create} ? "Create"
-                               : "See";
-
-    push @objects, $CurrentUser->UserObj
-        if $self->CurrentUser->HasRight(
-            Right  => "${prefix}OwnDashboard",
-            Object => $RT::System,
-        );
+    my $CurrentUser = $self->CurrentUser;
+    push @objects, $CurrentUser->UserObj;
 
     my $groups = RT::Groups->new($CurrentUser);
     $groups->LimitToUserDefinedGroups;
-    $groups->WithMember( PrincipalId => $CurrentUser->Id,
-                         Recursively => 1 );
+    $groups->WithCurrentUser;
+    push @objects, @{ $groups->ItemsArrayRef };
 
-    push @objects, grep {
-        $self->CurrentUser->HasRight(
-            Right  => "${prefix}GroupDashboard",
-            Object => $_,
-        )
-    } @{ $groups->ItemsArrayRef };
-
-    push @objects, RT::System->new($CurrentUser)
-        if $CurrentUser->HasRight(
-            Right  => "${prefix}Dashboard",
-            Object => $RT::System,
-        );
+    push @objects, RT::System->new($CurrentUser);
 
     return @objects;
 }
@@ -350,6 +341,130 @@ sub CurrentUserCanSubscribe {
     $self->_CurrentUserCan($privacy, FullRight => 'SubscribeDashboard');
 }
 
+=head2 Subscription
+
+Returns the L<RT::Attribute> representing the current user's subscription
+to this dashboard if there is one; otherwise, returns C<undef>.
+
+=cut
+
+sub Subscription {
+    my $self = shift;
+
+    # no subscription to unloaded dashboards
+    return unless $self->id;
+
+    for my $sub ($self->CurrentUser->UserObj->Attributes->Named('Subscription')) {
+        return $sub if $sub->SubValue('DashboardId') == $self->id;
+    }
+
+    return;
+}
+
+sub ObjectsForLoading {
+    my $self = shift;
+    my %args = (
+        IncludeSuperuserGroups => 1,
+        @_
+    );
+    my @objects;
+
+    # If you've been granted the SeeOwnDashboard global right (which you
+    # could have by way of global user right or global group right), you
+    # get to see your own dashboards
+    my $CurrentUser = $self->CurrentUser;
+    push @objects, $CurrentUser->UserObj
+        if $CurrentUser->HasRight(Object => $RT::System, Right => 'SeeOwnDashboard');
+
+    # Find groups for which: (a) you are a member of the group, and (b)
+    # you have been granted SeeGroupDashboard on (by any means), and (c)
+    # have at least one dashboard
+    my $groups = RT::Groups->new($CurrentUser);
+    $groups->LimitToUserDefinedGroups;
+    $groups->ForWhichCurrentUserHasRight(
+        Right             => 'SeeGroupDashboard',
+        IncludeSuperusers => $args{IncludeSuperuserGroups},
+    );
+    $groups->WithCurrentUser;
+    my $attrs = $groups->Join(
+        ALIAS1 => 'main',
+        FIELD1 => 'id',
+        TABLE2 => 'Attributes',
+        FIELD2 => 'ObjectId',
+    );
+    $groups->Limit(
+        ALIAS => $attrs,
+        FIELD => 'ObjectType',
+        VALUE => 'RT::Group',
+    );
+    $groups->Limit(
+        ALIAS => $attrs,
+        FIELD => 'Name',
+        VALUE => 'Dashboard',
+    );
+    push @objects, @{ $groups->ItemsArrayRef };
+
+    # Finally, if you have been granted the SeeDashboard right (which
+    # you could have by way of global user right or global group right),
+    # you can see system dashboards.
+    push @objects, RT::System->new($CurrentUser)
+        if $CurrentUser->HasRight(Object => $RT::System, Right => 'SeeDashboard');
+
+    return @objects;
+}
+
+sub CurrentUserCanCreateAny {
+    my $self = shift;
+    my @objects;
+
+    my $CurrentUser = $self->CurrentUser;
+    return 1
+        if $CurrentUser->HasRight(Object => $RT::System, Right => 'CreateOwnDashboard');
+
+    my $groups = RT::Groups->new($CurrentUser);
+    $groups->LimitToUserDefinedGroups;
+    $groups->ForWhichCurrentUserHasRight(
+        Right             => 'CreateGroupDashboard',
+        IncludeSuperusers => 1,
+    );
+    return 1 if $groups->Count;
+
+    return 1
+        if $CurrentUser->HasRight(Object => $RT::System, Right => 'CreateDashboard');
+
+    return 0;
+}
+
+=head2 Delete
+
+Deletes the dashboard and related subscriptions.
+Returns a tuple of status and message, where status is true upon success.
+
+=cut
+
+sub Delete {
+    my $self = shift;
+    my $id = $self->id;
+    my ( $status, $msg ) = $self->SUPER::Delete(@_);
+    if ( $status ) {
+        # delete all the subscriptions
+        my $subscriptions = RT::Attributes->new( RT->SystemUser );
+        $subscriptions->Limit(
+            FIELD => 'Name',
+            VALUE => 'Subscription',
+        );
+        $subscriptions->Limit(
+            FIELD => 'Description',
+            VALUE => "Subscription to dashboard $id",
+        );
+        while ( my $subscription = $subscriptions->Next ) {
+            $subscription->Delete();
+        }
+    }
+
+    return ( $status, $msg );
+}
+
 RT::Base->_ImportOverlays();
 
 1;