Implemented OAuth2 request access token with authorization code grant.

Change-Id: Ia3c427316748876db65373b31ea453bb71f9448b
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java b/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
index 0d31236..f134c79 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/OAuth2ResponseHandler.java
@@ -17,52 +17,19 @@
 import de.ids_mannheim.korap.exceptions.KustvaktException;
 import de.ids_mannheim.korap.exceptions.StatusCodes;
 import de.ids_mannheim.korap.interfaces.db.AuditingIface;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2Error;
 
-/** OAuth2ResponseHandler builds {@link Response}s from 
- * {@link OAuthResponse}s and handles exceptions by building 
- * OAuth error responses accordingly. 
+/**
+ * OAuth2ResponseHandler builds {@link Response}s from
+ * {@link OAuthResponse}s and handles exceptions by building
+ * OAuth error responses accordingly.
  * 
  * <br/><br/>
  * 
- * OAuth2 error response consists of error (required), 
+ * OAuth2 error response consists of error (required),
  * error_description (optional) and error_uri (optional).
  * 
- * According to RFC 6749, error indicates error code 
- * categorized into:
- * <ul>
- * <li>invalid_request: The request is missing a required parameter, 
- * includes an unsupported parameter value (other than grant type),
- * repeats a parameter, includes multiple credentials, utilizes 
- * more than one mechanism for authenticating the client, or is 
- * otherwise malformed.</li>
- * 
- * <li>invalid_client: Client authentication failed (e.g., unknown 
- * client, no client authentication included, or unsupported 
- * authentication method).  The authorization sever MAY return 
- * an HTTP 401 (Unauthorized) status code to indicate which 
- * HTTP authentication schemes are supported. If the client 
- * attempted to authenticate via the "Authorization" request 
- * header field, the authorization server MUST respond with 
- * an HTTP 401 (Unauthorized) status code and include 
- * the "WWW-Authenticate" response header field matching 
- * the authentication scheme used by the client</li>
- * 
- * <li>invalid_grant: The provided authorization grant 
- * (e.g., authorization code, resource owner credentials) or 
- * refresh token is invalid, expired, revoked, does not match 
- * the redirection URI used in the authorization request, or 
- * was issued to another client.</li>
- * 
- * <li>unauthorized_client:The authenticated client is not 
- * authorized to use this authorization grant type.</li>
- * 
- * <li>unsupported_grant_type: The authorization grant type 
- * is not supported by the authorization server.</li>
- * 
- * <li>invalid_scope: The requested scope is invalid, unknown, 
- * malformed, or exceeds the scope granted by the resource owner.</li>
- * </ul>
- * 
+ * @see OAuth2Error
  * 
  * @author margaretha
  *
@@ -95,21 +62,32 @@
         OAuthResponse oAuthResponse = null;
         String errorCode = e.getEntity();
         try {
-            if (errorCode.equals(OAuthError.TokenResponse.INVALID_CLIENT)
-                    || errorCode.equals(
-                            OAuthError.TokenResponse.UNAUTHORIZED_CLIENT)) {
+            if (errorCode.equals(OAuth2Error.INVALID_CLIENT)
+                    || errorCode.equals(OAuth2Error.UNAUTHORIZED_CLIENT)
+                    || errorCode.equals(OAuth2Error.INVALID_TOKEN)) {
                 oAuthResponse = createOAuthResponse(e,
                         Status.UNAUTHORIZED.getStatusCode());
             }
-            else if (errorCode.equals(OAuthError.TokenResponse.INVALID_GRANT)
-                    || errorCode
-                            .equals(OAuthError.TokenResponse.INVALID_REQUEST)
-                    || errorCode.equals(OAuthError.TokenResponse.INVALID_SCOPE)
-                    || errorCode.equals(
-                            OAuthError.TokenResponse.UNSUPPORTED_GRANT_TYPE)) {
+            else if (errorCode.equals(OAuth2Error.INVALID_GRANT)
+                    || errorCode.equals(OAuth2Error.INVALID_REQUEST)
+                    || errorCode.equals(OAuth2Error.INVALID_SCOPE)
+                    || errorCode.equals(OAuth2Error.UNSUPPORTED_GRANT_TYPE)
+                    || errorCode.equals(OAuth2Error.UNSUPPORTED_RESPONSE_TYPE)
+                    || errorCode.equals(OAuth2Error.ACCESS_DENIED)) {
                 oAuthResponse = createOAuthResponse(e,
                         Status.BAD_REQUEST.getStatusCode());
-
+            }
+            else if (errorCode.equals(OAuth2Error.INSUFFICIENT_SCOPE)) {
+                oAuthResponse = createOAuthResponse(e,
+                        Status.FORBIDDEN.getStatusCode());
+            }
+            else if (errorCode.equals(OAuth2Error.SERVER_ERROR)) {
+                oAuthResponse = createOAuthResponse(e,
+                        Status.INTERNAL_SERVER_ERROR.getStatusCode());
+            }
+            else if (errorCode.equals(OAuth2Error.TEMPORARILY_UNAVAILABLE)) {
+                oAuthResponse = createOAuthResponse(e,
+                        Status.SERVICE_UNAVAILABLE.getStatusCode());
             }
             else {
                 return super.throwit(e);
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 b0699b1..ac219bc 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
@@ -24,8 +24,8 @@
 import org.springframework.stereotype.Controller;
 
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.service.OAuth2AuthorizationService;
-import de.ids_mannheim.korap.service.OAuth2Service;
+import de.ids_mannheim.korap.oauth2.service.OAuth2AuthorizationService;
+import de.ids_mannheim.korap.oauth2.service.OAuth2Service;
 import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
 import de.ids_mannheim.korap.web.utils.FormRequestWrapper;
 
@@ -40,15 +40,26 @@
     @Autowired
     private OAuth2AuthorizationService authorizationService;
 
-    /** Kustvakt supports authorization only with Kalamar as the authorization 
-     * web-frontend or user interface. Thus authorization code request requires
-     * user credentials in the request body, similar to access token request in
-     * resource owner password grant request. 
+    /**
+     * Requests an authorization code.
      * 
-     * @param request
-     * @param authorization
-     * @param form
-     * @return
+     * Kustvakt supports authorization only with Kalamar as the
+     * authorization web-frontend or user interface. Thus
+     * authorization code request requires user credentials in the
+     * request body, similar to access token request in
+     * resource owner password grant request.
+     * 
+     * <br /><br />
+     * RFC 6749:
+     * If the client omits the scope parameter when requesting
+     * authorization, the authorization server MUST either process the
+     * request using a pre-defined default value or fail the request
+     * indicating an invalid scope.
+     * 
+     * @param request HttpServletRequest
+     * @param authorization authorization header
+     * @param form form parameters
+     * @return a redirect URL
      */
     @POST
     @Path("authorize")
