Added VC name pattern check.

Change-Id: Ie3e73af0c660ce0be103dcb3acc0062918f2aefc
diff --git a/full/Changes b/full/Changes
index 60bf81a..bf6739c 100644
--- a/full/Changes
+++ b/full/Changes
@@ -21,8 +21,9 @@
       controllers including OAuth2 controllers (margaretha)
 16/08/2018
     - Implemented degrading super clients (margaretha)
-    - Improved and added OAuth2 tests (margaretha)    
-
+    - Improved and added OAuth2 tests (margaretha)
+21/08/2018
+    - Added VC name pattern check (margaretha)
 
 # version 0.60.5
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
index 5375aad..27a9c97 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/VirtualCorpusService.java
@@ -4,6 +4,7 @@
 import java.util.Collections;
 import java.util.Iterator;
 import java.util.List;
+import java.util.regex.Pattern;
 
 import org.apache.logging.log4j.LogManager;
 import org.apache.logging.log4j.Logger;
@@ -39,9 +40,11 @@
 import de.ids_mannheim.korap.web.controller.VirtualCorpusController;
 import de.ids_mannheim.korap.web.input.VirtualCorpusJson;
 
-/** VirtualCorpusService handles the logic behind {@link VirtualCorpusController}. 
- *  It communicates with {@link VirtualCorpusDao} and returns 
- *  {@link VirtualCorpusDto} to {@link VirtualCorpusController}.
+/**
+ * VirtualCorpusService handles the logic behind
+ * {@link VirtualCorpusController}.
+ * It communicates with {@link VirtualCorpusDao} and returns
+ * {@link VirtualCorpusDto} to {@link VirtualCorpusController}.
  * 
  * @author margaretha
  *
@@ -52,6 +55,8 @@
     private static Logger jlog =
             LogManager.getLogger(VirtualCorpusService.class);
 
+    public static Pattern wordPattern = Pattern.compile("[\\w ]+");
+
     @Autowired
     private VirtualCorpusDao vcDao;
     @Autowired
@@ -127,11 +132,14 @@
         return dtos;
     }
 
-    /** Only admin and the owner of the virtual corpus are allowed to 
-     *  delete a virtual corpus.
-     *  
-     * @param username username
-     * @param vcId virtual corpus id
+    /**
+     * Only admin and the owner of the virtual corpus are allowed to
+     * delete a virtual corpus.
+     * 
+     * @param username
+     *            username
+     * @param vcId
+     *            virtual corpus id
      * @throws KustvaktException
      */
     public void deleteVC (String username, int vcId) throws KustvaktException {
@@ -219,11 +227,16 @@
 
     public int storeVC (VirtualCorpusJson vc, String username)
             throws KustvaktException {
-
         ParameterChecker.checkStringValue(vc.getName(), "name");
         ParameterChecker.checkObjectValue(vc.getType(), "type");
         ParameterChecker.checkStringValue(vc.getCorpusQuery(), "corpusQuery");
 
+        String name = vc.getName();
+        if (!wordPattern.matcher(name).matches()) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "Virtual corpus name must only contains letters, numbers, underscores and spaces",
+                    name);
+        }
 
         if (vc.getType().equals(VirtualCorpusType.SYSTEM)
                 && !adminDao.isAdmin(username)) {
@@ -331,20 +344,21 @@
         return false;
     }
 
-    //    public void editVCAccess (VirtualCorpusAccess access, String username)
-    //            throws KustvaktException {
+    // public void editVCAccess (VirtualCorpusAccess access, String
+    // username)
+    // throws KustvaktException {
     //
-    //        // get all the VCA admins
-    //        UserGroup userGroup = access.getUserGroup();
-    //        List<UserGroupMember> accessAdmins =
-    //                userGroupService.retrieveVCAccessAdmins(userGroup);
+    // // get all the VCA admins
+    // UserGroup userGroup = access.getUserGroup();
+    // List<UserGroupMember> accessAdmins =
+    // userGroupService.retrieveVCAccessAdmins(userGroup);
     //
-    //        User user = authManager.getUser(username);
-    //        if (!user.isSystemAdmin()) {
-    //            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
-    //                    "Unauthorized operation for user: " + username, username);
-    //        }
-    //    }
+    // User user = authManager.getUser(username);
+    // if (!user.isSystemAdmin()) {
+    // throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+    // "Unauthorized operation for user: " + username, username);
+    // }
+    // }
 
     public List<VirtualCorpusAccessDto> listVCAccessByVC (String username,
             int vcId) throws KustvaktException {
@@ -419,7 +433,7 @@
             }
 
             else if (VirtualCorpusType.PUBLISHED.equals(type)) {
-                // add user in the VC's auto group 
+                // add user in the VC's auto group
                 UserGroup userGroup =
                         userGroupService.retrieveHiddenUserGroupByVC(vcId);
                 try {
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
index cdc326e..a509249 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/VirtualCorpusControllerTest.java
@@ -464,6 +464,25 @@
 
         checkWWWAuthenticateHeader(response);
     }
+    
+    @Test
+    public void testCreateVCInvalidName () throws KustvaktException {
+        String json = "{\"name\": \"new $vc\",\"type\": \"PRIVATE\","
+                + "\"corpusQuery\": \"creationDate since 1820\"}";
+
+        ClientResponse response = resource().path("vc").path("create").header(
+                Attributes.AUTHORIZATION,
+                HttpAuthorizationHandler.createBasicAuthorizationHeaderValue(
+                        "VirtualCorpusControllerTest", "pass"))
+                .header(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON)
+                .entity(json).post(ClientResponse.class);
+        String entity = response.getEntity(String.class);
+        assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
+
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(StatusCodes.INVALID_ARGUMENT,
+                node.at("/errors/0/0").asInt());
+    }
 
     @Test
     public void testCreateVCUnauthorized () throws KustvaktException {