From cad70347041f308a3a0eb9afdb23253e9fd29e45 Mon Sep 17 00:00:00 2001 From: Jim Ewald Date: Fri, 7 Sep 2018 16:34:45 -0700 Subject: [PATCH 1/5] Add logging to account confirmation process. --- .../CloudSessionLocalUserService.java | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java index 353ac7a..32d3059 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java @@ -226,20 +226,28 @@ public boolean doConfirm(String email, String token) throws UnknownUserException, WrongAuthenticationSourceException, ServerException { + + String response = null; + String cloudSessionUri = null; try { Map data = new HashMap<>(); data.put("email", email); data.put("token", token); - HttpRequest request = HttpRequest.post( - getUrl(URI_CONFIRM_ACCOUNT)).form(data); + cloudSessionUri = getUrl(URI_CONFIRM_ACCOUNT); + + LOG.info("Requesting from Cloud Session server: '{}'", cloudSessionUri); + + HttpRequest request = HttpRequest.post(cloudSessionUri).form(data); // Get response from Cloud Session server - String response = request.body(); + response = request.body(); if (response == null) { throw new ServerException("No response from server."); } + + LOG.info("Cloud Session says: '{}'", response); JsonElement jelement = new JsonParser().parse(response); JsonObject responseObject = jelement.getAsJsonObject(); @@ -266,7 +274,7 @@ public boolean doConfirm(String email, String token) throw new ServerException(hre); } catch (JsonSyntaxException jse) { - LOG.error("Json syntace service error", jse); + LOG.error("Json syntax error", jse.getMessage()); throw new ServerException(jse); } } From b01498069b1452a03ef94fdcb59c350f6b33daca Mon Sep 17 00:00:00 2001 From: Jim Ewald Date: Fri, 7 Sep 2018 16:54:08 -0700 Subject: [PATCH 2/5] The /local/confirm endpoint does not require a trailing slash. In fact the trailing slash breaks that URI. --- .../client/cloudsession/CloudSessionLocalUserService.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java index 32d3059..6ff067b 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java @@ -64,7 +64,7 @@ public class CloudSessionLocalUserService { // REST endpoint URI constants private final String URI_PASSWORD_RESET = "/local/reset/"; - private final String URI_CONFIRM_ACCOUNT = "/local/confirm/"; + private final String URI_CONFIRM_ACCOUNT = "/local/confirm"; private final String URI_PASSWORD_SET = "/local/password/"; /** @@ -298,7 +298,7 @@ public boolean requestNewConfirmEmail(String email) try { HttpRequest request = HttpRequest.get( - getUrl(URI_CONFIRM_ACCOUNT + email)).header("server", SERVER); + getUrl(URI_CONFIRM_ACCOUNT + "/" + email)).header("server", SERVER); // Get response from Cloud Session server String response = request.body(); From c1be9dd98f7714d9ffe9bd6e61adbf603e731960 Mon Sep 17 00:00:00 2001 From: Jim Ewald Date: Mon, 10 Sep 2018 10:38:02 -0700 Subject: [PATCH 3/5] Add check for HTTP response code before attempting a JSON decode. --- pom.xml | 17 +- .../CloudSessionAuthenticateService.java | 16 +- ...loudSessionAuthenticationTokenService.java | 125 +++++++---- .../cloudsession/CloudSessionUserService.java | 206 ++++++++++++------ 4 files changed, 241 insertions(+), 123 deletions(-) diff --git a/pom.xml b/pom.xml index 2ad0fa6..93b2d4a 100644 --- a/pom.xml +++ b/pom.xml @@ -19,31 +19,42 @@ 4.12 test - org.mockito mockito-core 1.10.19 test - + + org.slf4j slf4j-api 1.7.6 + + org.slf4j + slf4j-log4j13 + 1.0.1 + + + com.github.kevinsawicki http-request 6.0 + + + com.google.code.gson gson - 2.3.1 + 2.8.5 + compile diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java index 757a943..47581fb 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java @@ -84,7 +84,7 @@ public User authenticateLocalUser(String login, String password) WrongAuthenticationSourceException, ServerException { - LOG.debug("Attempting to authenticate user: {}", login); + LOG.info("Contacting endpoint '/authenticate/local"); try { Map data = new HashMap<>(); @@ -92,24 +92,21 @@ public User authenticateLocalUser(String login, String password) data.put("password", password); // Issue POST request to attempt login - HttpRequest httpRequest = HttpRequest + HttpRequest request = HttpRequest .post(getUrl("/authenticate/local")) .header("server", SERVER) .form(data); - // Convert response from login attempt - String response = httpRequest.body(); - - LOG.debug("Received a response: {}", response); - + if (request.ok()) { + String response = request.body(); JsonElement jelement = new JsonParser().parse(response); JsonObject responseObject = jelement.getAsJsonObject(); if (responseObject.get("success").getAsBoolean()) { // Create and return a user object JsonObject userJson = responseObject.get("user").getAsJsonObject(); - User user = new User(); + User user = new User(); user.setId(userJson.get("id").getAsLong()); user.setEmail(userJson.get("email").getAsString()); user.setLocale(userJson.get("locale").getAsString()); @@ -154,6 +151,7 @@ public User authenticateLocalUser(String login, String password) LOG.warn("Unexpected error: {}", response); return null; } + } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); @@ -161,6 +159,8 @@ public User authenticateLocalUser(String login, String password) LOG.error("Json syntax error", jse); throw new ServerException(jse); } + + return null; } /** diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticationTokenService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticationTokenService.java index 7ec3f5c..d1f2165 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticationTokenService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticationTokenService.java @@ -6,19 +6,23 @@ package com.parallax.client.cloudsession; import com.github.kevinsawicki.http.HttpRequest; + import com.google.gson.JsonArray; import com.google.gson.JsonElement; import com.google.gson.JsonObject; import com.google.gson.JsonParser; import com.google.gson.JsonSyntaxException; + import com.parallax.client.cloudsession.exceptions.EmailNotConfirmedException; import com.parallax.client.cloudsession.exceptions.ServerException; import com.parallax.client.cloudsession.exceptions.UnknownUserIdException; import com.parallax.client.cloudsession.exceptions.UserBlockedException; + import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; + import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -29,6 +33,7 @@ public class CloudSessionAuthenticationTokenService { private final Logger LOG = LoggerFactory.getLogger(CloudSessionAuthenticationTokenService.class); + private final String BASE_URL; private final String SERVER; @@ -57,31 +62,44 @@ private String getUrl(String actionUrl) { * @throws EmailNotConfirmedException * @throws ServerException */ - public String request(Long idUser, String browser, String ipAddress) throws UnknownUserIdException, UserBlockedException, EmailNotConfirmedException, ServerException { + public String request(Long idUser, String browser, String ipAddress) throws + UnknownUserIdException, + UserBlockedException, + EmailNotConfirmedException, + ServerException { + + LOG.debug("Contacting endpoint '/authtoken/request"); + try { Map data = new HashMap<>(); data.put("idUser", String.valueOf(idUser)); data.put("browser", browser); data.put("ipAddress", ipAddress); - HttpRequest request = HttpRequest.post(getUrl("/authtoken/request")).header("server", SERVER).form(data); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return responseObject.get("token").getAsString(); - } else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserIdException(responseObject.get("data").getAsString()); - case 420: - throw new UserBlockedException(); - case 430: - throw new EmailNotConfirmedException(); - } + + HttpRequest request = HttpRequest + .post(getUrl("/authtoken/request")) + .header("server", SERVER) + .form(data); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + return responseObject.get("token").getAsString(); + } else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserIdException(responseObject.get("data").getAsString()); + case 420: + throw new UserBlockedException(); + case 430: + throw new EmailNotConfirmedException(); + } + return null; + } } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -90,7 +108,10 @@ public String request(Long idUser, String browser, String ipAddress) throws Unkn LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return null; } + /** * @@ -102,23 +123,31 @@ public String request(Long idUser, String browser, String ipAddress) throws Unkn * @throws ServerException */ public boolean doConfirm(String token, Long idUser, String browser, String ipAddress) throws ServerException { + + LOG.debug("Contacting endpoint '/authtoken/confirm"); + try { Map data = new HashMap<>(); data.put("token", token); data.put("idUser", String.valueOf(idUser)); data.put("browser", browser); data.put("ipAddress", ipAddress); - HttpRequest request = HttpRequest.post(getUrl("/authtoken/confirm")).header("server", SERVER).form(data); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return true; - } else { - return false; + + HttpRequest request = HttpRequest + .post(getUrl("/authtoken/confirm")) + .header("server", SERVER) + .form(data); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + return true; + } else { + return false; + } } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -127,8 +156,11 @@ public boolean doConfirm(String token, Long idUser, String browser, String ipAdd LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return false; } + /** * * @param idUser @@ -138,22 +170,31 @@ public boolean doConfirm(String token, Long idUser, String browser, String ipAdd * @throws ServerException */ public List getTokens(Long idUser, String browser, String ipAddress) throws ServerException { + + LOG.debug("Contacting endpoint '/authtoken/tokens"); + try { Map data = new HashMap<>(); data.put("browser", browser); data.put("ipAddress", ipAddress); - HttpRequest request = HttpRequest.post(getUrl("/authtoken/tokens/" + idUser)).header("server", SERVER).form(data); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonArray jsonTokens = jelement.getAsJsonArray(); - List tokens = new ArrayList<>(); - for (JsonElement token : jsonTokens) { - tokens.add(token.getAsString()); + + HttpRequest request = HttpRequest + .post(getUrl("/authtoken/tokens/" + idUser)) + .header("server", SERVER) + .form(data); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonArray jsonTokens = jelement.getAsJsonArray(); + List tokens = new ArrayList<>(); + + for (JsonElement token : jsonTokens) { + tokens.add(token.getAsString()); + } + + return tokens; } - return tokens; } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); @@ -161,6 +202,8 @@ public List getTokens(Long idUser, String browser, String ipAddress) thr LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return null; } } diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionUserService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionUserService.java index 492de14..5c68948 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionUserService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionUserService.java @@ -23,21 +23,29 @@ /** * Provide user account services for existing local user accounts + *

+ * Each public method will return a JSON document if the call is successful; + * a null if the call is unsuccessful but the cause is not anticipated; or + * the method will throw an exception of a failure that was anticipated. * * @author Michel */ public class CloudSessionUserService { + /** * */ private final Logger LOG = LoggerFactory.getLogger(CloudSessionUserService.class); + /** - * + * A string that provides the 'protocol://host.example.com' */ private final String BASE_URL; + + /** * * @param baseUrl @@ -56,37 +64,51 @@ public CloudSessionUserService(String baseUrl) { * @throws ServerException */ public User getUser(String email) throws UnknownUserException, ServerException { + + LOG.debug("Contacting endpoint '/user/email/{email}"); + try { HttpRequest request = HttpRequest.get(getUrl("/user/email/" + email)); - String response = request.body(); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); + + if (request.ok()) { + // Process the JSON response message + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - // Verify that we have a valid response object - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - return populateUser(userJson); - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException(email, message); - default: - throw new ServerException("Unknown response code."); + // Verify that the we have a 'success' message + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + return populateUser(userJson); + } else { + // Parse the embedded error message + String message = responseObject.get("message").getAsString(); + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException(email, message); + default: + throw new ServerException("Unknown response code."); + } } + } else { + LOG.error("Unable to contact Cloud Session endpoint '/user/email/', Code: {}", request.code()); + return null; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); + } catch (JsonSyntaxException jse) { LOG.error("Json syntax service error", jse); throw new ServerException(jse); + } catch (java.lang.NullPointerException npe) { LOG.error("Null pointer detected. Maybe we didn't get a valid Response object. Msg: ", npe); return null; } } + /** * Retrieve a user record with a matching screen name * @@ -96,25 +118,30 @@ public User getUser(String email) throws UnknownUserException, ServerException { * @throws ServerException */ public User getUserByScreenname(String screenname) throws UnknownUserException, ServerException { + + LOG.debug("Contacting endpoint '/user/screenname/{name}"); + try { HttpRequest request = HttpRequest.get(getUrl("/user/screenname/" + screenname)); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - return populateUser(userJson); - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + return populateUser(userJson); + } else { + String message = responseObject.get("message").getAsString(); + if (responseObject.get("code").getAsInt() == 400) { throw new UnknownUserException(screenname, message); + } else { + return null; + } } - return null; } + } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); @@ -122,8 +149,11 @@ public User getUserByScreenname(String screenname) throws UnknownUserException, LOG.error("Json syntax service error", jse); throw new ServerException(jse); } + + return null; } + /** * Retrieve a user record from the user ID key * @@ -133,20 +163,27 @@ public User getUserByScreenname(String screenname) throws UnknownUserException, * @throws ServerException */ public User getUser(Long idUser) throws UnknownUserIdException, ServerException { + + LOG.debug("Contacting endpoint '/user/id/{uid}"); + try { HttpRequest request = HttpRequest.get(getUrl("/user/id/" + idUser)); - String response = request.body(); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - return populateUser(userJson); - } else { - switch (responseObject.get("code").getAsInt()) { - case 400: + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + return populateUser(userJson); + } else { + if (responseObject.get("code").getAsInt() == 400) { throw new UnknownUserIdException(idUser); + } + + return null; } - return null; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -155,8 +192,11 @@ public User getUser(Long idUser) throws UnknownUserIdException, ServerException LOG.error("Json syntax service error", jse); throw new ServerException(jse); } + + return null; } + /** * Set user screen name on user record keyed on the user ID * @@ -169,39 +209,48 @@ public User getUser(Long idUser) throws UnknownUserIdException, ServerException */ public User changeUserInfo(Long idUser, String screenname) throws UnknownUserIdException, ScreennameUsedException, ServerException { + + LOG.debug("Contacting endpoint '/user/info/{uid}"); try { + // Set data that is being sent to the server Map data = new HashMap<>(); data.put("screenname", screenname); + HttpRequest request = HttpRequest.post(getUrl("/user/info/" + idUser)).form(data); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - return populateUser(userJson); - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserIdException(idUser, message); - case 500: - throw new ScreennameUsedException(responseObject.get("data").getAsString()); - } + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + return populateUser(userJson); + } else { + String message = responseObject.get("message").getAsString(); + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserIdException(idUser, message); + case 500: + throw new ScreennameUsedException(responseObject.get("data").getAsString()); + } + return null; + } } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); + } catch (JsonSyntaxException jse) { LOG.error("Json syntax service error", jse); throw new ServerException(jse); } + + return null; } + /** * Update the locale on the user record keyed on the user ID * @@ -212,26 +261,33 @@ public User changeUserInfo(Long idUser, String screenname) * @throws ServerException */ public User changeUserLocale(Long idUser, String locale) throws UnknownUserIdException, ServerException { + + LOG.debug("Contacting endpoint '/user/locale/{uid}"); + try { + Map data = new HashMap<>(); data.put("locale", locale); HttpRequest request = HttpRequest.post(getUrl("/user/locale/" + idUser)).form(data); - String response = request.body(); - - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - return populateUser(userJson); - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserIdException(idUser, message); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + return populateUser(userJson); + } else { + String message = responseObject.get("message").getAsString(); + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserIdException(idUser, message); + } + + return null; } - return null; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -240,12 +296,21 @@ public User changeUserLocale(Long idUser, String locale) throws UnknownUserIdExc LOG.error("Json syntax service error", jse); throw new ServerException(jse); } + + return null; } private String getUrl(String actionUrl) { return BASE_URL + actionUrl; } + + /** + * Populate an user object from a JSON document + * + * @param userJson + * @return + */ private User populateUser(JsonObject userJson) { User user = new User(); @@ -271,5 +336,4 @@ private User populateUser(JsonObject userJson) { return user; } - } From 4d66f5260f440625f2ee73bcc00a2b879bb7f35f Mon Sep 17 00:00:00 2001 From: Jim Ewald Date: Tue, 11 Sep 2018 07:53:50 -0700 Subject: [PATCH 4/5] Refactor additional classes to check HTTP status code before attempting to decode JSON payload. --- .../CloudSessionAuthenticateService.java | 2 + .../CloudSessionBucketService.java | 54 ++-- .../CloudSessionLocalUserService.java | 270 +++++++++--------- .../CloudSessionOAuthService.java | 108 ++++--- 4 files changed, 234 insertions(+), 200 deletions(-) diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java index 47581fb..1736bcb 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionAuthenticateService.java @@ -39,11 +39,13 @@ public class CloudSessionAuthenticateService { */ private final Logger LOG = LoggerFactory.getLogger(CloudSessionAuthenticateService.class); + /** * Base URL use to obtain authentication service. */ private final String BASE_URL; + /** * Host name */ diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionBucketService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionBucketService.java index a8054a6..817c49a 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionBucketService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionBucketService.java @@ -35,6 +35,7 @@ public class CloudSessionBucketService { public CloudSessionBucketService(String baseUrl) { this.BASE_URL = baseUrl; } + /** * Inform the Cloud Session service to decrement the token count for @@ -61,6 +62,7 @@ public boolean consumeOne(String type, Long id) throws ServerException { HttpRequest request = HttpRequest.get(getUrl("/bucket/consume/" + type + "/" + id)); + return handleResponse(type, id, request); } @@ -119,40 +121,44 @@ protected boolean handleResponse(String type, Long id, HttpRequest request) thro ServerException { try { - String response = request.body(); - - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return true; - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserIdException(id, message); - case 420: - throw new UserBlockedException(message); - case 430: - throw new EmailNotConfirmedException(message); - case 470: - // Rate exceeded - no tokens are left in the bucket - String nextTime = responseObject.get("data").getAsString(); - LOG.info("Compile bucket empty. Time to next token is:", nextTime); + if (responseObject.get("success").getAsBoolean()) { + return true; + } else { + String message = responseObject.get("message").getAsString(); + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserIdException(id, message); + case 420: + throw new UserBlockedException(message); + case 430: + throw new EmailNotConfirmedException(message); + case 470: + // Rate exceeded - no tokens are left in the bucket + String nextTime = responseObject.get("data").getAsString(); + LOG.info("Compile bucket empty. Time to next token is:", nextTime); - throw new InsufficientBucketTokensException(message, nextTime); - case 480: - throw new UnknownBucketTypeException(type, message); - } + throw new InsufficientBucketTokensException(message, nextTime); + case 480: + throw new UnknownBucketTypeException(type, message); + } + return false; + } } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); + } catch (JsonSyntaxException jse) { LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return false; } - } diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java index 6ff067b..8431d4b 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionLocalUserService.java @@ -98,12 +98,12 @@ public boolean doPasswordReset( String token, String email, String password, - String passwordConfirm) - throws UnknownUserException, - PasswordVerifyException, - PasswordComplexityException, - WrongAuthenticationSourceException, - ServerException { + String passwordConfirm) throws + UnknownUserException, + PasswordVerifyException, + PasswordComplexityException, + WrongAuthenticationSourceException, + ServerException { try { // Create a key-value pair structure to send to the endpoint @@ -116,32 +116,30 @@ public boolean doPasswordReset( HttpRequest request = HttpRequest.post( getUrl(URI_PASSWORD_RESET + email)).form(data); - // Get response from Cloud Session server - String response = request.body(); - if (response == null) { - throw new ServerException("No response from server."); - } - - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); + if (request.ok()) { + // Get response from Cloud Session server + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return true; - } - else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException( - responseObject.get("data").getAsString()); - case 460: - throw new PasswordVerifyException(); - case 490: - throw new PasswordComplexityException(); - case 480: - throw new WrongAuthenticationSourceException( - responseObject.get("data").getAsString()); + if (responseObject.get("success").getAsBoolean()) { + return true; + } + else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException( + responseObject.get("data").getAsString()); + case 460: + throw new PasswordVerifyException(); + case 490: + throw new PasswordComplexityException(); + case 480: + throw new WrongAuthenticationSourceException( + responseObject.get("data").getAsString()); + } + return false; } - return false; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -151,6 +149,8 @@ public boolean doPasswordReset( LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return false; } /** @@ -172,32 +172,30 @@ public boolean requestPasswordReset(String email) HttpRequest request = HttpRequest.get( getUrl(URI_PASSWORD_RESET + email)).header("server", SERVER); - // Get response from Cloud Session server - String response = request.body(); - if (response == null) { - throw new ServerException("No response from server."); - } + if (request.ok()) { + // Get response from Cloud Session server + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - - if (responseObject.get("success").getAsBoolean()) { - return true; - } - else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException( - responseObject.get("data").getAsString()); - case 470: - throw new InsufficientBucketTokensException( - responseObject.get("message").getAsString(), - responseObject.get("data").getAsString()); - case 480: - throw new WrongAuthenticationSourceException( - responseObject.get("data").getAsString()); + if (responseObject.get("success").getAsBoolean()) { + return true; + } + else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException( + responseObject.get("data").getAsString()); + case 470: + throw new InsufficientBucketTokensException( + responseObject.get("message").getAsString(), + responseObject.get("data").getAsString()); + case 480: + throw new WrongAuthenticationSourceException( + responseObject.get("data").getAsString()); + } + return false; } - return false; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -211,6 +209,8 @@ public boolean requestPasswordReset(String email) LOG.error("Encountered a Null Pointer exception."); throw new ServerException(npe); } + + return false; } /** @@ -241,33 +241,29 @@ public boolean doConfirm(String email, String token) HttpRequest request = HttpRequest.post(cloudSessionUri).form(data); - // Get response from Cloud Session server - response = request.body(); - if (response == null) { - throw new ServerException("No response from server."); - } - - LOG.info("Cloud Session says: '{}'", response); - - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); + if (request.ok()) { + // Get response from Cloud Session server + response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return true; - } - else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException( - responseObject.get("data").getAsString()); - case 480: - throw new WrongAuthenticationSourceException( - responseObject.get("data").getAsString()); - case 510: - // The submitted token has expired or was not found - return false; + if (responseObject.get("success").getAsBoolean()) { + return true; + } + else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException( + responseObject.get("data").getAsString()); + case 480: + throw new WrongAuthenticationSourceException( + responseObject.get("data").getAsString()); + case 510: + // The submitted token has expired or was not found + return false; + } + return false; } - return false; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); @@ -277,6 +273,8 @@ public boolean doConfirm(String email, String token) LOG.error("Json syntax error", jse.getMessage()); throw new ServerException(jse); } + + return false; } /** @@ -300,43 +298,43 @@ public boolean requestNewConfirmEmail(String email) HttpRequest request = HttpRequest.get( getUrl(URI_CONFIRM_ACCOUNT + "/" + email)).header("server", SERVER); - // Get response from Cloud Session server - String response = request.body(); - if (response == null) { - throw new ServerException("No response from server."); - } - - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); + if (request.ok()) { + // Get response from Cloud Session server + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return true; - } - else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException( - responseObject.get("data").getAsString()); - case 470: - throw new InsufficientBucketTokensException( - responseObject.get("message").getAsString(), - responseObject.get("data").getAsString()); - case 480: - throw new WrongAuthenticationSourceException( - responseObject.get("data").getAsString()); - case 520: - throw new EmailAlreadyConfirmedException( - responseObject.get("message").getAsString()); - case 540: - throw new ServerException ( - responseObject.get("message").getAsString()); + if (responseObject.get("success").getAsBoolean()) { + return true; + } + else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException( + responseObject.get("data").getAsString()); + case 470: + throw new InsufficientBucketTokensException( + responseObject.get("message").getAsString(), + responseObject.get("data").getAsString()); + case 480: + throw new WrongAuthenticationSourceException( + responseObject.get("data").getAsString()); + case 520: + throw new EmailAlreadyConfirmedException( + responseObject.get("message").getAsString()); + case 540: + throw new ServerException ( + responseObject.get("message").getAsString()); + } + return false; } - return false; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); } + + return false; } /** @@ -372,40 +370,40 @@ public boolean changePassword( HttpRequest request = HttpRequest.post( getUrl(URI_PASSWORD_SET + idUser)).form(data); - // Get response from Cloud Session server - String response = request.body(); - if (response == null) { - throw new ServerException("No response from server."); - } + if (request.ok()) { + // Get response from Cloud Session server + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - - if (responseObject.get("success").getAsBoolean()) { - return true; - } - else { - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserIdException( - responseObject.get("data").getAsString()); - case 460: - throw new PasswordVerifyException(); - case 480: - throw new WrongAuthenticationSourceException( - responseObject.get("data").getAsString()); - case 490: - throw new PasswordComplexityException(); - case 510: - // The submitted token has expired or was not found - return false; + if (responseObject.get("success").getAsBoolean()) { + return true; + } + else { + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserIdException( + responseObject.get("data").getAsString()); + case 460: + throw new PasswordVerifyException(); + case 480: + throw new WrongAuthenticationSourceException( + responseObject.get("data").getAsString()); + case 490: + throw new PasswordComplexityException(); + case 510: + // The submitted token has expired or was not found + return false; + } + return false; } - return false; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); } + + return false; } // Helper function to build a complete URL diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionOAuthService.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionOAuthService.java index 20e1e04..e716246 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionOAuthService.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionOAuthService.java @@ -39,9 +39,9 @@ public class CloudSessionOAuthService { public CloudSessionOAuthService(String server, String baseUrl) { this.SERVER = server; this.BASE_URL = baseUrl; - } + /** * * @param login @@ -56,38 +56,48 @@ public User validateUser(String login, String authenticationSource) throws Unkno Map data = new HashMap<>(); data.put("email", login); data.put("source", authenticationSource); - HttpRequest httpRequest = HttpRequest.post(getUrl("/oauth/validate")).header("server", SERVER).form(data); - String response = httpRequest.body(); + + HttpRequest request = HttpRequest + .post(getUrl("/oauth/validate")) + .header("server", SERVER).form(data); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + JsonObject userJson = responseObject.get("user").getAsJsonObject(); + User user = new User(); + user.setId(userJson.get("id").getAsLong()); + user.setEmail(userJson.get("email").getAsString()); + user.setLocale(userJson.get("locale").getAsString()); + user.setScreenname(userJson.get("screenname").getAsString()); + return user; + } else { + String message = responseObject.get("message").getAsString(); + switch (responseObject.get("code").getAsInt()) { + case 400: + throw new UnknownUserException(login, message); + case 480: + String userAuthenticationSource = responseObject.get("data").getAsString(); + throw new WrongAuthenticationSourceException(userAuthenticationSource); + } - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - JsonObject userJson = responseObject.get("user").getAsJsonObject(); - User user = new User(); - user.setId(userJson.get("id").getAsLong()); - user.setEmail(userJson.get("email").getAsString()); - user.setLocale(userJson.get("locale").getAsString()); - user.setScreenname(userJson.get("screenname").getAsString()); - return user; - } else { - String message = responseObject.get("message").getAsString(); - switch (responseObject.get("code").getAsInt()) { - case 400: - throw new UnknownUserException(login, message); - case 480: - String userAuthenticationSource = responseObject.get("data").getAsString(); - throw new WrongAuthenticationSourceException(userAuthenticationSource); + LOG.warn("Unexpected error: {}", response); + return null; } - LOG.warn("Unexpected error: {}", response); - return null; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); + } catch (JsonSyntaxException jse) { LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return null; } /** @@ -101,38 +111,56 @@ public User validateUser(String login, String authenticationSource) throws Unkno * @throws ScreennameUsedException * @throws ServerException */ - public Long registerUser(String email, String authenticationSource, String locale, String screenname) throws NonUniqueEmailException, ScreennameUsedException, ServerException { + public Long registerUser( + String email, + String authenticationSource, + String locale, + String screenname) throws + NonUniqueEmailException, + ScreennameUsedException, + ServerException { + try { + // Prepare payload to send with REST request Map data = new HashMap<>(); data.put("email", email); data.put("source", authenticationSource); data.put("locale", locale); data.put("screenname", screenname); - HttpRequest request = HttpRequest.post(getUrl("/oauth/create")).header("server", SERVER).form(data); -// int responseCode = request.code(); -// System.out.println("Response code: " + responseCode); - String response = request.body(); -// System.out.println(response); - JsonElement jelement = new JsonParser().parse(response); - JsonObject responseObject = jelement.getAsJsonObject(); - if (responseObject.get("success").getAsBoolean()) { - return responseObject.get("user").getAsLong(); - } else { - switch (responseObject.get("code").getAsInt()) { - case 450: - throw new NonUniqueEmailException(responseObject.get("data").getAsString()); - case 500: - throw new ScreennameUsedException(responseObject.get("data").getAsString()); + + HttpRequest request = HttpRequest + .post(getUrl("/oauth/create")) + .header("server", SERVER) + .form(data); + + if (request.ok()) { + String response = request.body(); + JsonElement jelement = new JsonParser().parse(response); + JsonObject responseObject = jelement.getAsJsonObject(); + + if (responseObject.get("success").getAsBoolean()) { + return responseObject.get("user").getAsLong(); + } else { + switch (responseObject.get("code").getAsInt()) { + case 450: + throw new NonUniqueEmailException(responseObject.get("data").getAsString()); + case 500: + throw new ScreennameUsedException(responseObject.get("data").getAsString()); + } + + return null; } - return null; } } catch (HttpRequest.HttpRequestException hre) { LOG.error("Inter service error", hre); throw new ServerException(hre); + } catch (JsonSyntaxException jse) { LOG.error("Json syntace service error", jse); throw new ServerException(jse); } + + return null; } private String getUrl(String actionUrl) { From e2f7837d2f63559a6b0124b04a6ebba67cd351eb Mon Sep 17 00:00:00 2001 From: Jim Ewald Date: Tue, 11 Sep 2018 09:53:57 -0700 Subject: [PATCH 5/5] Completed refactoring code to examine HTTP response code prior to accessing any data in the body of the response. --- .../client/cloudsession/CloudSessionVersion.java | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/src/main/java/com/parallax/client/cloudsession/CloudSessionVersion.java b/src/main/java/com/parallax/client/cloudsession/CloudSessionVersion.java index dc9293b..e94f4c6 100644 --- a/src/main/java/com/parallax/client/cloudsession/CloudSessionVersion.java +++ b/src/main/java/com/parallax/client/cloudsession/CloudSessionVersion.java @@ -13,6 +13,15 @@ */ public class CloudSessionVersion { - static final String Version = "1.2.0"; + static final String Version = "1.2.1"; } + +/* + * Revision history + * + * 1.2.1 All calls to REST services now check the HTTP response code prior + * to evaluating any data returned in the body of the response. + * + * Upgraded the Gson package to version 2.8.5. +*/ \ No newline at end of file