Added create, edit, retrieve user default setting controllers

Change-Id: Iba5d6d4868aafe5cf5787f86cad61cf48d0eda3e
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 fa2d380..99e707d 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
@@ -621,7 +621,7 @@
 		entHandler.updateAccount(u);
 	}
 
-		// todo:
+	@Deprecated	// todo:
 	private ShibbolethUser createShibbUserAccount(Map<String, Object> attributes) throws KustvaktException {
         if (DEBUG) {
             jlog.debug("creating shibboleth user account for user attr: "
@@ -746,6 +746,7 @@
 	}
 
 	// EM: not in the new DB
+	@Deprecated
 	@Override
 	public <T extends Userdata> T getUserData(User user, Class<T> clazz) throws WrappedException {
 		try {
@@ -765,6 +766,7 @@
 		}
 	}
 
+	@Deprecated
 	// todo: cache userdata outside of the user object!
 	@Override
 	public void updateUserData(Userdata data) throws WrappedException {
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
new file mode 100644
index 0000000..1a60efc
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/DefaultSettingDao.java
@@ -0,0 +1,81 @@
+package de.ids_mannheim.korap.dao;
+
+import javax.persistence.EntityManager;
+import javax.persistence.NoResultException;
+import javax.persistence.PersistenceContext;
+import javax.persistence.Query;
+import javax.persistence.criteria.CriteriaBuilder;
+import javax.persistence.criteria.CriteriaQuery;
+import javax.persistence.criteria.Root;
+
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.entity.DefaultSetting;
+import de.ids_mannheim.korap.entity.DefaultSetting_;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.ParameterChecker;
+
+@Transactional
+@Repository
+public class DefaultSettingDao {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    /**
+     * Creates a new entry of default setting in the database. This
+     * method allows storing settings of an empty json object, i.e.
+     * {}.
+     * 
+     * @param username
+     *            username
+     * @param settings
+     *            default settings in json
+     * @throws KustvaktException
+     */
+    public void createDefaultSetting (String username, String settings)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(username, "username");
+        ParameterChecker.checkStringValue(settings, "settings");
+        DefaultSetting us = new DefaultSetting(username, settings);
+        entityManager.persist(us);
+    }
+
+    public void updateDefaultSetting (DefaultSetting defaultSetting)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(defaultSetting, "defaultSetting");
+        entityManager.merge(defaultSetting);
+    }
+
+    public void deleteDefaultSetting (DefaultSetting defaultSetting)
+            throws KustvaktException {
+        ParameterChecker.checkObjectValue(defaultSetting, "defaultSetting");
+        if (!entityManager.contains(defaultSetting)) {
+            defaultSetting = entityManager.merge(defaultSetting);
+        }
+        entityManager.remove(defaultSetting);
+
+    }
+
+    public DefaultSetting retrieveDefautlSetting (String username)
+            throws KustvaktException {
+        ParameterChecker.checkStringValue(username, "username");
+
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<DefaultSetting> query =
+                criteriaBuilder.createQuery(DefaultSetting.class);
+        Root<DefaultSetting> defaultSetting = query.from(DefaultSetting.class);
+
+        query.select(defaultSetting);
+        query.where(criteriaBuilder
+                .equal(defaultSetting.get(DefaultSetting_.username), username));
+        Query q = entityManager.createQuery(query);
+        try {
+            return (DefaultSetting) q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            return null;
+        }
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java b/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java
new file mode 100644
index 0000000..b485ab5
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/DefaultSetting.java
@@ -0,0 +1,56 @@
+package de.ids_mannheim.korap.entity;
+
+import javax.persistence.Entity;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+/**
+ * Describes default_setting table. Each user may define one set of
+ * default settings. The elements of default settings are
+ * not strictly defined and thus are described as JSON strings.
+ * 
+ * Some elements that are often used may be adopted as columns.
+ * 
+ * Examples of the default settings' elements are foundry, layer and
+ * number of results per page.
+ * 
+ * @author margaretha
+ *
+ */
+@Entity
+@Table(name = "default_setting")
+public class DefaultSetting {
+
+    @Id
+    private String username;
+    private String settings; // json string
+
+    public DefaultSetting () {}
+
+    public DefaultSetting (String username, String settings) {
+        this.username = username;
+        this.settings = settings;
+    }
+
+    @Override
+    public String toString () {
+        return "name= " + getUsername() + ", settings= " + getSettings();
+    }
+
+    public String getUsername () {
+        return username;
+    }
+
+    public void setUsername (String username) {
+        this.username = username;
+    }
+
+    public String getSettings () {
+        return settings;
+    }
+
+    public void setSettings (String settings) {
+        this.settings = settings;
+    }
+
+}
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
new file mode 100644
index 0000000..39ee4ce
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/service/DefaultSettingService.java
@@ -0,0 +1,71 @@
+package de.ids_mannheim.korap.service;
+
+import java.util.Map;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Service;
+
+import de.ids_mannheim.korap.dao.DefaultSettingDao;
+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.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
+
+@Service
+public class DefaultSettingService {
+
+    @Autowired
+    private DefaultSettingDao settingDao;
+
+    public void handlePutRequest (String username,
+            Map<String, Object> form, String authenticatedUser)
+            throws KustvaktException {
+        if (!username.equals(authenticatedUser)) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "Username verification failed. Path parameter username "
+                            + "must be the same as the authenticated username.");
+        }
+        else if (form == null || form.isEmpty()) {
+            throw new KustvaktException(StatusCodes.INVALID_ARGUMENT,
+                    "Entity body is empty. No settings are given.");
+        }
+
+        Userdata userdata = new UserSettings(username);
+        userdata.readQuietly(form, false);
+
+        DefaultSetting defaultSetting =
+                settingDao.retrieveDefautlSetting(username);
+        if (defaultSetting == null) {
+            createDefaultSetting(username, userdata);
+        }
+        else {
+            updateDefaultSetting(defaultSetting, userdata);
+        }
+    }
+
+    public void createDefaultSetting (String username, Userdata userdata)
+            throws KustvaktException {
+        String jsonSettings = userdata.serialize();
+        settingDao.createDefaultSetting(username, jsonSettings);
+    }
+
+    public void updateDefaultSetting (DefaultSetting setting, Userdata newData)
+            throws KustvaktException {
+        Userdata existingData = new UserSettings(setting.getUsername());
+        existingData.setData(setting.getSettings());
+        existingData.update(newData);
+
+        String newSettings = existingData.serialize();
+        setting.setSettings(newSettings);
+        settingDao.updateDefaultSetting(setting);
+    }
+
+    public String retrieveDefaultSettings (String username)
+            throws KustvaktException {
+        DefaultSetting defaultSetting =
+                settingDao.retrieveDefautlSetting(username);
+        return defaultSetting.getSettings();
+    }
+
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java
new file mode 100644
index 0000000..bd95f13
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/ShibbolethUserController.java
@@ -0,0 +1,340 @@
+package de.ids_mannheim.korap.web.controller;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Set;
+
+import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.QueryParam;
+import javax.ws.rs.core.Context;
+import javax.ws.rs.core.MediaType;
+import javax.ws.rs.core.Response;
+import javax.ws.rs.core.SecurityContext;
+import javax.ws.rs.core.UriInfo;
+
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Controller;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.spi.container.ResourceFilters;
+
+import de.ids_mannheim.korap.authentication.AuthenticationManager;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.Scopes;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.security.context.TokenContext;
+import de.ids_mannheim.korap.user.KorAPUser;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.UserDetails;
+import de.ids_mannheim.korap.user.UserQuery;
+import de.ids_mannheim.korap.user.UserSettings;
+import de.ids_mannheim.korap.user.Userdata;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.web.KustvaktResponseHandler;
+import de.ids_mannheim.korap.web.filter.APIVersionFilter;
+import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
+import de.ids_mannheim.korap.web.filter.BlockingFilter;
+import de.ids_mannheim.korap.web.filter.DemoUserFilter;
+import de.ids_mannheim.korap.web.filter.PiwikFilter;
+
+/** 
+ * 
+ * @author hanl, margaretha
+ */
+@Controller
+@Path("{version}/shibboleth/user")
+@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+@ResourceFilters({APIVersionFilter.class, PiwikFilter.class })
+public class ShibbolethUserController {
+
+    @Autowired
+    private KustvaktResponseHandler kustvaktResponseHandler;
+
+    private static Logger jlog = LogManager.getLogger(ShibbolethUserController.class);
+    @Autowired
+    private AuthenticationManager controller;
+
+    private @Context UriInfo info;
+
+    // EM: may be used for managing shib users
+    //todo: password update in special function? --> password reset only!
+    @POST
+    @Path("update")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateAccount (@Context SecurityContext ctx, String json) {
+        TokenContext context = (TokenContext) ctx.getUserPrincipal();
+        try {
+            User user = controller.getUser(context.getUsername());
+
+            JsonNode node = JsonUtils.readTree(json);
+            KorAPUser ident = (KorAPUser) user;
+            KorAPUser values = User.UserFactory.toUser(json);
+            //            user = controller
+            //                    .checkPasswordAllowance(ident, values.getPassword(),
+            //                            node.path("new_password").asText());
+            //            controller.updateAccount(user);
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+    
+    // todo: refactor and make something out of if --> needs to give some sort of feedback!
+    @GET
+    @Path("info")
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response getStatus (@Context SecurityContext context,
+            @QueryParam("scopes") String scopes) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Scopes m;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserDetails.class);
+
+            Set<String> base_scope = StringUtils.toSet(scopes, " ");
+            if (scopes != null) base_scope.retainAll(StringUtils.toSet(scopes));
+            scopes = StringUtils.toString(base_scope);
+            m = Scopes.mapScopes(scopes, data);
+            return Response.ok(m.toEntity()).build();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+
+
+    @GET
+    @Path("settings")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getUserSettings (@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String result;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserSettings.class);
+            data.setField(Attributes.USERNAME, ctx.getUsername());
+            result = data.serialize();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
+
+
+    @Deprecated
+    @POST
+    @Path("settings")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateSettings (@Context SecurityContext context,
+            @Context Locale locale, Map settings) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+
+        if (settings == null) return Response.notModified().build();
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            if (User.UserFactory.isDemo(ctx.getUsername()))
+                return Response.notModified().build();
+
+            Userdata data = controller.getUserData(user, UserSettings.class);
+            // todo: check setting only within the scope of user settings permissions; not foundry range. Latter is part of
+            // frontend which only displays available foundries and
+            //            SecurityManager.findbyId(us.getDefaultConstfoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultLemmafoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultPOSfoundry(), user, Foundry.class);
+            //            SecurityManager.findbyId(us.getDefaultRelfoundry(), user, Foundry.class);
+            Userdata new_data = new UserSettings(user.getId());
+            new_data.readQuietly((Map<String, Object>) settings, false);
+            data.update(new_data);
+            controller.updateUserData(data);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+
+        return Response.ok().build();
+    }
+
+    @GET
+    @Path("details")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getDetails (@Context SecurityContext context,
+            @Context Locale locale, @QueryParam("pointer") String pointer) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String result;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            Userdata data = controller.getUserData(user, UserDetails.class);
+            data.setField(Attributes.USERNAME, ctx.getUsername());
+            if (pointer != null)
+                result = data.get(pointer).toString();
+            else
+                result = data.serialize();
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered: "+ e.string());
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(result).build();
+    }
+
+
+    // EM: may be used for managing shib users
+    @POST
+    @Path("details")
+    @Consumes({ MediaType.APPLICATION_JSON })
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateDetails (@Context SecurityContext context,
+            @Context Locale locale, Map details) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+
+        if (details == null) return Response.notModified().build();
+
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            if (User.UserFactory.isDemo(ctx.getUsername()))
+                return Response.notModified().build();
+
+            UserDetails new_data = new UserDetails(user.getId());
+            new_data.readQuietly((Map<String, Object>) details, false);
+
+            UserDetails det = controller.getUserData(user, UserDetails.class);
+            det.update(new_data);
+            controller.updateUserData(det);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+
+    //fixme: if policy allows, foreign user might be allowed to change search!
+    @POST
+    @Path("queries")
+    @Consumes(MediaType.APPLICATION_JSON)
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response updateQueries (@Context SecurityContext context,
+            String json) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        Collection<UserQuery> add = new HashSet<>();
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            List<UserQuery> userQuieres = new ArrayList<>();
+            JsonNode nodes = JsonUtils.readTree(json);
+            Iterator<JsonNode> node = nodes.elements();
+            while (node.hasNext()) {
+                JsonNode cursor = node.next();
+                UserQuery query =
+                        new UserQuery(cursor.path("id").asInt(), user.getId());
+                query.setQueryLanguage(cursor.path("queryLanguage").asText());
+                query.setQuery(cursor.path("query").asText());
+                query.setDescription(cursor.path("description").asText());
+                userQuieres.add(query);
+            }
+
+            //1: add all that are new, update all that are retained, delete the rest
+            //            Set<UserQuery> resources = ResourceFinder
+            //                    .search(user, UserQuery.class);
+            //
+            //            add.addAll(userQuieres);
+            //            add.removeAll(resources);
+            //            Collection<UserQuery> update = new HashSet<>(userQuieres);
+            //            update.retainAll(resources);
+            //            resources.removeAll(userQuieres);
+            //
+            //            if (!update.isEmpty()) {
+            //                resourceHandler.updateResources(user,
+            //                        update.toArray(new UserQuery[update.size()]));
+            //            }
+            //            if (!add.isEmpty()) {
+            //                resourceHandler.storeResources(user,
+            //                        add.toArray(new UserQuery[add.size()]));
+            //            }
+            //            if (!resources.isEmpty()) {
+            //                resourceHandler.deleteResources(user,
+            //                        resources.toArray(new UserQuery[resources.size()]));
+            //            }
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        try {
+            return Response.ok(JsonUtils.toJSON(add)).build();
+        }
+        catch (KustvaktException e) {
+            throw kustvaktResponseHandler.throwit(e);
+        }
+    }
+
+    // EM: may be used for managing shib users
+    @DELETE
+    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
+            BlockingFilter.class })
+    public Response deleteUser (@Context SecurityContext context) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            //todo: test that demo user cannot be deleted!
+            controller.deleteAccount(user);
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok().build();
+    }
+
+
+    @GET
+    @Path("queries")
+    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
+            PiwikFilter.class, BlockingFilter.class })
+    public Response getQueries (@Context SecurityContext context,
+            @Context Locale locale) {
+        TokenContext ctx = (TokenContext) context.getUserPrincipal();
+        String queryStr;
+        try {
+            User user = controller.getUser(ctx.getUsername());
+            //            Set<UserQuery> queries = ResourceFinder
+            //                    .search(user, UserQuery.class);
+            //            queryStr = JsonUtils.toJSON(queries);
+            //todo:
+            queryStr = "";
+        }
+        catch (KustvaktException e) {
+            jlog.error("Exception encountered!", e);
+            throw kustvaktResponseHandler.throwit(e);
+        }
+        return Response.ok(queryStr).build();
+    }
+}
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/UserController.java
index 216cad5..904fab4 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/UserController.java
@@ -1,339 +1,91 @@
 package de.ids_mannheim.korap.web.controller;
 
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
 import java.util.Map;
