Added default setting key validation & fixed UserdataTest.

Change-Id: If427a13cf68977ee53579c1286930482dd9bfbeb
diff --git a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
index 99b6b52..137812e 100644
--- a/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
+++ b/full/src/main/java/de/ids_mannheim/korap/authentication/KustvaktAuthenticationManager.java
@@ -1,10 +1,7 @@
 package de.ids_mannheim.korap.authentication;
 
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
 import java.net.InetAddress;
 import java.net.UnknownHostException;
-import java.security.NoSuchAlgorithmException;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.Map;
@@ -35,10 +32,8 @@
 import de.ids_mannheim.korap.exceptions.WrappedException;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.interfaces.EntityHandlerIface;
-import de.ids_mannheim.korap.interfaces.ValidatorIface;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
-import de.ids_mannheim.korap.interfaces.defaults.ApacheValidator;
 import de.ids_mannheim.korap.security.context.TokenContext;
 import de.ids_mannheim.korap.user.DemoUser;
 import de.ids_mannheim.korap.user.KorAPUser;
@@ -50,6 +45,7 @@
 import de.ids_mannheim.korap.user.UserSettingProcessor;
 import de.ids_mannheim.korap.user.Userdata;
 import de.ids_mannheim.korap.utils.TimeUtils;
+import de.ids_mannheim.korap.validator.Validator;
 
 /**
  * contains the logic to authentication and registration processes. Uses
@@ -69,9 +65,11 @@
 	private AdminDao adminDao;
 	private AuditingIface auditing;
 	private FullConfiguration config;
+	@Deprecated
 	private Collection userdatadaos;
 	private LoginCounter counter;
-	private ValidatorIface validator;
+	@Autowired
+	private Validator validator;
 	
 	public KustvaktAuthenticationManager(EntityHandlerIface userdb, EncryptionIface crypto,
 			FullConfiguration config, AuditingIface auditer, Collection<UserDataDbIface> userdatadaos) {
@@ -83,11 +81,11 @@
 		this.counter = new LoginCounter(config);
 		this.userdatadaos = userdatadaos;
 		// todo: load via beancontext
-		try {
-			this.validator = new ApacheValidator();
-		} catch (IOException e) {
-			e.printStackTrace();
-		}
+//		try {
+//			this.validator = new ApacheValidator();
+//		} catch (IOException e) {
+//			e.printStackTrace();
+//		}
 	}
 
 	/**
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
index 1a60efc..e1239cf 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
@@ -16,6 +16,13 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.utils.ParameterChecker;
 
+/**
+ * DefaultSettingDao manages database queries and transactions
+ * regarding user default setting.
+ * 
+ * @author margaretha
+ *
+ */
 @Transactional
 @Repository
 public class DefaultSettingDao {
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java b/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
index 1aabb9b..bd28723 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
@@ -10,16 +10,23 @@
 import de.ids_mannheim.korap.entity.DefaultSetting;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.user.DataFactory;
 import de.ids_mannheim.korap.user.UserSettingProcessor;
+import de.ids_mannheim.korap.validator.ApacheValidator;
 
+/**
+ * DefaultSettingService handles all business logic related to user
+ * default setting.
+ * 
+ * @author margaretha
+ *
+ */
 @Service
 public class DefaultSettingService {
 
     @Autowired
     private DefaultSettingDao settingDao;
-
-    public DataFactory dataFactory = DataFactory.getFactory();
+    @Autowired
+    private ApacheValidator validator;
 
     private String verifiyUsername (String username, String contextUsername)
             throws KustvaktException {
@@ -34,14 +41,21 @@
         return username;
     }
 
-    public int handlePutRequest (String username, Map<String, Object> map,
-            String contextUsername) throws KustvaktException {
-        username = verifiyUsername(username, contextUsername);
-
+    private void validateSettingMap (Map<String, Object> map)
+            throws KustvaktException {
         if (map == null || map.isEmpty()) {
             throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
                     "Entity body is empty. No settings are given.");
         }
+        for (String k : map.keySet()) {
+            validator.validateEntry(k, "setting");
+        }
+    }
+
+    public int handlePutRequest (String username, Map<String, Object> map,
+            String contextUsername) throws KustvaktException {
+        username = verifiyUsername(username, contextUsername);
+        validateSettingMap(map);
 
         UserSettingProcessor processor = new UserSettingProcessor();
         processor.readQuietly(map, false);
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserSettingController.java
similarity index 73%
rename from full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
rename to full/src/main/java/de/ids_mannheim/korap/web/controller/UserSettingController.java
index 0fba5b7..5f24f00 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserSettingController.java
@@ -31,14 +31,19 @@
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 
 /**
+ * UserSettingController defines web APIs related to user default
+ * setting.
+ * 
+ * All the APIs in this class are only available to logged-in users.
+ * 
  * @author margaretha
  *
  */
 @Controller
-@Path("{version}/{username: ~[a-zA-Z0-9_]+}")
+@Path("{version}/{username: ~[a-zA-Z0-9_]+}/setting")
 @ResourceFilters({ AuthenticationFilter.class, APIVersionFilter.class,
         PiwikFilter.class })
-public class UserController {
+public class UserSettingController {
 
     @Autowired
     private DefaultSettingService settingService;
@@ -47,8 +52,23 @@
     @Autowired
     private OAuth2ScopeService scopeService;
 
+    /**
+     * Creates a default setting of the given username.
+     * The setting inputs should be represented as a pair of keys and
+     * values (a map). The keys must only contains alphabets, numbers,
+     * hypens or underscores.
+     * 
+     * 
+     * @param context
+     *            security context
+     * @param username
+     *            username
+     * @param map
+     *            the default setting
+     * @return status code 201 if a new resource is created, or 200 if
+     *         an existing resource is edited.
+     */
     @PUT
-    @Path("setting")
     @Consumes(MediaType.APPLICATION_JSON)
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
@@ -69,8 +89,16 @@
 
     }
 
+    /**
+     * Retrieves the default setting of the given username.
+     * 
+     * @param context
+     *            a security context
+     * @param username
+     *            a username
+     * @return the default setting of the given username
+     */
     @GET
-    @Path("setting")
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
     @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
@@ -90,12 +118,20 @@
         }
     }
 
+    /**
+     * Deletes an entry of a default setting of a user by the given key.
+     * 
+     * @param context a security context
+     * @param username a username
+     * @param key the key of the default setting entry to be deleted
+     * @return
+     */
     @DELETE
-    @Path("setting/{key}")
+    @Path("{key}")
     @Consumes(MediaType.APPLICATION_JSON)
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
-    public Response createDefaultSetting (@Context SecurityContext context,
+    public Response deleteDefaultSettingEntry (@Context SecurityContext context,
             @PathParam("username") String username,
             @PathParam("key") String key) {
 
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index d543d53..c8fd658 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -198,6 +198,9 @@
 	<bean id="search_krill" class="de.ids_mannheim.korap.web.SearchKrill">
 		<constructor-arg value="${krill.indexDir}" />
 	</bean>
+	
+	<!-- Validator -->
+	<bean id="validator" class="de.ids_mannheim.korap.validator.ApacheValidator"/>
 
 	<!-- URLValidator -->
 	<bean id="redirectURIValidator" class="org.apache.commons.validator.routines.UrlValidator">