@@ -81,16 +92,50 @@
     }
 
 
-    /** Grants a client an access token, namely a string used in authenticated 
-     *  requests representing user authorization for the client to access user 
-     *  resources. 
+    /**
+     * Grants a client an access token, namely a string used in
+     * authenticated requests representing user authorization for
+     * the client to access user resources.
      * 
-     * @param request the request
-     * @param authorization authorization header
-     * @param form form parameters in a map
-     * @return a JSON object containing an access token, a refresh token, 
-     *  a token type and token expiry/life time (in seconds) if successful, 
-     *  an error code and an error description otherwise.
+     * <br /><br />
+     * 
+     * OAuth2 describes various ways of requesting an access token.
+     * Kustvakt supports:
+     * <ul>
+     * <li> Authorization code grant: obtains authorization from a
+     * third party application. Required parameters: grant_type,
+     * code, client_id, redirect_uri (if specified in the
+     * authorization request), client_secret (if the client is
+     * confidential or issued a secret).
+     * </li>
+     * <li> Resource owner password grant: strictly for clients that
+     * are parts of KorAP. Clients use user credentials, e.g. Kalamar
+     * (front-end) with login form. Required parameters: grant_type,
+     * username, password, client_id, client_secret (if the client is
+     * confidential or issued a secret). Optional parameters: scope.
+     * </li>
+     * <li> Client credentials grant: strictly for clients that are
+     * parts of KorAP. Clients access their own resources, not on
+     * behalf of a user. Required parameters: grant_type, client_id,
+     * client_secret. Optional parameters: scope.
+     * </li>
+     * </ul>
+     * 
+     * <br /><br />
+     * RFC 6749: The value of the scope parameter is expressed as a
+     * list of space-delimited, case-sensitive strings defined by the
+     * authorization server.
+     * 
+     * @param request
+     *            the request
+     * @param authorization
+     *            authorization header
+     * @param form
+     *            form parameters in a map
+     * @return a JSON object containing an access token, a refresh
+     *         token, a token type and the token expiration in seconds
+     *         if successful, an error code and an error description
+     *         otherwise.
      */
     @POST
     @Path("token")
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 39b93b7..05c0bd0 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
@@ -23,9 +23,9 @@
 
 import de.ids_mannheim.korap.dto.OAuth2ClientDto;
 import de.ids_mannheim.korap.exceptions.KustvaktException;
-import de.ids_mannheim.korap.oauth.OAuthDeregisterClientRequest;
+import de.ids_mannheim.korap.oauth2.OAuth2DeregisterClientRequest;
+import de.ids_mannheim.korap.oauth2.service.OAuth2ClientService;
 import de.ids_mannheim.korap.security.context.TokenContext;
-import de.ids_mannheim.korap.service.OAuth2ClientService;
 import de.ids_mannheim.korap.web.OAuth2ResponseHandler;
 import de.ids_mannheim.korap.web.filter.AuthenticationFilter;
 import de.ids_mannheim.korap.web.filter.BlockingFilter;
@@ -122,7 +122,7 @@
             @Context HttpServletRequest request,
             MultivaluedMap<String, String> form) {
         try {
-            OAuthRequest oAuthRequest = new OAuthDeregisterClientRequest(
+            OAuthRequest oAuthRequest = new OAuth2DeregisterClientRequest(
                     new FormRequestWrapper(request, form));
 
             clientService.deregisterConfidentialClient(oAuthRequest);
diff --git a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
index 99705e8..cec1806 100644
--- a/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
+++ b/full/src/main/java/de/ids_mannheim/korap/web/input/OAuth2ClientJson.java
@@ -1,6 +1,6 @@
 package de.ids_mannheim.korap.web.input;
 
-import de.ids_mannheim.korap.constant.OAuth2ClientType;
+import de.ids_mannheim.korap.oauth2.constant.OAuth2ClientType;
 import lombok.Getter;
 import lombok.Setter;