-import java.util.Set;
 
 import javax.ws.rs.Consumes;
-import javax.ws.rs.DELETE;
 import javax.ws.rs.GET;
-import javax.ws.rs.POST;
+import javax.ws.rs.PUT;
 import javax.ws.rs.Path;
+import javax.ws.rs.PathParam;
 import javax.ws.rs.Produces;
-import javax.ws.rs.QueryParam;
 import javax.ws.rs.core.Context;
 import javax.ws.rs.core.MediaType;
 import javax.ws.rs.core.Response;
 import javax.ws.rs.core.SecurityContext;
-import javax.ws.rs.core.UriInfo;
 
-import org.apache.logging.log4j.LogManager;
-import org.apache.logging.log4j.Logger;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.stereotype.Controller;
 
-import com.fasterxml.jackson.databind.JsonNode;
 import com.sun.jersey.spi.container.ResourceFilters;
 
-import de.ids_mannheim.korap.authentication.AuthenticationManager;
-import de.ids_mannheim.korap.config.Attributes;
-import de.ids_mannheim.korap.config.Scopes;
+import de.ids_mannheim.korap.constant.OAuth2Scope;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.oauth2.service.OAuth2ScopeService;
 import de.ids_mannheim.korap.security.context.TokenContext;
-import de.ids_mannheim.korap.user.KorAPUser;
-import de.ids_mannheim.korap.user.User;
-import de.ids_mannheim.korap.user.UserDetails;
-import de.ids_mannheim.korap.user.UserQuery;
-import de.ids_mannheim.korap.user.UserSettings;
-import de.ids_mannheim.korap.user.Userdata;
-import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.StringUtils;
+import de.ids_mannheim.korap.service.DefaultSettingService;
 import de.ids_mannheim.korap.web.KustvaktResponseHandler;
 import de.ids_mannheim.korap.web.filter.APIVersionFilter;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
