Handled super client id in plugin installation

Change-Id: Ice83e06c0dd8c8742f2fc60eeb765b12777833ed
diff --git a/full/Changes b/full/Changes
index 3dd1d7f..f5b9476 100644
--- a/full/Changes
+++ b/full/Changes
@@ -8,7 +8,7 @@
  - Added installed_plugins table
  - Added a new API: install plugin 
  - Handled redundant plugin installation
- 
+ - Handled super client id in plugin installation
 
 # version 0.67.1
 
@@ -47,7 +47,7 @@
  - Updated authorization error response. (Included error and error 
    description in the client redirect URI except for missing or 
    invalid client id or redirect URI.
- 
+
  
 # version 0.65.2
 
diff --git a/full/src/main/java/de/ids_mannheim/korap/dto/InstalledPluginDto.java b/full/src/main/java/de/ids_mannheim/korap/dto/InstalledPluginDto.java
index 3cef4c6..1c9943f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dto/InstalledPluginDto.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dto/InstalledPluginDto.java
@@ -13,7 +13,10 @@
 @Getter
 @JsonInclude(Include.NON_EMPTY)
 public class InstalledPluginDto {
-    private String client_id; // oauth2 client id
+    @JsonProperty("client_id")
+    private String clientId; // oauth2 client id
+    @JsonProperty("super_client_id")
+    private String superClientId;
     private String name;
     private String description;
     private String url;
@@ -22,7 +25,8 @@
     
     public InstalledPluginDto (InstalledPlugin plugin) {
         OAuth2Client client = plugin.getClient();
-        setClient_id(client.getId());
+        setClientId(client.getId());
+        setSuperClientId(plugin.getSuperClient().getId());
         setInstalledDate(plugin.getInstalledDate().toString());
         setName(client.getName());
         setDescription(client.getDescription());
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/InstalledPlugin.java b/full/src/main/java/de/ids_mannheim/korap/entity/InstalledPlugin.java
index 1aef8b6..b49b1b4 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/InstalledPlugin.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/InstalledPlugin.java
@@ -33,4 +33,9 @@
     @ManyToOne(fetch = FetchType.EAGER)
     @JoinColumn(name = "client_id")
     private OAuth2Client client;
+    
+    // where a plugin is installed
+    @ManyToOne(fetch = FetchType.LAZY)
+    @JoinColumn(name = "super_client_id")
+    private OAuth2Client superClient;
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/InstalledPluginDao.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/InstalledPluginDao.java
index 284c0fd..46ac078 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/InstalledPluginDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/dao/InstalledPluginDao.java
@@ -31,8 +31,8 @@
     @PersistenceContext
     private EntityManager entityManager;
 
-    public InstalledPlugin storeUserPlugin (OAuth2Client client,
-            String installedBy) throws KustvaktException {
+    public InstalledPlugin storeUserPlugin (OAuth2Client superClient,
+            OAuth2Client client, String installedBy) throws KustvaktException {
         ParameterChecker.checkStringValue(installedBy, "installed_by");
 
         InstalledPlugin p = new InstalledPlugin();
@@ -40,12 +40,14 @@
         p.setInstalledDate(
                 ZonedDateTime.now(ZoneId.of(Attributes.DEFAULT_TIME_ZONE)));
         p.setClient(client);
+        p.setSuperClient(superClient);
         entityManager.persist(p);
         return p;
     }
 
-    public InstalledPlugin retrieveInstalledPlugin (String clientId,
-            String installedBy) throws KustvaktException {
+    public InstalledPlugin retrieveInstalledPlugin (String superClientId,
+            String clientId, String installedBy) throws KustvaktException {
+        ParameterChecker.checkStringValue(superClientId, "super_client_id");
         ParameterChecker.checkStringValue(clientId, "client_id");
         ParameterChecker.checkStringValue(installedBy, "installedBy");
 
@@ -56,11 +58,15 @@
         Root<InstalledPlugin> root = query.from(InstalledPlugin.class);
         Join<InstalledPlugin, OAuth2Client> client =
                 root.join(InstalledPlugin_.client);
+        Join<InstalledPlugin, OAuth2Client> superClient =
+                root.join(InstalledPlugin_.superClient);
         query.select(root);
         query.where(builder.and(
                 builder.equal(root.get(InstalledPlugin_.INSTALLED_BY),
                         installedBy),
-                builder.equal(client.get(OAuth2Client_.id), clientId)));
+                builder.equal(client.get(OAuth2Client_.id), clientId),
+                builder.equal(superClient.get(OAuth2Client_.id),
+                        superClientId)));
 
         Query q = entityManager.createQuery(query);
         try {
diff --git a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
index 9e319f8..078219a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/oauth2/service/OAuth2ClientService.java
@@ -391,8 +391,8 @@
         return createClientDtos(plugins);
     }
     
-    public InstalledPluginDto installPlugin (String clientId,
-            String installedBy) throws KustvaktException {
+    public InstalledPluginDto installPlugin (String superClientId,
+            String clientId, String installedBy) throws KustvaktException {
         if (clientId == null || clientId.isEmpty()) {
             throw new KustvaktException(StatusCodes.MISSING_PARAMETER,
                     "Missing parameter: client_id");
@@ -403,21 +403,24 @@
                     "Plugin is not permitted", clientId);
         }
         
-        if (isPluginInstalled(clientId,installedBy)) {
+        if (isPluginInstalled(superClientId,clientId,installedBy)) {
             throw new KustvaktException(StatusCodes.PLUGIN_HAS_BEEN_INSTALLED,
                     "Plugin has been installed", clientId);
         }
         
+        OAuth2Client superClient = clientDao.retrieveClientById(superClientId);
         InstalledPlugin plugin =
-                pluginDao.storeUserPlugin(client, installedBy);
+                pluginDao.storeUserPlugin(superClient, client, installedBy);
         
         InstalledPluginDto dto = new InstalledPluginDto(plugin);
         return dto;
     }
 
-    private boolean isPluginInstalled (String clientId, String installedBy) {
+    private boolean isPluginInstalled (String superClientId, String clientId,
+            String installedBy) {
         try {
-            pluginDao.retrieveInstalledPlugin(clientId, installedBy);
+            pluginDao.retrieveInstalledPlugin(superClientId, clientId,
+                    installedBy);
         }
         catch (KustvaktException e) {
             return false;
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
index bbd013a..e8f634b 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/controller/OAuthClientController.java
@@ -275,7 +275,7 @@
                     OAuth2Scope.INSTALL_USER_CLIENT);
 
             clientService.verifySuperClient(superClientId, superClientSecret);
-            return clientService.installPlugin(clientId, username);
+            return clientService.installPlugin(superClientId,clientId, username);
         }
         catch (KustvaktException e) {
             throw responseHandler.throwit(e);
diff --git a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2PluginTest.java b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2PluginTest.java
index 55f7dbb..ff63cc1 100644
--- a/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2PluginTest.java
+++ b/full/src/test/java/de/ids_mannheim/korap/web/controller/OAuth2PluginTest.java
@@ -9,6 +9,7 @@
 
 import org.apache.http.entity.ContentType;
 import org.junit.Test;
+import org.springframework.beans.factory.annotation.Autowired;
 
 import com.fasterxml.jackson.databind.JsonNode;
 import com.google.common.net.HttpHeaders;
@@ -20,16 +21,21 @@
 
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.config.Attributes;
+import de.ids_mannheim.korap.entity.InstalledPlugin;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.oauth2.constant.OAuth2ClientType;
 import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
+import de.ids_mannheim.korap.oauth2.dao.InstalledPluginDao;
 import de.ids_mannheim.korap.utils.JsonUtils;
 import de.ids_mannheim.korap.web.input.OAuth2ClientJson;
 
 public class OAuth2PluginTest extends OAuth2TestBase {
 
     private String username = "plugin-user";
+    @Autowired
+    private InstalledPluginDao pluginDao;
+    
 
     @Test
     public void testRegisterPlugin () throws UniformInterfaceException,
@@ -233,12 +239,17 @@
         String entity = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(confidentialClientId2, node.at("/client_id").asText());
+        assertEquals(superClientId, node.at("/super_client_id").asText());
+        
         assertFalse(node.at("/name").isMissingNode());
         assertFalse(node.at("/description").isMissingNode());
         assertFalse(node.at("/url").isMissingNode());
         assertFalse(node.at("/installed_date").isMissingNode());
-        
+
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
+        
+        testRetrieveInstalledPlugin(superClientId, confidentialClientId2,
+                username);
     }
     
     @Test
@@ -251,6 +262,8 @@
         String entity = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
         assertEquals(publicClientId2, node.at("/client_id").asText());
+        assertEquals(superClientId, node.at("/super_client_id").asText());
+        
         assertFalse(node.at("/name").isMissingNode());
         assertFalse(node.at("/description").isMissingNode());
         assertFalse(node.at("/url").isMissingNode());
@@ -259,6 +272,9 @@
         assertEquals(Status.OK.getStatusCode(), response.getStatus());
         
         testInstallPluginRedundant(form);
+        
+        testRetrieveInstalledPlugin(superClientId, publicClientId2,
+                username);
     }
     
     private void testInstallPluginRedundant (
@@ -329,17 +345,18 @@
     }
     
     @Test
-    public void testInstallPluginMissingSuperClientId () throws UniformInterfaceException,
-            ClientHandlerException, KustvaktException {
+    public void testInstallPluginMissingSuperClientId ()
+            throws UniformInterfaceException, ClientHandlerException,
+            KustvaktException {
         MultivaluedMap<String, String> form = new MultivaluedMapImpl();
         ClientResponse response = installPlugin(form);
         String entity = response.getEntity(String.class);
         JsonNode node = JsonUtils.readTree(entity);
-        
+
         assertEquals("Missing parameter: super_client_id",
                 node.at("/error_description").asText());
         assertEquals("invalid_request", node.at("/error").asText());
-        
+
         assertEquals(Status.BAD_REQUEST.getStatusCode(), response.getStatus());
     }
     
@@ -370,4 +387,16 @@
                         ContentType.APPLICATION_FORM_URLENCODED)
                 .entity(form).post(ClientResponse.class);
     }
+    
+    private void testRetrieveInstalledPlugin (String superClientId,
+            String clientId, String installedBy) throws KustvaktException {
+        InstalledPlugin plugin = pluginDao
+                .retrieveInstalledPlugin(superClientId, clientId, installedBy);
+        assertEquals(clientId, plugin.getClient().getId());
+        assertEquals(superClientId, plugin.getSuperClient().getId());
+        assertEquals(installedBy, plugin.getInstalledBy());
+        
+        assertTrue(plugin.getId()>0);
+        assertTrue(plugin.getInstalledDate()!= null);
+    }
 }