Fixed admin service createPolicies and added a test.

Change-Id: Ic200338ccb928646321477f6b74e0393f14c47e4
diff --git a/policy.conf b/policy.conf
index 99f0409..4a6dfd2 100644
--- a/policy.conf
+++ b/policy.conf
@@ -1,17 +1,55 @@
 # type	id	name	description	condition	permissions
 
-virtualcollection	WPD15-VC	Wikipedia	Deutsche Wikipedia 2015	public	read
-corpus	WPD15	Wikipedia	Deutsche Wikipedia 2015	public	read
+virtualcollection	WPD15-VC	Wikipedia Virtual Collection	German Wikipedia 2015	public	read
+corpus	WPD15	Wikipedia	German Wikipedia 2015	public	read
 corpus	GOE	Goethe	Goethe corpus	public	read
-foundry	base	Base	base foundry	public	read
-foundry	dereko	Dereko	dereko foundry	public	read
-foundry	corenlp	CoreNLP	CoreNLP parser	public	read
-foundry	opennlp	OpenNLP	OpenNLP parser	public	read
-foundry	malt	MALT	MALT parser	public	read
-foundry	mdp	mdp	MD Parser	public	read
-foundry	tt	Tree Tagger	Tree Tagger parser	public	read
-layer	s	sentence	sentence	public	read
-layer	c	constituent	constituent	public	read
-layer	d	dependency	dependency	public	read
-layer	p	pos	part of speech	public	read
-layer	l	lemma	lemma	public	read
+type	id	name	description	condition	permissions
+foundry	base	base	Base foundry	public	read
+foundry	dereko	dereko	DeReKo foundry	public	read
+foundry	corenlp	corenlp	CoreNLP parser	public	read
+foundry	opennlp	opennlp	OpenNLP parser	public	read
+foundry	malt	malt	MALT parser	public	read
+foundry	mdp	mdp	MD parser	public	read
+foundry	tt	tt	Tree Tagger parser	public	read
+foundry	sgbr	sgbr	Schreibgebrauch	ids	read
+foundry	cnx	cnx	Connexor parser	ids	read
+foundry	drukola	drukola	DruKoLa parser	drukola	read
+foundry	glemm	glemm	Glemm	public	read
+foundry	marmot	marmot	MarMoT parser	public	read
+foundry	mate	mate	Mate parser	public	read
+foundry	xip	xip	Xerox Incremental Parser	ids	read
+layer	cnx/c	cnx/c	Connexor constituency layer	ids	read
+layer	cnx/syn	cnx/syn	Connexor syntax	ids	read
+layer	cnx/p	cnx/p	Connexor part of speech	ids	read
+layer	cnx/l	cnx/l	Connexor lemma	ids	read
+layer	cnx/m	cnx/m	Connexor morphology	ids	read
+layer	corenlp/c	corenlp/c	CoreNLP constituency	public	read
+layer	corenlp/p	corenlp/p	CoreNLP part of speech	public	read
+layer	corenlp/s	corenlp/s	CoreNLP structure	public	read
+layer	corenlp/ne	corenlp/ne	CoreNLP named entities	public	read
+layer	dereko/s	dereko/s	DeReKo structure	public	read
+layer	drukola/l	drukola/l	Drukola lemma	drukola	read
+layer	drukola/p	drukola/p	Drukola part of speech	drukola	read
+layer	drukola/m	drukola/m	Drukola morphology	drukola	read
+layer	glemm/l	glemm/l	GLEMM lemma	public	read
+layer	malt/d	malt/d	MALT dependency	public	read
+layer	marmot/p	marmot/p	Marmot part of speech	public	read
+layer	marmot/m	marmot/m	Marmot morphology	public	read
+layer	mate/d	mate/d	MATE dependency	public	read
+layer	mate/l	mate/l	MATE lemma	public	read
+layer	mate/p	mate/p	MATE part of speech	public	read
+layer	mate/m	mate/m	MATE morphology	public	read
+layer	mdp/d	mdp/d	MDP dependency	public	read
+layer	opennlp/p	opennlp/p	OpenNLP part of speech	public	read
+layer	opennlp/s	opennlp/s	OpenNLP part of speech	public	read
+layer	sgbr/p	sgbr/p	Schreibgebrauchp part of peech	ids	read
+layer	sgbr/l	sgbr/l	Schreibgebrauch lemma	ids	read
+layer	sgbr/lv	sgbr/lv	Schreibgebrauch lemmav ariant	ids	read
+layer	tt/p	tt/p	Tree Tagger part of speech	public	read
+layer	tt/l	tt/l	Tree Tagger lemma	public	read
+layer	tt/s	tt/s	Tree Tagger structure	public	read
+layer	xip/c	xip/c	XIP constituency	ids	read
+layer	xip/d	xip/d	XIP dependency	ids	read
+layer	xip/l	xip/l	XIP lemma	ids	read
+layer	xip/p	xip/p	XIP part of speech	ids	read
+layer	xip/s	xip/s	XIP structure	ids	read
diff --git a/src/main/java/de/ids_mannheim/korap/config/AdminSetup.java b/src/main/java/de/ids_mannheim/korap/config/AdminSetup.java
index 378e015..142b8f0 100644
--- a/src/main/java/de/ids_mannheim/korap/config/AdminSetup.java
+++ b/src/main/java/de/ids_mannheim/korap/config/AdminSetup.java
@@ -1,10 +1,9 @@
 package de.ids_mannheim.korap.config;
 
