Commits

Sebastian Sdorra  committed 5bf5cab Merge

merge with branch apache-shiro

  • Participants
  • Parent commits 4d6d09b, da92fa3

Comments (0)

Files changed (85)

     <freemarker.version>2.3.19</freemarker.version>
     <jetty.version>7.6.7.v20120910</jetty.version>
     
+    <!-- security libraries -->
+    <shiro.version>1.2.1</shiro.version>
+    
     <!-- repostitory libraries -->
     <jgit.version>2.1.0.201209190230-r</jgit.version>
     <svnkit.version>1.7.5-2</svnkit.version>

File scm-clients/pom.xml

   
   <dependencies>
 
+    <!-- 
+    scm-core with excludes.
+    TODO: create a module only for data objects.
+    -->
+    
     <dependency>
+      <artifactId>scm-core</artifactId>
       <groupId>sonia.scm</groupId>
-      <artifactId>scm-core</artifactId>
+      <type>jar</type>
       <version>1.21-SNAPSHOT</version>
+      <exclusions>
+        <exclusion>
+          <artifactId>shiro-core</artifactId>
+          <groupId>org.apache.shiro</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>aopalliance</artifactId>
+          <groupId>aopalliance</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>guice</artifactId>
+          <groupId>com.google.inject</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>guice-multibindings</artifactId>
+          <groupId>com.google.inject.extensions</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>guice-servlet</artifactId>
+          <groupId>com.google.inject.extensions</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>jersey-core</artifactId>
+          <groupId>com.sun.jersey</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>guice-throwingproviders</artifactId>
+          <groupId>com.google.inject.extensions</groupId>
+        </exclusion>
+        <exclusion>
+          <artifactId>commons-lang</artifactId>
+          <groupId>commons-lang</groupId>
+        </exclusion>
+      </exclusions>
     </dependency>
 
   </dependencies>

File scm-clients/scm-cli-client/pom.xml

     </dependency>
     
     <dependency>
-      <artifactId>scm-core</artifactId>
-      <groupId>sonia.scm</groupId>
-      <version>1.21-SNAPSHOT</version>
-      <exclusions>
-        <exclusion>
-          <artifactId>guice</artifactId>
-          <groupId>com.google.inject</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>guice-servlet</artifactId>
-          <groupId>com.google.inject.extensions</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>guice-multibindings</artifactId>
-          <groupId>com.google.inject.extensions</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-    
-    <dependency>
       <groupId>sonia.scm.clients</groupId>
       <artifactId>scm-client-impl</artifactId>
       <version>1.21-SNAPSHOT</version>

File scm-clients/scm-client-api/pom.xml

       <version>1.1</version>
       <scope>provided</scope>
     </dependency>
-  
+    
   </dependencies>
   
 </project>

File scm-clients/scm-client-impl/pom.xml

     </dependency>
     
     <dependency>
-      <artifactId>scm-core</artifactId>
-      <groupId>sonia.scm</groupId>
-      <version>1.21-SNAPSHOT</version>
-      <exclusions>
-        <exclusion>
-          <artifactId>aopalliance</artifactId>
-          <groupId>aopalliance</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>guice</artifactId>
-          <groupId>com.google.inject</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>guice-multibindings</artifactId>
-          <groupId>com.google.inject.extensions</groupId>
-        </exclusion>
-        <exclusion>
-          <artifactId>guice-servlet</artifactId>
-          <groupId>com.google.inject.extensions</groupId>
-        </exclusion>
-      </exclusions>
-    </dependency>
-  
-    <dependency>
       <groupId>sonia.scm.clients</groupId>
       <artifactId>scm-client-api</artifactId>
       <version>1.21-SNAPSHOT</version>

