Added admin-related SQL codes, updated AdminDao & group list controller.

Change-Id: I0000000000000000000000000000000000000000
diff --git a/core/Changes b/core/Changes
index 0ad7a54..00b1efe 100644
--- a/core/Changes
+++ b/core/Changes
@@ -1,3 +1,8 @@
+version 0.60.1
+14/03/2018
+	- removed AdminHandlerIface (margaretha)
+	- removed isSystemAdmin in User class (margaretha)
+
 version 0.60
 13/03/2018
 	- removed old policy and deprecated code (margaretha)
diff --git a/core/pom.xml b/core/pom.xml
index 9b8bce9..9f94268 100644
--- a/core/pom.xml
+++ b/core/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>de.ids_mannheim.korap</groupId>
 	<artifactId>Kustvakt-core</artifactId>
-	<version>0.60</version>
+	<version>0.60.1</version>
 
 	<properties>
 		<java.version>1.8</java.version>
diff --git a/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java b/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
index 4139f5b..b32bb3b 100644
--- a/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
+++ b/core/src/main/java/de/ids_mannheim/korap/config/ContextHolder.java
@@ -106,11 +106,6 @@
         return getBean(KUSTVAKT_USERDB);
     }
     
-    public AdminHandlerIface getAdminDBHandler () {
-        return getBean(KUSTVAKT_ADMINDB);
-    }
-
-
     public PolicyHandlerIface getPolicyDbProvider () {
         Object b = getBean(KUSTVAKT_POLICIES);
         return (PolicyHandlerIface) b;
diff --git a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/AdminHandlerIface.java b/core/src/main/java/de/ids_mannheim/korap/interfaces/db/AdminHandlerIface.java
deleted file mode 100644
index f9f56d6..0000000
--- a/core/src/main/java/de/ids_mannheim/korap/interfaces/db/AdminHandlerIface.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package de.ids_mannheim.korap.interfaces.db;
-
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.user.User;
-
-/**
- * @author margaretha
- */
-public interface AdminHandlerIface {
-
-    int updateAccount (User user) throws KustvaktException;
-
-
-    int addAccount (User user) throws KustvaktException;
-
-
-    int deleteAccount (Integer userid) throws KustvaktException;
-
-
-    int truncate () throws KustvaktException;
-
-	boolean isAdmin(int userId);
-
-}
diff --git a/core/src/main/java/de/ids_mannheim/korap/user/User.java b/core/src/main/java/de/ids_mannheim/korap/user/User.java
index 3cba4a2..871beb8 100644
--- a/core/src/main/java/de/ids_mannheim/korap/user/User.java
+++ b/core/src/main/java/de/ids_mannheim/korap/user/User.java
@@ -48,7 +48,7 @@
 
     private List<Userdata> userdata;
 
-    private boolean isSystemAdmin;
+//    private boolean isSystemAdmin;
 
     // Values for corpusAccess:
     public enum CorpusAccess	 {
diff --git a/full/Changes b/full/Changes
index 8ee4c63..24636ce 100644
--- a/full/Changes
+++ b/full/Changes
@@ -1,3 +1,9 @@
+version 0.60.1
+14/03/2018
+	- added admin-related SQL codes (margaretha)
+	- updated AdminDao (margaretha)
+	- added optional username query parameter to group list controller (margaretha) 
+	
 version 0.60 release
 14/03/2018
 	- set up mail settings using localhost port 25 (margaretha)
diff --git a/full/pom.xml b/full/pom.xml
index 62ded64..51a8342 100644
--- a/full/pom.xml
+++ b/full/pom.xml
@@ -3,7 +3,7 @@
 	<modelVersion>4.0.0</modelVersion>
 	<groupId>de.ids_mannheim.korap</groupId>
 	<artifactId>Kustvakt-full</artifactId>
-	<version>0.60</version>
+	<version>0.60.1</version>
 	<properties>
 		<java.version>1.8</java.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
@@ -156,8 +156,7 @@
 		<dependency>
 			<groupId>de.ids_mannheim.korap</groupId>
 			<artifactId>Kustvakt-core</artifactId>
-			<version>0.60</version>
-			<type>jar</type>
+			<version>0.60.1</version>
 		</dependency>
 		<!-- LDAP -->
 		<dependency>
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 13e5f78..0f75d84 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
@@ -14,6 +14,7 @@
 
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
+import org.springframework.beans.factory.annotation.Autowired;
 
 // import com.novell.ldap.*; search() funktioniert nicht korrekt, ausgewechselt gegen unboundID's Bibliothek 20.04.17/FB
 //Using JAR from unboundID:
@@ -26,6 +27,7 @@
 import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.config.TokenType;
 import de.ids_mannheim.korap.config.URIParam;
+import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.exceptions.EmptyResultException;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.NotAuthorizedException;
@@ -35,7 +37,6 @@
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 import de.ids_mannheim.korap.interfaces.ValidatorIface;
-import de.ids_mannheim.korap.interfaces.db.AdminHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.UserDataDbIface;
@@ -64,17 +65,17 @@
 	private static Logger jlog = LoggerFactory.getLogger(KustvaktAuthenticationManager.class);
 	private EncryptionIface crypto;
 	private EntityHandlerIface entHandler;
-	private AdminHandlerIface adminHandler;
+	@Autowired
+	private AdminDao adminDao;
 	private AuditingIface auditing;
 	private FullConfiguration config;
 	private Collection userdatadaos;
 	private LoginCounter counter;
 	private ValidatorIface validator;
 	
-	public KustvaktAuthenticationManager(EntityHandlerIface userdb, AdminHandlerIface admindb, EncryptionIface crypto,
+	public KustvaktAuthenticationManager(EntityHandlerIface userdb, EncryptionIface crypto,
 			FullConfiguration config, AuditingIface auditer, Collection<UserDataDbIface> userdatadaos) {
 		this.entHandler = userdb;
-		this.adminHandler = admindb;
 		this.config = config;
 		this.crypto = crypto;
 		this.auditing = auditer;
@@ -340,8 +341,7 @@
 			}
 		}
 
-		boolean isAdmin = adminHandler.isAdmin(unknown.getId());
-		unknown.setSystemAdmin(isAdmin);
+		boolean isAdmin = adminDao.isAdmin(unknown.getUsername());
 		jlog.debug("Authentication: found username " + unknown.getUsername());
 
 		if (unknown instanceof KorAPUser) {
@@ -712,9 +712,9 @@
 		}
 		user.setPassword(hash);
 
-		String o = (String) attributes.get(Attributes.IS_ADMIN);
-		boolean b = Boolean.parseBoolean(o);
-		user.setSystemAdmin(b);
+//		String o = (String) attributes.get(Attributes.IS_ADMIN);
+//		boolean b = Boolean.parseBoolean(o);
+//		user.setSystemAdmin(b);
 
 		try {
 			UserDetails details = new UserDetails();
@@ -725,10 +725,10 @@
 
 			jlog.info("Creating new user account for user {}", user.getUsername());
 			entHandler.createAccount(user);
-			if (user.isSystemAdmin() && user instanceof KorAPUser) {
-				adminHandler.addAccount(user);
-				user.setCorpusAccess(CorpusAccess.ALL);
-			}
+//			if (user.isSystemAdmin() && user instanceof KorAPUser) {
+//				adminDao.addAccount(user);
+//				user.setCorpusAccess(CorpusAccess.ALL);
+//			}
 			details.setUserId(user.getId());
 			settings.setUserId(user.getId());
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/AdminDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/AdminDao.java
new file mode 100644
index 0000000..1a749df
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/AdminDao.java
@@ -0,0 +1,56 @@
+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.Predicate;
+import javax.persistence.criteria.Root;
+
+import org.springframework.stereotype.Repository;
+import org.springframework.transaction.annotation.Transactional;
+
+import de.ids_mannheim.korap.entity.Admin;
+import de.ids_mannheim.korap.entity.Admin_;
+import de.ids_mannheim.korap.user.User;
+
+/**
+ * @author margaretha
+ *
+ */
+@Transactional
+@Repository
+public class AdminDao {
+
+    @PersistenceContext
+    private EntityManager entityManager;
+
+    public void addAccount (User user) {
+        Admin admin = new Admin();
+        admin.setUserId(user.getUsername());
+        entityManager.persist(admin);
+    }
+
+    public boolean isAdmin (String userId) {
+        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
+        CriteriaQuery<Admin> query = criteriaBuilder.createQuery(Admin.class);
+
+        Root<Admin> admin = query.from(Admin.class);
+        Predicate p = criteriaBuilder.equal(admin.get(Admin_.userId), userId);
+
+        query.select(admin);
+        query.where(p);
+
+        Query q = entityManager.createQuery(query);
+        try {
+            q.getSingleResult();
+        }
+        catch (NoResultException e) {
+            return false;
+        }
+
+        return true;
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/Admin.java b/full/src/main/java/de/ids_mannheim/korap/entity/Admin.java
new file mode 100644
index 0000000..654efe3
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/Admin.java
@@ -0,0 +1,34 @@
+package de.ids_mannheim.korap.entity;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+import lombok.Getter;
+import lombok.Setter;
+
+/** Describes admin users
+ * 
+ * @author margaretha
+ *
+ */
+@Getter
+@Setter
+@Entity
+@Table(name = "admin")
+public class Admin {
+
+    @Id
+    @GeneratedValue(strategy = GenerationType.IDENTITY)
+    private int id;
+    @Column(name = "user_id")
+    private String userId;
+
+    @Override
+    public String toString () {
+        return "id=" + id + ", userId=" + userId;
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/AdminDao.java b/full/src/main/java/de/ids_mannheim/korap/handlers/AdminDao.java
deleted file mode 100644
index ef020f0..0000000
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/AdminDao.java
+++ /dev/null
@@ -1,94 +0,0 @@
-package de.ids_mannheim.korap.handlers;
-
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-import org.springframework.dao.DataAccessException;
-import org.springframework.jdbc.core.namedparam.MapSqlParameterSource;
-import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
-
-import de.ids_mannheim.korap.config.KustvaktBaseDaoInterface;
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.interfaces.db.AdminHandlerIface;
-import de.ids_mannheim.korap.interfaces.db.PersistenceClient;
-import de.ids_mannheim.korap.user.User;
-
-public class AdminDao implements AdminHandlerIface, KustvaktBaseDaoInterface {
-	
-	private static Logger jlog = LoggerFactory.getLogger(AdminDao.class);
-	private NamedParameterJdbcTemplate jdbcTemplate;
-
-	public AdminDao(PersistenceClient client) {
-		this.jdbcTemplate = (NamedParameterJdbcTemplate) client.getSource();
-	}
-	
-	@Override
-	public int addAccount(User user) throws KustvaktException{
-		MapSqlParameterSource params = new MapSqlParameterSource();
-		params.addValue("user_id", user.getId());
-		String query = "INSERT INTO admin_users (user_id) VALUES (:user_id)";
-		try {
-            int r = this.jdbcTemplate.update(query, params);
-            return r;
-        }
-        catch (DataAccessException e) {
-            jlog.warn("Could not add {} as an admin. {} is already an admin.",
-                    user.getUsername());
-//            throw new dbException(user.getId().toString(), "admin_users",
-//                    StatusCodes.ENTRY_EXISTS, user.getId().toString());
-            return 0;
-        }
-	}
-
-	@Override
-	public int size() {
-		final String query = "SELECT COUNT(*) FROM admin_users;";
-		return this.jdbcTemplate.queryForObject(query, new HashMap<String, Object>(), Integer.class);
-	}
-
-	@Override
-	public int truncate() {
-		String sql = "DELETE FROM korap_users;";
-		try {
-			return this.jdbcTemplate.update(sql, new HashMap<String, Object>());
-		} catch (DataAccessException e) {
-			return -1;
-		}
-	}
-
-	@Override
-	public int updateAccount(User user) throws KustvaktException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	@Override
-	public int deleteAccount(Integer userid) throws KustvaktException {
-		// TODO Auto-generated method stub
-		return 0;
-	}
-
-	// EM: FIX ME
-	@Override
-	public boolean isAdmin(int userId) {
-		Map<String, String> namedParameters = Collections.singletonMap(
-                "user_id", String.valueOf(userId));
-		
-        final String sql = "select id from admin_users where user_id=:user_id;";
-        try {
-            List<Map<String, Object>> ids = this.jdbcTemplate.queryForList(sql, namedParameters);
-            if (ids.isEmpty()){
-            	return false;
-            }
-        }
-        catch (DataAccessException e) {
-            return false;
-        }
-		return true;
-	}
-
-}
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java b/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
index 981085e..147be56 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/UserGroupService.java
@@ -14,6 +14,7 @@
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.constant.PredefinedRole;
 import de.ids_mannheim.korap.constant.UserGroupStatus;
+import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.dao.RoleDao;
 import de.ids_mannheim.korap.dao.UserGroupDao;
 import de.ids_mannheim.korap.dao.UserGroupMemberDao;
@@ -24,8 +25,6 @@
 import de.ids_mannheim.korap.entity.UserGroupMember;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
-import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.ParameterChecker;
 import de.ids_mannheim.korap.web.controller.UserGroupController;
 import de.ids_mannheim.korap.web.input.UserGroupJson;
@@ -49,9 +48,9 @@
     @Autowired
     private RoleDao roleDao;
     @Autowired
-    private UserGroupConverter converter;
+    private AdminDao adminDao;
     @Autowired
-    private AuthenticationManagerIface authManager;
+    private UserGroupConverter converter;
     @Autowired
     private FullConfiguration config;
     @Autowired
@@ -68,8 +67,21 @@
      * 
      * @see {@link PredefinedRole}
      */
-    public List<UserGroupDto> retrieveUserGroup (String username)
-            throws KustvaktException {
+    public List<UserGroupDto> retrieveUserGroup (String username,
+            String contextUsername) throws KustvaktException {
+
+        boolean isAdmin = adminDao.isAdmin(contextUsername);
+
+        if (username != null) {
+            if (!username.equals(contextUsername) && !isAdmin) {
+                throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                        "Unauthorized operation for user: " + contextUsername,
+                        contextUsername);
+            }
+        }
+        else {
+            username = contextUsername;
+        }
 
         List<UserGroup> userGroups =
                 userGroupDao.retrieveGroupByUserId(username);
@@ -184,14 +196,14 @@
 
     public void deleteGroup (int groupId, String username)
             throws KustvaktException {
-        User user = authManager.getUser(username);
         UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
         if (userGroup.getStatus() == UserGroupStatus.DELETED) {
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
                     "Group " + userGroup.getName() + " has been deleted.",
                     userGroup.getName());
         }
-        else if (userGroup.getCreatedBy().equals(username) || user.isSystemAdmin()) {
+        else if (userGroup.getCreatedBy().equals(username)
+                || adminDao.isAdmin(username)) {
             // soft delete
             userGroupDao.deleteGroup(groupId, username,
                     config.isSoftDeleteGroup());
@@ -304,8 +316,7 @@
                     userGroup.getName());
         }
 
-        User user = authManager.getUser(inviter);
-        if (isUserGroupAdmin(inviter, userGroup) || user.isSystemAdmin()) {
+        if (isUserGroupAdmin(inviter, userGroup) || adminDao.isAdmin(inviter)) {
             for (String memberName : members) {
                 inviteGroupMember(memberName, userGroup, inviter,
                         GroupMemberStatus.PENDING);
@@ -397,7 +408,7 @@
 
     public void deleteGroupMember (String memberId, int groupId,
             String deletedBy) throws KustvaktException {
-        User user = authManager.getUser(deletedBy);
+
         UserGroup userGroup = userGroupDao.retrieveGroupById(groupId);
         if (userGroup.getStatus() == UserGroupStatus.DELETED) {
             throw new KustvaktException(StatusCodes.GROUP_DELETED,
@@ -411,7 +422,7 @@
         }
         else if (memberId.equals(deletedBy)
                 || isUserGroupAdmin(deletedBy, userGroup)
-                || user.isSystemAdmin()) {
+                || adminDao.isAdmin(deletedBy)) {
             // soft delete
             deleteMember(memberId, groupId, deletedBy,
                     config.isSoftDeleteGroupMember());
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 9706cfc..6ea1002 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
@@ -16,6 +16,7 @@
 import de.ids_mannheim.korap.constant.GroupMemberStatus;
 import de.ids_mannheim.korap.constant.VirtualCorpusAccessStatus;
 import de.ids_mannheim.korap.constant.VirtualCorpusType;
+import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.dao.VirtualCorpusAccessDao;
 import de.ids_mannheim.korap.dao.VirtualCorpusDao;
 import de.ids_mannheim.korap.dto.VirtualCorpusAccessDto;
@@ -28,9 +29,7 @@
 import de.ids_mannheim.korap.entity.VirtualCorpusAccess;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
-import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.query.serialize.QuerySerializer;
-import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.user.User.CorpusAccess;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.utils.KoralCollectionQueryBuilder;
@@ -57,14 +56,14 @@
     @Autowired
     private VirtualCorpusAccessDao accessDao;
     @Autowired
+    private AdminDao adminDao;
+    @Autowired
     private UserGroupService userGroupService;
     @Autowired
     private SearchKrill krill;
     @Autowired
     private FullConfiguration config;
     @Autowired
-    private AuthenticationManagerIface authManager;
-    @Autowired
     private VirtualCorpusConverter converter;
     @Autowired
     private VirtualCorpusAccessConverter accessConverter;
@@ -106,10 +105,9 @@
      */
     public void deleteVC (String username, int vcId) throws KustvaktException {
 
-        User user = authManager.getUser(username);
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
 
-        if (vc.getCreatedBy().equals(username) || user.isSystemAdmin()) {
+        if (vc.getCreatedBy().equals(username) || adminDao.isAdmin(username)) {
             vcDao.deleteVirtualCorpus(vcId);
         }
         else {
@@ -124,8 +122,8 @@
         int vcId = vcJson.getId();
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
 
-        User user = authManager.getUser(username);
-        if (!username.equals(vc.getCreatedBy()) && !user.isSystemAdmin()) {
+        if (!username.equals(vc.getCreatedBy())
+                && !adminDao.isAdmin(username)) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -188,10 +186,9 @@
         ParameterChecker.checkStringValue(vc.getCorpusQuery(), "corpusQuery");
         ParameterChecker.checkStringValue(vc.getCreatedBy(), "createdBy");
 
-        User user = authManager.getUser(username);
 
         if (vc.getType().equals(VirtualCorpusType.PREDEFINED)
-                && !user.isSystemAdmin()) {
+                && !adminDao.isAdmin(username)) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -262,17 +259,17 @@
     public void shareVC (String username, int vcId, int groupId)
             throws KustvaktException {
 
-        User user = authManager.getUser(username);
-
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
-        if (!username.equals(vc.getCreatedBy()) && !user.isSystemAdmin()) {
+        if (!username.equals(vc.getCreatedBy())
+                && !adminDao.isAdmin(username)) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
 
         UserGroup userGroup = userGroupService.retrieveUserGroupById(groupId);
 
-        if (!isVCAccessAdmin(userGroup, username) && !user.isSystemAdmin()) {
+        if (!isVCAccessAdmin(userGroup, username)
+                && !adminDao.isAdmin(username)) {
             throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
                     "Unauthorized operation for user: " + username, username);
         }
@@ -296,27 +293,26 @@
         return false;
     }
 
-//    public void editVCAccess (VirtualCorpusAccess access, String username)
-//            throws KustvaktException {
-//
-//        // 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);
-//        }
-//    }
+    //    public void editVCAccess (VirtualCorpusAccess access, String username)
+    //            throws KustvaktException {
+    //
+    //        // 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);
+    //        }
+    //    }
 
     public List<VirtualCorpusAccessDto> listVCAccessByVC (String username,
             int vcId) throws KustvaktException {
 
         List<VirtualCorpusAccess> accessList;
-        User user = authManager.getUser(username);
-        if (user.isSystemAdmin()) {
+        if (adminDao.isAdmin(username)) {
             accessList = accessDao.retrieveAllAccessByVC(vcId);
         }
         else {
@@ -335,11 +331,10 @@
 
     public List<VirtualCorpusAccessDto> listVCAccessByGroup (String username,
             int groupId) throws KustvaktException {
-        User user = authManager.getUser(username);
         UserGroup userGroup = userGroupService.retrieveUserGroupById(groupId);
 
         List<VirtualCorpusAccess> accessList;
-        if (user.isSystemAdmin()) {
+        if (adminDao.isAdmin(username)) {
             accessList = accessDao.retrieveAllAccessByGroup(groupId);
         }
         else if (isVCAccessAdmin(userGroup, username)) {
@@ -356,11 +351,10 @@
     public void deleteVCAccess (int accessId, String username)
             throws KustvaktException {
 
-        User user = authManager.getUser(username);
-
         VirtualCorpusAccess access = accessDao.retrieveAccessById(accessId);
         UserGroup userGroup = access.getUserGroup();
-        if (isVCAccessAdmin(userGroup, username) || user.isSystemAdmin()) {
+        if (isVCAccessAdmin(userGroup, username)
+                || adminDao.isAdmin(username)) {
             accessDao.deleteAccess(access, username);
         }
         else {
@@ -372,12 +366,12 @@
 
     public VirtualCorpusDto searchVCById (String username, int vcId)
             throws KustvaktException {
-        User user = authManager.getUser(username);
 
         VirtualCorpus vc = vcDao.retrieveVCById(vcId);
         VirtualCorpusType type = vc.getType();
 
-        if (!user.isSystemAdmin() && !username.equals(vc.getCreatedBy())) {
+        if (!adminDao.isAdmin(username)
+                && !username.equals(vc.getCreatedBy())) {
             if (type.equals(VirtualCorpusType.PRIVATE)
                     || (type.equals(VirtualCorpusType.PROJECT)
                             && !hasAccess(username, vcId))) {
@@ -388,12 +382,8 @@
 
             else if (VirtualCorpusType.PUBLISHED.equals(type)) {
                 // add user in the VC's auto group 
-                //                VirtualCorpusAccess access =
-                //                        accessDao.retrieveHiddenAccess(vcId);
-                //                UserGroup userGroup = access.getUserGroup();
                 UserGroup userGroup =
                         userGroupService.retrieveHiddenGroup(vcId);
-                //                if (!userGroupService.isMember(username, userGroup)) {
                 try {
                     userGroupService.inviteGroupMember(username, userGroup,
                             "system", GroupMemberStatus.ACTIVE);
@@ -424,6 +414,4 @@
         }
         return false;
     }
-
-
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
index 0bb4678..a838c13 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/UserGroupController.java
@@ -61,12 +61,13 @@
      */
     @GET
     @Path("list")
-    public Response getUserGroup (@Context SecurityContext securityContext) {
+    public Response getUserGroup (@Context SecurityContext securityContext,
+            @QueryParam("username") String username) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
             List<UserGroupDto> dtos =
-                    service.retrieveUserGroup(context.getUsername());
+                    service.retrieveUserGroup(username, context.getUsername());
             String result = JsonUtils.toJSON(dtos);
             return Response.ok(result).build();
         }
@@ -159,8 +160,8 @@
     @POST
     @Path("member/invite")
     @Consumes(MediaType.APPLICATION_JSON)
-    public Response inviteGroupMembers (@Context SecurityContext securityContext,
-            UserGroupJson group) {
+    public Response inviteGroupMembers (
+            @Context SecurityContext securityContext, UserGroupJson group) {
         TokenContext context =
                 (TokenContext) securityContext.getUserPrincipal();
         try {
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
index bac128c..5b3d68a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
@@ -19,6 +19,7 @@
 import de.ids_mannheim.korap.authentication.http.TransferEncoding;
 import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.AuthenticationMethod;
+import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
@@ -40,6 +41,8 @@
 public class AdminFilter implements ContainerRequestFilter, ResourceFilter {
 
     @Autowired
+    private AdminDao adminDao;
+    @Autowired
     private AuthenticationManagerIface authManager;
 
     @Autowired
@@ -71,7 +74,7 @@
             // EM: fix me: AuthenticationType based on header value
             User user = authManager.authenticate(AuthenticationMethod.LDAP,
                     data.getUsername(), data.getPassword(), attributes);
-            if (!user.isSystemAdmin()) {
+            if (!adminDao.isAdmin(user.getUsername())) {
                 throw new KustvaktException(StatusCodes.AUTHENTICATION_FAILED,
                         "Admin authentication failed.");
             }
diff --git a/full/src/main/resources/db/insert/V3.4__insert_admins.sql b/full/src/main/resources/db/insert/V3.4__insert_admins.sql
new file mode 100644
index 0000000..d8dbd8c
--- /dev/null
+++ b/full/src/main/resources/db/insert/V3.4__insert_admins.sql
@@ -0,0 +1,2 @@
+-- dummy admin
+INSERT INTO admin(user_id) VALUES ("admin");
\ No newline at end of file
diff --git a/full/src/main/resources/db/new-mysql/V1.2__create_admin_table.sql b/full/src/main/resources/db/new-mysql/V1.2__create_admin_table.sql
new file mode 100644
index 0000000..f51cd1a
--- /dev/null
+++ b/full/src/main/resources/db/new-mysql/V1.2__create_admin_table.sql
@@ -0,0 +1,5 @@
+CREATE TABLE IF NOT EXISTS admin (
+	id INTEGER PRIMARY KEY AUTOINCREMENT,
+	user_id varchar(100) NOT NULL,
+	UNIQUE INDEX unique_index (user_id)
+);
\ No newline at end of file
diff --git a/full/src/main/resources/db/new-sqlite/V1.3__create_admin_table.sql b/full/src/main/resources/db/new-sqlite/V1.3__create_admin_table.sql
new file mode 100644
index 0000000..3f4f32f
--- /dev/null
+++ b/full/src/main/resources/db/new-sqlite/V1.3__create_admin_table.sql
@@ -0,0 +1,6 @@
+CREATE TABLE IF NOT EXISTS admin(
+	id INTEGER PRIMARY KEY AUTOINCREMENT,
+	user_id varchar(100) NOT NULL
+);
+
+CREATE UNIQUE INDEX admin_index on admin(user_id);
\ No newline at end of file
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index 64fbe6a..1ef5429 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -187,10 +187,6 @@
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
 
-	<bean id="kustvakt_admindb" class="de.ids_mannheim.korap.handlers.AdminDao">
-		<constructor-arg ref="kustvakt_db" />
-	</bean>
-
 	<bean id="resource_provider" class="de.ids_mannheim.korap.handlers.ResourceDao">
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
@@ -266,8 +262,6 @@
 		class="de.ids_mannheim.korap.authentication.KustvaktAuthenticationManager">
 		<constructor-arg
 			type="de.ids_mannheim.korap.interfaces.db.EntityHandlerIface" ref="kustvakt_userdb" />
-		<constructor-arg
-			type="de.ids_mannheim.korap.interfaces.db.AdminHandlerIface" ref="kustvakt_admindb" />
 		<constructor-arg type="de.ids_mannheim.korap.interfaces.EncryptionIface"
 			ref="kustvakt_encryption" />
 		<constructor-arg ref="kustvakt_config" />
diff --git a/full/src/main/resources/properties/jdbc.properties b/full/src/main/resources/properties/jdbc.properties
index 2bc85dd..1afe44b 100644
--- a/full/src/main/resources/properties/jdbc.properties
+++ b/full/src/main/resources/properties/jdbc.properties
@@ -9,7 +9,7 @@
 #jdbc.password=password
 
 # db.insert contains test data, omit it in production setting
-#jdbc.schemaPath=db.new-mysql, db.insert, db.predefined
+#jdbc.schemaPath=db.new-mysql, db.predefined
 
 
 #-------------------------------------------------------------------------------
@@ -22,4 +22,4 @@
 jdbc.username=pc
 jdbc.password=pc
 # db.insert contains test data, omit it in production setting
-jdbc.schemaPath=db.new-sqlite, db.predefined, db.insert
+jdbc.schemaPath=db.new-sqlite, db.predefined
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java b/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
index d0c490c..3bbdb4f 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/TestBeans.java
@@ -4,7 +4,6 @@
 
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
-import de.ids_mannheim.korap.interfaces.db.AdminHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.interfaces.db.EntityHandlerIface;
 import de.ids_mannheim.korap.interfaces.db.PolicyHandlerIface;
@@ -23,8 +22,6 @@
 
 	public  EntityHandlerIface getUserDao();
 	
-	public  AdminHandlerIface getAdminDao();
-
 	public  AuditingIface getAuditingDao();
 
 	public  List<ResourceOperationIface> getResourceDaos();
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java
new file mode 100644
index 0000000..a9127cc
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerAdminTest.java
@@ -0,0 +1,62 @@
+package de.ids_mannheim.korap.web.controller;
+
+import static org.junit.Assert.assertEquals;
+
+import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.google.common.net.HttpHeaders;
+import com.sun.jersey.api.client.ClientHandlerException;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.ClientResponse.Status;
+import com.sun.jersey.api.client.UniformInterfaceException;
+
+import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.SpringJerseyTest;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.utils.JsonUtils;
+
+public class UserGroupControllerAdminTest extends SpringJerseyTest {
+    @Autowired
+    private HttpAuthorizationHandler handler;
+
+    @Test
+    public void testListDoryGroups () throws KustvaktException {
+        ClientResponse response = resource().path("group").path("list")
+                .queryParam("username", "dory")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue("admin",
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        String entity = response.getEntity(String.class);
+        //        System.out.println(entity);
+        JsonNode node = JsonUtils.readTree(entity);
+        JsonNode group = node.get(1);
+        assertEquals(2, group.at("/id").asInt());
+        assertEquals("dory group", group.at("/name").asText());
+        assertEquals("dory", group.at("/owner").asText());
+        assertEquals(3, group.at("/members").size());
+    }
+
+    @Test
+    public void testListWithoutUsername () throws UniformInterfaceException,
+            ClientHandlerException, KustvaktException {
+        ClientResponse response = resource().path("group").path("list")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue("admin",
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+
+        assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        String entity = response.getEntity(String.class);
+        assertEquals("[]", entity);
+    }
+
+
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerTest.java
index 04314fc..f748b69 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/UserGroupControllerTest.java
@@ -94,6 +94,7 @@
     @Test
     public void testListMarlinGroups () throws KustvaktException {
         ClientResponse response = resource().path("group").path("list")
+                .queryParam("username", "marlin")
                 .header(Attributes.AUTHORIZATION,
                         handler.createBasicAuthorizationHeaderValue("marlin",
                                 "pass"))
@@ -107,7 +108,7 @@
 
 
     @Test
-    public void testListUserGroupUnauthorized () throws KustvaktException {
+    public void testListGroupGuest () throws KustvaktException {
         ClientResponse response = resource().path("group").path("list")
                 .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
                 .get(ClientResponse.class);
@@ -121,6 +122,25 @@
         assertEquals("Unauthorized operation for user: guest",
                 node.at("/errors/0/1").asText());
     }
+    
+    @Test
+    public void testListGroupOtherUser() throws KustvaktException {
+        ClientResponse response = resource().path("group").path("list")
+                .queryParam("username", "dory")
+                .header(Attributes.AUTHORIZATION,
+                        handler.createBasicAuthorizationHeaderValue("marlin",
+                                "pass"))
+                .header(HttpHeaders.X_FORWARDED_FOR, "149.27.0.32")
+                .get(ClientResponse.class);
+        assertEquals(Status.UNAUTHORIZED.getStatusCode(), response.getStatus());
+        
+        String entity = response.getEntity(String.class);
+        JsonNode node = JsonUtils.readTree(entity);
+        assertEquals(StatusCodes.AUTHORIZATION_FAILED,
+                node.at("/errors/0/0").asInt());
+        assertEquals("Unauthorized operation for user: marlin",
+                node.at("/errors/0/1").asText());
+    }
 
     @Test
     public void testCreateUserGroup () throws UniformInterfaceException,
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index 9ac801c..99b2dd7 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -58,7 +58,7 @@
 
 	<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
 		lazy-init="true">
-		<property name="driverClassName" value="${jdbc.driverClassName}" />
+		<!-- <property name="driverClassName" value="${jdbc.driverClassName}" /> -->
 		<property name="url" value="${jdbc.url}" />
 		<property name="username" value="${jdbc.username}" />
 		<property name="password" value="${jdbc.password}" />
@@ -182,10 +182,6 @@
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
 
-	<bean id="kustvakt_admindb" class="de.ids_mannheim.korap.handlers.AdminDao">
-		<constructor-arg ref="kustvakt_db" />
-	</bean>
-
 	<bean id="resource_provider" class="de.ids_mannheim.korap.handlers.ResourceDao">
 		<constructor-arg ref="kustvakt_db" />
 	</bean>
@@ -263,8 +259,6 @@
 		class="de.ids_mannheim.korap.authentication.KustvaktAuthenticationManager">
 		<constructor-arg
 			type="de.ids_mannheim.korap.interfaces.db.EntityHandlerIface" ref="kustvakt_userdb" />
-		<constructor-arg
-			type="de.ids_mannheim.korap.interfaces.db.AdminHandlerIface" ref="kustvakt_admindb" />
 		<constructor-arg type="de.ids_mannheim.korap.interfaces.EncryptionIface"
 			ref="kustvakt_encryption" />
 		<constructor-arg ref="kustvakt_config" />