safe read-only when using shell scripts

This commit is contained in:
Jan Prochazka
2022-03-19 10:09:27 +01:00
parent ff661ec89b
commit 8824262395
16 changed files with 80 additions and 34 deletions

View File

@@ -33,6 +33,7 @@ module.exports = {
runAsPortal: !!connections.portalConnections,
singleDatabase: connections.singleDatabase,
hideAppEditor: !!process.env.HIDE_APP_EDITOR,
allowShellConnection: platformInfo.allowShellConnection,
permissions,
...currentVersion,
};

View File

@@ -20,7 +20,7 @@ function start() {
if (handleProcessCommunication(connection)) return;
try {
const driver = requireEngineDriver(connection);
const conn = await connectUtility(driver, connection);
const conn = await connectUtility(driver, connection, 'app');
const res = await driver.getVersion(conn);
process.send({ msgtype: 'connected', ...res });
} catch (e) {

View File

@@ -108,7 +108,7 @@ async function handleConnect({ connection, structure, globalSettings }) {
if (!structure) setStatusName('pending');
const driver = requireEngineDriver(storedConnection);
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection));
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
await checkedAsyncCall(readVersion());
if (structure) {
analysedStructure = structure;

View File

@@ -58,11 +58,14 @@ async function handleConnect(connection) {
const driver = requireEngineDriver(storedConnection);
try {
systemConnection = await connectUtility(driver, storedConnection);
systemConnection = await connectUtility(driver, storedConnection, 'app');
readVersion();
handleRefresh();
if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', false)) {
setInterval(handleRefresh, extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 5, 3600) * 1000);
setInterval(
handleRefresh,
extractIntSettingsValue(globalSettings, 'connection.autoRefreshInterval', 30, 5, 3600) * 1000
);
}
} catch (err) {
setStatus({
@@ -80,7 +83,7 @@ function handlePing() {
async function handleCreateDatabase({ name }) {
const driver = requireEngineDriver(storedConnection);
systemConnection = await connectUtility(driver, storedConnection);
systemConnection = await connectUtility(driver, storedConnection, 'app');
console.log(`RUNNING SCRIPT: CREATE DATABASE ${driver.dialect.quoteIdentifier(name)}`);
if (driver.createDatabase) {
await driver.createDatabase(systemConnection, name);

View File

@@ -181,7 +181,7 @@ async function handleConnect(connection) {
storedConnection = connection;
const driver = requireEngineDriver(storedConnection);
systemConnection = await connectUtility(driver, storedConnection);
systemConnection = await connectUtility(driver, storedConnection, 'app');
for (const [resolve] of afterConnectCallbacks) {
resolve();
}

View File

@@ -5,7 +5,7 @@ async function executeQuery({ connection = undefined, systemConnection = undefin
console.log(`Execute query ${sql}`);
if (!driver) driver = requireEngineDriver(connection);
const pool = systemConnection || (await connectUtility(driver, connection));
const pool = systemConnection || (await connectUtility(driver, connection, 'write'));
console.log(`Connected.`);
await driver.script(pool, sql);

View File

@@ -21,7 +21,7 @@ async function generateDeploySql({
}) {
if (!driver) driver = requireEngineDriver(connection);
const pool = systemConnection || (await connectUtility(driver, connection));
const pool = systemConnection || (await connectUtility(driver, connection, 'read'));
if (!analysedStructure) {
analysedStructure = await driver.analyseFull(pool);
}

View File

@@ -6,7 +6,7 @@ async function queryReader({ connection, sql }) {
console.log(`Reading query ${sql}`);
const driver = requireEngineDriver(connection);
const pool = await connectUtility(driver, connection);
const pool = await connectUtility(driver, connection, 'script');
console.log(`Connected.`);
return await driver.readQuery(pool, sql);
}

View File

@@ -4,7 +4,7 @@ const connectUtility = require('../utility/connectUtility');
async function tableReader({ connection, pureName, schemaName }) {
const driver = requireEngineDriver(connection);
const pool = await connectUtility(driver, connection);
const pool = await connectUtility(driver, connection, 'read');
console.log(`Connected.`);
const fullName = { pureName, schemaName };

View File

@@ -8,7 +8,7 @@ async function tableWriter({ connection, schemaName, pureName, driver, systemCon
if (!driver) {
driver = requireEngineDriver(connection);
}
const pool = systemConnection || (await connectUtility(driver, connection));
const pool = systemConnection || (await connectUtility(driver, connection, 'write'));
console.log(`Connected.`);
return await driver.writeTable(pool, { schemaName, pureName }, options);

View File

@@ -4,11 +4,47 @@ const fs = require('fs-extra');
const { decryptConnection } = require('./crypting');
const { getSshTunnel } = require('./sshTunnel');
const { getSshTunnelProxy } = require('./sshTunnelProxy');
const platformInfo = require('../utility/platformInfo');
const connections = require('../controllers/connections');
async function loadConnection(driver, storedConnection, connectionMode) {
const { allowShellConnection } = platformInfo;
if (connectionMode == 'app') {
return storedConnection;
}
if (storedConnection._id || !allowShellConnection) {
if (!storedConnection._id) {
throw new Error('Missing connection _id');
}
await connections._init();
const loaded = await connections.get({ conid: storedConnection._id });
const loadedWithDb = {
...loaded,
database: storedConnection.database,
};
if (loaded.isReadOnly) {
if (connectionMode == 'read') return loadedWithDb;
if (connectionMode == 'write') throw new Error('Cannot wwrite readonly connection');
if (connectionMode == 'script') {
if (driver.readOnlySessions) return loadedWithDb;
throw new Error('Cannot wwrite readonly connection');
}
}
return loadedWithDb;
}
return storedConnection;
}
async function connectUtility(driver, storedConnection, connectionMode) {
const connectionLoaded = await loadConnection(driver, storedConnection, connectionMode);
async function connectUtility(driver, storedConnection) {
const connection = {
database: storedConnection.defaultDatabase,
...decryptConnection(storedConnection),
database: connectionLoaded.defaultDatabase,
...decryptConnection(connectionLoaded),
};
if (!connection.port && driver.defaultPort) connection.port = driver.defaultPort.toString();

View File

@@ -39,6 +39,7 @@ const platformInfo = {
environment: process.env.NODE_ENV,
platform,
runningInWebpack: !!process.env.WEBPACK_DEV_SERVER_URL,
allowShellConnection: !!process.env.SHELL_CONNECTION || !!isElectron(),
defaultKeyfile: path.join(os.homedir(), '.ssh/id_rsa'),
};