-import de.ids_mannheim.korap.web.filter.DemoUserFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 
-/** 
- * 
- * @author hanl, margaretha
+/**
+ * @author margaretha
+ *
  */
 @Controller
 @Path("{version}/user")
-@Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
-@ResourceFilters({APIVersionFilter.class, PiwikFilter.class })
+@ResourceFilters({ AuthenticationFilter.class, APIVersionFilter.class,
+        PiwikFilter.class })
 public class UserController {
 
     @Autowired
-    private KustvaktResponseHandler kustvaktResponseHandler;
-
-    private static Logger jlog = LogManager.getLogger(UserController.class);
+    private DefaultSettingService settingService;
     @Autowired
-    private AuthenticationManager controller;
+    private KustvaktResponseHandler kustvaktResponseHandler;
+    @Autowired
+    private OAuth2ScopeService scopeService;
 
-    private @Context UriInfo info;
-
-    // EM: may be used for managing shib users
-    //todo: password update in special function? --> password reset only!
-    @POST
-    @Path("update")
+    @PUT
+    @Path("settings/{username}")
     @Consumes(MediaType.APPLICATION_JSON)
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
-    public Response updateAccount (@Context SecurityContext ctx, String json) {
-        TokenContext context = (TokenContext) ctx.getUserPrincipal();
-        try {
-            User user = controller.getUser(context.getUsername());
+    public Response createDefaultSetting (@Context SecurityContext context,
+            @PathParam("username") String username,
+            Map<String, Object> form) {
 
-            JsonNode node = JsonUtils.readTree(json);
-            KorAPUser ident = (KorAPUser) user;
-            KorAPUser values = User.UserFactory.toUser(json);
-            //            user = controller
-            //                    .checkPasswordAllowance(ident, values.getPassword(),
-            //                            node.path("new_password").asText());
-            //            controller.updateAccount(user);
+        TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
+        try {
+            scopeService.verifyScope(tokenContext,
+                    OAuth2Scope.CREATE_DEFAULT_SETTING);
+            settingService.handlePutRequest(username, form,
+                    tokenContext.getUsername());
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
         }
         return Response.ok().build();
     }
-    
-    // todo: refactor and make something out of if --> needs to give some sort of feedback!
-    @GET
-    @Path("info")
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response getStatus (@Context SecurityContext context,
-            @QueryParam("scopes") String scopes) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        Scopes m;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserDetails.class);
-
-            Set<String> base_scope = StringUtils.toSet(scopes, " ");
-            if (scopes != null) base_scope.retainAll(StringUtils.toSet(scopes));
-            scopes = StringUtils.toString(base_scope);
-            m = Scopes.mapScopes(scopes, data);
-            return Response.ok(m.toEntity()).build();
-        }
-        catch (KustvaktException e) {
-            throw kustvaktResponseHandler.throwit(e);
-        }
-    }
-
-
-    @GET
-    @Path("settings")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getUserSettings (@Context SecurityContext context,
-            @Context Locale locale) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String result;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserSettings.class);
-            data.setField(Attributes.USERNAME, ctx.getUsername());
-            result = data.serialize();
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(result).build();
-    }
-
-
-    @POST
-    @Path("settings")
-    @Consumes({ MediaType.APPLICATION_JSON })
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response updateSettings (@Context SecurityContext context,
-            @Context Locale locale, Map settings) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-
-        if (settings == null) return Response.notModified().build();
-
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            if (User.UserFactory.isDemo(ctx.getUsername()))
-                return Response.notModified().build();
-
-            Userdata data = controller.getUserData(user, UserSettings.class);
-            // todo: check setting only within the scope of user settings permissions; not foundry range. Latter is part of
-            // frontend which only displays available foundries and
-            //            SecurityManager.findbyId(us.getDefaultConstfoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultLemmafoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultPOSfoundry(), user, Foundry.class);
-            //            SecurityManager.findbyId(us.getDefaultRelfoundry(), user, Foundry.class);
-            Userdata new_data = new UserSettings(user.getId());
-            new_data.readQuietly((Map<String, Object>) settings, false);
-            data.update(new_data);
-            controller.updateUserData(data);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-
-        return Response.ok().build();
-    }
 
     @GET
