Implemented deregister public client task.

Change-Id: I6ad6c54ff1c44d5313b8cf23bdddf42230c213cd
diff --git a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
index 94ad319..21b3e2a 100644
--- a/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
+++ b/full/src/main/java/de/ids_mannheim/korap/dao/OAuth2ClientDao.java
@@ -27,8 +27,8 @@
     private EntityManager entityManager;
 
     public void registerClient (String id, String secret, String name,
-            OAuth2ClientType type, String url, String redirectURI,
-            String registeredBy) throws KustvaktException {
+            OAuth2ClientType type, String url, int urlHashCode,
+            String redirectURI, String registeredBy) throws KustvaktException {
         ParameterChecker.checkStringValue(id, "client id");
         ParameterChecker.checkStringValue(name, "client name");
         ParameterChecker.checkObjectValue(type, "client type");
@@ -42,9 +42,9 @@
         client.setSecret(secret);
         client.setType(type);
         client.setUrl(url);
+        client.setUrlHashCode(urlHashCode);
         client.setRedirectURI(redirectURI);
         client.setRegisteredBy(registeredBy);
-
         entityManager.persist(client);
     }
 
@@ -69,5 +69,11 @@
         }
     }
 
+    public void deregisterClient (OAuth2Client client) {
+        if (!entityManager.contains(client)) {
+            client = entityManager.merge(client);
+        }
+        entityManager.remove(client);
+    }
 
 }
diff --git a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
index 9d91d93..c6d179f 100644
--- a/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
+++ b/full/src/main/java/de/ids_mannheim/korap/entity/OAuth2Client.java
@@ -28,6 +28,8 @@
     @Enumerated(EnumType.STRING)
     private OAuth2ClientType type;
     private String url;
+    @Column(name = "url_hashcode")
+    private int urlHashCode;
     @Column(name = "redirect_uri")
     private String redirectURI;
     private String registeredBy;
diff --git a/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java b/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
index 828d61e..04736b0 100644
--- a/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
+++ b/full/src/main/java/de/ids_mannheim/korap/handlers/OAuthDb.java
@@ -249,7 +249,7 @@
             jlog.error("removing client '{}' failed", info.getClient_id());
             throw new DatabaseException(new KustvaktException(user.getId(),
                     StatusCodes.ILLEGAL_ARGUMENT, "arguments given not valid",
-                    info.toJSON()), StatusCodes.CLIENT_REMOVAL_FAILURE,
+                    info.toJSON()), StatusCodes.CLIENT_DEREGISTRATION_FAILED,
                     info.toJSON());
 
         }
diff --git a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
index ec146fd..75d09fb 100644
--- a/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
+++ b/full/src/main/java/de/ids_mannheim/korap/service/OAuth2ClientService.java
@@ -1,5 +1,7 @@
 package de.ids_mannheim.korap.service;
 
+import java.sql.SQLException;
+
 import org.apache.commons.validator.routines.UrlValidator;
 import org.apache.oltu.oauth2.common.message.types.GrantType;
 import org.springframework.beans.factory.annotation.Autowired;
@@ -9,6 +11,7 @@
 import de.ids_mannheim.korap.authentication.http.HttpAuthorizationHandler;
 import de.ids_mannheim.korap.constant.AuthenticationScheme;
 import de.ids_mannheim.korap.constant.OAuth2ClientType;
+import de.ids_mannheim.korap.dao.AdminDao;
 import de.ids_mannheim.korap.dao.OAuth2ClientDao;
 import de.ids_mannheim.korap.dto.OAuth2ClientDto;
 import de.ids_mannheim.korap.entity.OAuth2Client;
@@ -24,12 +27,15 @@
     @Autowired
     private OAuth2ClientDao clientDao;
     @Autowired
+    private AdminDao adminDao;
+    @Autowired
     private UrlValidator urlValidator;
     @Autowired
     private EncryptionIface encryption;
     @Autowired
     private HttpAuthorizationHandler authorizationHandler;
 
+
     public OAuth2ClientDto registerClient (OAuth2ClientJson clientJson,
             String registeredBy) throws KustvaktException {
         if (!urlValidator.isValid(clientJson.getUrl())) {
@@ -48,19 +54,49 @@
         }
 
         String id = encryption.createRandomNumber();
-
-        clientDao.registerClient(id, secret, clientJson.getName(),
-                clientJson.getType(), clientJson.getUrl(),
-                clientJson.getRedirectURI(), registeredBy);
+        try {
+            clientDao.registerClient(id, secret, clientJson.getName(),
+                    clientJson.getType(), clientJson.getUrl(),
+                    clientJson.getUrl().hashCode(), clientJson.getRedirectURI(),
+                    registeredBy);
+        }
+        catch (Exception e) {
+            Throwable cause = e;
+            Throwable lastCause = null;
+            while ((cause = cause.getCause()) != null
+                    && !cause.equals(lastCause)) {
+                if (cause instanceof SQLException) {
+                    throw new KustvaktException(
+                            StatusCodes.CLIENT_REGISTRATION_FAILED,
+                            cause.getMessage(), cause);
+                }
+                lastCause = cause;
+            }
+        }
 
         return new OAuth2ClientDto(id, secret);
     }
 
 