File scm-clients/scm-client-impl/src/main/java/sonia/scm/client/ClientUtil.java

    * @param response
    */
   public static void appendContent(ScmClientException exception,
-                                   ClientResponse response)
+    ClientResponse response)
   {
     try
     {
    * @param expectedStatusCode
    */
   public static void checkResponse(ClientResponse response,
-                                   int expectedStatusCode)
+    int expectedStatusCode)
   {
     int sc = response.getStatus();
 
     if (sc != expectedStatusCode)
     {
+      if (logger.isWarnEnabled())
+      {
+        logger.warn("response code {} expected, but {} returned",
+          expectedStatusCode, sc);
+      }
+
       sendException(response, sc);
     }
   }
 
     if (sc >= 300)
     {
+      if (logger.isWarnEnabled())
+      {
+        logger.warn("request failed, response code {} returned", sc);
+      }
+      
       sendException(response, sc);
     }
   }
    * @return
    */
   public static WebResource createResource(Client client, String url,
-          boolean enableLogging)
+    boolean enableLogging)
   {
     WebResource resource = client.resource(url);
 

File scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyRepositoryClientHandler.java

 
 import sonia.scm.NotSupportedFeatuerException;
 import sonia.scm.Type;
-import sonia.scm.repository.Changeset;
 import sonia.scm.repository.Repository;
 import sonia.scm.repository.Tags;
 

File scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java

 import sonia.scm.client.ClientUtil;
 import sonia.scm.client.JerseyClientProvider;
 import sonia.scm.client.JerseyClientSession;
-import sonia.scm.client.ScmUrlProvider;
 import sonia.scm.config.ScmConfiguration;
 import sonia.scm.url.UrlProvider;
 
    *
    */
   public static JerseyClientSession createSession(String username,
-          String password)
+    String password)
   {
     JerseyClientProvider provider = new JerseyClientProvider(REQUEST_LOGGING);
 

File scm-core/pom.xml

       <version>${slf4j.version}</version>
     </dependency>
     
+    <!-- security -->
+    
+    <dependency>
+      <groupId>org.apache.shiro</groupId>
+      <artifactId>shiro-core</artifactId>
+      <version>${shiro.version}</version>
+    </dependency>
+    
     <!-- injection -->
 
     <dependency>

File scm-core/src/main/java/sonia/scm/HandlerEvent.java

   /**
    * After a new object is stored by a handler.
    */
-  CREATE,
+  CREATE(true),
 
   /**
    * After a object is modified by a handler.
    */
-  MODIFY,
+  MODIFY(true),
 
   /**
    * After a object is removed by a handler.
    */
-  DELETE,
+  DELETE(true),
 
   /**
    * Before a new object is stored by a handler.
    * @since 1.16
    */
-  BEFORE_CREATE,
+  BEFORE_CREATE(false),
 
   /**
    * Before a object is modified by a handler.
    * @since 1.16
    */
-  BEFORE_MODIFY,
+  BEFORE_MODIFY(false),
 
   /**
    * Before a object is removed by a handler.
    * @since 1.16
    */
-  BEFORE_DELETE
+  BEFORE_DELETE(false);
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param post
+   */
+  private HandlerEvent(boolean post)
+  {
+    this.post = post;
+  }
+
+  //~--- get methods ----------------------------------------------------------
+
+  /**
+   * Returns true if the event is fired after the action is occurred.
+   *
+   *
+   * @return true if the event is fired after the action is occurred
+   * @since 1.21
+   */
+  public boolean isPost()
+  {
+    return post;
+  }
+
+  /**
+   * Returns true if the event is fired before the action is occurred.
+   *
+   *
+   * @return true if the event is fired before the action is occurred
+   * @since 1.21
+   */
+  public boolean isPre()
+  {
+    return !post;
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private boolean post;
 }

File scm-core/src/main/java/sonia/scm/SCMContext.java

 
 //~--- non-JDK imports --------------------------------------------------------
 
+import sonia.scm.user.User;
 import sonia.scm.util.ServiceUtil;
 
 /**
   /** Name of the anonymous user */
   public static final String USER_ANONYMOUS = "anonymous";
 
+  /** 
+   * the anonymous user 
+   * @since 1.21
+   */
+  public static final User ANONYMOUS = new User(USER_ANONYMOUS,
+                                         "SCM Anonymous",
+                                         "scm-anonymous@scm-manager.com");
+
   /** Singleton instance of {@link SCMContextProvider} */
   private static volatile SCMContextProvider provider;
 

File scm-core/src/main/java/sonia/scm/ScmState.java

    * @param repositoryTypes - available repository types
    * @param clientConfig - client configuration
    */
+  @Deprecated
   public ScmState(SCMContextProvider provider,
-                  WebSecurityContext securityContext,
-                  Collection<Type> repositoryTypes,
-                  ScmClientConfig clientConfig)
+    WebSecurityContext securityContext, Collection<Type> repositoryTypes,
+    ScmClientConfig clientConfig)
   {
     this(provider, securityContext, repositoryTypes, null, clientConfig);
   }
    *
    * @since 1.14
    */
+  @Deprecated
   public ScmState(SCMContextProvider provider,
-                  WebSecurityContext securityContext,
-                  Collection<Type> repositoryTypes, String defaultUserType,
-                  ScmClientConfig clientConfig)
+    WebSecurityContext securityContext, Collection<Type> repositoryTypes,
+    String defaultUserType, ScmClientConfig clientConfig)
   {
     this.version = provider.getVersion();
     this.user = securityContext.getUser();
     this.defaultUserType = defaultUserType;
   }
 
