From df1558f6134d5ba461c64525a69240ed10c182a5 Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Thu, 7 Nov 2024 18:00:54 +0100 Subject: [PATCH 1/9] CB-5584. Added more logs for gql and rest in RM. Added new parameter in global preferences for showing additional logs --- .../server/graphql/GraphQLEndpoint.java | 13 ++-- .../server/graphql/GraphQLLoggerUtil.java | 77 +++++++++++++++++++ .../graphql/GraphQLProhibitedVariables.java | 48 ++++++++++++ 3 files changed, 131 insertions(+), 7 deletions(-) create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java create mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java index 15506f79dd..f1dd83ae4c 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java @@ -51,10 +51,7 @@ import java.io.Reader; import java.lang.reflect.InvocationTargetException; import java.net.URL; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; -import java.util.Map; +import java.util.*; import java.util.concurrent.CompletableFuture; public class GraphQLEndpoint extends HttpServlet { @@ -68,7 +65,6 @@ public class GraphQLEndpoint extends HttpServlet { private static final String HEADER_ACCESS_CONTROL_ALLOW_CREDENTIALS = "Access-Control-Allow-Credentials"; private static final String CORE_SCHEMA_FILE_NAME = "schema/schema.graphqls"; - private final GraphQL graphQL; private static final Gson gson = new GsonBuilder() @@ -253,10 +249,13 @@ private void executeQuery(HttpServletRequest request, HttpServletResponse respon // apiCall += " (" + variables + ")"; // } // } + String sessionId = request.getSession().getId(); + String userId = GraphQLLoggerUtil.getUserId(request); + String loggerMessage = GraphQLLoggerUtil.buildLoggerMessage(sessionId, userId, variables); if (apiCall != null) { - log.debug("API > " + apiCall); + log.debug("API > " + apiCall + loggerMessage); } else if (DEBUG) { - log.debug("API > " + query); + log.debug("API > " + query + loggerMessage); } } ExecutionInput executionInput = contextBuilder.build(); diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java new file mode 100644 index 0000000000..220cb4459b --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -0,0 +1,77 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 io.cloudbeaver.server.graphql; + +import io.cloudbeaver.model.session.WebSession; +import io.cloudbeaver.server.CBApplication; +import io.cloudbeaver.server.CBPlatform; +import jakarta.servlet.http.HttpServletRequest; +import org.jkiss.utils.CommonUtils; + +import java.util.Map; +import java.util.Set; + +public class GraphQLLoggerUtil { + + private static final Set PROHIBITED_VARIABLES = GraphQLProhibitedVariables.getAllProhibitedVariables(); + + public static String getUserId(HttpServletRequest request) { + String userId = null; + WebSession session = (WebSession) CBApplication.getInstance().getSessionManager().getSession(request.getSession().getId()); + if (session != null) { + userId = session.getUserContext().getUserId(); + if (userId == null && session.getUserContext().isAuthorizedInSecurityManager()) { + userId = "anonymous"; + } + } + return userId; + } + + public static String buildLoggerMessage(String sessionId, String userId, Map variables) { + StringBuilder loggerMessage = new StringBuilder(" [user: ").append(userId) + .append(", sessionId: ").append(sessionId).append("]"); + + if (CBPlatform.getInstance().getPreferenceStore().getBoolean("log.on.show.variables") && variables != null) { + loggerMessage.append(" [variables] "); + String parsedVariables = parseVarialbes(variables); + if (CommonUtils.isNotEmpty(parsedVariables)) { + loggerMessage.append(parseVarialbes(variables)); + } + } + return loggerMessage.toString(); + } + + private static String parseVarialbes(Map map) { + StringBuilder result = new StringBuilder(); + + for (Map.Entry entry : map.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + + if (PROHIBITED_VARIABLES.contains(key)) { + continue; + } + + if (value instanceof Map) { + result.append(parseVarialbes((Map) value)); + } else { + result.append(key).append(": ").append(value).append(" "); + } + } + return result.toString().trim(); + } +} diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java new file mode 100644 index 0000000000..dfd46231ec --- /dev/null +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java @@ -0,0 +1,48 @@ +/* + * DBeaver - Universal Database Manager + * Copyright (C) 2010-2024 DBeaver Corp and others + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * 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 io.cloudbeaver.server.graphql; + +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; + +public enum GraphQLProhibitedVariables { + + + PASSWORD("password"), + CONFIG("config"), + PARAMETERS("parameters"), + SETTINGS("settings"), + LICENSE_TEXT("licenseText"); + + private final String name; + + GraphQLProhibitedVariables(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static Set getAllProhibitedVariables() { + return Arrays.stream(GraphQLProhibitedVariables.values()) + .map(GraphQLProhibitedVariables::getName) + .collect(Collectors.toSet()); + } +} From eab4c98730bb70b28d8ca8208771f5f2b57a6145 Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Thu, 7 Nov 2024 18:07:22 +0100 Subject: [PATCH 2/9] CB-5584. Added more logs for gql and rest in RM. Added new parameter in global preferences for showing additional logs --- server/bundles/io.cloudbeaver.server/plugin.xml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index 73656b40b7..9c3f01f3be 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -75,4 +75,12 @@ + + + + + + From b41e9514350e4ea60c39c417b19f95cf99300e2e Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Fri, 8 Nov 2024 17:17:45 +0100 Subject: [PATCH 3/9] CB-5584. Rename parameter --- server/bundles/io.cloudbeaver.server/plugin.xml | 2 +- .../src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index 9c3f01f3be..f21f24c320 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -77,7 +77,7 @@ - diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index 220cb4459b..dd1e1968e3 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -45,7 +45,7 @@ public static String buildLoggerMessage(String sessionId, String userId, Map Date: Mon, 11 Nov 2024 15:21:50 +0100 Subject: [PATCH 4/9] CB-5584. Rename parameter --- .../bundles/io.cloudbeaver.server/plugin.xml | 2 +- .../server/graphql/GraphQLLoggerUtil.java | 19 +++++--- .../graphql/GraphQLProhibitedVariables.java | 48 ------------------- 3 files changed, 13 insertions(+), 56 deletions(-) delete mode 100644 server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index f21f24c320..f73f9043fd 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -77,7 +77,7 @@ - diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index dd1e1968e3..c5550a97aa 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -27,25 +27,30 @@ public class GraphQLLoggerUtil { - private static final Set PROHIBITED_VARIABLES = GraphQLProhibitedVariables.getAllProhibitedVariables(); + private static final Set PROHIBITED_VARIABLES = + Set.of("password", "config", "parameters", "settings", "licenseText", "credentials", "username"); public static String getUserId(HttpServletRequest request) { String userId = null; - WebSession session = (WebSession) CBApplication.getInstance().getSessionManager().getSession(request.getSession().getId()); - if (session != null) { - userId = session.getUserContext().getUserId(); - if (userId == null && session.getUserContext().isAuthorizedInSecurityManager()) { - userId = "anonymous"; + if (request.getSession() != null) { + WebSession session = + (WebSession) CBApplication.getInstance().getSessionManager().getSession(request.getSession().getId()); + if (session != null) { + userId = session.getUserContext().getUserId(); + if (userId == null && session.getUserContext().isAuthorizedInSecurityManager()) { + userId = "anonymous"; + } } } return userId; + } public static String buildLoggerMessage(String sessionId, String userId, Map variables) { StringBuilder loggerMessage = new StringBuilder(" [user: ").append(userId) .append(", sessionId: ").append(sessionId).append("]"); - if (CBPlatform.getInstance().getPreferenceStore().getBoolean("log.debug") && variables != null) { + if (CBPlatform.getInstance().getPreferenceStore().getBoolean("log.api.graphql.debug") && variables != null) { loggerMessage.append(" [variables] "); String parsedVariables = parseVarialbes(variables); if (CommonUtils.isNotEmpty(parsedVariables)) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java deleted file mode 100644 index dfd46231ec..0000000000 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLProhibitedVariables.java +++ /dev/null @@ -1,48 +0,0 @@ -/* - * DBeaver - Universal Database Manager - * Copyright (C) 2010-2024 DBeaver Corp and others - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * 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 io.cloudbeaver.server.graphql; - -import java.util.Arrays; -import java.util.List; -import java.util.Set; -import java.util.stream.Collectors; - -public enum GraphQLProhibitedVariables { - - - PASSWORD("password"), - CONFIG("config"), - PARAMETERS("parameters"), - SETTINGS("settings"), - LICENSE_TEXT("licenseText"); - - private final String name; - - GraphQLProhibitedVariables(String name) { - this.name = name; - } - - public String getName() { - return name; - } - - public static Set getAllProhibitedVariables() { - return Arrays.stream(GraphQLProhibitedVariables.values()) - .map(GraphQLProhibitedVariables::getName) - .collect(Collectors.toSet()); - } -} From a3347e586b2470b64366395bc481a0273a089b75 Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Mon, 11 Nov 2024 16:56:16 +0100 Subject: [PATCH 5/9] CB-5584. Refactor after review --- .../src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java | 1 + 1 file changed, 1 insertion(+) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index c5550a97aa..7df43269bd 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -68,6 +68,7 @@ private static String parseVarialbes(Map map) { Object value = entry.getValue(); if (PROHIBITED_VARIABLES.contains(key)) { + result.append(key).append(": ").append("******** "); continue; } From 8ecb8e9c100b3043aa1b8ba7b1c8c7b97c071540 Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Mon, 11 Nov 2024 17:05:26 +0100 Subject: [PATCH 6/9] CB-5584. Refactor after review --- .../src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index 7df43269bd..067e6beddb 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -27,6 +27,7 @@ public class GraphQLLoggerUtil { + public static final String LOG_API_GRAPHQL_DEBUG_PARAMETER = "log.api.graphql.debug"; private static final Set PROHIBITED_VARIABLES = Set.of("password", "config", "parameters", "settings", "licenseText", "credentials", "username"); @@ -50,7 +51,9 @@ public static String buildLoggerMessage(String sessionId, String userId, Map Date: Mon, 18 Nov 2024 13:19:03 +0100 Subject: [PATCH 7/9] CB-5584. Renamed parameter --- server/bundles/io.cloudbeaver.server/plugin.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/plugin.xml b/server/bundles/io.cloudbeaver.server/plugin.xml index f73f9043fd..9259eddd80 100644 --- a/server/bundles/io.cloudbeaver.server/plugin.xml +++ b/server/bundles/io.cloudbeaver.server/plugin.xml @@ -77,9 +77,9 @@ - + description="Enable detailed logging of GraphQL queries in the server log, including all provided variables"/> From aebad33a3b80539ed26626253f8babea3fcafc67 Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Tue, 19 Nov 2024 12:31:12 +0100 Subject: [PATCH 8/9] CB-5584. Added check variable for contains restricted variable --- .../src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index 067e6beddb..6ccbbe7623 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -70,7 +70,10 @@ private static String parseVarialbes(Map map) { String key = entry.getKey(); Object value = entry.getValue(); - if (PROHIBITED_VARIABLES.contains(key)) { + boolean isProhibited = PROHIBITED_VARIABLES.stream() + .anyMatch(prohibitedKey -> key.toLowerCase().contains(prohibitedKey.toLowerCase())); + + if (isProhibited) { result.append(key).append(": ").append("******** "); continue; } From 738f5a956b0823018c404678f5fb006e3caf218d Mon Sep 17 00:00:00 2001 From: "denis.sinelnikov" Date: Thu, 21 Nov 2024 14:38:05 +0100 Subject: [PATCH 9/9] CB-5584. Fixed showing wrong sessionId. --- .../server/graphql/GraphQLEndpoint.java | 2 +- .../server/graphql/GraphQLLoggerUtil.java | 33 +++++++++++++------ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java index f1dd83ae4c..d47612147b 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLEndpoint.java @@ -249,7 +249,7 @@ private void executeQuery(HttpServletRequest request, HttpServletResponse respon // apiCall += " (" + variables + ")"; // } // } - String sessionId = request.getSession().getId(); + String sessionId = GraphQLLoggerUtil.getSessionId(request); String userId = GraphQLLoggerUtil.getUserId(request); String loggerMessage = GraphQLLoggerUtil.buildLoggerMessage(sessionId, userId, variables); if (apiCall != null) { diff --git a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java index 6ccbbe7623..b42e1f28d9 100644 --- a/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java +++ b/server/bundles/io.cloudbeaver.server/src/io/cloudbeaver/server/graphql/GraphQLLoggerUtil.java @@ -32,19 +32,32 @@ public class GraphQLLoggerUtil { Set.of("password", "config", "parameters", "settings", "licenseText", "credentials", "username"); public static String getUserId(HttpServletRequest request) { - String userId = null; - if (request.getSession() != null) { - WebSession session = - (WebSession) CBApplication.getInstance().getSessionManager().getSession(request.getSession().getId()); - if (session != null) { - userId = session.getUserContext().getUserId(); - if (userId == null && session.getUserContext().isAuthorizedInSecurityManager()) { - userId = "anonymous"; - } - } + WebSession session = getWebSession(request); + if (session == null) { + return null; + } + String userId = session.getUserContext().getUserId(); + if (userId == null && session.getUserContext().isAuthorizedInSecurityManager()) { + return "anonymous"; } return userId; + } + public static String getSessionId(HttpServletRequest request) { + WebSession session = getWebSession(request); + if (session == null) { + return null; + } + return session.getUserContext().getSmSessionId(); + } + + private static WebSession getWebSession(HttpServletRequest request) { + if (request.getSession() == null) { + return null; + } + return (WebSession) CBApplication.getInstance() + .getSessionManager() + .getSession(request.getSession().getId()); } public static String buildLoggerMessage(String sessionId, String userId, Map variables) {