Added setting default access scopes in the config file & fixed #21.

Change-Id: Ic9cdf2c1aed100d6c0aa37f4d1195a3f6f2c3fda
diff --git a/full/Changes b/full/Changes
index 9e0be4b..9445c94 100644
--- a/full/Changes
+++ b/full/Changes
@@ -1,5 +1,5 @@
 version 0.60.2
-25/04/2018
+26/04/2018
 	- implemented OAuth2 client registration (margaretha)
 	- implemented OAuth2 client authentication (margaretha)
 	- changed virtual corpus search to retrieval (margaretha)
@@ -15,6 +15,8 @@
 	- added OAuth2 authorization, scope and access token tables for SQLite (margaretha)
 	- implemented OAuth2 authorization, scope and access token DAO (margaretha)
 	- implemented OAuth2 request access token with authorization code grant (margaretha)
+	- added setting default scopes in the config file (margaretha)
+	- fixed loading spring config multiple times in the test suite (margaretha)
 	
 version 0.60.1
 28/03/2018
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
index b0da1f8..5fb08a8 100644
--- a/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
+++ b/full/src/main/java/de/ids_mannheim/korap/config/FullConfiguration.java
@@ -2,15 +2,20 @@
 
 import java.io.IOException;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Properties;
+import java.util.Set;
 import java.util.regex.Pattern;
+import java.util.stream.Collectors;
 
 import de.ids_mannheim.korap.constant.AuthenticationMethod;
 import de.ids_mannheim.korap.interfaces.EncryptionIface;
 
-/** Configuration for Kustvakt full version including properties concerning
- *  authentication and licenses. 
+/**
+ * Configuration for Kustvakt full version including properties
+ * concerning
+ * authentication and licenses.
  * 
  * @author margaretha
  *
@@ -49,6 +54,8 @@
 
     private AuthenticationMethod OAuth2passwordAuthentication;
     private String nativeClientHost;
+    private Set<String> accessScopes;
+    private int maxAuthenticationAttempts;
 
     public FullConfiguration (Properties properties) throws IOException {
         super(properties);
@@ -75,10 +82,19 @@
 
     private void setOAuth2Configuration (Properties properties) {
         setOAuth2passwordAuthentication(
-                Enum.valueOf(AuthenticationMethod.class, properties
-                        .getProperty("oauth.password.authentication", "TEST")));
-        setNativeClientHost(properties.getProperty("oauth.native.client.host",
+                Enum.valueOf(AuthenticationMethod.class, properties.getProperty(
+                        "oauth2.password.authentication", "TEST")));
+        setNativeClientHost(properties.getProperty("oauth2.native.client.host",
                 "korap.ids-mannheim.de"));
+
+        setMaxAuthenticationAttempts(Integer
+                .parseInt(properties.getProperty("oauth2.max.attempts", "3")));
+
+        String scopes = properties.getProperty("oauth2.default.scopes",
+                "read_username read_email");
+        Set<String> scopeSet =
+                Arrays.stream(scopes.split(" ")).collect(Collectors.toSet());
+        setAccessScopes(scopeSet);
     }
 
     private void setMailConfiguration (Properties properties) {
@@ -328,4 +344,20 @@
         this.nativeClientHost = nativeClientHost;
     }
 
+    public int getMaxAuthenticationAttempts () {
+        return maxAuthenticationAttempts;
+    }
+
+    public void setMaxAuthenticationAttempts (int maxAuthenticationAttempts) {
+        this.maxAuthenticationAttempts = maxAuthenticationAttempts;
+    }
+
+    public Set<String> getAccessScopes () {
+        return accessScopes;
+    }
+
+    public void setAccessScopes (Set<String> accessScopes) {
+        this.accessScopes = accessScopes;
+    }
+
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/config/Initializator.java b/full/src/main/java/de/ids_mannheim/korap/config/Initializator.java
new file mode 100644
index 0000000..e77f006
--- /dev/null
+++ b/full/src/main/java/de/ids_mannheim/korap/config/Initializator.java
@@ -0,0 +1,31 @@
+package de.ids_mannheim.korap.config;
+
+import java.util.Set;
+
+import de.ids_mannheim.korap.oauth2.dao.AccessScopeDao;
+
+/** Initializes values in the database from kustvakt configuration.
+ * 
+ * @author margaretha
+ *
+ */
+public class Initializator {
+
+    private FullConfiguration config;
+    private AccessScopeDao accessScopeDao;
+    
+
+    public Initializator (FullConfiguration config, AccessScopeDao accessScopeDao) {
+        this.config = config;
+        this.accessScopeDao = accessScopeDao;
+    }
+    
+    public void init () {
+        setAccessScope();
+    }
+    
+    private void setAccessScope(){
+        Set<String> accessScopes = config.getAccessScopes();
+        accessScopeDao.storeAccessScopes(accessScopes);
+    }
+}
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessScopeDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessScopeDao.java
index 492a529..29ab54f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessScopeDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/AccessScopeDao.java
@@ -1,6 +1,7 @@
 package de.ids_mannheim.korap.oauth2.dao;
 
 import java.util.List;
