diff --git a/scm-webapp/src/main/java/sonia/scm/security/AuthorizationCollector.java b/scm-webapp/src/main/java/sonia/scm/security/AuthorizationCollector.java index 40a8f4f130..5c8c45cf28 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/AuthorizationCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/AuthorizationCollector.java @@ -72,6 +72,7 @@ import sonia.scm.util.Util; import java.util.List; import java.util.Set; import sonia.scm.Filter; +import sonia.scm.repository.RepositoryModificationEvent; import sonia.scm.user.UserModificationEvent; /** @@ -161,7 +162,7 @@ public class AuthorizationCollector if (event instanceof UserModificationEvent) { User beforeModification = ((UserModificationEvent) event).getItemBeforeModification(); - if ( user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive() ) + if ( shouldCacheBeCleared(user, beforeModification) ) { invalidateUserCache(username); } @@ -177,6 +178,11 @@ public class AuthorizationCollector } } + private boolean shouldCacheBeCleared(User user, User beforeModification) + { + return user.isAdmin() != beforeModification.isAdmin() || user.isActive() != beforeModification.isActive(); + } + private void invalidateUserCache(final String username){ logger.debug("invalidate cache of user {}, because user properties have changed", username); cache.removeAll(new Filter() @@ -200,15 +206,42 @@ public class AuthorizationCollector { if (event.getEventType().isPost()) { + Repository repository = event.getItem(); if (logger.isDebugEnabled()) { - logger.debug("clear cache, because repository {} has changed", - event.getItem().getName()); + logger.debug("clear cache, because repository {} has changed", repository.getName()); } - cache.clear(); + if (event instanceof RepositoryModificationEvent) + { + Repository beforeModification = ((RepositoryModificationEvent) event).getItemBeforeModification(); + if (shouldCacheBeCleared(repository, beforeModification)) + { + logger.debug("clear cache, because a relevant field of repository {} has changed", repository.getName()); + cache.clear(); + } + else + { + logger.debug( + "cache of repository {} is not invalidated, because non relevant fields have changed", + repository.getName() + ); + } + } + else + { + logger.debug("clear cache, because repository {} has changed", repository.getName()); + cache.clear(); + } } } + + private boolean shouldCacheBeCleared(Repository repository, Repository beforeModification) + { + return repository.isArchived() != beforeModification.isArchived() + || repository.isPublicReadable() != beforeModification.isPublicReadable() + || ! repository.getPermissions().equals(beforeModification.getPermissions()); + } /** * Method description diff --git a/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java b/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java index 6cbd68bd23..75e282fc4f 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/AuthorizationCollectorTest.java @@ -64,6 +64,7 @@ import sonia.scm.repository.PermissionType; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; import sonia.scm.repository.RepositoryEvent; +import sonia.scm.repository.RepositoryModificationEvent; import sonia.scm.repository.RepositoryTestData; import sonia.scm.user.User; import sonia.scm.user.UserEvent; @@ -176,6 +177,34 @@ public class AuthorizationCollectorTest { verify(cache).clear(); } + /** + * Tests {@link AuthorizationCollector#onEvent(sonia.scm.repository.RepositoryEvent)} with modified repository. + */ + @Test + public void testOnRepositoryModificationEvent() + { + Repository repositoryModified = RepositoryTestData.createHeartOfGold(); + repositoryModified.setName("test123"); + repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test"))); + + Repository repository = RepositoryTestData.createHeartOfGold(); + repository.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test"))); + + collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.BEFORE_CREATE)); + verify(cache, never()).clear(); + + collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE)); + verify(cache, never()).clear(); + + repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test"))); + collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE)); + verify(cache, never()).clear(); + + repositoryModified.setPermissions(Lists.newArrayList(new sonia.scm.repository.Permission("test123"))); + collector.onEvent(new RepositoryModificationEvent(repositoryModified, repository, HandlerEvent.CREATE)); + verify(cache).clear(); + } + /** * Tests {@link AuthorizationCollector#onEvent(sonia.scm.security.StoredAssignedPermissionEvent)}. */