This is an automated email from the ASF dual-hosted git repository.

pzampino pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/knox.git


The following commit(s) were added to refs/heads/master by this push:
     new 9ee06f3  KNOX-2396 - TokenResource Renew and Revoke Should Respond 
With Error Codes That Identify Specific Errors (#480)
9ee06f3 is described below

commit 9ee06f3b6b0695afbeb02fe133871ec66600cd0b
Author: Attila Magyar <[email protected]>
AuthorDate: Wed Aug 25 05:55:36 2021 +0200

    KNOX-2396 - TokenResource Renew and Revoke Should Respond With Error Codes 
That Identify Specific Errors (#480)
---
 .../gateway/service/knoxtoken/TokenResource.java   | 43 ++++++++++++++++++++--
 .../knoxtoken/TokenServiceResourceTest.java        | 36 +++++++++++-------
 2 files changed, 62 insertions(+), 17 deletions(-)

diff --git 
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
 
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
index 244cbe9..7bc84e4 100644
--- 
a/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
+++ 
b/gateway-service-knoxtoken/src/main/java/org/apache/knox/gateway/service/knoxtoken/TokenResource.java
@@ -155,6 +155,27 @@ public class TokenResource {
   @Context
   ServletContext context;
 
+  public enum ErrorCode {
+    UNKNOWN(0),
+    CONFIGURATION_ERROR(10),
+    UNAUTHORIZED(20),
+    INTERNAL_ERROR(30),
+    INVALID_TOKEN(40),
+    UNKNOWN_TOKEN(50),
+    ALREADY_DISABLED(60),
+    ALREADY_ENABLED(70);
+
+    private final int code;
+
+    ErrorCode(int code) {
+      this.code = code;
+    }
+
+    public int toInt() {
+      return code;
+    }
+  }
+
   @PostConstruct
   public void init() throws AliasServiceException, ServiceLifecycleException, 
KeyLengthException {
 
@@ -393,6 +414,7 @@ public class TokenResource {
     long expiration = 0;
 
     String          error       = "";
+    ErrorCode       errorCode   = ErrorCode.UNKNOWN;
     Response.Status errorStatus = Response.Status.BAD_REQUEST;
 
     if (tokenStateService == null) {
@@ -406,8 +428,10 @@ public class TokenResource {
       } catch (ParseException e) {
         log.invalidToken(getTopologyName(), Tokens.getTokenDisplayText(token), 
e);
         error = safeGetMessage(e);
+        errorCode = ErrorCode.INVALID_TOKEN;
       } catch (Exception e) {
         error = safeGetMessage(e);
+        errorCode = ErrorCode.INTERNAL_ERROR;
       }
     } else {
       String renewer = SubjectUtils.getCurrentEffectivePrincipalName();
@@ -423,13 +447,16 @@ public class TokenResource {
                            renewer);
         } catch (ParseException e) {
           log.invalidToken(getTopologyName(), 
Tokens.getTokenDisplayText(token), e);
+          errorCode = ErrorCode.INVALID_TOKEN;
           error = safeGetMessage(e);
         } catch (Exception e) {
           error = safeGetMessage(e);
+          errorCode = ErrorCode.INTERNAL_ERROR;
         }
       } else {
         errorStatus = Response.Status.FORBIDDEN;
         error = "Caller (" + renewer + ") not authorized to renew tokens.";
+        errorCode = ErrorCode.UNAUTHORIZED;
       }
     }
 
@@ -440,7 +467,7 @@ public class TokenResource {
     } else {
       log.badRenewalRequest(getTopologyName(), 
Tokens.getTokenDisplayText(token), error);
       resp = Response.status(errorStatus)
-                     .entity("{\n  \"renewed\": \"false\",\n  \"error\": \"" + 
error + "\"\n}\n")
+                     .entity("{\n  \"renewed\": \"false\",\n  \"error\": \"" + 
error + "\",\n  \"code\": " + errorCode.toInt() + "\n}\n")
                      .build();
     }
 
@@ -454,10 +481,12 @@ public class TokenResource {
     Response resp;
 
     String          error       = "";
+    ErrorCode       errorCode   = ErrorCode.UNKNOWN;
     Response.Status errorStatus = Response.Status.BAD_REQUEST;
 
     if (tokenStateService == null) {
       error = "Token revocation support is not configured";
+      errorCode = ErrorCode.CONFIGURATION_ERROR;
     } else {
       String renewer = SubjectUtils.getCurrentEffectivePrincipalName();
       if (allowedRenewers.contains(renewer)) {
@@ -471,12 +500,15 @@ public class TokenResource {
         } catch (ParseException e) {
           log.invalidToken(getTopologyName(), 
Tokens.getTokenDisplayText(token), e);
           error = safeGetMessage(e);
+          errorCode = ErrorCode.INVALID_TOKEN;
         } catch (UnknownTokenException e) {
           error = safeGetMessage(e);
+          errorCode = ErrorCode.UNKNOWN_TOKEN;
         }
       } else {
         errorStatus = Response.Status.FORBIDDEN;
         error = "Caller (" + renewer + ") not authorized to revoke tokens.";
+        errorCode = ErrorCode.UNAUTHORIZED;
       }
     }
 
@@ -487,7 +519,7 @@ public class TokenResource {
     } else {
       log.badRevocationRequest(getTopologyName(), 
Tokens.getTokenDisplayText(token), error);
       resp = Response.status(errorStatus)
-                     .entity("{\n  \"revoked\": \"false\",\n  \"error\": \"" + 
error + "\"\n}\n")
+                     .entity("{\n  \"revoked\": \"false\",\n  \"error\": \"" + 
error + "\",\n  \"code\": " + errorCode.toInt() + "\n}\n")
                      .build();
     }
 
@@ -526,28 +558,33 @@ public class TokenResource {
 
   private Response setTokenEnabledFlag(String tokenId, boolean enabled) {
     String error = "";
+    ErrorCode errorCode = ErrorCode.UNKNOWN;
     if (tokenStateService == null) {
       error = "Unable to " + (enabled ? "enable" : "disable") + " tokens 
because token management is not configured";
+      errorCode = ErrorCode.CONFIGURATION_ERROR;
     } else {
       try {
         final TokenMetadata tokenMetadata = 
tokenStateService.getTokenMetadata(tokenId);
         if (enabled && tokenMetadata.isEnabled()) {
           error = "Token is already enabled";
+          errorCode = ErrorCode.ALREADY_ENABLED;
         } else if (!enabled && !tokenMetadata.isEnabled()) {
           error = "Token is already disabled";
+          errorCode = ErrorCode.ALREADY_DISABLED;
         } else {
           tokenMetadata.setEnabled(enabled);
           tokenStateService.addMetadata(tokenId, tokenMetadata);
         }
       } catch (UnknownTokenException e) {
         error = safeGetMessage(e);
+        errorCode = ErrorCode.UNKNOWN_TOKEN;
       }
     }
     if (error.isEmpty()) {
       return Response.status(Response.Status.OK).entity("{\n  
\"setEnabledFlag\": \"true\",\n  \"isEnabled\": \"" + enabled + 
"\"\n}\n").build();
     } else {
       log.badSetEnabledFlagRequest(getTopologyName(), 
Tokens.getTokenIDDisplayText(tokenId), error);
-      return Response.status(Response.Status.BAD_REQUEST).entity("{\n  
\"setEnabledFlag\": \"false\",\n  \"error\": \"" + error + "\"\n}\n").build();
+      return Response.status(Response.Status.BAD_REQUEST).entity("{\n  
\"setEnabledFlag\": \"false\",\n  \"error\": \"" + error + "\",\n  \"code\": " 
+ errorCode.toInt() + "\n}\n").build();
     }
   }
 
diff --git 
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
 
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
index 0069212..a0fded1 100644
--- 
a/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
+++ 
b/gateway-service-knoxtoken/src/test/java/org/apache/knox/gateway/service/knoxtoken/TokenServiceResourceTest.java
@@ -684,7 +684,7 @@ public class TokenServiceResourceTest {
   @Test
   public void testTokenRenewal_Enabled_NoRenewersNoSubject() throws Exception {
     Response renewalResponse = doTestTokenRenewal(true, null, null);
-    validateRenewalResponse(renewalResponse, 403, false, "Caller (null) not 
authorized to renew tokens.");
+    validateRenewalResponse(renewalResponse, 403, false, "Caller (null) not 
authorized to renew tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -694,7 +694,7 @@ public class TokenServiceResourceTest {
     validateRenewalResponse(renewalResponse,
                             403,
                             false,
-                            "Caller (" + caller + ") not authorized to renew 
tokens.");
+                            "Caller (" + caller + ") not authorized to renew 
tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -703,7 +703,7 @@ public class TokenServiceResourceTest {
     validateRenewalResponse(renewalResponse,
                             403,
                             false,
-                            "Caller (null) not authorized to renew tokens.");
+                            "Caller (null) not authorized to renew tokens.", 
TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -713,7 +713,7 @@ public class TokenServiceResourceTest {
     validateRenewalResponse(renewalResponse,
                             403,
                             false,
-                            "Caller (" + caller + ") not authorized to renew 
tokens.");
+                            "Caller (" + caller + ") not authorized to renew 
tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -764,7 +764,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                400,
                                false,
-                               "Token revocation support is not configured");
+                               "Token revocation support is not configured", 
TokenResource.ErrorCode.CONFIGURATION_ERROR);
   }
 
   @Test
@@ -773,7 +773,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                400,
                                false,
-                               "Token revocation support is not configured");
+                               "Token revocation support is not configured", 
TokenResource.ErrorCode.CONFIGURATION_ERROR);
   }
 
   @Test
@@ -782,7 +782,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                403,
                                false,
-                               "Caller (null) not authorized to revoke 
tokens.");
+                               "Caller (null) not authorized to revoke 
tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -792,7 +792,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                403,
                                false,
-                               "Caller (" + caller + ") not authorized to 
revoke tokens.");
+                               "Caller (" + caller + ") not authorized to 
revoke tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -801,7 +801,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                403,
                                false,
-                               "Caller (null) not authorized to revoke 
tokens.");
+                               "Caller (null) not authorized to revoke 
tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -811,7 +811,7 @@ public class TokenServiceResourceTest {
     validateRevocationResponse(renewalResponse,
                                403,
                                false,
-                               "Caller (" + caller + ") not authorized to 
revoke tokens.");
+                               "Caller (" + caller + ") not authorized to 
revoke tokens.", TokenResource.ErrorCode.UNAUTHORIZED);
   }
 
   @Test
@@ -1220,13 +1220,14 @@ public class TokenServiceResourceTest {
   }
 
   private static void validateSuccessfulRenewalResponse(final Response 
response) throws IOException {
-    validateRenewalResponse(response, 200, true, null);
+    validateRenewalResponse(response, 200, true, null, null);
   }
 
   private static void validateRenewalResponse(final Response response,
                                               final int      
expectedStatusCode,
                                               final boolean  expectedResult,
-                                              final String   expectedMessage) 
throws IOException {
+                                              final String   expectedMessage,
+                                              final TokenResource.ErrorCode 
expectedCode) throws IOException {
     assertEquals(expectedStatusCode, response.getStatus());
     assertTrue(response.hasEntity());
     String responseContent = (String) response.getEntity();
@@ -1236,16 +1237,20 @@ public class TokenServiceResourceTest {
     boolean result = Boolean.valueOf(json.get("renewed"));
     assertEquals(expectedResult, result);
     assertEquals(expectedMessage, json.get("error"));
+    if (expectedCode != null) {
+      assertEquals(expectedCode.toInt(), Integer.parseInt(json.get("code")));
+    }
   }
 
   private static void validateSuccessfulRevocationResponse(final Response 
response) throws IOException {
-    validateRevocationResponse(response, 200, true, null);
+    validateRevocationResponse(response, 200, true, null, null);
   }
 
   private static void validateRevocationResponse(final Response response,
                                                  final int      
expectedStatusCode,
                                                  final boolean  expectedResult,
-                                                 final String   
expectedMessage) throws IOException {
+                                                 final String   
expectedMessage,
+                                                 final TokenResource.ErrorCode 
expectedCode) throws IOException {
     assertEquals(expectedStatusCode, response.getStatus());
     assertTrue(response.hasEntity());
     String responseContent = (String) response.getEntity();
@@ -1255,6 +1260,9 @@ public class TokenServiceResourceTest {
     boolean result = Boolean.valueOf(json.get("revoked"));
     assertEquals(expectedResult, result);
     assertEquals(expectedMessage, json.get("error"));
+    if (expectedCode != null) {
+      assertEquals(expectedCode.toInt(), Integer.parseInt(json.get("code")));
+    }
   }
 
 

Reply via email to