+  /**
+   * Constructs {@link ScmState} object.
+   *
+   *
+   * @param provider context provider
+   * @param user current user
+   * @param groups groups of the current user
+   * @param repositoryTypes available repository types
+   * @param defaultUserType default user type
+   * @param clientConfig client configuration
+   *
+   * @since 1.21
+   */
+  public ScmState(SCMContextProvider provider, User user,
+    Collection<String> groups, Collection<Type> repositoryTypes,
+    String defaultUserType, ScmClientConfig clientConfig)
+  {
+    this.version = provider.getVersion();
+    this.user = user;
+    this.groups = groups;
+    this.repositoryTypes = repositoryTypes;
+    this.clientConfig = clientConfig;
+    this.defaultUserType = defaultUserType;
+  }
+
   //~--- get methods ----------------------------------------------------------
 
   /**

File scm-core/src/main/java/sonia/scm/group/GroupNames.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.group;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.common.collect.Lists;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.io.Serializable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+
+/**
+ * This class represents all associated groups for a user.
+ *
+ * @author Sebastian Sdorra
+ * @since 1.21
+ */
+public final class GroupNames implements Serializable, Iterable<String>
+{
+
+  /** Field description */
+  private static final long serialVersionUID = 8615685985213897947L;
+
+  //~--- constructors ---------------------------------------------------------
+
+  /**
+   * Constructs ...
+   *
+   */
+  public GroupNames()
+  {
+    this.collection = Collections.EMPTY_LIST;
+  }
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param collection
+   */
+  public GroupNames(Collection<String> collection)
+  {
+    this.collection = Collections.unmodifiableCollection(collection);
+  }
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param groupName
+   * @param groupNames
+   */
+  public GroupNames(String groupName, String... groupNames)
+  {
+    this.collection = Lists.asList(groupName, groupNames);
+  }
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param groupName
+   *
+   * @return
+   */
+  public boolean contains(String groupName)
+  {
+    return collection.contains(groupName);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  @Override
+  public Iterator<String> iterator()
+  {
+    return collection.iterator();
+  }
+
+  //~--- get methods ----------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  public Collection<String> getCollection()
+  {
+    return collection;
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private Collection<String> collection;
+}

File scm-core/src/main/java/sonia/scm/repository/PermissionUtil.java

 
 import com.google.inject.Provider;
 
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import sonia.scm.config.ScmConfiguration;
+import sonia.scm.group.GroupNames;
+import sonia.scm.security.Role;
 import sonia.scm.security.ScmSecurityException;
-import sonia.scm.user.User;
 import sonia.scm.util.AssertUtil;
 import sonia.scm.web.security.WebSecurityContext;
 
 //~--- JDK imports ------------------------------------------------------------
 
-import java.util.Collection;
 import java.util.List;
 
 /**
    * @param repository
    * @param securityContext
    * @param pt
+   * @deprecated
    */
+  @Deprecated
   public static void assertPermission(Repository repository,
-          WebSecurityContext securityContext, PermissionType pt)
+    WebSecurityContext securityContext, PermissionType pt)
   {
-    if (!hasPermission(repository, securityContext, pt))
-    {
-      throw new ScmSecurityException("action denied");
-    }
+    assertPermission(repository, pt);
   }
 
   /**
    * @param securityContextProvider
    * @param pt
    */
+  @Deprecated
   public static void assertPermission(Repository repository,
-          Provider<WebSecurityContext> securityContextProvider,
-          PermissionType pt)
+    Provider<WebSecurityContext> securityContextProvider, PermissionType pt)
   {
     assertPermission(repository, securityContextProvider.get(), pt);
   }
 
+  /**
+   * Method description
+   *
+   *
+   * @param repository
+   * @param securityContextProvider
+   * @param pt
+   *
+   * @since 1.21
+   */
+  @Deprecated
+  public static void assertPermission(Repository repository, PermissionType pt)
+  {
+    if (!hasPermission(null, repository, pt))
+    {
+      throw new ScmSecurityException("action denied");
+    }
+  }
+
   //~--- get methods ----------------------------------------------------------
 
   /**
    * @param pt
    *
    * @return
+   * @deprecated
    */