-    public OAuth2ClientDto deregisterClient (String clientId, String username) {
+    public void deregisterClient (String clientId, String username)
+            throws KustvaktException {
 
-
-        return null;
+        OAuth2Client client = clientDao.retrieveClientById(clientId);
+        if (adminDao.isAdmin(username)) {
+            clientDao.deregisterClient(client);
+        }
+        else if (client.getType().equals(OAuth2ClientType.CONFIDENTIAL)) {
+            throw new KustvaktException(
+                    StatusCodes.CLIENT_DEREGISTRATION_FAILED,
+                    "Service is limited to public clients.");
+        }
+        else if (client.getRegisteredBy().equals(username)) {
+            clientDao.deregisterClient(client);
+        }
+        else {
+            throw new KustvaktException(StatusCodes.AUTHORIZATION_FAILED,
+                    "Unauthorized operation for user: " + username, username);
+        }
     }
 
 
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 d766537..a770e0f 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
@@ -1,11 +1,14 @@
 package de.ids_mannheim.korap.web.controller;
 
 import javax.ws.rs.Consumes;
+import javax.ws.rs.DELETE;
+import javax.ws.rs.FormParam;
 import javax.ws.rs.POST;
 import javax.ws.rs.Path;
 import javax.ws.rs.Produces;
 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.springframework.beans.factory.annotation.Autowired;
@@ -64,45 +67,44 @@
     }
 
 
-    //    /** Deregisters a client via owner authentication. 
-    //     * 
-    //     * EM: who can deregister clients? The user registered the clients or the client itself?
-    //     * 
-    //     * @param securityContext
-    //     * @param clientId
-    //     * @return HTTP Response OK if successful.
-    //     */
-    //    @POST
-    //    @Path("deregister")
-    //    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
-    //    @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
-    //    public OAuth2ClientDto deregisterClient (
-    //            @Context SecurityContext securityContext,
-    //            @FormParam("client_id") String clientId) {
-    //        TokenContext context =
-    //                (TokenContext) securityContext.getUserPrincipal();
-    //        try {
-    //            return clientService.deregisterClient(clientId,
-    //                    context.getUsername());
-    //        }
-    //        catch (KustvaktException e) {
-    //            throw responseHandler.throwit(e);
-    //        }
-    //    }
-    //
-    //    @POST
-    //    @Path("deregister")
-    //    @ResourceFilters({ OAuth2ClientAuthenticationFilter.class,
-    //            BlockingFilter.class })
-    //    public OAuth2ClientDto deregisterClient (
-    //            @Context SecurityContext securityContext) {
-    //        TokenContext context =
-    //                (TokenContext) securityContext.getUserPrincipal();
-    //        try {
-    //            return clientService.deregisterClient();
-    //        }
-    //        catch (KustvaktException e) {
-    //            throw responseHandler.throwit(e);
-    //        }
-    //    }
+    /** Deregisters a public client via owner authentication.
+     * 
+     * 
+     * @param securityContext
+     * @param clientId the client id
+     * @return HTTP Response OK if successful.
+     */
+    @DELETE
+    @Path("deregister")
+    @Consumes(MediaType.APPLICATION_FORM_URLENCODED)
+    @ResourceFilters({ AuthenticationFilter.class, BlockingFilter.class })
+    public Response deregisterClient (
+            @Context SecurityContext securityContext,
+            @FormParam("client_id") String clientId) {
+        TokenContext context =
+                (TokenContext) securityContext.getUserPrincipal();
+        try {
+            clientService.deregisterClient(clientId,
+                    context.getUsername());
+            return Response.ok().build();
+        }
+        catch (KustvaktException e) {
+            throw responseHandler.throwit(e);
+        }
+    }
+    
+
+//    @POST
+//    @Path("deregister")
+//    public OAuth2ClientDto deregisterClient (
+//            @Context SecurityContext securityContext) {
+//        TokenContext context =
+//                (TokenContext) securityContext.getUserPrincipal();
+//        try {
+//            return clientService.deregisterClient();
+//        }
+//        catch (KustvaktException e) {
+//            throw responseHandler.throwit(e);
+//        }
+//    }
 }