-    @Path("details")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getDetails (@Context SecurityContext context,
-            @Context Locale locale, @QueryParam("pointer") String pointer) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String result;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            Userdata data = controller.getUserData(user, UserDetails.class);
-            data.setField(Attributes.USERNAME, ctx.getUsername());
-            if (pointer != null)
-                result = data.get(pointer).toString();
-            else
-                result = data.serialize();
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered: "+ e.string());
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(result).build();
-    }
-
-
-    // EM: may be used for managing shib users
-    @POST
-    @Path("details")
-    @Consumes({ MediaType.APPLICATION_JSON })
+    @Path("settings")
     @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
             BlockingFilter.class })
-    public Response updateDetails (@Context SecurityContext context,
-            @Context Locale locale, Map details) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-
-        if (details == null) return Response.notModified().build();
+    @Produces(MediaType.APPLICATION_JSON + ";charset=utf-8")
+    public Response createDefaultSetting (@Context SecurityContext context) {
+        TokenContext tokenContext = (TokenContext) context.getUserPrincipal();
 
         try {
-            User user = controller.getUser(ctx.getUsername());
-            if (User.UserFactory.isDemo(ctx.getUsername()))
-                return Response.notModified().build();
-
-            UserDetails new_data = new UserDetails(user.getId());
-            new_data.readQuietly((Map<String, Object>) details, false);
-
-            UserDetails det = controller.getUserData(user, UserDetails.class);
-            det.update(new_data);
-            controller.updateUserData(det);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok().build();
-    }
-
-
-    //fixme: if policy allows, foreign user might be allowed to change search!
-    @POST
-    @Path("queries")
-    @Consumes(MediaType.APPLICATION_JSON)
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response updateQueries (@Context SecurityContext context,
-            String json) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        Collection<UserQuery> add = new HashSet<>();
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            List<UserQuery> userQuieres = new ArrayList<>();
-            JsonNode nodes = JsonUtils.readTree(json);
-            Iterator<JsonNode> node = nodes.elements();
-            while (node.hasNext()) {
-                JsonNode cursor = node.next();
-                UserQuery query =
-                        new UserQuery(cursor.path("id").asInt(), user.getId());
-                query.setQueryLanguage(cursor.path("queryLanguage").asText());
-                query.setQuery(cursor.path("query").asText());
-                query.setDescription(cursor.path("description").asText());
-                userQuieres.add(query);
-            }
-
-            //1: add all that are new, update all that are retained, delete the rest
-            //            Set<UserQuery> resources = ResourceFinder
-            //                    .search(user, UserQuery.class);
-            //
-            //            add.addAll(userQuieres);
-            //            add.removeAll(resources);
-            //            Collection<UserQuery> update = new HashSet<>(userQuieres);
-            //            update.retainAll(resources);
-            //            resources.removeAll(userQuieres);
-            //
-            //            if (!update.isEmpty()) {
-            //                resourceHandler.updateResources(user,
-            //                        update.toArray(new UserQuery[update.size()]));
-            //            }
-            //            if (!add.isEmpty()) {
-            //                resourceHandler.storeResources(user,
-            //                        add.toArray(new UserQuery[add.size()]));
-            //            }
-            //            if (!resources.isEmpty()) {
-            //                resourceHandler.deleteResources(user,
-            //                        resources.toArray(new UserQuery[resources.size()]));
-            //            }
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        try {
-            return Response.ok(JsonUtils.toJSON(add)).build();
+            scopeService.verifyScope(tokenContext,
+                    OAuth2Scope.CREATE_DEFAULT_SETTING);
+            String settings = settingService
+                    .retrieveDefaultSettings(tokenContext.getUsername());
+            return Response.ok(settings).build();
         }
         catch (KustvaktException e) {
             throw kustvaktResponseHandler.throwit(e);
         }
     }
 