+  @Deprecated
   public static boolean hasPermission(Repository repository,
-          Provider<WebSecurityContext> securityContextProvider,
-          PermissionType pt)
+    Provider<WebSecurityContext> securityContextProvider, PermissionType pt)
   {
-    return hasPermission(repository, securityContextProvider.get(), pt);
+    return hasPermission(null, repository, pt);
   }
 
   /**
    * @param pt
    *
    * @return
+   * @deprecated use {@link #hasPermission(Repository,PermissionType)} instead
    */
+  @Deprecated
   public static boolean hasPermission(Repository repository,
-          WebSecurityContext securityContext, PermissionType pt)
+    WebSecurityContext securityContext, PermissionType pt)
+  {
+    return hasPermission(null, repository, pt);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param configuration
+   * @param repository
+   * @param pt
+   *
+   * @return
+   *
+   * @since 1.21
+   */
+  public static boolean hasPermission(ScmConfiguration configuration,
+    Repository repository, PermissionType pt)
   {
     boolean result = false;
 
-    if (securityContext != null)
+    Subject subject = SecurityUtils.getSubject();
+
+    if (subject.isAuthenticated())
     {
-      User user = securityContext.getUser();
+      String username = subject.getPrincipal().toString();
 
-      if (user != null)
+      AssertUtil.assertIsNotEmpty(username);
+
+      if (subject.hasRole(Role.ADMIN)
+        || ((pt == PermissionType.READ) && repository.isPublicReadable()))
       {
-        String username = user.getName();
+        result = true;
+      }
+      else
+      {
+        List<Permission> permissions = repository.getPermissions();
 
-        AssertUtil.assertIsNotEmpty(username);
+        if (permissions != null)
+        {
+          GroupNames groupNames =
+            subject.getPrincipals().oneByType(GroupNames.class);
 
-        if (user.isAdmin()
-            || ((pt == PermissionType.READ) && repository.isPublicReadable()))
-        {
-          result = true;
-        }
-        else
-        {
-          List<Permission> permissions = repository.getPermissions();
+          result = hasPermission(permissions, username, groupNames, pt);
 
-          if (permissions != null)
-          {
-            result = hasPermission(permissions, username,
-                                   securityContext.getGroups(), pt);
-          }
         }
       }
     }
+    else
+    {
+
+      // check anonymous access
+      result = (configuration != null)
+        && configuration.isAnonymousAccessEnabled()
+        && repository.isPublicReadable() && (pt == PermissionType.READ);
+    }
 
     return result;
   }
    *
    * @return true if the repository is writable
    * @since 1.14
+   * @deprecated use {@link #isWritable(ScmConfiguration, Repository)} instead
+   */
+  @Deprecated
+  public static boolean isWritable(ScmConfiguration configuration,
+    Repository repository, WebSecurityContext securityContext)
+  {
+    return isWritable(configuration, repository);
+  }
+
+  /**
+   * 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.21
    */
   public static boolean isWritable(ScmConfiguration configuration,
-                                    Repository repository,
-                                    WebSecurityContext securityContext)
+    Repository repository)
   {
     boolean permitted = false;
 
       if (logger.isWarnEnabled())
       {
         logger.warn("{} is archived and is not writeable",
-                    repository.getName());
+          repository.getName());
       }
     }
     else
     {
-      permitted = PermissionUtil.hasPermission(repository, securityContext,
-              PermissionType.WRITE);
+      permitted = PermissionUtil.hasPermission(configuration, repository,
+        PermissionType.WRITE);
     }
 
     return permitted;
    * @return
    */
   private static boolean hasPermission(List<Permission> permissions,
-          String username, Collection<String> groups, PermissionType pt)
+    String username, GroupNames groups, PermissionType pt)
   {
     boolean result = false;
 
       String name = p.getName();
 
       if (((name != null) && (p.getType().getValue() >= pt.getValue()))
-          && (name.equals(username)
-              || (p.isGroupPermission() && groups.contains(p.getName()))))
+        && (name.equals(username)
+          || (p.isGroupPermission() && groups.contains(p.getName()))))
       {
         result = true;
 

File scm-core/src/main/java/sonia/scm/repository/api/RepositoryServiceFactory.java

 import com.google.common.base.Preconditions;
 import com.google.common.base.Strings;
 import com.google.inject.Inject;
-import com.google.inject.Provider;
 import com.google.inject.Singleton;
 
 import org.slf4j.Logger;
 import sonia.scm.HandlerEvent;
 import sonia.scm.cache.Cache;
 import sonia.scm.cache.CacheManager;
+import sonia.scm.config.ScmConfiguration;
 import sonia.scm.repository.BlameResult;
 import sonia.scm.repository.Branches;
 import sonia.scm.repository.BrowserResult;
 import sonia.scm.repository.spi.RepositoryServiceProvider;
 import sonia.scm.repository.spi.RepositoryServiceResolver;
 import sonia.scm.security.ScmSecurityException;
-import sonia.scm.web.security.WebSecurityContext;
 
 //~--- JDK imports ------------------------------------------------------------
 
    * @param securityContextProvider provider for the current security context
    * @param resolvers a set of {@link RepositoryServiceResolver}
    * @param preProcessorUtil helper object for pre processor handling
+   *
+   * @deprecated
+   */
+  @Deprecated
+  public RepositoryServiceFactory(CacheManager cacheManager,
+    RepositoryManager repositoryManager,
+    Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil)
+  {
+    this(null, cacheManager, repositoryManager, resolvers, preProcessorUtil);
+  }
+
+  /**
+   * Constructs a new {@link RepositoryServiceFactory}. This constructor
+   * should not be called manually, it should only be used by the injection
+   * container.
+   *
+   *
+   * @param configuration configuration
+   * @param cacheManager cache manager
+   * @param repositoryManager manager for repositories
+   * @param securityContextProvider provider for the current security context
+   * @param resolvers a set of {@link RepositoryServiceResolver}
+   * @param preProcessorUtil helper object for pre processor handling
+   * 
+   * @since 1.21
    */
   @Inject
-  public RepositoryServiceFactory(CacheManager cacheManager,
-    RepositoryManager repositoryManager,
-    Provider<WebSecurityContext> securityContextProvider,
+  public RepositoryServiceFactory(ScmConfiguration configuration,
+    CacheManager cacheManager, RepositoryManager repositoryManager,
     Set<RepositoryServiceResolver> resolvers, PreProcessorUtil preProcessorUtil)
   {
+    this.configuration = configuration;
     this.cacheManager = cacheManager;
     this.repositoryManager = repositoryManager;
-    this.securityContextProvider = securityContextProvider;
     this.resolvers = resolvers;
     this.preProcessorUtil = preProcessorUtil;
 
     Preconditions.checkNotNull(repository, "repository is required");
 
     // check for read permissions of current user
-    PermissionUtil.assertPermission(repository, securityContextProvider,
-      PermissionType.READ);
+    if (!PermissionUtil.hasPermission(configuration, repository,
+      PermissionType.READ))
+    {
+      throw new ScmSecurityException("read permission are required");
+    }
 
     RepositoryService service = null;
 
   /** Field description */
   private CacheManager cacheManager;
 
+  /** scm-manager configuration */
+  private ScmConfiguration configuration;
+
   /** Field description */
   private PreProcessorUtil preProcessorUtil;
 
 
   /** Field description */
   private Set<RepositoryServiceResolver> resolvers;
-
-  /** Field description */
-  private Provider<WebSecurityContext> securityContextProvider;
 }

File scm-core/src/main/java/sonia/scm/security/RepositoryPermission.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.security;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.common.base.Objects;
+
+import org.apache.shiro.authz.Permission;
+
+import sonia.scm.repository.PermissionType;
+import sonia.scm.repository.Repository;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.io.Serializable;
+
+/**
+ * This class represents the permission to a repository of a user.
+ *
+ * @author Sebastian Sdorra
+ * @since 1.21
+ */
+public final class RepositoryPermission implements Permission, Serializable
+{
+
+  /** Field description */
+  public static final String WILDCARD = "*";
+
+  /** Field description */
+  private static final long serialVersionUID = 3832804235417228043L;
+
+  //~--- constructors ---------------------------------------------------------
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param repository
+   * @param permissionType
+   */
+  public RepositoryPermission(Repository repository,
+    PermissionType permissionType)
+  {
+    this(repository.getId(), permissionType);
+  }
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param repositoryId
+   * @param permissionType
+   */
+  public RepositoryPermission(String repositoryId,
+    PermissionType permissionType)
+  {
+    this.repositoryId = repositoryId;
+    this.permissionType = permissionType;
+  }
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param obj
+   *
+   * @return
+   */
+  @Override
+  public boolean equals(Object obj)
+  {
+    if (obj == null)
+    {
+      return false;
+    }
+
+    if (getClass() != obj.getClass())
+    {
+      return false;
+    }
+
+    final RepositoryPermission other = (RepositoryPermission) obj;
+
+    return Objects.equal(repositoryId, other.repositoryId)
+      && Objects.equal(permissionType, other.permissionType);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  @Override
+  public int hashCode()
+  {
+    return Objects.hashCode(repositoryId, permissionType);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param p
+   *
+   * @return
+   */
+  @Override
+  public boolean implies(Permission p)
+  {
+    boolean result = false;
+
+    if (p instanceof RepositoryPermission)
+    {
+      RepositoryPermission rp = (RepositoryPermission) p;
+
+      //J-
+      result = (repositoryId.equals(WILDCARD) || repositoryId.equals(rp.repositoryId)) 
+                && (permissionType.getValue() >= rp.permissionType.getValue());
+      //J+
+    }
+
+    return result;
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  @Override
+  public String toString()
+  {
+    //J-
+    return Objects.toStringHelper(this)
+                  .add("repositoryId", repositoryId)
+                  .add("permissionType", permissionType)
+                  .toString();
+    //J+
+  }
+
+  //~--- get methods ----------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  public PermissionType getPermissionType()
+  {
+    return permissionType;
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  public String getRepositoryId()
+  {
+    return repositoryId;
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private PermissionType permissionType;
+
+  /** Field description */
+  private String repositoryId;
+}

File scm-core/src/main/java/sonia/scm/security/Role.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.security;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ * @since 1.21
+ */
+public final class Role
+{
+
+  /** Field description */
+  public static final String ADMIN = "admin";
+
+  /** Field description */
+  public static final String USER = "user";
+}

File scm-core/src/main/java/sonia/scm/security/SecurityContext.java

 /**
  *
  * @author Sebastian Sdorra
+ * @deprecated use {@link SecurityUtils#getSecurityManager()} instead.
  */
+@Deprecated
 public interface SecurityContext
 {
 

File scm-core/src/main/java/sonia/scm/security/Tokens.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.security;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import org.apache.shiro.authc.AuthenticationToken;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * Create tokens for security reasons.
+ *
+ * @author Sebastian Sdorra
+ * @since 1.21
+ */
+public final class Tokens
+{
+
+  /**
+   * Build an {@link AuthenticationToken} for use with
+   * {@link Subject#login(org.apache.shiro.authc.AuthenticationToken)}.
+   *
+   *
+   * @param request servlet request
+   * @param username username of the user to authenticate
+   * @param password password of the user to authenticate
+   *
+   * @return
+   */
+  public static AuthenticationToken createAuthenticationToken(
+    HttpServletRequest request, String username, String password)
+  {
+    return new UsernamePasswordToken(username, password,
+      request.getRemoteAddr());
+  }
+}

File scm-core/src/main/java/sonia/scm/template/TemplateParseException.java

 /**
- * Copyright (c) 2010, Sebastian Sdorra All rights reserved.
+ * 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 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.
+ * 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.template;
 
 //~--- JDK imports ------------------------------------------------------------

File scm-core/src/main/java/sonia/scm/util/SecurityUtil.java

 
 import com.google.inject.Provider;
 
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
 import sonia.scm.SCMContext;
+import sonia.scm.security.Role;
 import sonia.scm.security.ScmSecurityException;
 import sonia.scm.security.SecurityContext;
 import sonia.scm.user.User;
    *
    *
    * @param contextProvider
+   * @deprecated use {@link Subject#checkRole(java.lang.String)} with {
+   * @link Role#ADMIN} instead.
    */
+  @Deprecated
   public static void assertIsAdmin(
-          Provider<? extends SecurityContext> contextProvider)
+    Provider<? extends SecurityContext> contextProvider)
   {
-    assertIsAdmin(contextProvider.get());
+    assertIsAdmin();
   }
 
   /**
-   * Method description
+   * This method is only present for compatibility reasons.
+   * Use {@link Subject#checkRole(java.lang.String)} with {
+   * @link Role#ADMIN} instead.
    *
-   *
-   * @param context
+   * @since 1.21
    */
-  public static void assertIsAdmin(SecurityContext context)
+  public static void assertIsAdmin()
   {
-    AssertUtil.assertIsNotNull(context);
+    Subject subject = SecurityUtils.getSubject();
 
-    User user = context.getUser();
-
-    if (user == null)
+    if (!subject.isAuthenticated())
     {
       throw new ScmSecurityException("user is not authenticated");
     }
-
-    if (!user.isAdmin())
+    else if (!subject.hasRole(Role.ADMIN))
     {
       throw new ScmSecurityException("admin account is required");
     }
    * Method description
    *
    *
+   * @param context
+   * @deprecated use {@link Subject#checkRole(java.lang.String)} with {
+   * @link Role#ADMIN} instead.
+   */
+  @Deprecated
+  public static void assertIsAdmin(SecurityContext context)
+  {
+    assertIsAdmin();
+  }
+
+  /**
+   * Method description
+   *
+   *
    * @param contextProvider
    */
   public static void assertIsNotAnonymous(
-          Provider<? extends SecurityContext> contextProvider)
+    Provider<? extends SecurityContext> contextProvider)
   {
     if (isAnonymous(contextProvider))
     {
    * @return
    */
   public static User getCurrentUser(
-          Provider<? extends SecurityContext> contextProvider)
+    Provider<? extends SecurityContext> contextProvider)
   {
     AssertUtil.assertIsNotNull(contextProvider);
 
    * @return
    */
   public static boolean isAdmin(
-          Provider<? extends SecurityContext> contextProvider)
+    Provider<? extends SecurityContext> contextProvider)
   {
     return isAdmin(contextProvider.get());
   }
     AssertUtil.assertIsNotNull(contextProvider);
 
     return (contextProvider.getUser() != null)
-           && contextProvider.getUser().isAdmin();
+      && contextProvider.getUser().isAdmin();
   }
 
   /**
    * @return
    */
   public static boolean isAnonymous(
-          Provider<? extends SecurityContext> contextProvider)
+    Provider<? extends SecurityContext> contextProvider)
   {
     return isAnonymous(contextProvider.get());
   }

File scm-core/src/main/java/sonia/scm/web/filter/BasicAuthenticationFilter.java

 import com.google.inject.Provider;
 import com.google.inject.Singleton;
 
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.authc.AuthenticationException;
+import org.apache.shiro.authc.UsernamePasswordToken;
+import org.apache.shiro.subject.Subject;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import sonia.scm.SCMContext;
+import sonia.scm.config.ScmConfiguration;
 import sonia.scm.user.User;
-import sonia.scm.util.AssertUtil;
 import sonia.scm.util.HttpUtil;
 import sonia.scm.util.Util;
 import sonia.scm.web.security.WebSecurityContext;
    *
    *
    * @param securityContextProvider
+   * @deprecated use the constructor with out arguments instead.
+   */
+  @Deprecated
+  public BasicAuthenticationFilter(
+    Provider<WebSecurityContext> securityContextProvider) {}
+
+  /**
+   * Constructs a new basic authenticaton filter
+   *
+   * @param configuration scm-manager global configuration
+   *
+   * @since 1.21
    */
   @Inject
-  public BasicAuthenticationFilter(
-          Provider<WebSecurityContext> securityContextProvider)
+  public BasicAuthenticationFilter(ScmConfiguration configuration)
   {
-    this.securityContextProvider = securityContextProvider;
+    this.configuration = configuration;
   }
 
   //~--- methods --------------------------------------------------------------
    */
   @Override
   protected void doFilter(HttpServletRequest request,
-                          HttpServletResponse response, FilterChain chain)
-          throws IOException, ServletException
+    HttpServletResponse response, FilterChain chain)
+    throws IOException, ServletException
   {
-    WebSecurityContext securityContext = securityContextProvider.get();
-
-    AssertUtil.assertIsNotNull(securityContext);
+    Subject subject = SecurityUtils.getSubject();
 
     User user = null;
     String authentication = request.getHeader(HEADER_AUTHORIZATION);
         logger.trace("found basic authorization header, start authentication");
       }
 
-      user = authenticate(request, response, securityContext, authentication);
+      user = authenticate(request, response, subject, authentication);
 
       if (logger.isTraceEnabled())
       {
         }
       }
     }
-    else if (securityContext.isAuthenticated())
+    else if (subject.isAuthenticated())
     {
       if (logger.isTraceEnabled())
       {
         logger.trace("user is allready authenticated");
       }
 
-      user = securityContext.getUser();
+      user = subject.getPrincipals().oneByType(User.class);
+    }
+    else if ((configuration != null)
+      && configuration.isAnonymousAccessEnabled())
+    {
+      user = SCMContext.ANONYMOUS;
+
     }
 
     if (user == null)
         logger.trace("could not find user send unauthorized");
       }
 
-      HttpUtil.sendUnauthorized(request, response);
+      handleUnauthorized(request, response, chain);
     }
     else
     {
       chain.doFilter(new SecurityHttpServletRequestWrapper(request, user),
-                     response);
+        response);
     }
   }
 
    * @since 1.8
    */
   protected void handleUnauthorized(HttpServletRequest request,
-                                    HttpServletResponse response,
-                                    FilterChain chain)
-          throws IOException, ServletException
+    HttpServletResponse response, FilterChain chain)
+    throws IOException, ServletException
   {
     HttpUtil.sendUnauthorized(request, response);
   }
    * @param request
    * @param response
    * @param securityContext
