1. Sebastian Sdorra
  2. scm-manager

Commits

Sebastian Sdorra  committed 2d6f57d

implement administration context with apache shiro

  • Participants
  • Parent commits 4a123e5
  • Branches apache-shiro

Comments (0)

Files changed (7)

File scm-core/src/main/java/sonia/scm/group/GroupNames.java

View file
   /**
    * Constructs ...
    *
+   */
+  public GroupNames()
+  {
+    this.collection = Collections.EMPTY_LIST;
+  }
+
+  /**
+   * Constructs ...
+   *
    *
    * @param collection
    */

File scm-webapp/src/main/java/sonia/scm/ScmContextListener.java

View file
 import sonia.scm.user.UserManager;
 import sonia.scm.util.IOUtil;
 import sonia.scm.web.security.AuthenticationManager;
-import sonia.scm.web.security.LocalSecurityContextHolder;
 
 //~--- JDK imports ------------------------------------------------------------
 
       // 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(

File scm-webapp/src/main/java/sonia/scm/ScmServletModule.java

View file
 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 ------------------------------------------------------------
 
     // 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

File scm-webapp/src/main/java/sonia/scm/web/security/AdministrationSecurityContext.java

-/**
- * 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<String> 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<String> groups = new ArrayList<String>();
-
-  /** Field description */
-  private User user;
-}

File scm-webapp/src/main/java/sonia/scm/web/security/DefaultAdministrationContext.java

View file
  */
 
 
+
 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;
 
    * @param contextHolder
    */
   @Inject
-  public DefaultAdministrationContext(Injector injector,
-          @Named("userSession") Provider<WebSecurityContext> userSessionProvider,
-          LocalSecurityContextHolder contextHolder)
+  public DefaultAdministrationContext(Injector injector)
   {
     this.injector = injector;
-    this.userSessionProvider = userSessionProvider;
-    this.contextHolder = contextHolder;
 
     URL url = DefaultAdministrationContext.class.getResource(SYSTEM_ACCOUNT);
 
       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 --------------------------------------------------------------
   {
     AssertUtil.assertIsNotNull(action);
 
-    if (logger.isWarnEnabled())
+    Subject subject = SecurityUtils.getSubject();
+
+    if (logger.isInfoEnabled())
     {
-      String user = SecurityUtil.getUsername(userSessionProvider);
+      String username = null;
 
-      logger.warn("user {} executes {} as admin", user,
-                  action.getClass().getName());
+      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
     {
     }
     finally
     {
-      contextHolder.remove();
+
+      PrincipalCollection collection = subject.releaseRunAs();
+
+      if (logger.isDebugEnabled())
+      {
+        logger.debug("release runas for user {}",
+          collection.getPrimaryPrincipal());
+      }
     }
   }
 
     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<WebSecurityContext> userSessionProvider;
+  private PrincipalCollection principalCollection;
 }

File scm-webapp/src/main/java/sonia/scm/web/security/LocalSecurityContextHolder.java

-/**
- * 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<WebSecurityContext> store =
-    new ThreadLocal<WebSecurityContext>();
-}

File scm-webapp/src/main/java/sonia/scm/web/security/SecurityContextProvider.java

-/**
- * 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<WebSecurityContext>
-{
-
-  /** 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<WebSecurityContext> 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<WebSecurityContext> sessionContext;
-}