Skip to content

Commit

Permalink
Merge branch 'devel' into CB-4700-allow-admin-copy
Browse files Browse the repository at this point in the history
  • Loading branch information
dariamarutkina authored Feb 26, 2024
2 parents 8b0e54c + c0c4e18 commit 2b7f60a
Show file tree
Hide file tree
Showing 100 changed files with 604 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -521,6 +521,7 @@ public synchronized void updateInfo(
HttpServletRequest request,
HttpServletResponse response
) throws DBWebException {
log.debug("Update session lifetime " + getSessionId() + " for user " + getUserId());
touchSession();
HttpSession httpSession = request.getSession();
this.lastRemoteAddr = request.getRemoteAddr();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -566,7 +566,9 @@ extend type Mutation {
closeSession: Boolean

# Refreshes session on server and returns its state
touchSession: Boolean
touchSession: Boolean @deprecated(reason: "use updateSession instead")
# Refreshes session on server and returns session state
updateSession: SessionInfo! @since(version: "24.0.0")

# Refresh session connection list
refreshSessionConnections: Boolean
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,14 @@ WebSession openSession(
@WebAction(authRequired = false)
boolean closeSession(HttpServletRequest request) throws DBWebException;

@Deprecated
@WebAction(authRequired = false)
boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse servletResponse) throws DBWebException;

@WebAction(authRequired = false)
WebSession updateSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response)
throws DBWebException;

@WebAction(authRequired = false)
boolean refreshSessionConnections(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,8 @@ public void bindWiring(DBWBindingContext model) throws DBWebException {
.dataFetcher("closeSession", env -> getService(env).closeSession(GraphQLEndpoint.getServletRequest(env)))
.dataFetcher("touchSession", env -> getService(env).touchSession(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("updateSession", env -> getService(env).updateSession(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("refreshSessionConnections", env -> getService(env).refreshSessionConnections(
GraphQLEndpoint.getServletRequest(env), GraphQLEndpoint.getServletResponse(env)))
.dataFetcher("changeSessionLanguage", env -> getService(env).changeSessionLanguage(getWebSession(env), env.getArgument("locale")))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.cloudbeaver.server.CBPlatform;
import io.cloudbeaver.service.core.DBWServiceCore;
import io.cloudbeaver.service.security.SMUtils;
import io.cloudbeaver.service.session.WebSessionManager;
import io.cloudbeaver.utils.WebConnectionFolderUtils;
import io.cloudbeaver.utils.WebDataSourceUtils;
import io.cloudbeaver.utils.WebEventUtils;
Expand Down Expand Up @@ -285,6 +286,14 @@ public boolean touchSession(@NotNull HttpServletRequest request, @NotNull HttpSe
return CBPlatform.getInstance().getSessionManager().touchSession(request, response);
}

@Override
public WebSession updateSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response)
throws DBWebException {
WebSessionManager sessionManager = CBPlatform.getInstance().getSessionManager();
sessionManager.touchSession(request, response);
return sessionManager.getWebSession(request, response, true);
}

@Override
public boolean refreshSessionConnections(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response) throws DBWebException {
WebSession session = CBPlatform.getInstance().getSessionManager().getWebSession(request, response);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,11 @@ public WebSession getWebSession(@NotNull HttpServletRequest request,
}

@NotNull
public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean errorOnNoFound) throws DBWebException {
return getWebSession(request, response, true, errorOnNoFound);
}

@NotNull
public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull HttpServletResponse response, boolean updateInfo, boolean errorOnNoFound) throws DBWebException {
public WebSession getWebSession(
@NotNull HttpServletRequest request,
@NotNull HttpServletResponse response,
boolean errorOnNoFound
) throws DBWebException {
HttpSession httpSession = request.getSession(true);
String sessionId = httpSession.getId();
WebSession webSession;
Expand Down Expand Up @@ -132,20 +131,14 @@ public WebSession getWebSession(@NotNull HttpServletRequest request, @NotNull Ht
log.debug((restored ? "Restored " : "New ") + "web session '" + webSession.getSessionId() + "'");

webSession.setCacheExpired(!httpSession.isNew());
webSession.updateInfo(request, response);

sessionMap.put(sessionId, webSession);
} else {
if (!(baseWebSession instanceof WebSession)) {
throw new DBWebException("Unexpected session type: " + baseWebSession.getClass().getName());
}
webSession = (WebSession) baseWebSession;
if (updateInfo) {
// Update only once per request
if (!CommonUtils.toBoolean(request.getAttribute("sessionUpdated"))) {
webSession.updateInfo(request, response);
request.setAttribute("sessionUpdated", true);
}
}
}
}

Expand Down Expand Up @@ -328,16 +321,21 @@ public WebHeadlessSession getHeadlessSession(HttpServletRequest request, boolean
*/
public void sendSessionsStates() {
synchronized (sessionMap) {
for (var session : sessionMap.values()) {
if (session instanceof WebHeadlessSession) {
continue;
}
try {
session.addSessionEvent(new WSSessionStateEvent(session.getRemainingTime(), session.isValid()));
} catch (Exception e) {
log.error("Failed to refresh session state: " + session.getSessionId(), e);
}
}
sessionMap.values()
.parallelStream()
.filter(session -> {
if (session instanceof WebSession webSession) {
return webSession.isAuthorizedInSecurityManager();
}
return false;
})
.forEach(session -> {
try {
session.addSessionEvent(new WSSessionStateEvent(session.getRemainingTime(), session.isValid()));
} catch (Exception e) {
log.error("Failed to refresh session state: " + session.getSessionId(), e);
}
});
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
import io.cloudbeaver.service.DBWServiceServerConfigurator;
import io.cloudbeaver.service.admin.*;
import io.cloudbeaver.service.security.SMUtils;
import io.cloudbeaver.utils.WebAppUtils;
import org.jkiss.code.NotNull;
import org.jkiss.code.Nullable;
import org.jkiss.dbeaver.DBException;
Expand Down Expand Up @@ -257,7 +258,9 @@ public boolean grantUserTeam(@NotNull WebSession webSession, String user, String
if (grantor == null) {
throw new DBWebException("Cannot grant team in anonymous mode");
}
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
if (!WebAppUtils.getWebApplication().isDistributed()
&& CommonUtils.equalObjects(user, webSession.getUser().getUserId())
) {
throw new DBWebException("You cannot edit your own permissions");
}
try {
Expand All @@ -281,7 +284,9 @@ public boolean revokeUserTeam(@NotNull WebSession webSession, String user, Strin
if (grantor == null) {
throw new DBWebException("Cannot revoke team in anonymous mode");
}
if (CommonUtils.equalObjects(user, webSession.getUser().getUserId())) {
if (!WebAppUtils.getWebApplication().isDistributed() &&
CommonUtils.equalObjects(user, webSession.getUser().getUserId())
) {
throw new DBWebException("You cannot edit your own permissions");
}
try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Map;

public class WebDataTransferServlet extends WebServiceServletBase {

Expand Down Expand Up @@ -67,7 +68,7 @@ protected void processServiceRequest(WebSession session, HttpServletRequest requ
}
String fileName = taskInfo.getExportFileName();
if (!CommonUtils.isEmpty(fileName)) {
fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor);
fileName += "." + WebDataTransferUtils.getProcessorFileExtension(processor, taskInfo.getParameters().getProcessorProperties());
} else {
fileName = taskInfo.getDataFileId();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,12 @@
import org.jkiss.dbeaver.tools.transfer.registry.DataTransferProcessorDescriptor;
import org.jkiss.utils.CommonUtils;

import java.util.Map;

class WebDataTransferUtils {

private static final Log log = Log.getLog(WebDataTransferUtils.class);
public static final String EXTENSION = "extension";


public static String getProcessorFileExtension(DataTransferProcessorDescriptor processor) {
Expand All @@ -34,6 +37,14 @@ public static String getProcessorFileExtension(DataTransferProcessorDescriptor p
return CommonUtils.isEmpty(ext) ? "data" : ext;
}

public static String getProcessorFileExtension(DataTransferProcessorDescriptor processor, Map<String, Object> processorProperties) {
if (processorProperties != null && processorProperties.get(EXTENSION) != null) {
return CommonUtils.toString(processorProperties.get(EXTENSION), "data");
}

return getProcessorFileExtension(processor);
}

public static String normalizeFileName(
@NotNull String fileName,
@NotNull WebDataTransferOutputSettings outputSettings
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,15 @@ public WebAsyncTaskInfo dataTransferExportDataFromContainer(
}

@NotNull
private String makeUniqueFileName(WebSQLProcessor sqlProcessor, DataTransferProcessorDescriptor processor) {
private String makeUniqueFileName(
WebSQLProcessor sqlProcessor,
DataTransferProcessorDescriptor processor,
Map<String, Object> processorProperties
) {
if (processorProperties != null && processorProperties.get(StreamConsumerSettings.PROP_FILE_EXTENSION) != null) {
return sqlProcessor.getWebSession().getSessionId() + "_" + UUID.randomUUID() +
"." + processorProperties.get(StreamConsumerSettings.PROP_FILE_EXTENSION);
}
return sqlProcessor.getWebSession().getSessionId() + "_" + UUID.randomUUID() + "." + WebDataTransferUtils.getProcessorFileExtension(processor);
}

Expand Down Expand Up @@ -157,7 +165,8 @@ public void run(DBRProgressMonitor monitor) throws InvocationTargetException {
monitor.beginTask("Export data", 1);
try {
monitor.subTask("Export data using " + processor.getName());
Path exportFile = dataExportFolder.resolve(makeUniqueFileName(sqlProcessor, processor));
Path exportFile = dataExportFolder.resolve(
makeUniqueFileName(sqlProcessor, processor, parameters.getProcessorProperties()));
try {
exportData(monitor, processor, dataContainer, parameters, resultsInfo, exportFile);
} catch (Exception e) {
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-administration/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '@testing-library/jest-dom';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreEventsManifest } from '@cloudbeaver/core-events';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
Expand Down Expand Up @@ -37,6 +38,7 @@ const app = createApp(
// coreRoutingManifest,
// coreThemingManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

const server = mockGraphQL(...mockAppInit(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-administration/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-data-context/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
},
"dependencies": {
"@cloudbeaver/core-blocks": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-di": "~0.1.0",
"@cloudbeaver/core-executor": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
Expand Down
2 changes: 2 additions & 0 deletions webapp/packages/core-app/src/Body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import { useAppVersion } from '@cloudbeaver/core-version';

import style from './Body.m.css';
import { useAppHeight } from './useAppHeight';
import { useClientActivity } from './useClientActivity';

export const Body = observer(function Body() {
// const serverConfigLoader = useResource(Body, ServerConfigResource, undefined);
Expand All @@ -44,6 +45,7 @@ export const Body = observer(function Body() {
});

useAppHeight();
useClientActivity();

return (
<DNDProvider>
Expand Down
46 changes: 46 additions & 0 deletions webapp/packages/core-app/src/useClientActivity.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/*
* CloudBeaver - Cloud Database Manager
* Copyright (C) 2020-2024 DBeaver Corp and others
*
* Licensed under the Apache License, Version 2.0.
* you may not use this file except in compliance with the License.
*/
import { useEffect } from 'react';

import { ClientActivityService } from '@cloudbeaver/core-client-activity';
import { useService } from '@cloudbeaver/core-di';
import { throttle } from '@cloudbeaver/core-utils';

const UPDATE_THROTTLE = 300;

export function useClientActivity() {
const clientActivityService = useService(ClientActivityService);

const updateActivity = throttle(function updateActivity() {
clientActivityService.updateActivity();
}, UPDATE_THROTTLE);

function subscribeEvents() {
document.addEventListener('mousemove', updateActivity);
document.addEventListener('click', updateActivity);
document.addEventListener('keydown', updateActivity);
document.addEventListener('scroll', updateActivity);
document.addEventListener('touchstart', updateActivity);
}

function unsubscribeEvents() {
document.removeEventListener('mousemove', updateActivity);
document.removeEventListener('click', updateActivity);
document.removeEventListener('keydown', updateActivity);
document.removeEventListener('scroll', updateActivity);
document.removeEventListener('touchstart', updateActivity);
}

useEffect(() => {
subscribeEvents();

return () => {
unsubscribeEvents();
};
}, []);
}
3 changes: 3 additions & 0 deletions webapp/packages/core-app/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,9 @@
{
"path": "../core-blocks/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-di/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-authentication/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import '@testing-library/jest-dom';

import { coreBrowserManifest } from '@cloudbeaver/core-browser';
import { coreClientActivityManifest } from '@cloudbeaver/core-client-activity';
import { coreEventsManifest } from '@cloudbeaver/core-events';
import { coreLocalizationManifest } from '@cloudbeaver/core-localization';
import { corePluginManifest } from '@cloudbeaver/core-plugin';
Expand Down Expand Up @@ -40,6 +41,7 @@ const app = createApp(
coreRoutingManifest,
coreThemingManifest,
coreLocalizationManifest,
coreClientActivityManifest,
);

const server = mockGraphQL(...mockAppInit(endpoint), ...mockAuthentication(endpoint));
Expand Down
3 changes: 3 additions & 0 deletions webapp/packages/core-authentication/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@
{
"path": "../core-browser/tsconfig.json"
},
{
"path": "../core-client-activity/tsconfig.json"
},
{
"path": "../core-data-context/tsconfig.json"
},
Expand Down
1 change: 1 addition & 0 deletions webapp/packages/core-blocks/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
"peerDependencies": {},
"devDependencies": {
"@cloudbeaver/core-browser": "~0.1.0",
"@cloudbeaver/core-client-activity": "~0.1.0",
"@cloudbeaver/core-events": "~0.1.0",
"@cloudbeaver/core-localization": "~0.1.0",
"@cloudbeaver/core-plugin": "~0.1.0",
Expand Down
Loading

0 comments on commit 2b7f60a

Please sign in to comment.