+   * @param subject
    * @param authentication
    *
    * @return
    */
   private User authenticate(HttpServletRequest request,
-                            HttpServletResponse response,
-                            WebSecurityContext securityContext,
-                            String authentication)
+    HttpServletResponse response, Subject subject, String authentication)
   {
     String token = authentication.substring(6);
 
           logger.trace("try to authenticate user {}", username);
         }
 
-        user = securityContext.authenticate(request, response, username,
-                password);
+        try
+        {
+
+          subject.login(new UsernamePasswordToken(username, password,
+            request.getRemoteAddr()));
+          user = subject.getPrincipals().oneByType(User.class);
+        }
+        catch (AuthenticationException ex)
+        {
+          if (logger.isTraceEnabled())
+          {
+            logger.trace("authentication failed for user ".concat(username),
+              ex);
+          }
+          else if (logger.isWarnEnabled())
+          {
+            logger.warn("authentication failed for user {}", username);
+          }
+        }
       }
       else if (logger.isWarnEnabled())
       {
   //~--- fields ---------------------------------------------------------------
 
   /** Field description */
-  private Provider<WebSecurityContext> securityContextProvider;
+  private ScmConfiguration configuration;
 }

File scm-core/src/main/java/sonia/scm/web/filter/PermissionFilter.java

 import com.google.common.base.Splitter;
 import com.google.inject.Provider;
 
