diff --git a/scm-core/src/main/java/sonia/scm/group/GroupNames.java b/scm-core/src/main/java/sonia/scm/group/GroupNames.java index 2427101175..81843e905e 100644 --- a/scm-core/src/main/java/sonia/scm/group/GroupNames.java +++ b/scm-core/src/main/java/sonia/scm/group/GroupNames.java @@ -57,6 +57,15 @@ public final class GroupNames implements Serializable, Iterable //~--- constructors --------------------------------------------------------- + /** + * Constructs ... + * + */ + public GroupNames() + { + this.collection = Collections.EMPTY_LIST; + } + /** * Constructs ... * diff --git a/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java b/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java index fae0aa9f7f..2a876502a2 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java @@ -52,7 +52,6 @@ import sonia.scm.store.StoreFactory; import sonia.scm.user.UserManager; import sonia.scm.util.IOUtil; import sonia.scm.web.security.AuthenticationManager; -import sonia.scm.web.security.LocalSecurityContextHolder; //~--- JDK imports ------------------------------------------------------------ @@ -98,9 +97,6 @@ public class ScmContextListener extends GuiceServletContextListener // close CacheManager IOUtil.close(globalInjector.getInstance(CacheManager.class)); - // remove thread local store - globalInjector.getInstance(LocalSecurityContextHolder.class).destroy(); - // call destroy event globalInjector.getInstance( ServletContextListenerHolder.class).contextDestroyed( diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index 738e1fdbbe..ac2518d9f3 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -115,8 +115,6 @@ import sonia.scm.web.security.AuthenticationManager; import sonia.scm.web.security.BasicSecurityContext; import sonia.scm.web.security.ChainAuthenticatonManager; import sonia.scm.web.security.DefaultAdministrationContext; -import sonia.scm.web.security.LocalSecurityContextHolder; -import sonia.scm.web.security.SecurityContextProvider; import sonia.scm.web.security.WebSecurityContext; //~--- JDK imports ------------------------------------------------------------ @@ -261,11 +259,8 @@ public class ScmServletModule extends ServletModule // bind security stuff bind(AuthenticationManager.class, ChainAuthenticatonManager.class); - bind(LocalSecurityContextHolder.class); - bind(WebSecurityContext.class).annotatedWith(Names.named("userSession")).to( - BasicSecurityContext.class); - bind(SecurityContext.class).toProvider(SecurityContextProvider.class); - bind(WebSecurityContext.class).toProvider(SecurityContextProvider.class); + bind(SecurityContext.class).to(BasicSecurityContext.class); + bind(WebSecurityContext.class).to(BasicSecurityContext.class); bind(AdministrationContext.class, DefaultAdministrationContext.class); // bind security cache diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/AdministrationSecurityContext.java b/scm-webapp/src/main/java/sonia/scm/web/security/AdministrationSecurityContext.java deleted file mode 100644 index a77142d3af..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/web/security/AdministrationSecurityContext.java +++ /dev/null @@ -1,146 +0,0 @@ -/** - * 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.web.security; - -//~--- non-JDK imports -------------------------------------------------------- - -import sonia.scm.user.User; - -//~--- JDK imports ------------------------------------------------------------ - -import java.util.ArrayList; -import java.util.Collection; -import java.util.List; - -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; - -/** - * - * @author Sebastian Sdorra - */ -public class AdministrationSecurityContext implements WebSecurityContext -{ - - /** - * Constructs ... - * - * - * @param user - */ - public AdministrationSecurityContext(User user) - { - this.user = user; - } - - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param request - * @param response - * @param username - * @param password - * - * @return - */ - @Override - public User authenticate(HttpServletRequest request, - HttpServletResponse response, String username, - String password) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - /** - * Method description - * - * - * @param request - * @param response - */ - @Override - public void logout(HttpServletRequest request, HttpServletResponse response) - { - throw new UnsupportedOperationException("Not supported yet."); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - @Override - public Collection getGroups() - { - return groups; - } - - /** - * Method description - * - * - * @return - */ - @Override - public User getUser() - { - return user; - } - - /** - * Method description - * - * - * @return - */ - @Override - public boolean isAuthenticated() - { - return true; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private List groups = new ArrayList(); - - /** Field description */ - private User user; -} diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/DefaultAdministrationContext.java b/scm-webapp/src/main/java/sonia/scm/web/security/DefaultAdministrationContext.java index 31c80b680f..376c8d2574 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/DefaultAdministrationContext.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/DefaultAdministrationContext.java @@ -30,19 +30,26 @@ */ + package sonia.scm.web.security; //~--- non-JDK imports -------------------------------------------------------- import com.google.inject.Inject; import com.google.inject.Injector; -import com.google.inject.Provider; import com.google.inject.Singleton; -import com.google.inject.name.Named; + +import org.apache.shiro.SecurityUtils; +import org.apache.shiro.subject.PrincipalCollection; +import org.apache.shiro.subject.SimplePrincipalCollection; +import org.apache.shiro.subject.Subject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.SCMContext; +import sonia.scm.group.GroupNames; +import sonia.scm.security.ScmRealm; import sonia.scm.user.User; import sonia.scm.util.AssertUtil; @@ -79,13 +86,9 @@ public class DefaultAdministrationContext implements AdministrationContext * @param contextHolder */ @Inject - public DefaultAdministrationContext(Injector injector, - @Named("userSession") Provider userSessionProvider, - LocalSecurityContextHolder contextHolder) + public DefaultAdministrationContext(Injector injector) { this.injector = injector; - this.userSessionProvider = userSessionProvider; - this.contextHolder = contextHolder; URL url = DefaultAdministrationContext.class.getResource(SYSTEM_ACCOUNT); @@ -94,9 +97,9 @@ public class DefaultAdministrationContext implements AdministrationContext throw new RuntimeException("could not find resource for system account"); } - User user = JAXB.unmarshal(url, User.class); + User adminUser = JAXB.unmarshal(url, User.class); - adminContext = new AdministrationSecurityContext(user); + principalCollection = createAdminCollection(adminUser); } //~--- methods -------------------------------------------------------------- @@ -112,15 +115,26 @@ public class DefaultAdministrationContext implements AdministrationContext { AssertUtil.assertIsNotNull(action); - if (logger.isWarnEnabled()) - { - String user = SecurityUtil.getUsername(userSessionProvider); + Subject subject = SecurityUtils.getSubject(); - logger.warn("user {} executes {} as admin", user, - action.getClass().getName()); + if (logger.isInfoEnabled()) + { + String username = null; + + if (subject.isAuthenticated()) + { + username = subject.getPrincipal().toString(); + } + else + { + username = SCMContext.USER_ANONYMOUS; + } + + logger.info("user {} executes {} as admin", username, + action.getClass().getName()); } - contextHolder.set(adminContext); + subject.runAs(principalCollection); try { @@ -128,7 +142,14 @@ public class DefaultAdministrationContext implements AdministrationContext } finally { - contextHolder.remove(); + + PrincipalCollection collection = subject.releaseRunAs(); + + if (logger.isDebugEnabled()) + { + logger.debug("release runas for user {}", + collection.getPrimaryPrincipal()); + } } } @@ -146,17 +167,30 @@ public class DefaultAdministrationContext implements AdministrationContext runAsAdmin(action); } + /** + * Method description + * + * + * @param adminUser + * + * @return + */ + private PrincipalCollection createAdminCollection(User adminUser) + { + SimplePrincipalCollection collection = new SimplePrincipalCollection(); + + collection.add(adminUser.getId(), ScmRealm.NAME); + collection.add(adminUser, ScmRealm.NAME); + collection.add(new GroupNames(), ScmRealm.NAME); + + return collection; + } + //~--- fields --------------------------------------------------------------- - /** Field description */ - private AdministrationSecurityContext adminContext; - - /** Field description */ - private LocalSecurityContextHolder contextHolder; - /** Field description */ private Injector injector; /** Field description */ - private Provider userSessionProvider; + private PrincipalCollection principalCollection; } diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/LocalSecurityContextHolder.java b/scm-webapp/src/main/java/sonia/scm/web/security/LocalSecurityContextHolder.java deleted file mode 100644 index 6f0277f25a..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/web/security/LocalSecurityContextHolder.java +++ /dev/null @@ -1,96 +0,0 @@ -/** - * 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.web.security; - -import com.google.inject.Singleton; - -/** - * - * @author Sebastian Sdorra - */ -@Singleton -public class LocalSecurityContextHolder -{ - - /** - * Method description - * - */ - public void destroy() - { - store.remove(); - store = null; - } - - /** - * Method description - * - */ - public void remove() - { - store.remove(); - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public WebSecurityContext get() - { - return store.get(); - } - - //~--- set methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param value - */ - public void set(WebSecurityContext value) - { - store.set(value); - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private ThreadLocal store = - new ThreadLocal(); -} diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/SecurityContextProvider.java b/scm-webapp/src/main/java/sonia/scm/web/security/SecurityContextProvider.java deleted file mode 100644 index fae4f1dfb3..0000000000 --- a/scm-webapp/src/main/java/sonia/scm/web/security/SecurityContextProvider.java +++ /dev/null @@ -1,108 +0,0 @@ -/** - * 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.web.security; - -//~--- non-JDK imports -------------------------------------------------------- - -import com.google.inject.Inject; -import com.google.inject.Provider; -import com.google.inject.name.Named; - -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -/** - * - * @author Sebastian Sdorra - */ -public class SecurityContextProvider implements Provider -{ - - /** the logger for SecurityContextProvider */ - private static final Logger logger = - LoggerFactory.getLogger(SecurityContextProvider.class); - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param sessionContext - * @param localContext - */ - @Inject - public SecurityContextProvider( - @Named("userSession") Provider sessionContext, - LocalSecurityContextHolder localContext) - { - this.sessionContext = sessionContext; - this.localContext = localContext; - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - @Override - public WebSecurityContext get() - { - WebSecurityContext context = localContext.get(); - - if (context == null) - { - context = sessionContext.get(); - } - else if (logger.isDebugEnabled()) - { - String user = SecurityUtil.getUsername(sessionContext); - - logger.debug("return system session for user {}", user); - } - - return context; - } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private LocalSecurityContextHolder localContext; - - /** Field description */ - private Provider sessionContext; -}