diff --git a/pom.xml b/pom.xml index fb1017d6f1..40ef40af0b 100644 --- a/pom.xml +++ b/pom.xml @@ -431,7 +431,7 @@ 2.3.1.201302201838-r - 1.7.8-scm1 + 1.7.9-scm1 1.6 diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java index d5f93fadb5..60e01e4e1f 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java @@ -338,7 +338,7 @@ public class AuthenticationResource Builder builder = ImmutableList.builder(); - for (Permission p : permissionCollector.collect(user, groups)) + for (Permission p : permissionCollector.collect()) { if (p instanceof StringablePermission) { diff --git a/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java b/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java index a226ab03d6..0d7d231b99 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java +++ b/scm-webapp/src/main/java/sonia/scm/security/PermissionCollector.java @@ -36,24 +36,32 @@ package sonia.scm.security; import com.google.common.base.Predicate; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableList.Builder; +import com.google.common.eventbus.Subscribe; import com.google.inject.Inject; import com.google.inject.Singleton; +import org.apache.shiro.SecurityUtils; import org.apache.shiro.authz.Permission; import org.apache.shiro.authz.permission.PermissionResolver; +import org.apache.shiro.subject.PrincipalCollection; +import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.cache.Cache; +import sonia.scm.cache.CacheManager; import sonia.scm.group.GroupNames; import sonia.scm.repository.PermissionType; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryDAO; +import sonia.scm.repository.RepositoryEvent; import sonia.scm.user.User; import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import java.util.Collections; import java.util.List; /** @@ -64,6 +72,11 @@ import java.util.List; public class PermissionCollector { + // CACHE Authorization info ??? + + /** Field description */ + private static final String NAME = "sonia.cache.permissions"; + /** * the logger for PermissionCollector */ @@ -76,14 +89,18 @@ public class PermissionCollector * Constructs ... * * + * + * @param cacheManager * @param repositoryDAO * @param securitySystem * @param resolver */ @Inject - public PermissionCollector(RepositoryDAO repositoryDAO, - SecuritySystem securitySystem, PermissionResolver resolver) + public PermissionCollector(CacheManager cacheManager, + RepositoryDAO repositoryDAO, SecuritySystem securitySystem, + PermissionResolver resolver) { + this.cache = cacheManager.getCache(String.class, List.class, NAME); this.repositoryDAO = repositoryDAO; this.securitySystem = securitySystem; this.resolver = resolver; @@ -91,6 +108,74 @@ public class PermissionCollector //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @return + */ + public List collect() + { + List permissions; + Subject subject = SecurityUtils.getSubject(); + + if (subject.hasRole(Role.USER)) + { + PrincipalCollection pc = subject.getPrincipals(); + + permissions = collect(pc.oneByType(User.class), + pc.oneByType(GroupNames.class)); + } + else + { + permissions = Collections.EMPTY_LIST; + } + + return permissions; + } + + /** + * Method description + * + * + * @param event + */ + @Subscribe + public void onEvent(RepositoryEvent event) + { + if (event.getEventType().isPost()) + { + if (logger.isDebugEnabled()) + { + logger.debug("clear cache, because repository {} has changed", + event.getItem().getName()); + } + + cache.clear(); + } + } + + /** + * Method description + * + * + * @param event + */ + @Subscribe + public void onEvent(StoredAssignedPermissionEvent event) + { + if (event.getEventType().isPost()) + { + if (logger.isDebugEnabled()) + { + logger.debug("clear cache, because permission {} has changed", + event.getPermission().getId()); + } + + cache.clear(); + } + } + /** * Method description * @@ -100,31 +185,17 @@ public class PermissionCollector * * @return */ - public List collect(User user, GroupNames groups) + List collect(User user, GroupNames groups) { - Builder builder = ImmutableList.builder(); + List permissions = cache.get(user.getName()); - if (user.isActive()) + if (permissions == null) { - if (user.isAdmin()) - { - //J- - builder.add( - new RepositoryPermission( - RepositoryPermission.WILDCARD, - PermissionType.OWNER - ) - ); - //J+ - } - else - { - collectRepositoryPermissions(builder, user, groups); - collectGlobalPermissions(builder, user, groups); - } + permissions = doCollect(user, groups); + cache.put(user.getName(), permissions); } - return builder.build(); + return permissions; } /** @@ -244,6 +315,42 @@ public class PermissionCollector } } + /** + * Method description + * + * + * @param user + * @param groups + * + * @return + */ + private List doCollect(User user, GroupNames groups) + { + Builder builder = ImmutableList.builder(); + + if (user.isActive()) + { + if (user.isAdmin()) + { + //J- + builder.add( + new RepositoryPermission( + RepositoryPermission.WILDCARD, + PermissionType.OWNER + ) + ); + //J+ + } + else + { + collectRepositoryPermissions(builder, user, groups); + collectGlobalPermissions(builder, user, groups); + } + } + + return builder.build(); + } + //~--- get methods ---------------------------------------------------------- /** @@ -267,6 +374,9 @@ public class PermissionCollector //~--- fields --------------------------------------------------------------- + /** Field description */ + private Cache cache; + /** Field description */ private RepositoryDAO repositoryDAO; diff --git a/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java b/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java index 3087aad459..ad9b12bd62 100644 --- a/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java +++ b/scm-webapp/src/main/java/sonia/scm/security/ScmRealm.java @@ -68,7 +68,6 @@ import sonia.scm.event.Subscriber; import sonia.scm.group.Group; import sonia.scm.group.GroupManager; import sonia.scm.group.GroupNames; -import sonia.scm.repository.RepositoryEvent; import sonia.scm.repository.RepositoryManager; import sonia.scm.user.User; import sonia.scm.user.UserDAO; @@ -169,48 +168,6 @@ public class ScmRealm extends AuthorizingRealm //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * - * @param event - */ - @Subscribe - public void onEvent(RepositoryEvent event) - { - if (event.getEventType().isPost()) - { - if (logger.isDebugEnabled()) - { - logger.debug("clear cache, because repository {} has changed", - event.getItem().getName()); - } - - cache.clear(); - } - } - - /** - * Method description - * - * - * @param event - */ - @Subscribe - public void onEvent(StoredAssignedPermissionEvent event) - { - if (event.getEventType().isPost()) - { - if (logger.isDebugEnabled()) - { - logger.debug("clear cache, because permission {} has changed", - event.getPermission().getId()); - } - - cache.clear(); - } - } - /** * Method description * diff --git a/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java b/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java index 570e220e95..6d132c19ca 100644 --- a/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java +++ b/scm-webapp/src/test/java/sonia/scm/security/ScmRealmTest.java @@ -53,6 +53,7 @@ import org.junit.Test; import org.mockito.Mockito; +import sonia.scm.cache.CacheManager; import sonia.scm.cache.MapCacheManager; import sonia.scm.config.ScmConfiguration; import sonia.scm.group.Group; @@ -475,13 +476,19 @@ public class ScmRealmTest Collections.EMPTY_LIST ); - PermissionCollector collector = new PermissionCollector(repositoryDAO, - securitySystem, new RepositoryPermissionResolver()); + CacheManager cacheManager = new MapCacheManager(); + + PermissionCollector collector = new PermissionCollector( + cacheManager, + repositoryDAO, + securitySystem, + new RepositoryPermissionResolver() + ); return new ScmRealm( new ScmConfiguration(), collector, - new MapCacheManager(), + cacheManager, userManager, groupManager, userDAO,