Sebastian Sdorra avatar Sebastian Sdorra committed 135ff0a

create new key generator for shorter repository ids

Comments (0)

Files changed (5)

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

 import sonia.scm.resources.ScriptResourceServlet;
 import sonia.scm.security.CipherHandler;
 import sonia.scm.security.CipherUtil;
+import sonia.scm.security.DefaultKeyGenerator;
 import sonia.scm.security.EncryptionHandler;
 import sonia.scm.security.KeyGenerator;
 import sonia.scm.security.MessageDigestEncryptionHandler;
     bind(ScmConfiguration.class).toInstance(config);
     bind(PluginLoader.class).toInstance(pluginLoader);
     bind(PluginManager.class, DefaultPluginManager.class);
-    bind(KeyGenerator.class).toInstance(cu.getKeyGenerator());
+
+    // note CipherUtil uses an other generator
+    bind(KeyGenerator.class).to(DefaultKeyGenerator.class);
     bind(CipherHandler.class).toInstance(cu.getCipherHandler());
     bind(EncryptionHandler.class, MessageDigestEncryptionHandler.class);
     bindExtProcessor.bindExtensions(binder());

scm-webapp/src/main/java/sonia/scm/repository/DefaultRepositoryManager.java

 import sonia.scm.SCMContextProvider;
 import sonia.scm.Type;
 import sonia.scm.config.ScmConfiguration;
+import sonia.scm.security.KeyGenerator;
 import sonia.scm.security.ScmSecurityException;
 import sonia.scm.util.AssertUtil;
 import sonia.scm.util.CollectionAppender;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 
    *
    * @param configuration
    * @param contextProvider
+   * @param keyGenerator
    * @param securityContextProvider
    * @param repositoryDAO
    * @param handlerSet
    */
   @Inject
   public DefaultRepositoryManager(ScmConfiguration configuration,
-    SCMContextProvider contextProvider,
+    SCMContextProvider contextProvider, KeyGenerator keyGenerator,
     Provider<WebSecurityContext> securityContextProvider,
     RepositoryDAO repositoryDAO, Set<RepositoryHandler> handlerSet,
     Provider<Set<RepositoryListener>> repositoryListenersProvider,
   {
     this.configuration = configuration;
     this.securityContextProvider = securityContextProvider;
+    this.keyGenerator = keyGenerator;
     this.repositoryDAO = repositoryDAO;
     this.repositoryListenersProvider = repositoryListenersProvider;
     this.repositoryHooksProvider = repositoryHooksProvider;
       throw new RepositoryAllreadyExistExeption();
     }
 
-    repository.setId(UUID.randomUUID().toString());
+    repository.setId(keyGenerator.createKey());
     repository.setCreationDate(System.currentTimeMillis());
 
     if (createRepository)
   private Map<String, RepositoryHandler> handlerMap;
 
   /** Field description */
+  private KeyGenerator keyGenerator;
+
+  /** Field description */
   private RepositoryDAO repositoryDAO;
 
   /** Field description */

scm-webapp/src/main/java/sonia/scm/security/DefaultKeyGenerator.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.inject.Singleton;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.util.Random;
+import java.util.concurrent.atomic.AtomicLong;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+@Singleton
+public class DefaultKeyGenerator implements KeyGenerator
+{
+
+  /**
+   * the logger for DefaultKeyGenerator
+   */
+  private static final Logger logger =
+    LoggerFactory.getLogger(DefaultKeyGenerator.class);
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @return
+   */
+  @Override
+  public String createKey()
+  {
+    StringBuilder buffer = new StringBuilder();
+
+    buffer.append(Long.toHexString(System.currentTimeMillis()));
+    buffer.append(Long.toHexString(sessionKey.incrementAndGet()));
+    buffer.append(Integer.toHexString(random.nextInt(999)));
+
+    String key = buffer.toString();
+
+    if (logger.isTraceEnabled())
+    {
+      logger.trace("create new key {}", key);
+    }
+
+    return key;
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private AtomicLong sessionKey = new AtomicLong();
+
+  /** Field description */
+  private Random random = new Random();
+}

scm-webapp/src/test/java/sonia/scm/repository/DefaultRepositoryManagerTest.java

 import org.junit.Test;
 
 import sonia.scm.Type;
+import sonia.scm.config.ScmConfiguration;
 import sonia.scm.repository.xml.XmlRepositoryDAO;
-import sonia.scm.config.ScmConfiguration;
+import sonia.scm.security.DefaultKeyGenerator;
 import sonia.scm.store.JAXBStoreFactory;
 import sonia.scm.store.StoreFactory;
 import sonia.scm.util.MockUtil;
    */
   @Test
   public void getRepositoryFromRequestUriTest()
-          throws RepositoryException, IOException
+    throws RepositoryException, IOException
   {
     RepositoryManager m = createManager();
 
     assertEquals("scm-test", m.getFromUri("hg/scm-test").getName());
     assertEquals("scm-test", m.getFromUri("/hg/scm-test").getName());
     assertEquals("project1/test-1",
-                 m.getFromUri("/git/project1/test-1").getName());
+      m.getFromUri("/git/project1/test-1").getName());
     assertEquals("project1/test-1",
-                 m.getFromUri("/git/project1/test-1/ka/some/path").getName());
+      m.getFromUri("/git/project1/test-1/ka/some/path").getName());
     assertNull(m.getFromUri("/git/project1/test-3/ka/some/path"));
   }
 
     ScmConfiguration configuration = new ScmConfiguration();
 
     return new DefaultRepositoryManager(configuration, contextProvider,
-            MockUtil.getAdminSecurityContextProvider(), repositoryDAO,
-            handlerSet, listenerProvider, hookProvider);
+      new DefaultKeyGenerator(), MockUtil.getAdminSecurityContextProvider(),
+      repositoryDAO, handlerSet, listenerProvider, hookProvider);
   }
 
   /**
    * @throws RepositoryException
    */
   private void createRepository(RepositoryManager m, Repository repository)
