diff --git a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java index 90b854900f..2aec8356f0 100644 --- a/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java +++ b/plugins/scm-git-plugin/src/main/java/sonia/scm/web/GitPermissionFilter.java @@ -42,7 +42,7 @@ import com.google.inject.Singleton; import sonia.scm.repository.GitRepositoryHandler; import sonia.scm.repository.RepositoryManager; import sonia.scm.web.filter.RegexPermissionFilter; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -70,7 +70,7 @@ public class GitPermissionFilter extends RegexPermissionFilter * @param repositoryManager */ @Inject - public GitPermissionFilter(Provider securityContextProvider, + public GitPermissionFilter(Provider securityContextProvider, RepositoryManager repositoryManager) { super(securityContextProvider, repositoryManager); diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java index 2b5c44a89d..9babba09b0 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgPermissionFilter.java @@ -44,7 +44,7 @@ import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; import sonia.scm.web.filter.PermissionFilter; import sonia.scm.web.filter.RegexPermissionFilter; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -66,7 +66,7 @@ public class HgPermissionFilter extends RegexPermissionFilter * @param repositoryManager */ @Inject - public HgPermissionFilter(Provider securityContextProvider, + public HgPermissionFilter(Provider securityContextProvider, RepositoryManager repositoryManager) { super(securityContextProvider, repositoryManager); diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java index ed289cf6b7..9d67d7e9c3 100644 --- a/plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/web/SvnPermissionFilter.java @@ -44,7 +44,7 @@ import sonia.scm.repository.RepositoryManager; import sonia.scm.repository.SvnRepositoryHandler; import sonia.scm.web.filter.PermissionFilter; import sonia.scm.web.filter.RegexPermissionFilter; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -79,7 +79,7 @@ public class SvnPermissionFilter extends RegexPermissionFilter * @param repositoryManager */ @Inject - public SvnPermissionFilter(Provider securityContextProvider, + public SvnPermissionFilter(Provider securityContextProvider, RepositoryManager repositoryManager) { super(securityContextProvider, repositoryManager); diff --git a/scm-core/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java b/scm-core/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java index 42b9e6ac08..2669f7651e 100644 --- a/scm-core/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java +++ b/scm-core/src/main/java/sonia/scm/repository/xml/XmlRepositoryManager.java @@ -36,6 +36,7 @@ package sonia.scm.repository.xml; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; +import com.google.inject.Provider; import com.google.inject.Singleton; import org.slf4j.Logger; @@ -47,11 +48,15 @@ import sonia.scm.SCMContext; import sonia.scm.SCMContextProvider; import sonia.scm.Type; import sonia.scm.repository.AbstractRepositoryManager; +import sonia.scm.repository.PermissionType; +import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryAllreadyExistExeption; import sonia.scm.repository.RepositoryException; import sonia.scm.repository.RepositoryHandler; import sonia.scm.repository.RepositoryHandlerNotFoundException; +import sonia.scm.security.SecurityContext; +import sonia.scm.user.User; import sonia.scm.util.AssertUtil; import sonia.scm.util.IOUtil; @@ -92,11 +97,16 @@ public class XmlRepositoryManager extends AbstractRepositoryManager * Constructs ... * * + * + * @param securityContextProvider * @param handlerSet */ @Inject - public XmlRepositoryManager(Set handlerSet) + public XmlRepositoryManager( + Provider securityContextProvider, + Set handlerSet) { + this.securityContextProvider = securityContextProvider; handlerMap = new HashMap(); types = new HashSet(); @@ -142,6 +152,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager repository.getType()); } + assertIsAdmin(); AssertUtil.assertIsValid(repository); if (repositoryDB.contains(repository)) @@ -181,6 +192,8 @@ public class XmlRepositoryManager extends AbstractRepositoryManager repository.getType()); } + assertIsOwner(repository); + if (repositoryDB.contains(repository)) { getHandler(repository).delete(repository); @@ -244,6 +257,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager repository.getType()); } + assertIsOwner(repository); AssertUtil.assertIsValid(repository); if (repositoryDB.contains(repository)) @@ -281,6 +295,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager throws RepositoryException, IOException { AssertUtil.assertIsNotNull(repository); + assertIsReader(repository); Repository fresh = repositoryDB.get(repository.getType(), repository.getName()); @@ -315,6 +330,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager if (repository != null) { + assertIsReader(repository); repository = repository.clone(); } @@ -340,7 +356,14 @@ public class XmlRepositoryManager extends AbstractRepositoryManager if (repository != null) { - repository = repository.clone(); + if (isReader(repository)) + { + repository = repository.clone(); + } + else + { + repository = null; + } } return repository; @@ -359,7 +382,10 @@ public class XmlRepositoryManager extends AbstractRepositoryManager for (Repository repository : repositoryDB.values()) { - repositories.add(repository.clone()); + if (isReader(repository)) + { + repositories.add(repository.clone()); + } } return repositories; @@ -424,6 +450,44 @@ public class XmlRepositoryManager extends AbstractRepositoryManager types.add(type); } + /** + * Method description + * + * + * @throws RepositoryException + */ + private void assertIsAdmin() throws RepositoryException + { + if (!getCurrentUser().isAdmin()) + { + throw new RepositoryException("admin permsission required"); + } + } + + /** + * Method description + * + * + * @param repository + */ + private void assertIsOwner(Repository repository) + { + PermissionUtil.assertPermission(repository, getCurrentUser(), + PermissionType.OWNER); + } + + /** + * Method description + * + * + * @param repository + */ + private void assertIsReader(Repository repository) + { + PermissionUtil.assertPermission(repository, getCurrentUser(), + PermissionType.READ); + } + /** * Method description * @@ -446,6 +510,25 @@ public class XmlRepositoryManager extends AbstractRepositoryManager //~--- get methods ---------------------------------------------------------- + /** + * Method description + * + * + * @return + */ + private User getCurrentUser() + { + SecurityContext context = securityContextProvider.get(); + + AssertUtil.assertIsNotNull(context); + + User user = context.getUser(); + + AssertUtil.assertIsNotNull(user); + + return user; + } + /** * Method description * @@ -476,6 +559,20 @@ public class XmlRepositoryManager extends AbstractRepositoryManager return handler; } + /** + * Method description + * + * + * @param repository + * + * @return + */ + private boolean isReader(Repository repository) + { + return PermissionUtil.hasPermission(repository, getCurrentUser(), + PermissionType.READ); + } + //~--- fields --------------------------------------------------------------- /** Field description */ @@ -487,6 +584,9 @@ public class XmlRepositoryManager extends AbstractRepositoryManager /** Field description */ private File repositoryDBFile; + /** Field description */ + private Provider securityContextProvider; + /** Field description */ private Set types; } diff --git a/scm-core/src/main/java/sonia/scm/security/SecurityContext.java b/scm-core/src/main/java/sonia/scm/security/SecurityContext.java new file mode 100644 index 0000000000..226a247d4a --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/security/SecurityContext.java @@ -0,0 +1,54 @@ +/** + * Copyright (c) 2010, Sebastian Sdorra + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * 3. Neither the name of SCM-Manager; nor the names of its + * contributors may be used to endorse or promote products derived from this + * software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * http://bitbucket.org/sdorra/scm-manager + * + */ + + + +package sonia.scm.security; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.user.User; + +/** + * + * @author Sebastian Sdorra + */ +public interface SecurityContext +{ + + /** + * Method description + * + * + * @return + */ + public User getUser(); +} diff --git a/scm-web-api/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java b/scm-web-api/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java index 19155b5150..891efedcf6 100644 --- a/scm-web-api/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java +++ b/scm-web-api/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java @@ -39,7 +39,7 @@ import com.google.inject.Singleton; import sonia.scm.user.User; import sonia.scm.util.Util; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -91,7 +91,7 @@ public class BasicAuthenticationFilter extends HttpFilter */ @Inject public BasicAuthenticationFilter( - Provider securityContextProvider) + Provider securityContextProvider) { this.securityContextProvider = securityContextProvider; } @@ -114,7 +114,7 @@ public class BasicAuthenticationFilter extends HttpFilter HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - SecurityContext securityContext = securityContextProvider.get(); + WebSecurityContext securityContext = securityContextProvider.get(); User user = null; if (securityContext != null) @@ -179,5 +179,5 @@ public class BasicAuthenticationFilter extends HttpFilter //~--- fields --------------------------------------------------------------- /** Field description */ - private Provider securityContextProvider; + private Provider securityContextProvider; } diff --git a/scm-web-api/src/main/java/sonia/scm/web/filter/PermissionFilter.java b/scm-web-api/src/main/java/sonia/scm/web/filter/PermissionFilter.java index 489fcc1577..ecaf350d35 100644 --- a/scm-web-api/src/main/java/sonia/scm/web/filter/PermissionFilter.java +++ b/scm-web-api/src/main/java/sonia/scm/web/filter/PermissionFilter.java @@ -45,7 +45,7 @@ import sonia.scm.repository.PermissionUtil; import sonia.scm.repository.Repository; import sonia.scm.user.User; import sonia.scm.util.AssertUtil; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -75,7 +75,7 @@ public abstract class PermissionFilter extends HttpFilter * * @param securityContextProvider */ - public PermissionFilter(Provider securityContextProvider) + public PermissionFilter(Provider securityContextProvider) { this.securityContextProvider = securityContextProvider; } @@ -120,7 +120,7 @@ public abstract class PermissionFilter extends HttpFilter HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - SecurityContext securityContext = securityContextProvider.get(); + WebSecurityContext securityContext = securityContextProvider.get(); AssertUtil.assertIsNotNull(securityContext); @@ -179,5 +179,5 @@ public abstract class PermissionFilter extends HttpFilter //~--- fields --------------------------------------------------------------- /** Field description */ - protected Provider securityContextProvider; + protected Provider securityContextProvider; } diff --git a/scm-web-api/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java b/scm-web-api/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java index 06fba0089e..d3e95e9b99 100644 --- a/scm-web-api/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java +++ b/scm-web-api/src/main/java/sonia/scm/web/filter/RegexPermissionFilter.java @@ -39,7 +39,7 @@ import com.google.inject.Provider; import sonia.scm.repository.Repository; import sonia.scm.repository.RepositoryManager; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -69,7 +69,7 @@ public abstract class RegexPermissionFilter extends PermissionFilter * @param repositoryManager */ public RegexPermissionFilter( - Provider securityContextProvider, + Provider securityContextProvider, RepositoryManager repositoryManager) { super(securityContextProvider); diff --git a/scm-web-api/src/main/java/sonia/scm/web/security/BasicSecurityContext.java b/scm-web-api/src/main/java/sonia/scm/web/security/BasicSecurityContext.java index c4602c91e4..8849c59a41 100644 --- a/scm-web-api/src/main/java/sonia/scm/web/security/BasicSecurityContext.java +++ b/scm-web-api/src/main/java/sonia/scm/web/security/BasicSecurityContext.java @@ -48,7 +48,7 @@ import javax.servlet.http.HttpServletResponse; * @author Sebastian Sdorra */ @SessionScoped -public class BasicSecurityContext implements SecurityContext +public class BasicSecurityContext implements WebSecurityContext { /** diff --git a/scm-web-api/src/main/java/sonia/scm/web/security/SecurityContext.java b/scm-web-api/src/main/java/sonia/scm/web/security/WebSecurityContext.java similarity index 95% rename from scm-web-api/src/main/java/sonia/scm/web/security/SecurityContext.java rename to scm-web-api/src/main/java/sonia/scm/web/security/WebSecurityContext.java index 636788a1f3..d113ae672b 100644 --- a/scm-web-api/src/main/java/sonia/scm/web/security/SecurityContext.java +++ b/scm-web-api/src/main/java/sonia/scm/web/security/WebSecurityContext.java @@ -29,10 +29,13 @@ * */ + + package sonia.scm.web.security; //~--- non-JDK imports -------------------------------------------------------- +import sonia.scm.security.SecurityContext; import sonia.scm.user.User; //~--- JDK imports ------------------------------------------------------------ @@ -44,7 +47,7 @@ import javax.servlet.http.HttpServletResponse; * * @author Sebastian Sdorra */ -public interface SecurityContext +public interface WebSecurityContext extends SecurityContext { /** @@ -73,14 +76,6 @@ public interface SecurityContext //~--- get methods ---------------------------------------------------------- - /** - * Method description - * - * - * @return - */ - public User getUser(); - /** * Method description * diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 254b6f9449..7ad5041fbc 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -62,7 +62,7 @@ import sonia.scm.web.plugin.ScmWebPluginContext; import sonia.scm.web.plugin.SecurityConfig; import sonia.scm.web.security.Authenticator; import sonia.scm.web.security.BasicSecurityContext; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; import sonia.scm.web.security.XmlAuthenticator; //~--- JDK imports ------------------------------------------------------------ @@ -81,6 +81,7 @@ import java.util.Map; import java.util.Set; import javax.xml.bind.JAXB; +import sonia.scm.security.SecurityContext; /** * @@ -161,6 +162,7 @@ public class ScmServletModule extends ServletModule // bind(EncryptionHandler.class).to(MessageDigestEncryptionHandler.class); // bind(Authenticator.class).to(XmlAuthenticator.class); bind(SecurityContext.class).to(BasicSecurityContext.class); + bind(WebSecurityContext.class).to(BasicSecurityContext.class); loadPlugins(pluginManager); bind(CacheManager.class).to(EhCacheManager.class); 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 db5f34e74b..7fc717cd9d 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 @@ -45,7 +45,7 @@ import sonia.scm.ScmState; import sonia.scm.Type; import sonia.scm.repository.RepositoryManager; import sonia.scm.user.User; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -193,5 +193,5 @@ public class AuthenticationResource /** Field description */ @Inject - private SecurityContext securityContext; + private WebSecurityContext securityContext; } diff --git a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java index 4a57e55d48..5bf0cb0a3a 100644 --- a/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/filter/SecurityFilter.java @@ -39,7 +39,7 @@ import com.google.inject.Singleton; import sonia.scm.web.filter.HttpFilter; import sonia.scm.web.filter.SecurityHttpServletRequestWrapper; -import sonia.scm.web.security.SecurityContext; +import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -70,7 +70,7 @@ public class SecurityFilter extends HttpFilter * @param securityContextProvider */ @Inject - public SecurityFilter(Provider securityContextProvider) + public SecurityFilter(Provider securityContextProvider) { this.securityContextProvider = securityContextProvider; } @@ -93,7 +93,7 @@ public class SecurityFilter extends HttpFilter HttpServletResponse response, FilterChain chain) throws IOException, ServletException { - SecurityContext securityContext = securityContextProvider.get(); + WebSecurityContext securityContext = securityContextProvider.get(); if (securityContext != null) { @@ -126,5 +126,5 @@ public class SecurityFilter extends HttpFilter //~--- fields --------------------------------------------------------------- /** Field description */ - private Provider securityContextProvider; + private Provider securityContextProvider; }