-import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import java.io.File;
+import java.io.FileOutputStream;
 
-import java.io.*;
-import java.security.NoSuchAlgorithmException;
+import de.ids_mannheim.korap.interfaces.EncryptionIface;
 
 /**
  * Created by hanl on 30.05.16.
diff --git a/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java b/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
index dc60e89..f66646a 100644
--- a/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
+++ b/src/main/java/de/ids_mannheim/korap/web/filter/AdminFilter.java
@@ -5,8 +5,13 @@
 import com.sun.jersey.spi.container.ContainerResponseFilter;
 import com.sun.jersey.spi.container.ResourceFilter;
 import de.ids_mannheim.korap.config.AdminSetup;
+import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeansFactory;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
+import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
+import de.ids_mannheim.korap.security.auth.KustvaktAuthenticationManager;
 import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.NamingUtils;
@@ -14,6 +19,9 @@
 import de.ids_mannheim.korap.web.utils.KustvaktContext;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
 
+import java.util.HashMap;
+import java.util.Map;
+
 import javax.ws.rs.ext.Provider;
 
 /**
@@ -23,33 +31,51 @@
 @Provider
 public class AdminFilter implements ContainerRequestFilter, ResourceFilter {
 
+//	private static AuthenticationManagerIface authManager = BeansFactory.getKustvaktContext()
+//	        .getAuthenticationManager();
+	
     @Override
     public ContainerRequest filter (ContainerRequest cr) {
         // todo:
         String host = cr.getHeaderValue(ContainerRequest.HOST);
-        String ua = cr.getHeaderValue(ContainerRequest.USER_AGENT);
-
+        String agent = cr.getHeaderValue(ContainerRequest.USER_AGENT);
         String authentication = cr
                 .getHeaderValue(ContainerRequest.AUTHORIZATION);
-
-        //if (authentication != null
-        //        && authentication.endsWith(BeansFactory.getKustvaktContext()
-        //                .getConfiguration().getAdminToken())) {
-        if (authentication != null && cr.isSecure()) {
-            String token = StringUtils.stripTokenType(authentication);
-            EncryptionIface crypto = BeansFactory.getKustvaktContext()
-                    .getEncryption();
-
-            if (crypto.checkHash(token, AdminSetup.getInstance().getHash())) {
-                TokenContext c = new TokenContext();
-                c.setUsername(User.ADMINISTRATOR_NAME);
-                c.setTokenType(StringUtils.getTokenType(authentication));
-                c.setToken(StringUtils.stripTokenType(authentication));
-                cr.setSecurityContext(new KustvaktContext(c));
-            }
+        
+        //decode password
+        String authenticationType = StringUtils.getTokenType(authentication);
+        String authenticationCode = StringUtils.stripTokenType(authentication);
+        String username = null, token=null;
+        if (authenticationType.equals("basic")){
+        	String[] authContent = BasicHttpAuth.decode(authenticationCode);
+        	username = authContent[0];
+        	token= authContent[1];
         }
-        else
-            throw KustvaktResponseHandler.throwAuthenticationException("");
+        
+//        if (authentication != null
+//                && authentication.endsWith(BeansFactory.getKustvaktContext()
+//                        .getConfiguration().getAdminToken())) {
+        
+//        EM: to do ssl
+//        if (authentication != null && cr.isSecure()) {
+//            String token = StringUtils.stripTokenType(authentication);
+//            EncryptionIface crypto = BeansFactory.getKustvaktContext()
+//                    .getEncryption();
+            
+            // EM: Another method of authentification using admin token
+//            if (crypto.checkHash(token, AdminSetup.getInstance().getHash())) {
+                TokenContext c = new TokenContext();
+                c.setUsername(username);
+                c.setTokenType(authenticationType);
+                c.setToken(token);
+                c.setHostAddress(host);
+                c.setUserAgent(agent);
+                cr.setSecurityContext(new KustvaktContext(c));
+                
+//            }
+//        }
+//        else
+//            throw KustvaktResponseHandler.throwAuthenticationException("");
         return cr;
     }
 
diff --git a/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java b/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
index 77f6a8c..983f619 100644
--- a/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
+++ b/src/main/java/de/ids_mannheim/korap/web/service/full/AdminService.java
@@ -1,39 +1,49 @@
 package de.ids_mannheim.korap.web.service.full;
 
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+
+import javax.ws.rs.GET;
+import javax.ws.rs.POST;
+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 org.joda.time.DateTime;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import com.sun.jersey.spi.container.ResourceFilters;
+
 import de.ids_mannheim.korap.auditing.AuditRecord;
+import de.ids_mannheim.korap.config.Attributes;
 import de.ids_mannheim.korap.config.BeansFactory;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.handlers.DocumentDao;
-import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.interfaces.AuthenticationManagerIface;
+import de.ids_mannheim.korap.interfaces.db.AuditingIface;
 import de.ids_mannheim.korap.resources.Document;
 import de.ids_mannheim.korap.resources.KustvaktResource;
 import de.ids_mannheim.korap.resources.Permissions;
 import de.ids_mannheim.korap.resources.ResourceFactory;
 import de.ids_mannheim.korap.security.PolicyCondition;
 import de.ids_mannheim.korap.security.ac.PolicyBuilder;
+import de.ids_mannheim.korap.user.TokenContext;
 import de.ids_mannheim.korap.user.User;
 import de.ids_mannheim.korap.utils.JsonUtils;
-import de.ids_mannheim.korap.utils.KustvaktLogger;
 import de.ids_mannheim.korap.utils.TimeUtils;
 import de.ids_mannheim.korap.web.KustvaktServer;
 import de.ids_mannheim.korap.web.filter.AdminFilter;
 import de.ids_mannheim.korap.web.filter.PiwikFilter;
 import de.ids_mannheim.korap.web.utils.KustvaktResponseHandler;
-import org.joda.time.DateTime;
-import org.joda.time.format.DateTimeFormat;
-import org.joda.time.format.DateTimeFormatter;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import javax.ws.rs.*;
-import javax.ws.rs.core.Context;
-import javax.ws.rs.core.MediaType;
-import javax.ws.rs.core.Response;
-import java.util.List;
-import java.util.Locale;
 
 /**
  * Created by hanl on 6/11/14.
@@ -45,7 +55,7 @@
 
     private static Logger jlog = LoggerFactory.getLogger(AdminService.class);
 
-    private AuthenticationManagerIface controller;
+    private AuthenticationManagerIface authManager;
     private AuditingIface auditingController;
     private DocumentDao documentDao;
 
@@ -53,7 +63,7 @@
     public AdminService () {
         this.auditingController = BeansFactory.getKustvaktContext()
                 .getAuditingProvider();
-        this.controller = BeansFactory.getKustvaktContext()
+        this.authManager = BeansFactory.getKustvaktContext()
                 .getAuthenticationManager();
         this.documentDao = new DocumentDao(BeansFactory.getKustvaktContext()
                 .getPersistenceClient());
@@ -100,7 +110,8 @@
             @QueryParam("description") String description,
             @QueryParam("group") String group,
             @QueryParam("perm") List<String> permissions,
-            @QueryParam("loc") String loc, @QueryParam("expire") String duration) {
+            @QueryParam("loc") String loc, @QueryParam("expire") String duration, 
+            @Context SecurityContext context) {
 
         try {
             KustvaktResource resource = ResourceFactory.getResource(type);
@@ -110,18 +121,34 @@
 
             Permissions.Permission[] p = Permissions.read(permissions
                     .toArray(new String[0]));
-
-            PolicyBuilder cr = new PolicyBuilder(User.UserFactory.getAdmin())
-                    .setConditions(new PolicyCondition(group)).setResources(
-                            resource);
+          
+            TokenContext tc = (TokenContext) context.getUserPrincipal();
+            Map<String, Object> attributes = new HashMap<>();
+            attributes.put(Attributes.HOST, tc.getHostAddress());
+            attributes.put(Attributes.USER_AGENT, tc.getUserAgent());
+            
+            User user = null;
+            int tokenType = 0;
+     	   	// EM: Use enum for the authentication types
+        	if(!tc.getTokenType().equals("basic")){
+        		tokenType = 1;
+        	}
+        	
+        	user = authManager.authenticate(tokenType, tc.getUsername(), tc.getToken(), attributes);
+            
+            PolicyBuilder pb = new PolicyBuilder(user)
+                    .setConditions(new PolicyCondition(group))
+                    .setResources(resource);
+            
             if (loc != null && !loc.isEmpty())
-                cr.setLocation(loc);
+                pb.setLocation(loc);
 
-            if (duration != null && duration.isEmpty())
-                cr.setContext(TimeUtils.getNow().getMillis(),
+            if (duration != null && !duration.isEmpty())
+                pb.setContext(TimeUtils.getNow().getMillis(),
                         TimeUtils.convertTimeToSeconds(duration));
 
-            cr.setPermissions(p).create();
+            pb.setPermissions(p);
+            pb.create();
         }
         catch (KustvaktException e) {
             throw KustvaktResponseHandler.throwit(e);
diff --git a/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java b/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java
new file mode 100644
index 0000000..f47dd68
--- /dev/null
+++ b/src/test/java/de/ids_mannheim/korap/web/service/full/PolicyServiceTest.java
@@ -0,0 +1,148 @@
+package de.ids_mannheim.korap.web.service.full;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.security.KeyManagementException;
+import java.security.NoSuchAlgorithmException;
+import java.security.cert.X509Certificate;
+import java.util.Collection;
+import java.util.List;
+import java.util.UUID;
+
+import javax.net.ssl.HostnameVerifier;
+import javax.net.ssl.HttpsURLConnection;
+import javax.net.ssl.SSLContext;
+import javax.net.ssl.TrustManager;
+import javax.net.ssl.X509TrustManager;
+
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mindrot.jbcrypt.BCrypt;
+
+import com.fasterxml.jackson.databind.JsonNode;
+import com.sun.jersey.api.client.Client;
+import com.sun.jersey.api.client.ClientResponse;
+import com.sun.jersey.api.client.config.ClientConfig;
+import com.sun.jersey.api.client.config.DefaultClientConfig;
+import com.sun.jersey.client.urlconnection.HTTPSProperties;
+
+import de.ids_mannheim.korap.config.AdminSetup;
+import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.TestHelper;
+import de.ids_mannheim.korap.exceptions.KustvaktException;
+import de.ids_mannheim.korap.handlers.ResourceDao;
+import de.ids_mannheim.korap.interfaces.db.PolicyHandlerIface;
+import de.ids_mannheim.korap.interfaces.db.ResourceOperationIface;
+import de.ids_mannheim.korap.resources.Corpus;
+import de.ids_mannheim.korap.resources.KustvaktResource;
+import de.ids_mannheim.korap.resources.Permissions;
+import de.ids_mannheim.korap.resources.Permissions.Permission;
+import de.ids_mannheim.korap.resources.VirtualCollection;
+import de.ids_mannheim.korap.security.PolicyCondition;
+import de.ids_mannheim.korap.security.SecurityPolicy;
+import de.ids_mannheim.korap.security.auth.BasicHttpAuth;
+import de.ids_mannheim.korap.user.User;
+import de.ids_mannheim.korap.user.User.UserFactory;
+import de.ids_mannheim.korap.utils.JsonUtils;
+import de.ids_mannheim.korap.web.service.FastJerseyTest;
+
+/**
+ * @author margaretha
+ */
+public class PolicyServiceTest extends FastJerseyTest {
+
+	@BeforeClass
+	public static void configure() throws Exception {
+		FastJerseyTest.setPackages("de.ids_mannheim.korap.web.service.full", "de.ids_mannheim.korap.web.filter",
+				"de.ids_mannheim.korap.web.utils");
+		// containerURI = "https://localhost/";
+	}
+
+//	public void initServer(int port) {
+//		super.initServer(port);
+//
+//		TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
+//			public X509Certificate[] getAcceptedIssuers() {
+//				return null;
+//			}
+//
+//			public void checkClientTrusted(X509Certificate[] certs, String authType) {
+//			}
+//
+//			public void checkServerTrusted(X509Certificate[] certs, String authType) {
+//			}
+//		} };
+//
+//		HostnameVerifier hostnameVerifier = HttpsURLConnection.getDefaultHostnameVerifier();
+//		ClientConfig config = new DefaultClientConfig();
+//		SSLContext ctx = null;
+//		try {
+//			ctx = SSLContext.getInstance("SSL");
+//			ctx.init(null, trustAllCerts, new java.security.SecureRandom());
+//		} catch (NoSuchAlgorithmException | KeyManagementException e) {
+//			e.printStackTrace();
+//		}
+//
+//		config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES,
+//				new HTTPSProperties(hostnameVerifier, ctx));
+//		client = Client.create(config);
+//		
+//		AdminSetup.getInstance();
+//	}
+
+	@Test
+    public void testCreatePolicyForResource() throws IOException, KustvaktException {
+    	//Path p = FileSystems.getDefault().getPath("admin_token");
+    	//List<String> content = Files.readAllLines(p, StandardCharsets.UTF_8);
+    	//String adminToken = content.get(0);
+		String id = UUID.randomUUID().toString();
+    	ClientResponse response = resource()
+                .path(getAPIVersion())
+                .path("admin")
+                .path("createPolicies")
+                .path(id)
+                .queryParam("type", "virtualcollection")
+                .queryParam("name", "Goethe VC")
+                .queryParam("description", "Goethe corpus")
+                .queryParam("group", "public")
+                .queryParam("perm", Permission.READ.name())
+                .queryParam("loc", "")
+                .queryParam("expire", "")
+                .header(Attributes.AUTHORIZATION,
+                        BasicHttpAuth.encode("kustvakt","kustvakt2015"))
+                .post(ClientResponse.class);
+        
+        assertEquals(ClientResponse.Status.OK.getStatusCode(),
+                response.getStatus());
+        
+        // Check the policies
+        PolicyHandlerIface dao = helper().getContext().getPolicyDbProvider();
+        List<SecurityPolicy> policies = dao.getPolicies(
+                new PolicyCondition("public"), VirtualCollection.class,
+                Permissions.Permission.READ.toByte());
+        assertEquals(2, policies.size());
+        
+        // Check resource store
+        List<ResourceOperationIface> providers= (List<ResourceOperationIface>) helper().getContext().getResourceProviders();
+        ResourceOperationIface resourceDao = providers.get(0);
+        
+        User user = UserFactory.getDemoUser();
+		KustvaktResource resource = resourceDao.findbyId(id,user);
+		assertEquals("Goethe VC", resource.getName());
+        	
+	}
+
+	@Override
+	public void initMethod() throws KustvaktException {
+		helper().runBootInterfaces();
+	}
+}