-          throws RepositoryException, IOException
+    throws RepositoryException, IOException
   {
     m.create(repository);
   }

scm-webapp/src/test/java/sonia/scm/security/DefaultKeyGeneratorTest.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.collect.Sets;
+
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.util.Set;
+import java.util.concurrent.Callable;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class DefaultKeyGeneratorTest
+{
+
+  /**
+   * Method description
+   *
+   *
+   * @throws ExecutionException
+   * @throws InterruptedException
+   * @throws TimeoutException
+   */
+  @Test
+  public void testMultiThreaded()
+    throws InterruptedException, ExecutionException, TimeoutException
+  {
+    final DefaultKeyGenerator generator = new DefaultKeyGenerator();
+
+    ExecutorService executor = Executors.newFixedThreadPool(30);
+
+    Set<Future<Set<String>>> futureSet = Sets.newHashSet();
+
+    for (int i = 0; i < 10; i++)
+    {
+      Future<Set<String>> future = executor.submit(new Callable<Set<String>>()
+      {
+
+        @Override
+        public Set<String> call()
+        {
+          Set<String> keys = Sets.newHashSet();
+
+          for (int i = 0; i < 1000; i++)
+          {
+            String key = generator.createKey();
+
+            if (keys.contains(key))
+            {
+              fail("dublicate key");
+            }
+
+            keys.add(key);
+          }
+
+          return keys;
+        }
+      });
+
+      futureSet.add(future);
+    }
+
+    executor.shutdown();
+
+    Set<String> keys = Sets.newHashSet();
+
+    for (Future<Set<String>> future : futureSet)
+    {
+      Set<String> futureKeys = future.get(5, TimeUnit.SECONDS);
+
+      assertNotNull(futureKeys);
+      assertEquals(1000, futureKeys.size());
+
+      for (String key : futureKeys)
+      {
+        if (keys.contains(key))
+        {
+          fail("dublicate key");
+        }
+
+        keys.add(key);
+      }
+    }
+
+    assertEquals(10000, keys.size());
+
+  }
+
+  /**
+   * Method description
+   *
+   */
+  @Test
+  public void testSimple()
+  {
+    DefaultKeyGenerator generator = new DefaultKeyGenerator();
+
+    String key = generator.createKey();
+
+    assertNotNull(key);
+    assertTrue(key.length() > 0);
+  }
+
+  /**
+   * Method description
+   *
+   */
+  @Test
+  public void testUniqueness()
+  {
+    DefaultKeyGenerator generator = new DefaultKeyGenerator();
+    Set<String> keys = Sets.newHashSet();
+
+    for (int i = 0; i < 10000; i++)
+    {
+      String key = generator.createKey();
+
+      if (keys.contains(key))
+      {
+        fail("dublicate key");
+      }
+
+      keys.add(key);
+    }
+
+    assertEquals(10000, keys.size());
+  }
+}
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.