-    // EM: may be used for managing shib users
-    @DELETE
-    @ResourceFilters({ AuthenticationFilter.class, PiwikFilter.class,
-            BlockingFilter.class })
-    public Response deleteUser (@Context SecurityContext context) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            //todo: test that demo user cannot be deleted!
-            controller.deleteAccount(user);
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok().build();
-    }
-
-
-    @GET
-    @Path("queries")
-    @ResourceFilters({ AuthenticationFilter.class, DemoUserFilter.class,
-            PiwikFilter.class, BlockingFilter.class })
-    public Response getQueries (@Context SecurityContext context,
-            @Context Locale locale) {
-        TokenContext ctx = (TokenContext) context.getUserPrincipal();
-        String queryStr;
-        try {
-            User user = controller.getUser(ctx.getUsername());
-            //            Set<UserQuery> queries = ResourceFinder
-            //                    .search(user, UserQuery.class);
-            //            queryStr = JsonUtils.toJSON(queries);
-            //todo:
-            queryStr = "";
-        }
-        catch (KustvaktException e) {
-            jlog.error("Exception encountered!", e);
-            throw kustvaktResponseHandler.throwit(e);
-        }
-        return Response.ok(queryStr).build();
-    }
 }
diff --git a/full/src/main/resources/db/sqlite/V1.6__user_tables.sql b/full/src/main/resources/db/sqlite/V1.6__user_tables.sql
new file mode 100644
index 0000000..9df4a20
--- /dev/null
+++ b/full/src/main/resources/db/sqlite/V1.6__user_tables.sql
@@ -0,0 +1,4 @@
+CREATE TABLE IF NOT EXISTS default_setting (
+    username VARCHAR(100) PRIMARY KEY,
+    settings TEXT NOT NULL
+);
\ No newline at end of file