mirror of
https://github.com/dbgate/dbgate
synced 2024-11-21 23:39:46 +00:00
safe read-only when using shell scripts
This commit is contained in:
parent
ff661ec89b
commit
8824262395
@ -33,6 +33,7 @@ module.exports = {
|
||||
runAsPortal: !!connections.portalConnections,
|
||||
singleDatabase: connections.singleDatabase,
|
||||
hideAppEditor: !!process.env.HIDE_APP_EDITOR,
|
||||
allowShellConnection: platformInfo.allowShellConnection,
|
||||
permissions,
|
||||
...currentVersion,
|
||||
};
|
||||
|
@ -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) {
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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 };
|
||||
|
@ -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);
|
||||
|
@ -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();
|
||||
|
@ -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'),
|
||||
};
|
||||
|
||||
|
@ -417,10 +417,7 @@
|
||||
{
|
||||
functionName: menu.functionName,
|
||||
props: {
|
||||
connection: {
|
||||
..._.omit(coninfo, ['_id', 'displayName']),
|
||||
..._.pick(data, ['database']),
|
||||
},
|
||||
connection: extractShellConnection(coninfo, data.database),
|
||||
..._.pick(data, ['pureName', 'schemaName']),
|
||||
},
|
||||
},
|
||||
@ -629,6 +626,7 @@
|
||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||
import { apiCall } from '../utility/api';
|
||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||
|
||||
export let data;
|
||||
export let passProps;
|
||||
|
@ -112,6 +112,7 @@
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||
import ConfirmNoSqlModal from '../modals/ConfirmNoSqlModal.svelte';
|
||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||
@ -202,10 +203,7 @@
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
connection: {
|
||||
..._.omit(coninfo, ['_id', 'displayName']),
|
||||
database,
|
||||
},
|
||||
connection: extractShellConnection(coninfo, database),
|
||||
sql: getExportQuery(),
|
||||
},
|
||||
},
|
||||
|
@ -69,6 +69,7 @@
|
||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||
|
||||
import registerCommand from '../commands/registerCommand';
|
||||
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||
import { showModal } from '../modals/modalTools';
|
||||
import { apiCall } from '../utility/api';
|
||||
@ -187,10 +188,7 @@
|
||||
{
|
||||
functionName: 'queryReader',
|
||||
props: {
|
||||
connection: {
|
||||
..._.omit(coninfo, ['_id', 'displayName']),
|
||||
database,
|
||||
},
|
||||
connection: extractShellConnection(coninfo, database),
|
||||
sql: display.getExportQuery(),
|
||||
},
|
||||
},
|
||||
|
@ -4,6 +4,7 @@ import getAsArray from '../utility/getAsArray';
|
||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||
import { findEngineDriver, findObjectLike } from 'dbgate-tools';
|
||||
import { findFileFormat } from '../plugins/fileformats';
|
||||
import { getCurrentConfig } from '../stores';
|
||||
|
||||
export function getTargetName(extensions, source, values) {
|
||||
const key = `targetName_${source}`;
|
||||
@ -33,17 +34,27 @@ function extractDriverApiParameters(values, direction, driver) {
|
||||
return _.fromPairs(pairs);
|
||||
}
|
||||
|
||||
export function extractShellConnection(connection, database) {
|
||||
const config = getCurrentConfig();
|
||||
|
||||
return config.allowShellConnection
|
||||
? {
|
||||
..._.omit(connection, ['_id', 'displayName', 'databases', 'connectionColor']),
|
||||
database,
|
||||
}
|
||||
: {
|
||||
_id: connection._id,
|
||||
engine: connection.engine,
|
||||
database,
|
||||
};
|
||||
}
|
||||
|
||||
async function getConnection(extensions, storageType, conid, database) {
|
||||
if (storageType == 'database' || storageType == 'query') {
|
||||
const conn = await getConnectionInfo({ conid });
|
||||
const driver = findEngineDriver(conn, extensions);
|
||||
return [
|
||||
{
|
||||
..._.omit(conn, ['_id', 'displayName']),
|
||||
database,
|
||||
},
|
||||
driver,
|
||||
];
|
||||
const connection = extractShellConnection(conn, database);
|
||||
return [connection, driver];
|
||||
}
|
||||
return [null, null];
|
||||
}
|
||||
@ -201,7 +212,7 @@ export default async function createImpExpScript(extensions, values, addEditorIn
|
||||
// @ts-ignore
|
||||
script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver));
|
||||
|
||||
const colmap = normalizeExportColumnMap(values[`columns_${sourceName}`] );
|
||||
const colmap = normalizeExportColumnMap(values[`columns_${sourceName}`]);
|
||||
|
||||
let colmapVar = null;
|
||||
if (colmap) {
|
||||
|
Loading…
Reference in New Issue
Block a user