From 6acde03327c378bf8ffd119d462025411a2e3d60 Mon Sep 17 00:00:00 2001 From: Paulo Gustavo Veiga Date: Sat, 1 Apr 2023 13:33:15 -0700 Subject: [PATCH] Improve OAuth error handling. --- wise-webapp/pom.xml | 17 +- .../MultipleSessionsOpenException.java | 38 ---- .../OAuthAuthenticationException.java | 13 ++ .../com/wisemapping/rest/BaseController.java | 15 ++ ...2Controller.java => OAuth2Controller.java} | 4 +- .../wisemapping/service/UserServiceImpl.java | 110 ++++++------ .../service/google/GoogleService.java | 37 ++-- .../service/google/http/HttpInvoker.java | 167 ++++++++++++++++++ .../http/HttpInvokerContentType.java | 4 +- .../google/http/HttpInvokerException.java | 44 +++++ .../wisemapping/service/http/HttpInvoker.java | 147 --------------- .../service/http/HttpInvokerException.java | 13 -- .../wisemapping/service/http/HttpMethod.java | 5 - .../src/main/resources/messages_de.properties | 1 - .../src/main/resources/messages_en.properties | 1 - .../src/main/resources/messages_es.properties | 1 - .../src/main/resources/messages_fr.properties | 1 - .../src/main/resources/messages_ru.properties | 1 - .../src/main/resources/messages_zh.properties | 1 - .../webapp/WEB-INF/wisemapping-service.xml | 2 +- 20 files changed, 333 insertions(+), 289 deletions(-) delete mode 100755 wise-webapp/src/main/java/com/wisemapping/exceptions/MultipleSessionsOpenException.java create mode 100644 wise-webapp/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java rename wise-webapp/src/main/java/com/wisemapping/rest/{Oauth2Controller.java => OAuth2Controller.java} (96%) create mode 100644 wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvoker.java rename wise-webapp/src/main/java/com/wisemapping/service/{ => google}/http/HttpInvokerContentType.java (75%) create mode 100644 wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerException.java delete mode 100644 wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvoker.java delete mode 100644 wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerException.java delete mode 100644 wise-webapp/src/main/java/com/wisemapping/service/http/HttpMethod.java diff --git a/wise-webapp/pom.xml b/wise-webapp/pom.xml index e07f5909..ddef5427 100644 --- a/wise-webapp/pom.xml +++ b/wise-webapp/pom.xml @@ -13,8 +13,8 @@ - 5.3.24 - 5.7.3 + 5.3.26 + 5.7.7 5.6.12.Final 6.0.21.Final 5.6.1 @@ -36,7 +36,7 @@ org.testng testng - 6.9.8 + 7.7.0 test @@ -54,7 +54,7 @@ org.postgresql postgresql - 42.5.1 + 42.5.4 org.springframework.security @@ -358,7 +358,7 @@ com.mysql.jdbc.Driver root - + jdbc:mysql://127.0.0.1:3306/?useUnicode=true&characterEncoding=UTF-8 false @@ -556,11 +556,9 @@ true true 0 - true false 200 - ${integrationTestArgLine} -Ddatabase.base.url=${project.build.directory} - -Djetty.port=8080 + -Ddatabase.base.url=${project.build.directory} -Djetty.port=8080 @@ -570,9 +568,6 @@ stop - - 1 - diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/MultipleSessionsOpenException.java b/wise-webapp/src/main/java/com/wisemapping/exceptions/MultipleSessionsOpenException.java deleted file mode 100755 index e3915da8..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/exceptions/MultipleSessionsOpenException.java +++ /dev/null @@ -1,38 +0,0 @@ -/* -* Copyright [2022] [wisemapping] -* -* Licensed under WiseMapping Public License, Version 1.0 (the "License"). -* It is basically the Apache License, Version 2.0 (the "License") plus the -* "powered by wisemapping" text requirement on every single page; -* you may not use this file except in compliance with the License. -* You may obtain a copy of the license at -* -* http://www.wisemapping.org/license -* -* Unless required by applicable law or agreed to in writing, software -* distributed under the License is distributed on an "AS IS" BASIS, -* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -* See the License for the specific language governing permissions and -* limitations under the License. -*/ - -package com.wisemapping.exceptions; - -import org.jetbrains.annotations.NotNull; - -public class MultipleSessionsOpenException - extends ClientException -{ - private static final String MSG_KEY = "MINDMAP_OUTDATED_BY_YOU"; - - public MultipleSessionsOpenException(@NotNull String techInfo) - { - super(techInfo,Severity.INFO); - } - - @NotNull - @Override - protected String getMsgBundleKey() { - return MSG_KEY; - } -} diff --git a/wise-webapp/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java b/wise-webapp/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java new file mode 100644 index 00000000..f321ca30 --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/exceptions/OAuthAuthenticationException.java @@ -0,0 +1,13 @@ +package com.wisemapping.exceptions; + + +import com.wisemapping.service.google.http.HttpInvokerException; + +import javax.validation.constraints.NotNull; + +public class OAuthAuthenticationException extends WiseMappingException { + + public OAuthAuthenticationException(@NotNull HttpInvokerException exception) { + super(exception.getMessage()); + } +} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/BaseController.java b/wise-webapp/src/main/java/com/wisemapping/rest/BaseController.java index 2eadc4a9..89d4953e 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/BaseController.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/BaseController.java @@ -18,6 +18,7 @@ package com.wisemapping.rest; import com.wisemapping.exceptions.ClientException; +import com.wisemapping.exceptions.OAuthAuthenticationException; import com.wisemapping.exceptions.Severity; import com.wisemapping.mail.NotificationService; import com.wisemapping.model.User; @@ -38,6 +39,7 @@ import org.springframework.web.bind.annotation.ResponseStatus; import javax.servlet.ServletContext; import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import java.lang.reflect.UndeclaredThrowableException; import java.util.Locale; @@ -95,6 +97,19 @@ public class BaseController { return new RestErrors(ex.getMessage(messageSource, locale), ex.getSeverity(), ex.getTechInfo()); } + @ExceptionHandler(OAuthAuthenticationException.class) + @ResponseBody + public OAuthAuthenticationException handleOAuthErrors(@NotNull OAuthAuthenticationException ex, HttpServletResponse response) { + // @todo: Further research needed for this error. No clear why this happens. + // Caused by: com.wisemapping.service.http.HttpInvokerException: error invoking https://oauth2.googleapis.com/token, response: { + // "error": "invalid_grant", + // "error_description": "Bad Request" + //}, status: 400 + // + response.setStatus(response.getStatus()); + return ex; + } + @ExceptionHandler(Exception.class) @ResponseStatus(HttpStatus.INTERNAL_SERVER_ERROR) @ResponseBody diff --git a/wise-webapp/src/main/java/com/wisemapping/rest/Oauth2Controller.java b/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java similarity index 96% rename from wise-webapp/src/main/java/com/wisemapping/rest/Oauth2Controller.java rename to wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java index a3381a3c..feba7457 100644 --- a/wise-webapp/src/main/java/com/wisemapping/rest/Oauth2Controller.java +++ b/wise-webapp/src/main/java/com/wisemapping/rest/OAuth2Controller.java @@ -40,7 +40,7 @@ import javax.servlet.http.HttpSession; @Controller @CrossOrigin -public class Oauth2Controller extends BaseController { +public class OAuth2Controller extends BaseController { @Qualifier("userService") @Autowired private UserService userService; @@ -68,7 +68,7 @@ public class Oauth2Controller extends BaseController { @ResponseStatus(value = HttpStatus.OK) public RestOath2CallbackResponse processGoogleCallback(@NotNull @RequestParam String code, @NotNull HttpServletRequest request) throws WiseMappingException { User user = userService.createUserFromGoogle(code); - if (user.getGoogleSync() != null && user.getGoogleSync().booleanValue()) { + if (user.getGoogleSync() != null && user.getGoogleSync()) { doLogin(request, user.getEmail()); } RestOath2CallbackResponse response = new RestOath2CallbackResponse(); diff --git a/wise-webapp/src/main/java/com/wisemapping/service/UserServiceImpl.java b/wise-webapp/src/main/java/com/wisemapping/service/UserServiceImpl.java index a3e78721..5054ef99 100755 --- a/wise-webapp/src/main/java/com/wisemapping/service/UserServiceImpl.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/UserServiceImpl.java @@ -20,6 +20,7 @@ package com.wisemapping.service; import com.wisemapping.dao.UserManager; import com.wisemapping.exceptions.InvalidMindmapException; +import com.wisemapping.exceptions.OAuthAuthenticationException; import com.wisemapping.exceptions.WiseMappingException; import com.wisemapping.mail.NotificationService; import com.wisemapping.model.*; @@ -27,6 +28,7 @@ import com.wisemapping.rest.model.RestResetPasswordAction; import com.wisemapping.rest.model.RestResetPasswordResponse; import com.wisemapping.service.google.GoogleAccountBasicData; import com.wisemapping.service.google.GoogleService; +import com.wisemapping.service.google.http.HttpInvokerException; import com.wisemapping.util.VelocityEngineUtils; import com.wisemapping.util.VelocityEngineWrapper; import org.jetbrains.annotations.NotNull; @@ -43,7 +45,7 @@ public class UserServiceImpl private NotificationService notificationService; private MessageSource messageSource; private VelocityEngineWrapper velocityEngineWrapper; - private GoogleService googleService; + private GoogleService googleService; @Override public void activateAccount(long code) @@ -64,11 +66,11 @@ public class UserServiceImpl throws InvalidUserEmailException, InvalidAuthSchemaException { final User user = userManager.getUserBy(email); if (user != null) { - RestResetPasswordResponse response = new RestResetPasswordResponse(); - if (user.getAuthenticationType().equals(AuthenticationType.GOOGLE_OAUTH2)) { - response.setAction(RestResetPasswordAction.OAUTH2_USER); - return response; - } + RestResetPasswordResponse response = new RestResetPasswordResponse(); + if (user.getAuthenticationType().equals(AuthenticationType.GOOGLE_OAUTH2)) { + response.setAction(RestResetPasswordAction.OAUTH2_USER); + return response; + } if (user.getAuthenticationType() != AuthenticationType.DATABASE) { throw new InvalidAuthSchemaException("Could not change password for " + user.getAuthenticationType().getCode()); @@ -82,8 +84,8 @@ public class UserServiceImpl // Send an email with the new temporal password ... notificationService.resetPassword(user, password); - response.setAction(RestResetPasswordAction.EMAIL_SENT); - return response; + response.setAction(RestResetPasswordAction.EMAIL_SENT); + return response; } else { throw new InvalidUserEmailException("The email '" + email + "' does not exists."); } @@ -161,51 +163,53 @@ public class UserServiceImpl @NotNull public User createUserFromGoogle(@NotNull String callbackCode) throws WiseMappingException { - try { - GoogleAccountBasicData data = googleService.processCallback(callbackCode); - User existingUser = userManager.getUserBy(data.getEmail()); - if (existingUser == null) { - User newUser = new User(); - // new registrations from google starts synched - newUser.setGoogleSync(true); - newUser.setEmail(data.getEmail()); - newUser.setFirstname(data.getName()); - newUser.setLastname(data.getLastName()); - newUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2); - newUser.setGoogleToken(data.getAccessToken()); - existingUser = this.createUser(newUser, false, true); - } else { - // user exists and doesnt have confirmed account linking, I must wait for confirmation - if (existingUser.getGoogleSync() == null) { - existingUser.setGoogleSync(false); - existingUser.setSyncCode(callbackCode); - existingUser.setGoogleToken(data.getAccessToken()); - userManager.updateUser(existingUser); - } + GoogleAccountBasicData data; + try { + data = googleService.processCallback(callbackCode); + } catch (HttpInvokerException e) { + throw new OAuthAuthenticationException(e); + } + + User existingUser = userManager.getUserBy(data.getEmail()); + if (existingUser == null) { + User newUser = new User(); + // new registrations from google starts synched + newUser.setGoogleSync(true); + newUser.setEmail(data.getEmail()); + newUser.setFirstname(data.getName()); + newUser.setLastname(data.getLastName()); + newUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2); + newUser.setGoogleToken(data.getAccessToken()); + existingUser = this.createUser(newUser, false, true); + } else { + // user exists and doesn't have confirmed account linking, I must wait for confirmation + if (existingUser.getGoogleSync() == null) { + existingUser.setGoogleSync(false); + existingUser.setSyncCode(callbackCode); + existingUser.setGoogleToken(data.getAccessToken()); + userManager.updateUser(existingUser); + } + + } + return existingUser; - } - return existingUser; - } catch (Exception e) { - throw new WiseMappingException("Cant create user", e); - } } - public User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException { - User existingUser = userManager.getUserBy(email); - // additional security check - if (existingUser == null || !existingUser.getSyncCode().equals(code)) { - throw new WiseMappingException("User not found / incorrect code"); - } - existingUser.setGoogleSync(true); - existingUser.setSyncCode(null); - // user will not be able to login again with usr/pwd schema - existingUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2); - existingUser.setPassword(""); - userManager.updateUser(existingUser); - - return existingUser; - } + public User confirmAccountSync(@NotNull String email, @NotNull String code) throws WiseMappingException { + User existingUser = userManager.getUserBy(email); + // additional security check + if (existingUser == null || !existingUser.getSyncCode().equals(code)) { + throw new WiseMappingException("User not found / incorrect code"); + } + existingUser.setGoogleSync(true); + existingUser.setSyncCode(null); + // user will not be able to login again with usr/pwd schema + existingUser.setAuthenticationType(AuthenticationType.GOOGLE_OAUTH2); + existingUser.setPassword(""); + userManager.updateUser(existingUser); + return existingUser; + } public Mindmap buildTutorialMindmap(@NotNull String firstName) throws InvalidMindmapException { @@ -270,11 +274,11 @@ public class UserServiceImpl this.velocityEngineWrapper = velocityEngineWrapper; } - public void setGoogleService(GoogleService googleService) { - this.googleService = googleService; - } + public void setGoogleService(GoogleService googleService) { + this.googleService = googleService; + } - @Override + @Override public User getCasUserBy(String uid) { // TODO Auto-generated method stub return null; diff --git a/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java b/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java index 2a4e8f6d..24cc4256 100644 --- a/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/google/GoogleService.java @@ -1,17 +1,32 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package com.wisemapping.service.google; import java.util.HashMap; import java.util.Map; +import org.springframework.http.HttpMethod; import org.springframework.stereotype.Service; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; -import com.wisemapping.service.http.HttpInvoker; -import com.wisemapping.service.http.HttpInvokerContentType; -import com.wisemapping.service.http.HttpInvokerException; -import com.wisemapping.service.http.HttpMethod; +import com.wisemapping.service.google.http.HttpInvoker; +import com.wisemapping.service.google.http.HttpInvokerContentType; +import com.wisemapping.service.google.http.HttpInvokerException; @Service public class GoogleService { @@ -83,10 +98,10 @@ public class GoogleService { return result; } - public GoogleAccountBasicData processCallback(String code) - throws HttpInvokerException, JsonMappingException, JsonProcessingException { + public GoogleAccountBasicData processCallback(final String code) + throws HttpInvokerException { Map body = this.getOptinConfirmBody(code); - JsonNode optinConfirmResponse = httpInvoker.invoke( + JsonNode optionConfirmResponse = httpInvoker.invoke( optinConfirmUrl, HttpInvokerContentType.FORM_ENCODED, HttpMethod.POST, @@ -94,8 +109,8 @@ public class GoogleService { null, body); - String accessToken = getNodeAsString(optinConfirmResponse, "access_token"); - String refreshToken = getNodeAsString(optinConfirmResponse, "refresh_token"); + final String accessToken = getNodeAsString(optionConfirmResponse, "access_token"); + final String refreshToken = getNodeAsString(optionConfirmResponse, "refresh_token"); GoogleAccountBasicData data = this.getAccountBasicData(accessToken); data.setAccessToken(accessToken); diff --git a/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvoker.java b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvoker.java new file mode 100644 index 00000000..a33bf8af --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvoker.java @@ -0,0 +1,167 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.wisemapping.service.google.http; + +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; +import java.util.Set; + +import org.apache.commons.io.IOUtils; +import org.apache.http.HttpEntity; +import org.apache.http.HttpStatus; +import org.apache.http.NameValuePair; +import org.apache.http.client.entity.UrlEncodedFormEntity; +import org.apache.http.client.methods.CloseableHttpResponse; +import org.apache.http.client.methods.HttpDelete; +import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; +import org.apache.http.client.methods.HttpGet; +import org.apache.http.client.methods.HttpPost; +import org.apache.http.client.methods.HttpPut; +import org.apache.http.client.methods.HttpRequestBase; +import org.apache.http.entity.StringEntity; +import org.apache.http.impl.client.CloseableHttpClient; +import org.apache.http.impl.client.HttpClients; +import org.apache.http.message.BasicNameValuePair; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; +import org.springframework.http.HttpMethod; +import org.springframework.stereotype.Service; + +import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.ObjectMapper; + +import javax.validation.constraints.NotNull; + +@Service +public class HttpInvoker { + + protected static Logger logger = LogManager.getLogger(HttpInvoker.class); + + private final ObjectMapper mapper = new ObjectMapper(); + + public HttpInvoker() { + super(); + } + + public JsonNode invoke( + @NotNull String url, + HttpInvokerContentType requestContentType, + HttpMethod method, + Map headers, + String jsonPayload, + Map formData) + throws HttpInvokerException { + String responseBody = null; + try { + if (logger.isDebugEnabled()) { + logger.debug("finalUrl: " + url); + logger.debug("method: " + method); + logger.debug("payload: " + jsonPayload); + logger.debug("header: " + headers); + } + + CloseableHttpClient httpClient = HttpClients.createDefault(); + HttpRequestBase httpRequest; + + // build request + if (method.equals(HttpMethod.POST)) + httpRequest = new HttpPost(url); + else if (method.equals(HttpMethod.PUT)) + httpRequest = new HttpPut(url); + else if (method.equals(HttpMethod.GET)) + httpRequest = new HttpGet(url); + else if (method.equals(HttpMethod.DELETE)) + httpRequest = new HttpDelete(url); + else + throw new HttpInvokerException("Method " + method + " not supported by http connector"); + + if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) { + HttpEntity entity = null; + if (requestContentType.equals(HttpInvokerContentType.JSON)) { + if (jsonPayload == null) + throw new HttpInvokerException("Json content is required"); + entity = new StringEntity(jsonPayload, StandardCharsets.UTF_8); + ((HttpEntityEnclosingRequestBase) httpRequest).setEntity(entity); + } + if (requestContentType.equals(HttpInvokerContentType.FORM_ENCODED)) { + List nameValuePairs = new ArrayList<>(); + Set keys = formData.keySet(); + for (String key : keys) { + nameValuePairs.add(new BasicNameValuePair(key, formData.get(key).toString())); + } + entity = new UrlEncodedFormEntity(nameValuePairs); + ((HttpEntityEnclosingRequestBase) httpRequest).setEntity(entity); + } + if (entity == null) + throw new HttpInvokerException("Cant build entity to send"); + } + + if (headers != null) { + Set keys = headers.keySet(); + for (String key : keys) { + httpRequest.setHeader(key, headers.get(key)); + } + } + + if (requestContentType != null) + httpRequest.setHeader("Content-Type", requestContentType.getHttpContentType()); + + // invoke + CloseableHttpResponse response = httpClient.execute(httpRequest); + // response process + JsonNode root = null; + responseBody = response.getEntity() != null && response.getEntity().getContent() != null + ? IOUtils.toString(response.getEntity().getContent(), (String) null) + : null; + if (responseBody != null) { + if (logger.isDebugEnabled()) { + logger.debug("response plain: " + responseBody); + } + try { + root = mapper.readTree(responseBody); + } catch (Exception e) { + int returnCode = response.getStatusLine().getStatusCode(); + throw new HttpInvokerException("cant transform response to JSON. RQ: " + jsonPayload + ", RS: " + + responseBody + ", status: " + returnCode, e); + } + } + + if (response.getStatusLine().getStatusCode() >= 400) { + logger.error("error response: " + responseBody); + throw new HttpInvokerException("error invoking " + url + ", response: " + responseBody + ", status: " + + response.getStatusLine().getStatusCode(), HttpStatus.SC_BAD_REQUEST); + } + + httpRequest.releaseConnection(); + response.close(); + httpClient.close(); + + return root; + } catch (HttpInvokerException e) { + throw e; + } catch (Exception e) { + logger.error("cant invoke service " + url); + logger.error("response: " + responseBody, e); + throw new HttpInvokerException("cant invoke service " + url, e); + } + } + + +} diff --git a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerContentType.java b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerContentType.java similarity index 75% rename from wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerContentType.java rename to wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerContentType.java index e80da507..d97998ca 100644 --- a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerContentType.java +++ b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerContentType.java @@ -1,4 +1,4 @@ -package com.wisemapping.service.http; +package com.wisemapping.service.google.http; public enum HttpInvokerContentType { @@ -7,7 +7,7 @@ public enum HttpInvokerContentType { private String httpContentType; - private HttpInvokerContentType(String type) { + HttpInvokerContentType(String type) { this.httpContentType = type; } diff --git a/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerException.java b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerException.java new file mode 100644 index 00000000..bb06f4a7 --- /dev/null +++ b/wise-webapp/src/main/java/com/wisemapping/service/google/http/HttpInvokerException.java @@ -0,0 +1,44 @@ +/* + * Copyright [2022] [wisemapping] + * + * Licensed under WiseMapping Public License, Version 1.0 (the "License"). + * It is basically the Apache License, Version 2.0 (the "License") plus the + * "powered by wisemapping" text requirement on every single page; + * you may not use this file except in compliance with the License. + * You may obtain a copy of the license at + * + * http://www.wisemapping.org/license + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package com.wisemapping.service.google.http; + +import org.apache.http.HttpStatus; + +public class HttpInvokerException extends Exception { + private final int statusCode; + + public HttpInvokerException(String message) { + this(message, HttpStatus.SC_INTERNAL_SERVER_ERROR, null); + } + + public HttpInvokerException(String message, int statusCode) { + this(message, statusCode, null); + } + public HttpInvokerException(String message, Throwable cause) { + this(message, HttpStatus.SC_INTERNAL_SERVER_ERROR, cause); + } + + public HttpInvokerException(String message, int statusCode, Throwable cause) { + super(message, cause); + this.statusCode = statusCode; + } + + public int getStatusCode() { + return statusCode; + } +} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvoker.java b/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvoker.java deleted file mode 100644 index be05d8a4..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvoker.java +++ /dev/null @@ -1,147 +0,0 @@ -package com.wisemapping.service.http; - -import java.nio.charset.Charset; -import java.util.ArrayList; -import java.util.List; -import java.util.Map; -import java.util.Set; - -import org.apache.commons.io.IOUtils; -import org.apache.http.HttpEntity; -import org.apache.http.NameValuePair; -import org.apache.http.client.entity.UrlEncodedFormEntity; -import org.apache.http.client.methods.CloseableHttpResponse; -import org.apache.http.client.methods.HttpDelete; -import org.apache.http.client.methods.HttpEntityEnclosingRequestBase; -import org.apache.http.client.methods.HttpGet; -import org.apache.http.client.methods.HttpPost; -import org.apache.http.client.methods.HttpPut; -import org.apache.http.client.methods.HttpRequestBase; -import org.apache.http.entity.StringEntity; -import org.apache.http.impl.client.CloseableHttpClient; -import org.apache.http.impl.client.HttpClients; -import org.apache.http.message.BasicNameValuePair; -import org.apache.logging.log4j.LogManager; -import org.apache.logging.log4j.Logger; -import org.springframework.stereotype.Service; - -import com.fasterxml.jackson.databind.JsonNode; -import com.fasterxml.jackson.databind.ObjectMapper; - -@Service -public class HttpInvoker { - - protected static Logger logger = LogManager.getLogger(HttpInvoker.class); - - private ObjectMapper mapper = new ObjectMapper(); - - public HttpInvoker() { - super(); - } - - public JsonNode invoke( - String url, - HttpInvokerContentType requestContentType, - HttpMethod method, - Map headers, - String jsonPayload, - Map formData) - throws HttpInvokerException { - String responseBody = null; - try { - if (logger.isDebugEnabled()) { - logger.debug("finalUrl: " + url); - logger.debug("method: " + method); - logger.debug("payload: " + jsonPayload); - logger.debug("header: " + headers); - } - - CloseableHttpClient httpClient = HttpClients.createDefault(); - HttpRequestBase httpRequst = null; - - // build request - if (method.equals(HttpMethod.POST)) - httpRequst = new HttpPost(url); - else if (method.equals(HttpMethod.PUT)) - httpRequst = new HttpPut(url); - else if (method.equals(HttpMethod.GET)) - httpRequst = new HttpGet(url); - else if (method.equals(HttpMethod.DELETE)) - httpRequst = new HttpDelete(url); - else - throw new HttpInvokerException("Method " + method + " not suppoprted by http connector"); - - if (method.equals(HttpMethod.POST) || method.equals(HttpMethod.PUT)) { - HttpEntity entity = null; - if (requestContentType.equals(HttpInvokerContentType.JSON)) { - if (jsonPayload == null) - throw new HttpInvokerException("Json content is required"); - entity = new StringEntity(jsonPayload, Charset.forName("UTF-8")); - ((HttpEntityEnclosingRequestBase) httpRequst).setEntity(entity); - } - if (requestContentType.equals(HttpInvokerContentType.FORM_ENCODED)) { - List nameValuePairs = new ArrayList(); - Set keys = formData.keySet(); - for (String key : keys) { - nameValuePairs.add(new BasicNameValuePair(key, formData.get(key).toString())); - } - entity = new UrlEncodedFormEntity(nameValuePairs); - ((HttpEntityEnclosingRequestBase) httpRequst).setEntity(entity); - } - if (entity == null) - throw new HttpInvokerException("Cant build entity to send"); - } - - if (headers != null) { - Set keys = headers.keySet(); - for (String key : keys) { - httpRequst.setHeader(key, headers.get(key)); - } - } - - if (requestContentType != null) - httpRequst.setHeader("Content-Type", requestContentType.getHttpContentType()); - - // invoke - CloseableHttpResponse response = httpClient.execute(httpRequst); - // response process - JsonNode root = null; - responseBody = response.getEntity() != null && response.getEntity().getContent() != null - ? IOUtils.toString(response.getEntity().getContent(), (String) null) - : null; - if (responseBody != null) { - if (logger.isDebugEnabled()) { - logger.debug("response plain: " + responseBody); - } - try { - root = mapper.readTree(responseBody); - } catch (Exception e) { - int returnCode = response.getStatusLine().getStatusCode(); - throw new HttpInvokerException("cant transform response to JSON. RQ: " + jsonPayload + ", RS: " - + responseBody + ", status: " + returnCode, e); - } - } - - if (response.getStatusLine().getStatusCode() >= 400) { - logger.error("error response: " + responseBody); - throw new HttpInvokerException("error invoking " + url + ", response: " + responseBody + ", status: " - + response.getStatusLine().getStatusCode()); - } - - httpRequst.releaseConnection(); - response.close(); - httpClient.close(); - - return root; - } catch (HttpInvokerException e) { - throw e; - } catch (Exception e) { - logger.error("cant invoke service " + url); - logger.error("response: " + responseBody, e); - throw new HttpInvokerException("cant invoke service " + url, e); - } - } - - - -} diff --git a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerException.java b/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerException.java deleted file mode 100644 index 8ee37835..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpInvokerException.java +++ /dev/null @@ -1,13 +0,0 @@ -package com.wisemapping.service.http; - -public class HttpInvokerException extends Exception { - - public HttpInvokerException(String message) { - super(message); - } - - public HttpInvokerException(String message, Throwable cause) { - super(message, cause); - } - -} \ No newline at end of file diff --git a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpMethod.java b/wise-webapp/src/main/java/com/wisemapping/service/http/HttpMethod.java deleted file mode 100644 index 42553bfa..00000000 --- a/wise-webapp/src/main/java/com/wisemapping/service/http/HttpMethod.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.wisemapping.service.http; - -public enum HttpMethod { - POST, GET, DELETE, PUT -} diff --git a/wise-webapp/src/main/resources/messages_de.properties b/wise-webapp/src/main/resources/messages_de.properties index 9333e6d7..0bca3979 100644 --- a/wise-webapp/src/main/resources/messages_de.properties +++ b/wise-webapp/src/main/resources/messages_de.properties @@ -41,7 +41,6 @@ ACCESS_HAS_BEEN_REVOKED=Deine Zugriffsrechte auf diese Mindmap sind zur MAP_CAN_NOT_BE_FOUND=Die Mindmap kann nicht gefunden werden. Sie muss gelscht worden sein. LABEL_CAN_NOT_BE_FOUND=Das Label kann nicht gefunden werden. Es muss gelscht worden sein. MINDMAP_TIMESTAMP_OUTDATED=Es ist nicht mglich, deine nderungen zu speichern, da deine Mindmap von {0} gendert wurde. Aktualisiere die Seite und versuche es erneut. -MINDMAP_OUTDATED_BY_YOU=Deine nderungen knnen nicht gespeichert werden, da die Mindmap veraltet ist. Hast du mehrere Tabs geffnet? Aktualisiere die Seite und versuche es erneut. MINDMAP_LOCKED=Mindmap wird bearbeitet von {0} <{1}>. Die Mindmap wird im schreibgeschtzten Modus geffnet. MINDMAP_IS_LOCKED=Mindmap ist fr die Bearbeitung gesperrt. # Confirmed diff --git a/wise-webapp/src/main/resources/messages_en.properties b/wise-webapp/src/main/resources/messages_en.properties index 12008527..cef83f55 100644 --- a/wise-webapp/src/main/resources/messages_en.properties +++ b/wise-webapp/src/main/resources/messages_en.properties @@ -42,7 +42,6 @@ ACCESS_HAS_BEEN_REVOKED=Your access permissions to this map has been revoked. Co MAP_CAN_NOT_BE_FOUND=The map can not be found. It must have been deleted. LABEL_CAN_NOT_BE_FOUND=The label can not be found. It must have been deleted. MINDMAP_TIMESTAMP_OUTDATED=It's not possible to save your changes because your mind map has been modified by ''{0}''. Refresh the page and try again. -MINDMAP_OUTDATED_BY_YOU=It's not possible to save your changes because map is out of date. Do you have multiple tabs opened ?. Refresh the page and try again. MINDMAP_LOCKED=Map is being edited by {0} <{1}>. Map is opened in read only mode. MINDMAP_IS_LOCKED=Min map is locked for edition. # Confirmed diff --git a/wise-webapp/src/main/resources/messages_es.properties b/wise-webapp/src/main/resources/messages_es.properties index bdf231d2..d95e5ecb 100644 --- a/wise-webapp/src/main/resources/messages_es.properties +++ b/wise-webapp/src/main/resources/messages_es.properties @@ -41,7 +41,6 @@ ACCESS_HAS_BEEN_REVOKED = Los permisos de acceso al mapa han sido revocados. No MAP_CAN_NOT_BE_FOUND = No se puede encontrar el mapa. Debe haber sido borrado. LABEL_CAN_NOT_BE_FOUND = No se puede encontrar la etiqueta. Debe haber sido borrado. MINDMAP_TIMESTAMP_OUTDATED = No es posible grabar sus cambios por que el mapa ha sido modificado por {0}''. Refresque la pagina y intentelo nuevamente. -MINDMAP_OUTDATED_BY_YOU = No es posible guardar los cambios porque el mapa no está actualizado. ¿Tienes varias pestañas abiertas?. Actualice la página y vuelva a intentarlo. MINDMAP_LOCKED = El mapa esta siendo editado por {0} <{1}>. Mapa sera abierto en modo lectura. MINDMAP_IS_LOCKED = Mindmap está bloqueado para la edición. # Confirmed diff --git a/wise-webapp/src/main/resources/messages_fr.properties b/wise-webapp/src/main/resources/messages_fr.properties index 7ce438b6..b0aba7aa 100644 --- a/wise-webapp/src/main/resources/messages_fr.properties +++ b/wise-webapp/src/main/resources/messages_fr.properties @@ -41,7 +41,6 @@ ACCESS_HAS_BEEN_REVOKED=Vos autorisations d'accès à cette carte ont été rév MAP_CAN_NOT_BE_FOUND=La carte est introuvable. Il a dû être supprimé. LABEL_CAN_NOT_BE_FOUND=L'étiquette est introuvable. Il a dû être supprimé. MINDMAP_TIMESTAMP_OUTDATED=Il n''est pas possible d''enregistrer vos modifications car votre mindmap a été modifiée par ''{0}''. Actualisez la page et réessayez. -MINDMAP_OUTDATED_BY_YOU=Il n'est pas possible d'enregistrer vos modifications car la carte n'est pas à jour. Avez-vous plusieurs onglets ouverts ?. Actualisez la page et réessayez. MINDMAP_LOCKED=La carte est en cours de modification par {0} <{1}>. La carte est ouverte en mode lecture seule. MINDMAP_IS_LOCKED=Mindmap est verrouillé pour l'édition. # Confirmed diff --git a/wise-webapp/src/main/resources/messages_ru.properties b/wise-webapp/src/main/resources/messages_ru.properties index 53cbd9be..a8da170f 100644 --- a/wise-webapp/src/main/resources/messages_ru.properties +++ b/wise-webapp/src/main/resources/messages_ru.properties @@ -41,7 +41,6 @@ ACCESS_HAS_BEEN_REVOKED=Ваш доступ к карте был отозван. MAP_CAN_NOT_BE_FOUND=Карта не найдена. Вероятно, она удалена. LABEL_CAN_NOT_BE_FOUND=Метка не найдена. Вероятно, она удалена. MINDMAP_TIMESTAMP_OUTDATED=Невозможно сохранить, карта была изменена ''{0}''. Обновите страницу и попробуйте еще раз. -MINDMAP_OUTDATED_BY_YOU=Невозможно сохранить - карта устарела. У вас открыто несколько вкладок браузера?. Обновите страницу и попробуйте еще раз. MINDMAP_LOCKED=Карта редактируется {0} <{1}>. Карта открыта в режиме чтения. MINDMAP_IS_LOCKED=Карта доступна только для просмотра. # Confirmed diff --git a/wise-webapp/src/main/resources/messages_zh.properties b/wise-webapp/src/main/resources/messages_zh.properties index 0fa5ea2b..fe1d731d 100644 --- a/wise-webapp/src/main/resources/messages_zh.properties +++ b/wise-webapp/src/main/resources/messages_zh.properties @@ -41,7 +41,6 @@ ACCESS_HAS_BEEN_REVOKED=您对该脑图的访问权限已被撤销。联系脑 MAP_CAN_NOT_BE_FOUND=找不到该脑图,应该是被删除了。 LABEL_CAN_NOT_BE_FOUND=找不到该标签,应该是被删除了。 MINDMAP_TIMESTAMP_OUTDATED=无法保存您的更改,因为您的思维导图已被''{0}''修改。刷新页面,然后重试。 -MINDMAP_OUTDATED_BY_YOU=无法保存您的更改,因为脑图已经过期。您打开了多个页面吗?刷新页面,然后重试。 MINDMAP_LOCKED=脑图正在被{0}<{1}>编辑。脑图以只读模式打开。 MINDMAP_IS_LOCKED=脑图被锁定编辑。 # Confirmed diff --git a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml index 41d18444..3d341cb6 100755 --- a/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml +++ b/wise-webapp/src/main/webapp/WEB-INF/wisemapping-service.xml @@ -18,7 +18,7 @@ - +