Added character set filter to random code generator, e.g. for client_id.

Change-Id: Ifc1f4be39752806baaaa0be3bc69f55558360f56
diff --git a/core/Changes b/core/Changes
index c1b2d80..b599c9a 100644
--- a/core/Changes
+++ b/core/Changes
@@ -1,7 +1,7 @@
 # version 0.63.2
 2021-06-11
  - Updated OAuth2 token length & secure random algorithm config.
-
+ - Added character set filter to random code generator, e.g. for client_id.
 # version 0.63.1
 2021-03-25
  - Updated Koral version for InfoController.
diff --git a/core/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java b/core/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
index fe23f22..ea67bd6 100644
--- a/core/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
+++ b/core/src/main/java/de/ids_mannheim/korap/encryption/RandomCodeGenerator.java
@@ -3,7 +3,11 @@
 import java.security.MessageDigest;
 import java.security.NoSuchAlgorithmException;
 import java.security.SecureRandom;
+import java.util.Arrays;
+import java.util.List;
 import java.util.UUID;
+import java.util.concurrent.ThreadLocalRandom;
+import java.util.stream.Collectors;
 
 import javax.annotation.PostConstruct;
 
@@ -26,6 +30,15 @@
 @Component
 public class RandomCodeGenerator {
 
+    public static String alphanumeric = "34679bdfhmnprtFGHJLMNPRT";
+    public static List<Character> charList = alphanumeric.chars()
+            .mapToObj(c -> (char) c).collect(Collectors.toList());
+
+    public final static List<String> LIMITED_CHARACTERS =
+            Arrays.asList(new String[] { "3", "4", "6", "7", "9", "b", "d", "f",
+                    "h", "m", "n", "p", "r", "t", "F", "G", "H", "J", "L", "M",
+                    "N", "P", "R", "T" });
+
     @Autowired
     public KustvaktConfiguration config;
 
@@ -33,15 +46,15 @@
 
     @PostConstruct
     public void init () throws NoSuchAlgorithmException {
-        String algorithm = config.getSecureRandomAlgorithm(); 
+        String algorithm = config.getSecureRandomAlgorithm();
         if (!algorithm.isEmpty()) {
-            secureRandom =
-                    SecureRandom.getInstance(algorithm);    
+            secureRandom = SecureRandom.getInstance(algorithm);
         }
         else {
             secureRandom = new SecureRandom();
         }
-        System.out.println("Secure random algorithm: "+secureRandom.getAlgorithm());        
+        System.out.println(
+                "Secure random algorithm: " + secureRandom.getAlgorithm());
     }
 
     public String createRandomCode (KustvaktConfiguration c)
@@ -75,4 +88,16 @@
         }
     }
 
+    public String filterRandomCode (String code) {
+        StringBuffer s = new StringBuffer();
+        for (char c : code.toCharArray()) {
+            if (!charList.contains(c)) {
+                int n = ThreadLocalRandom.current().nextInt(0,
+                        charList.size());
+                c = charList.get(n);
+            }
+            s.append(c);
+        }
+        return s.toString();
+    }
 }
diff --git a/full/Changes b/full/Changes
index 7d19904..9f8e800 100644
--- a/full/Changes
+++ b/full/Changes
@@ -1,7 +1,8 @@
 # version 0.63.2
 2021-06-11
  - Updated OAuth2 token length & secure random algorithm config.
-
+ - Added character set filter to random code generator, e.g. for client_id.
+ 
 # version 0.63.1
 2021-02-22
  - Updated libraries (margaretha)
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
index 7328c81..0180c27 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
@@ -126,6 +126,7 @@
         }
 
         String id = codeGenerator.createRandomCode();
+        id = codeGenerator.filterRandomCode(id);
         try {
             clientDao.registerClient(id, secretHashcode, clientJson.getName(),
                     clientJson.getType(), url, redirectURI, registeredBy,
diff --git a/full/src/test/java/de/ids_mannheim/korap/authentication/RandomCodeGeneratorTest.java b/full/src/test/java/de/ids_mannheim/korap/authentication/RandomCodeGeneratorTest.java
index 6097cd2..952f804 100644
--- a/full/src/test/java/de/ids_mannheim/korap/authentication/RandomCodeGeneratorTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/authentication/RandomCodeGeneratorTest.java
@@ -6,6 +6,7 @@
 
 import org.apache.oltu.oauth2.as.issuer.MD5Generator;
 import org.apache.oltu.oauth2.common.exception.OAuthSystemException;
+import org.junit.Ignore;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
 
@@ -26,14 +27,17 @@
         //System.out.println(value);
     }
 
+    @Ignore
     public void testRandomGeneratorPerformance () throws OAuthSystemException,
             NoSuchAlgorithmException, KustvaktException {
         long min = Integer.MAX_VALUE, max = Integer.MIN_VALUE;
 
+        String code;
         while (true) {
             long start = System.currentTimeMillis();
             for (int i = 0; i < 10000; i++) {
-                random.createRandomCode();
+                code = random.createRandomCode();
+                code = random.filterRandomCode(code);
             }
             long end = System.currentTimeMillis();
             long duration = end - start;
@@ -46,6 +50,7 @@
         }
     }
 
+    @Ignore
     public void testMD5Generator () throws OAuthSystemException,
             NoSuchAlgorithmException, KustvaktException {
         MD5Generator m = new MD5Generator();
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
index a0d0f88..a232d43 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ClientControllerTest.java
@@ -141,6 +141,8 @@
         assertNotNull(clientId);
         assertNotNull(clientSecret);
 
+        assertFalse(clientId.contains("a"));
+            
         testResetConfidentialClientSecret(clientId, clientSecret);
         testDeregisterConfidentialClient(clientId);
     }
diff --git a/full/src/test/resources/kustvakt-test.conf b/full/src/test/resources/kustvakt-test.conf
index 512ef34..bc6f8e3 100644
--- a/full/src/test/resources/kustvakt-test.conf
+++ b/full/src/test/resources/kustvakt-test.conf
@@ -62,7 +62,7 @@
 oauth2.refresh.token.expiry = 90D
 oauth2.authorization.code.expiry = 10M
 # -- scopes separated by space
-oauth2.default.scopes = openid search match_info
+oauth2.default.scopes = search match_info
 oauth2.client.credentials.scopes = client_info
 
 ## OpenId