+import java.util.Set;
 
 import javax.persistence.EntityManager;
 import javax.persistence.PersistenceContext;
@@ -30,4 +31,17 @@
         Query q = entityManager.createQuery(query);
         return q.getResultList();
     }
+
+    public void storeAccessScopes (Set<String> scopes) {
+        List<AccessScope> existingScopes = retrieveAccessScopes();
+        AccessScope newScope;
+        for (String scope : scopes) {
+            newScope = new AccessScope(scope);
+            if (!existingScopes.contains(newScope)) {
+                entityManager.persist(newScope);
+            }
+            // else skip
+        }
+
+    }
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/AccessScope.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/AccessScope.java
index cc0e41a..29c94eb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/AccessScope.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/entity/AccessScope.java
@@ -4,8 +4,6 @@
 
 import javax.persistence.Entity;
 import javax.persistence.FetchType;
-import javax.persistence.GeneratedValue;
-import javax.persistence.GenerationType;
 import javax.persistence.Id;
 import javax.persistence.ManyToMany;
 import javax.persistence.Table;
@@ -20,22 +18,26 @@
 public class AccessScope {
 
     @Id
-    @GeneratedValue(strategy = GenerationType.IDENTITY)
-    private int id;
-    private String name;
+    private String id;
+
+    public AccessScope () {}
+
+    public AccessScope (String scope) {
+        this.id = scope;
+    }
 
     @ManyToMany(mappedBy = "scopes", fetch = FetchType.LAZY)
     private List<Authorization> authorizationCodes;
 
     @Override
     public String toString () {
-        return "id: " + id + ", name: " + name;
+        return "id: " + id;
     }
 
     @Override
     public boolean equals (Object obj) {
-        String scope = (String) obj;
-        if (scope.equals(this.name)) {
+        AccessScope scope = (AccessScope) obj;
+        if (scope.getId().equals(this.id)) {
             return true;
         }
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
index bb014e5..8b654a5 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2AuthorizationService.java
@@ -20,6 +20,7 @@
 import com.sun.jersey.api.client.ClientResponse.Status;
 
 import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.config.FullConfiguration;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
@@ -35,12 +36,10 @@
     private static Logger jlog =
             LoggerFactory.getLogger(OAuth2AuthorizationService.class);
 
-    public static int MAX_ATTEMPTS = 3;
-    
     @Autowired
     private OAuth2ClientService clientService;
     @Autowired
-    private OAuth2Service auth2Service;
+    private OAuth2TokenService auth2Service;
     @Autowired
     private OAuthIssuer oauthIssuer;
 
@@ -49,6 +48,9 @@
     @Autowired
     private AccessScopeDao accessScopeDao;
 
+    @Autowired
+    private FullConfiguration config;
+
     public OAuthResponse requestAuthorizationCode (HttpServletRequest request,
             OAuthAuthzRequest authzRequest, String authorization)
             throws KustvaktException, OAuthSystemException {
@@ -96,7 +98,7 @@
                 new HashSet<AccessScope>(scopes.size());
         int index;
         for (String scope : scopes) {
-            index = definedScopes.indexOf(scope);
+            index = definedScopes.indexOf(new AccessScope(scope));
             if (index == -1) {
                 throw new KustvaktException(StatusCodes.INVALID_SCOPE,
                         scope + " is invalid.", OAuth2Error.INVALID_SCOPE);
@@ -190,17 +192,17 @@
             throw new KustvaktException(StatusCodes.INVALID_REDIRECT_URI,
                     "Invalid redirect URI", OAuth2Error.INVALID_REQUEST);
         }
-        
+
         authorization.setRevoked(true);
         authorizationDao.updateAuthorization(authorization);
     }
 
     public void addTotalAttempts (Authorization authorization) {
         int totalAttempts = authorization.getTotalAttempts() + 1;
-        if (totalAttempts > MAX_ATTEMPTS){
+        if (totalAttempts > config.getMaxAuthenticationAttempts()) {
             authorization.setRevoked(true);
         }
-        else{
+        else {
             authorization.setTotalAttempts(totalAttempts);
         }
         authorizationDao.updateAuthorization(authorization);
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2Service.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
similarity index 99%
rename from full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2Service.java
rename to full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
index 07037ce..067ad81 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2Service.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2TokenService.java
@@ -27,7 +27,7 @@
 import de.ids_mannheim.korap.oauth2.entity.OAuth2Client;
 
 @Service
-public class OAuth2Service {
+public class OAuth2TokenService {
 
     @Autowired
     private OAuth2ClientService clientService;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
index ac219bc..791c226 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuth2Controller.java
@@ -25,7 +25,7 @@
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
-import de.ids_mannheim.korap.oauth2.service.OAuth2Service;
+import de.ids_mannheim.korap.oauth2.service.OAuth2TokenService;
 import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
 import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
 
@@ -36,7 +36,7 @@
     @Autowired
     private OAuth2ResponseHandler responseHandler;
     @Autowired
-    private OAuth2Service oAuth2Service;
+    private OAuth2TokenService oAuth2Service;
     @Autowired
     private OAuth2AuthorizationService authorizationService;
 
diff --git a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
index 28a5de2..a76e745 100644
--- a/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
+++ b/full/src/main/resources/db/new-sqlite/V1.4__oauth2_tables.sql
@@ -33,18 +33,17 @@
 CREATE UNIQUE INDEX authorization_index on oauth2_authorization(code, client_id);
 
 CREATE TABLE IF NOT EXISTS oauth2_access_scope (
-	id INTEGER PRIMARY KEY AUTOINCREMENT,
-	name VARCHAR(200) NOT NULL
+	id VARCHAR(200) PRIMARY KEY NOT NULL
 );
 
 CREATE TABLE IF NOT EXISTS oauth2_authorization_scope (
 	id INTEGER PRIMARY KEY AUTOINCREMENT,
 	authorization_id INTEGER NOT NULL,
-	scope_id INTEGER NOT NULL,
+	scope_id VARCHAR(200) NOT NULL,
 	FOREIGN KEY (authorization_id)
 	   REFERENCES oauth2_authorization(id),
 	FOREIGN KEY (scope_id)
-	   REFERENCES access_scope(id)
+	   REFERENCES oauth2_access_scope(id)
 );
 
 CREATE UNIQUE INDEX authorization_scope_index on 
diff --git a/full/src/main/resources/default-config.xml b/full/src/main/resources/default-config.xml
index 955d197..eef04e8 100644
--- a/full/src/main/resources/default-config.xml
+++ b/full/src/main/resources/default-config.xml
@@ -56,11 +56,6 @@
 		class='org.springframework.cache.ehcache.EhCacheManagerFactoryBean'
 		p:configLocation='classpath:ehcache.xml' p:shared='true' />
 
-	<!-- props are injected from default-config.xml -->
-	<bean id="kustvakt_config" class="de.ids_mannheim.korap.config.FullConfiguration">
-		<constructor-arg name="properties" ref="props" />
-	</bean>
-
 	<!--class="org.apache.commons.dbcp2.BasicDataSource" -->
 	<!-- org.springframework.jdbc.datasource.SingleConnectionDataSource -->
 	<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
@@ -163,7 +158,18 @@
 
 	<!-- Data access objects -->
 	<bean id="resourceDao" class="de.ids_mannheim.korap.dao.ResourceDao" />
-	<!-- <bean id="annotationDao" class="de.ids_mannheim.korap.dao.AnnotationDao"/> -->
+	<bean id="accessScopeDao" class="de.ids_mannheim.korap.oauth2.dao.AccessScopeDao" />
+
+	<!-- props are injected from default-config.xml -->
+	<bean id="kustvakt_config" class="de.ids_mannheim.korap.config.FullConfiguration">
+		<constructor-arg name="properties" ref="props" />
+	</bean>
+
+	<bean id="initializator" class="de.ids_mannheim.korap.config.Initializator"
+		init-method="init">
+		<constructor-arg name="config" ref="kustvakt_config" />
+		<constructor-arg name="accessScopeDao" ref="accessScopeDao" />
+	</bean>
 
 	<!-- Krill -->
 	<bean id="search_krill" class="de.ids_mannheim.korap.web.SearchKrill">
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
index 9173038..5c821e8 100644
--- a/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/config/SpringJerseyTest.java
@@ -3,9 +3,11 @@
 import java.util.concurrent.ThreadLocalRandom;
 
 import org.junit.runner.RunWith;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
 import org.springframework.test.context.ContextConfiguration;
 import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
-import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
 
 import com.sun.jersey.spi.spring.container.servlet.SpringServlet;
 import com.sun.jersey.test.framework.AppDescriptor;
@@ -19,6 +21,9 @@
 @ContextConfiguration("classpath:test-config.xml")
 public abstract class SpringJerseyTest extends JerseyTest {
 
+    @Autowired
+    protected ApplicationContext applicationContext;
+
     private static String[] classPackages =
             new String[] { "de.ids_mannheim.korap.web.controller",
                     "de.ids_mannheim.korap.web.filter",
@@ -33,9 +38,13 @@
 
     @Override
     protected AppDescriptor configure () {
+
+        StaticContextLoaderListener.applicationContext =
+                (WebApplicationContext) applicationContext;
+
         return new WebAppDescriptor.Builder(classPackages)
                 .servletClass(SpringServlet.class)
-                .contextListenerClass(ContextLoaderListener.class)
+                .contextListenerClass(StaticContextLoaderListener.class)
                 .contextParam("contextConfigLocation",
                         "classpath:test-config.xml")
                 .build();
@@ -45,4 +54,5 @@
     protected int getPort (int defaultPort) {
         return ThreadLocalRandom.current().nextInt(5000, 8000 + 1);
     }
+
 }
diff --git a/full/src/test/java/de/ids_mannheim/korap/config/StaticContextLoaderListener.java b/full/src/test/java/de/ids_mannheim/korap/config/StaticContextLoaderListener.java
new file mode 100644
index 0000000..578c94e
--- /dev/null
+++ b/full/src/test/java/de/ids_mannheim/korap/config/StaticContextLoaderListener.java
@@ -0,0 +1,22 @@
+package de.ids_mannheim.korap.config;
+
+import org.springframework.web.context.ContextLoaderListener;
+import org.springframework.web.context.WebApplicationContext;
+
+/**
+ * A hack to inject the application context generated by
+ * SpringJUnit4ClassRunner in the test suite.
+ * 
+ * @author margaretha
+ *
+ */
+public class StaticContextLoaderListener extends ContextLoaderListener {
+
+    public static WebApplicationContext applicationContext;
+
+    public StaticContextLoaderListener () {
+        super(applicationContext);
+    }
+
+
+}
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
index 835284b..92461ad 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2ControllerTest.java
@@ -11,7 +11,6 @@
 
 import org.apache.http.entity.ContentType;
 import org.apache.oltu.oauth2.common.error.OAuthError;
-import org.apache.oltu.oauth2.common.message.types.GrantType;
 import org.apache.oltu.oauth2.common.message.types.TokenType;
 import org.junit.Test;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -35,7 +34,7 @@
 
     @Autowired
     private HttpAuthorizationHandler handler;
-
+    
     private ClientResponse requestAuthorizationConfidentialClient (
             MultivaluedMap<String, String> form) throws KustvaktException {
 
diff --git a/full/src/test/resources/test-config.xml b/full/src/test/resources/test-config.xml
index 8f0d54f..964487a 100644
--- a/full/src/test/resources/test-config.xml
+++ b/full/src/test/resources/test-config.xml
@@ -51,11 +51,6 @@
 		class='org.springframework.cache.ehcache.EhCacheManagerFactoryBean'
 		p:configLocation='classpath:ehcache.xml' p:shared='true' />
 
-	<!-- props are injected from default-config.xml -->
-	<bean id="kustvakt_config" class="de.ids_mannheim.korap.config.FullConfiguration">
-		<constructor-arg name="properties" ref="props" />
-	</bean>
-
 	<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"
 		lazy-init="true">
 		<!-- <property name="driverClassName" value="${jdbc.driverClassName}" /> -->
@@ -163,7 +158,19 @@
 
 	<!-- Data access objects -->
 	<bean id="resourceDao" class="de.ids_mannheim.korap.dao.ResourceDao" />
-	<!-- <bean id="annotationDao" class="de.ids_mannheim.korap.dao.AnnotationDao"/> -->
+	<bean id="accessScopeDao" class="de.ids_mannheim.korap.oauth2.dao.AccessScopeDao" />
+
+	<!-- props are injected from default-config.xml -->
+	<bean id="kustvakt_config" class="de.ids_mannheim.korap.config.FullConfiguration">
+		<constructor-arg name="properties" ref="props" />
+	</bean>
+
+	<bean id="initializator" class="de.ids_mannheim.korap.config.Initializator"
+		init-method="init">
+		<constructor-arg name="config" ref="kustvakt_config" />
+		<constructor-arg name="accessScopeDao" ref="accessScopeDao" />
+	</bean>
+
 
 	<!-- Krill -->
 	<bean id="search_krill" class="de.ids_mannheim.korap.web.SearchKrill">