[Rt-commit] rt branch, 4.2/acl-cache-handlers, created. rt-4.1.6-210-gb574711

Thomas Sibley trs at bestpractical.com
Fri Feb 8 00:35:21 EST 2013


The branch, 4.2/acl-cache-handlers has been created
        at  b574711a1018accc93dd667d7e684c4abcb09820 (commit)

- Log -----------------------------------------------------------------
commit fde493555c999942894fcbd8c4ff233d91b15d3e
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Feb 7 17:43:25 2013 -0800

    Only invalidate the ACL cache on RT::ACE creation if successful
    
    Failure indicates that the row wasn't created, so nothing changed.

diff --git a/lib/RT/ACE.pm b/lib/RT/ACE.pm
index 1bfa677..d23a4b1 100644
--- a/lib/RT/ACE.pm
+++ b/lib/RT/ACE.pm
@@ -280,10 +280,10 @@ sub Create {
                                    ObjectId      => $args{'Object'}->id,
                                );
 
-    #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
-    RT::Principal->InvalidateACLCache();
-
     if ( $id ) {
+        # Clear the key cache. TODO someday we may want to just clear a little
+        # bit of the keycache space.
+        RT::Principal->InvalidateACLCache();
         return ( $id, $self->loc('Right Granted') );
     }
     else {

commit bcdaa87a86cd6145d7d08aae66f36fc267b08322
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Feb 7 18:17:13 2013 -0800

    Add ability to register invalidation handlers for caches relying on ACLs
    
    Currently only called on a successful grant/revoke.
    
    This is useful for extensions which need to handle clearing their own
    internal caches when rights change.  It also provides a framework for
    the queue cache and RT::Principal ACL cache.

diff --git a/lib/RT/ACE.pm b/lib/RT/ACE.pm
index d23a4b1..8757436 100644
--- a/lib/RT/ACE.pm
+++ b/lib/RT/ACE.pm
@@ -80,6 +80,8 @@ use vars qw (
   %OBJECT_TYPES
 );
 
+my (@_ACL_CACHE_HANDLERS);
+
 
 
 =head1 Rights
@@ -284,6 +286,11 @@ sub Create {
         # Clear the key cache. TODO someday we may want to just clear a little
         # bit of the keycache space.
         RT::Principal->InvalidateACLCache();
+        RT::ACE->InvalidateCaches(
+            Action      => "Grant",
+            RightName   => $self->RightName,
+            ACE         => $self,
+        );
         return ( $id, $self->loc('Right Granted') );
     }
     else {
@@ -328,12 +335,15 @@ sub _Delete {
 
     $RT::Handle->BeginTransaction() unless $InsideTransaction;
 
+    my $right = $self->RightName;
+
     my ( $val, $msg ) = $self->SUPER::Delete(@_);
 
     if ($val) {
         #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
         # TODO what about the groups key cache?
         RT::Principal->InvalidateACLCache();
+        RT::ACE->InvalidateCaches( Action => "Revoke", RightName => $right );
         $RT::Handle->Commit() unless $InsideTransaction;
         return ( $val, $self->loc('Right revoked') );
     }
@@ -380,7 +390,67 @@ sub _BootstrapCreate {
 
 }
 
+=head2 InvalidateCaches
+
+Calls any registered ACL cache handlers (see L</RegisterCacheHandler>).
+
+Usually called from L</Create> and L</Delete>.
+
+=cut
+
+sub InvalidateCaches {
+    my $class = shift;
+
+    for my $handler (@_ACL_CACHE_HANDLERS) {
+        next unless ref($handler) eq "CODE";
+        $handler->(@_);
+    }
+}
+
+=head2 RegisterCacheHandler
+
+Class method.  Takes a coderef and adds it to the ACL cache handlers.  These
+handlers are called by L</InvalidateCaches>, usually called itself from
+L</Create> and L</Delete>.
+
+The handlers are passed a hash which may contain any (or none) of these
+optional keys:
+
+=over
+
+=item Action
 
+A string indicating the action that (may have) invalidated the cache.  Expected
+values are currently:
+
+=over
+
+=item Grant
+
+=item Revoke
+
+=back
+
+However, other values may be passed in the future.
+
+=item RightName
+
+The (canonicalized) right being granted or revoked.
+
+=item ACE
+
+The L<RT::ACE> object just created.
+
+=back
+
+Your handler should be flexible enough to account for additional arguments
+being passed in the future.
+
+=cut
+
+sub RegisterCacheHandler {
+    push @_ACL_CACHE_HANDLERS, $_[1];
+}
 
 sub RightName {
     my $self = shift;

commit 8226020e45cbea850ece21bd00fd3f5c5582a200
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Feb 7 19:41:49 2013 -0800

    Switch to run-time loading of classes in RT::ACE
    
    In order for Queues and Principals to start registering ACL cache
    handlers through RT::ACE, they need to be evaluated _after_ RT::ACE has
    been fully evaluated.  Since there are no notable import methods in any
    of the classes, changing from use to require is safe.

diff --git a/lib/RT/ACE.pm b/lib/RT/ACE.pm
index 8757436..c01c2cf 100644
--- a/lib/RT/ACE.pm
+++ b/lib/RT/ACE.pm
@@ -71,9 +71,9 @@ sub Table {'ACL'}
 use strict;
 use warnings;
 
-use RT::Principals;
-use RT::Queues;
-use RT::Groups;
+require RT::Principals;
+require RT::Queues;
+require RT::Groups;
 
 use vars qw (
   %LOWERCASERIGHTNAMES

commit 9f1786a9755b9a433e5bd2a8c3bf7dbb334fc1f8
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Feb 7 18:19:56 2013 -0800

    Register the RT::Principal ACL cache invalidation handler through RT::ACE

diff --git a/lib/RT/ACE.pm b/lib/RT/ACE.pm
index c01c2cf..e3350e5 100644
--- a/lib/RT/ACE.pm
+++ b/lib/RT/ACE.pm
@@ -283,9 +283,6 @@ sub Create {
                                );
 
     if ( $id ) {
-        # Clear the key cache. TODO someday we may want to just clear a little
-        # bit of the keycache space.
-        RT::Principal->InvalidateACLCache();
         RT::ACE->InvalidateCaches(
             Action      => "Grant",
             RightName   => $self->RightName,
@@ -340,9 +337,6 @@ sub _Delete {
     my ( $val, $msg ) = $self->SUPER::Delete(@_);
 
     if ($val) {
-        #Clear the key cache. TODO someday we may want to just clear a little bit of the keycache space. 
-        # TODO what about the groups key cache?
-        RT::Principal->InvalidateACLCache();
         RT::ACE->InvalidateCaches( Action => "Revoke", RightName => $right );
         $RT::Handle->Commit() unless $InsideTransaction;
         return ( $val, $self->loc('Right revoked') );
diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index a2a964d..d3c85c8 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -71,6 +71,8 @@ use RT::User;
 our $_ACL_CACHE;
 InvalidateACLCache();
 
+require RT::ACE;
+RT::ACE->RegisterCacheHandler(sub { RT::Principal->InvalidateACLCache() });
 
 =head2 IsGroup
 

commit b574711a1018accc93dd667d7e684c4abcb09820
Author: Thomas Sibley <trs at bestpractical.com>
Date:   Thu Feb 7 18:20:58 2013 -0800

    Register the queue cache invalidation handler with RT::ACE

diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index d3c85c8..fbb88d9 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -187,9 +187,6 @@ sub GrantRight {
         PrincipalId   => $self->Id,
     );
 
-    RT->System->QueueCacheNeedsUpdate(1)
-        if $id and grep { $ace->RightName eq $_ } qw(SeeQueue CreateTicket);
-
     return ($id, $msg);
 }
 
@@ -239,9 +236,6 @@ sub RevokeRight {
     my $right = $ace->RightName;
     ($status, $msg) = $ace->Delete;
 
-    RT->System->QueueCacheNeedsUpdate(1)
-        if $status and grep { $right eq $_ } qw(SeeQueue CreateTicket);
-
     return ($status, $msg);
 }
 
diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 3db7597..86d05c9 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -80,6 +80,19 @@ sub LifecycleType { "ticket" }
 
 sub ModifyLinkRight { "AdminQueue" }
 
+require RT::ACE;
+RT::ACE->RegisterCacheHandler(sub {
+    my %args = (
+        Action      => "",
+        RightName   => "",
+        @_
+    );
+
+    return unless $args{Action}    =~ /^(Grant|Revoke)$/i
+              and $args{RightName} =~ /^(SeeQueue|CreateTicket)$/;
+
+    RT->System->QueueCacheNeedsUpdate(1);
+});
 
 use RT::Groups;
 use RT::ACL;

-----------------------------------------------------------------------


More information about the Rt-commit mailing list