diff --git a/scm-core/src/main/java/sonia/scm/repository/PermissionUtil.java b/scm-core/src/main/java/sonia/scm/repository/PermissionUtil.java index 17e684d5e7..dc6a48b118 100644 --- a/scm-core/src/main/java/sonia/scm/repository/PermissionUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/PermissionUtil.java @@ -37,6 +37,10 @@ package sonia.scm.repository; import com.google.inject.Provider; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.config.ScmConfiguration; import sonia.scm.security.ScmSecurityException; import sonia.scm.user.User; import sonia.scm.util.AssertUtil; @@ -54,6 +58,14 @@ import java.util.List; public class PermissionUtil { + /** + * the logger for PermissionUtil + */ + private static final Logger logger = + LoggerFactory.getLogger(PermissionUtil.class); + + //~--- methods -------------------------------------------------------------- + /** * Method description * @@ -151,6 +163,40 @@ public class PermissionUtil return result; } + /** + * Returns true if the repository is writable. + * + * + * @param configuration SCM-Manager main configuration + * @param repository repository to check + * @param securityContext current user security context + * + * @return true if the repository is writable + * @since 1.14 + */ + public static boolean isWritable(ScmConfiguration configuration, + Repository repository, + WebSecurityContext securityContext) + { + boolean permitted = false; + + if (configuration.isEnableRepositoryArchive() && repository.isArchived()) + { + if (logger.isWarnEnabled()) + { + logger.warn("{} is archived and is not writeable", + repository.getName()); + } + } + else + { + permitted = PermissionUtil.hasPermission(repository, securityContext, + PermissionType.WRITE); + } + + return permitted; + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java index 5f37f222b4..181c743232 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java @@ -41,6 +41,7 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import sonia.scm.SCMContext; +import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.PermissionType; import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; @@ -76,10 +77,14 @@ public abstract class PermissionFilter extends HttpFilter * Constructs ... * * + * + * @param configuration * @param securityContextProvider */ - public PermissionFilter(Provider securityContextProvider) + public PermissionFilter(ScmConfiguration configuration, + Provider securityContextProvider) { + this.configuration = configuration; this.securityContextProvider = securityContextProvider; } @@ -139,10 +144,7 @@ public abstract class PermissionFilter extends HttpFilter { boolean writeRequest = isWriteRequest(request); - if (PermissionUtil.hasPermission(repository, securityContext, - writeRequest - ? PermissionType.WRITE - : PermissionType.READ)) + if (hasPermission(repository, securityContext, writeRequest)) { chain.doFilter(request, response); } @@ -213,8 +215,43 @@ public abstract class PermissionFilter extends HttpFilter } } + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * @param securityContext + * @param writeRequest + * + * @return + */ + private boolean hasPermission(Repository repository, + WebSecurityContext securityContext, + boolean writeRequest) + { + boolean permitted = false; + + if (writeRequest) + { + permitted = PermissionUtil.isWritable(configuration, repository, + securityContext); + } + else + { + permitted = PermissionUtil.hasPermission(repository, securityContext, + PermissionType.READ); + } + + return permitted; + } + //~--- fields --------------------------------------------------------------- /** Field description */ protected Provider securityContextProvider; + + /** Field description */ + private ScmConfiguration configuration; } diff --git a/scm-core/src/main/java/sonia/scm/web/filter/ProviderPermissionFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/ProviderPermissionFilter.java index 3b728da799..e1b233f5ab 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/ProviderPermissionFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/ProviderPermissionFilter.java @@ -44,6 +44,7 @@ import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import javax.servlet.http.HttpServletRequest; +import sonia.scm.config.ScmConfiguration; /** * @@ -61,10 +62,11 @@ public abstract class ProviderPermissionFilter extends PermissionFilter * @param repositoryProvider */ public ProviderPermissionFilter( + ScmConfiguration configuration, Provider securityContextProvider, RepositoryProvider repositoryProvider) { - super(securityContextProvider); + super(configuration, securityContextProvider); this.repositoryProvider = repositoryProvider; } diff --git a/scm-core/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java b/scm-core/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java index d3e95e9b99..0deac57121 100644 --- a/scm-core/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java +++ b/scm-core/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java @@ -37,6 +37,7 @@ package sonia.scm.web.filter; import com.google.inject.Provider; +import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; import sonia.scm.web.security.WebSecurityContext; @@ -65,14 +66,17 @@ public abstract class RegexPermissionFilter extends PermissionFilter * Constructs ... * * + * + * @param configuration * @param securityContextProvider * @param repositoryManager */ public RegexPermissionFilter( + ScmConfiguration configuration, Provider securityContextProvider, RepositoryManager repositoryManager) { - super(securityContextProvider); + super(configuration, securityContextProvider); this.repositoryManager = repositoryManager; } diff --git a/scm-core/src/test/java/sonia/scm/repository/PermissionUtilTest.java b/scm-core/src/test/java/sonia/scm/repository/PermissionUtilTest.java index 25acd561de..ae485a66bc 100644 --- a/scm-core/src/test/java/sonia/scm/repository/PermissionUtilTest.java +++ b/scm-core/src/test/java/sonia/scm/repository/PermissionUtilTest.java @@ -35,8 +35,10 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- +import org.junit.Before; import org.junit.Test; +import sonia.scm.config.ScmConfiguration; import sonia.scm.security.ScmSecurityException; import sonia.scm.user.User; import sonia.scm.web.security.WebSecurityContext; @@ -65,17 +67,7 @@ public class PermissionUtilTest */ public PermissionUtilTest() { - repository = new Repository(); admams.getUser().setAdmin(true); - - Permission[] permissions = new Permission[] { - new Permission("dent", PermissionType.READ), - new Permission("perfect", - PermissionType.WRITE), - new Permission("marvin", - PermissionType.OWNER) }; - - repository.setPermissions(Arrays.asList(permissions)); } //~--- methods -------------------------------------------------------------- @@ -108,6 +100,25 @@ public class PermissionUtilTest PermissionUtil.assertPermission(repository, admams, PermissionType.OWNER); } + /** + * Method description + * + */ + @Before + public void before() + { + repository = new Repository(); + + Permission[] permissions = new Permission[] { + new Permission("dent", PermissionType.READ), + new Permission("perfect", + PermissionType.WRITE), + new Permission("marvin", + PermissionType.OWNER) }; + + repository.setPermissions(Arrays.asList(permissions)); + } + /** * Method description * @@ -161,6 +172,31 @@ public class PermissionUtilTest PermissionType.OWNER)); } + /** + * Method description + * + */ + @Test + public void testIsWritable() + { + ScmConfiguration configuration = new ScmConfiguration(); + + configuration.setEnableRepositoryArchive(true); + assertTrue(PermissionUtil.isWritable(configuration, repository, perfect)); + repository.setArchived(true); + assertFalse(PermissionUtil.isWritable(configuration, repository, perfect)); + assertFalse(PermissionUtil.isWritable(configuration, repository, admams)); + configuration.setEnableRepositoryArchive(false); + assertTrue(PermissionUtil.isWritable(configuration, repository, perfect)); + assertTrue(PermissionUtil.isWritable(configuration, repository, admams)); + assertFalse(PermissionUtil.isWritable(configuration, repository, dent)); + configuration.setEnableRepositoryArchive(true); + repository.setArchived(false); + assertTrue(PermissionUtil.isWritable(configuration, repository, perfect)); + assertTrue(PermissionUtil.isWritable(configuration, repository, admams)); + assertFalse(PermissionUtil.isWritable(configuration, repository, dent)); + } + //~--- get methods ---------------------------------------------------------- /** diff --git a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java index 6986848a5f..6842f24566 100644 --- a/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java +++ b/scm-plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java @@ -46,6 +46,7 @@ import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import javax.servlet.http.HttpServletRequest; +import sonia.scm.config.ScmConfiguration; /** * @@ -79,10 +80,11 @@ public class GitPermissionFilter extends ProviderPermissionFilter */ @Inject public GitPermissionFilter( + ScmConfiguration configuration, Provider securityContextProvider, RepositoryProvider repositoryProvider) { - super(securityContextProvider, repositoryProvider); + super(configuration, securityContextProvider, repositoryProvider); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java index b759c29e99..5df19d5042 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java @@ -46,6 +46,7 @@ import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ import javax.servlet.http.HttpServletRequest; +import sonia.scm.config.ScmConfiguration; /** * @@ -64,10 +65,11 @@ public class HgPermissionFilter extends ProviderPermissionFilter */ @Inject public HgPermissionFilter( + ScmConfiguration configuration, Provider securityContextProvider, RepositoryProvider repositoryProvider) { - super(securityContextProvider, repositoryProvider); + super(configuration, securityContextProvider, repositoryProvider); } //~--- get methods ---------------------------------------------------------- diff --git a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java index 99cba65c93..60b06bdca3 100644 --- a/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java +++ b/scm-plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java @@ -39,6 +39,7 @@ import com.google.inject.Inject; import com.google.inject.Provider; import com.google.inject.Singleton; +import sonia.scm.config.ScmConfiguration; import sonia.scm.repository.RepositoryProvider; import sonia.scm.web.filter.ProviderPermissionFilter; import sonia.scm.web.security.WebSecurityContext; @@ -72,15 +73,18 @@ public class SvnPermissionFilter extends ProviderPermissionFilter * * * + * + * @param configuration * @param securityContextProvider * @param repository */ @Inject public SvnPermissionFilter( + ScmConfiguration configuration, Provider securityContextProvider, RepositoryProvider repository) { - super(securityContextProvider, repository); + super(configuration, securityContextProvider, repository); } //~--- get methods ----------------------------------------------------------