+import org.apache.shiro.SecurityUtils;
+import org.apache.shiro.subject.Subject;
+
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import sonia.scm.ArgumentIsInvalidException;
-import sonia.scm.SCMContext;
 import sonia.scm.config.ScmConfiguration;
 import sonia.scm.repository.PermissionType;
 import sonia.scm.repository.PermissionUtil;
 import sonia.scm.repository.Repository;
 import sonia.scm.security.ScmSecurityException;
-import sonia.scm.user.User;
-import sonia.scm.util.AssertUtil;
 import sonia.scm.util.HttpUtil;
 import sonia.scm.util.Util;
 import sonia.scm.web.security.WebSecurityContext;
   //~--- constructors ---------------------------------------------------------
 
   /**
+   * Constructs a new permission filter
+   * 
+   * @param configuration global scm-manager configuration
+   * 
+   * @since 1.21
+   */
+  public PermissionFilter(ScmConfiguration configuration)
+  {
+    this.configuration = configuration;
+  }
+
+  /**
    * Constructs ...
    *
    *
    *
    * @param configuration
    * @param securityContextProvider
+   * @deprecated
    */
+  @Deprecated
   public PermissionFilter(ScmConfiguration configuration,
-                          Provider<WebSecurityContext> securityContextProvider)
+    Provider<WebSecurityContext> securityContextProvider)
   {
     this.configuration = configuration;
-    this.securityContextProvider = securityContextProvider;
   }
 
   //~--- get methods ----------------------------------------------------------
    */
   @Override
   protected void doFilter(HttpServletRequest request,
-                          HttpServletResponse response, FilterChain chain)
-          throws IOException, ServletException
+    HttpServletResponse response, FilterChain chain)
+    throws IOException, ServletException
   {
-    WebSecurityContext securityContext = securityContextProvider.get();
+    Subject subject = SecurityUtils.getSubject();
 
-    AssertUtil.assertIsNotNull(securityContext);
+    try
+    {
+      Repository repository = getRepository(request);
 
-    User user = securityContext.getUser();
+      if (repository != null)
+      {
+        boolean writeRequest = isWriteRequest(request);
 
-    if (user != null)
-    {
-      try
-      {
-        Repository repository = getRepository(request);
+        if (hasPermission(repository, writeRequest))
+        {
+          if (logger.isTraceEnabled())
+          {
+            logger.trace("{} access to repository {} for user {} granted",
+              new Object[] { writeRequest
+              ? "write"
+              : "read", repository.getName(), subject.getPrincipal() });
+          }
 
-        if (repository != null)
-        {
-          boolean writeRequest = isWriteRequest(request);
-
-          if (hasPermission(repository, securityContext, writeRequest))
-          {
-            if (logger.isTraceEnabled())
-            {
-              logger.trace("{} access to repository {} for user {} granted",
-                           new Object[] { writeRequest
-                                          ? "write"
-                                          : "read", repository.getName(),
-                                          user.getName() });
-            }
-
-            chain.doFilter(request, response);
-          }
-          else
-          {
-            if (logger.isInfoEnabled())
-            {
-              logger.info("{} access to repository {} for user {} denied",
-                          new Object[] { writeRequest
-                                         ? "write"
-                                         : "read", repository.getName(),