mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-05-03 21:03:59 +00:00
safe read-only when using shell scripts
This commit is contained in:
@@ -33,6 +33,7 @@ module.exports = {
|
|||||||
runAsPortal: !!connections.portalConnections,
|
runAsPortal: !!connections.portalConnections,
|
||||||
singleDatabase: connections.singleDatabase,
|
singleDatabase: connections.singleDatabase,
|
||||||
hideAppEditor: !!process.env.HIDE_APP_EDITOR,
|
hideAppEditor: !!process.env.HIDE_APP_EDITOR,
|
||||||
|
allowShellConnection: platformInfo.allowShellConnection,
|
||||||
permissions,
|
permissions,
|
||||||
...currentVersion,
|
...currentVersion,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ function start() {
|
|||||||
if (handleProcessCommunication(connection)) return;
|
if (handleProcessCommunication(connection)) return;
|
||||||
try {
|
try {
|
||||||
const driver = requireEngineDriver(connection);
|
const driver = requireEngineDriver(connection);
|
||||||
const conn = await connectUtility(driver, connection);
|
const conn = await connectUtility(driver, connection, 'app');
|
||||||
const res = await driver.getVersion(conn);
|
const res = await driver.getVersion(conn);
|
||||||
process.send({ msgtype: 'connected', ...res });
|
process.send({ msgtype: 'connected', ...res });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ async function handleConnect({ connection, structure, globalSettings }) {
|
|||||||
|
|
||||||
if (!structure) setStatusName('pending');
|
if (!structure) setStatusName('pending');
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection));
|
systemConnection = await checkedAsyncCall(connectUtility(driver, storedConnection, 'app'));
|
||||||
await checkedAsyncCall(readVersion());
|
await checkedAsyncCall(readVersion());
|
||||||
if (structure) {
|
if (structure) {
|
||||||
analysedStructure = structure;
|
analysedStructure = structure;
|
||||||
|
|||||||
@@ -58,11 +58,14 @@ async function handleConnect(connection) {
|
|||||||
|
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
try {
|
try {
|
||||||
systemConnection = await connectUtility(driver, storedConnection);
|
systemConnection = await connectUtility(driver, storedConnection, 'app');
|
||||||
readVersion();
|
readVersion();
|
||||||
handleRefresh();
|
handleRefresh();
|
||||||
if (extractBoolSettingsValue(globalSettings, 'connection.autoRefresh', false)) {
|
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) {
|
} catch (err) {
|
||||||
setStatus({
|
setStatus({
|
||||||
@@ -80,7 +83,7 @@ function handlePing() {
|
|||||||
|
|
||||||
async function handleCreateDatabase({ name }) {
|
async function handleCreateDatabase({ name }) {
|
||||||
const driver = requireEngineDriver(storedConnection);
|
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)}`);
|
console.log(`RUNNING SCRIPT: CREATE DATABASE ${driver.dialect.quoteIdentifier(name)}`);
|
||||||
if (driver.createDatabase) {
|
if (driver.createDatabase) {
|
||||||
await driver.createDatabase(systemConnection, name);
|
await driver.createDatabase(systemConnection, name);
|
||||||
|
|||||||
@@ -181,7 +181,7 @@ async function handleConnect(connection) {
|
|||||||
storedConnection = connection;
|
storedConnection = connection;
|
||||||
|
|
||||||
const driver = requireEngineDriver(storedConnection);
|
const driver = requireEngineDriver(storedConnection);
|
||||||
systemConnection = await connectUtility(driver, storedConnection);
|
systemConnection = await connectUtility(driver, storedConnection, 'app');
|
||||||
for (const [resolve] of afterConnectCallbacks) {
|
for (const [resolve] of afterConnectCallbacks) {
|
||||||
resolve();
|
resolve();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ async function executeQuery({ connection = undefined, systemConnection = undefin
|
|||||||
console.log(`Execute query ${sql}`);
|
console.log(`Execute query ${sql}`);
|
||||||
|
|
||||||
if (!driver) driver = requireEngineDriver(connection);
|
if (!driver) driver = requireEngineDriver(connection);
|
||||||
const pool = systemConnection || (await connectUtility(driver, connection));
|
const pool = systemConnection || (await connectUtility(driver, connection, 'write'));
|
||||||
console.log(`Connected.`);
|
console.log(`Connected.`);
|
||||||
|
|
||||||
await driver.script(pool, sql);
|
await driver.script(pool, sql);
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ async function generateDeploySql({
|
|||||||
}) {
|
}) {
|
||||||
if (!driver) driver = requireEngineDriver(connection);
|
if (!driver) driver = requireEngineDriver(connection);
|
||||||
|
|
||||||
const pool = systemConnection || (await connectUtility(driver, connection));
|
const pool = systemConnection || (await connectUtility(driver, connection, 'read'));
|
||||||
if (!analysedStructure) {
|
if (!analysedStructure) {
|
||||||
analysedStructure = await driver.analyseFull(pool);
|
analysedStructure = await driver.analyseFull(pool);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ async function queryReader({ connection, sql }) {
|
|||||||
console.log(`Reading query ${sql}`);
|
console.log(`Reading query ${sql}`);
|
||||||
|
|
||||||
const driver = requireEngineDriver(connection);
|
const driver = requireEngineDriver(connection);
|
||||||
const pool = await connectUtility(driver, connection);
|
const pool = await connectUtility(driver, connection, 'script');
|
||||||
console.log(`Connected.`);
|
console.log(`Connected.`);
|
||||||
return await driver.readQuery(pool, sql);
|
return await driver.readQuery(pool, sql);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ const connectUtility = require('../utility/connectUtility');
|
|||||||
|
|
||||||
async function tableReader({ connection, pureName, schemaName }) {
|
async function tableReader({ connection, pureName, schemaName }) {
|
||||||
const driver = requireEngineDriver(connection);
|
const driver = requireEngineDriver(connection);
|
||||||
const pool = await connectUtility(driver, connection);
|
const pool = await connectUtility(driver, connection, 'read');
|
||||||
console.log(`Connected.`);
|
console.log(`Connected.`);
|
||||||
|
|
||||||
const fullName = { pureName, schemaName };
|
const fullName = { pureName, schemaName };
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ async function tableWriter({ connection, schemaName, pureName, driver, systemCon
|
|||||||
if (!driver) {
|
if (!driver) {
|
||||||
driver = requireEngineDriver(connection);
|
driver = requireEngineDriver(connection);
|
||||||
}
|
}
|
||||||
const pool = systemConnection || (await connectUtility(driver, connection));
|
const pool = systemConnection || (await connectUtility(driver, connection, 'write'));
|
||||||
|
|
||||||
console.log(`Connected.`);
|
console.log(`Connected.`);
|
||||||
return await driver.writeTable(pool, { schemaName, pureName }, options);
|
return await driver.writeTable(pool, { schemaName, pureName }, options);
|
||||||
|
|||||||
@@ -4,11 +4,47 @@ const fs = require('fs-extra');
|
|||||||
const { decryptConnection } = require('./crypting');
|
const { decryptConnection } = require('./crypting');
|
||||||
const { getSshTunnel } = require('./sshTunnel');
|
const { getSshTunnel } = require('./sshTunnel');
|
||||||
const { getSshTunnelProxy } = require('./sshTunnelProxy');
|
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 = {
|
const connection = {
|
||||||
database: storedConnection.defaultDatabase,
|
database: connectionLoaded.defaultDatabase,
|
||||||
...decryptConnection(storedConnection),
|
...decryptConnection(connectionLoaded),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!connection.port && driver.defaultPort) connection.port = driver.defaultPort.toString();
|
if (!connection.port && driver.defaultPort) connection.port = driver.defaultPort.toString();
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ const platformInfo = {
|
|||||||
environment: process.env.NODE_ENV,
|
environment: process.env.NODE_ENV,
|
||||||
platform,
|
platform,
|
||||||
runningInWebpack: !!process.env.WEBPACK_DEV_SERVER_URL,
|
runningInWebpack: !!process.env.WEBPACK_DEV_SERVER_URL,
|
||||||
|
allowShellConnection: !!process.env.SHELL_CONNECTION || !!isElectron(),
|
||||||
defaultKeyfile: path.join(os.homedir(), '.ssh/id_rsa'),
|
defaultKeyfile: path.join(os.homedir(), '.ssh/id_rsa'),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -417,10 +417,7 @@
|
|||||||
{
|
{
|
||||||
functionName: menu.functionName,
|
functionName: menu.functionName,
|
||||||
props: {
|
props: {
|
||||||
connection: {
|
connection: extractShellConnection(coninfo, data.database),
|
||||||
..._.omit(coninfo, ['_id', 'displayName']),
|
|
||||||
..._.pick(data, ['database']),
|
|
||||||
},
|
|
||||||
..._.pick(data, ['pureName', 'schemaName']),
|
..._.pick(data, ['pureName', 'schemaName']),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -629,6 +626,7 @@
|
|||||||
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
import ConfirmModal from '../modals/ConfirmModal.svelte';
|
||||||
import { apiCall } from '../utility/api';
|
import { apiCall } from '../utility/api';
|
||||||
import InputTextModal from '../modals/InputTextModal.svelte';
|
import InputTextModal from '../modals/InputTextModal.svelte';
|
||||||
|
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||||
|
|
||||||
export let data;
|
export let data;
|
||||||
export let passProps;
|
export let passProps;
|
||||||
|
|||||||
@@ -112,6 +112,7 @@
|
|||||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
import ErrorInfo from '../elements/ErrorInfo.svelte';
|
||||||
|
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||||
import ConfirmNoSqlModal from '../modals/ConfirmNoSqlModal.svelte';
|
import ConfirmNoSqlModal from '../modals/ConfirmNoSqlModal.svelte';
|
||||||
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
import ErrorMessageModal from '../modals/ErrorMessageModal.svelte';
|
||||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||||
@@ -202,10 +203,7 @@
|
|||||||
{
|
{
|
||||||
functionName: 'queryReader',
|
functionName: 'queryReader',
|
||||||
props: {
|
props: {
|
||||||
connection: {
|
connection: extractShellConnection(coninfo, database),
|
||||||
..._.omit(coninfo, ['_id', 'displayName']),
|
|
||||||
database,
|
|
||||||
},
|
|
||||||
sql: getExportQuery(),
|
sql: getExportQuery(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -69,6 +69,7 @@
|
|||||||
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
import { registerQuickExportHandler } from '../buttons/ToolStripExportButton.svelte';
|
||||||
|
|
||||||
import registerCommand from '../commands/registerCommand';
|
import registerCommand from '../commands/registerCommand';
|
||||||
|
import { extractShellConnection } from '../impexp/createImpExpScript';
|
||||||
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
import ImportExportModal from '../modals/ImportExportModal.svelte';
|
||||||
import { showModal } from '../modals/modalTools';
|
import { showModal } from '../modals/modalTools';
|
||||||
import { apiCall } from '../utility/api';
|
import { apiCall } from '../utility/api';
|
||||||
@@ -187,10 +188,7 @@
|
|||||||
{
|
{
|
||||||
functionName: 'queryReader',
|
functionName: 'queryReader',
|
||||||
props: {
|
props: {
|
||||||
connection: {
|
connection: extractShellConnection(coninfo, database),
|
||||||
..._.omit(coninfo, ['_id', 'displayName']),
|
|
||||||
database,
|
|
||||||
},
|
|
||||||
sql: display.getExportQuery(),
|
sql: display.getExportQuery(),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import getAsArray from '../utility/getAsArray';
|
|||||||
import { getConnectionInfo } from '../utility/metadataLoaders';
|
import { getConnectionInfo } from '../utility/metadataLoaders';
|
||||||
import { findEngineDriver, findObjectLike } from 'dbgate-tools';
|
import { findEngineDriver, findObjectLike } from 'dbgate-tools';
|
||||||
import { findFileFormat } from '../plugins/fileformats';
|
import { findFileFormat } from '../plugins/fileformats';
|
||||||
|
import { getCurrentConfig } from '../stores';
|
||||||
|
|
||||||
export function getTargetName(extensions, source, values) {
|
export function getTargetName(extensions, source, values) {
|
||||||
const key = `targetName_${source}`;
|
const key = `targetName_${source}`;
|
||||||
@@ -33,17 +34,27 @@ function extractDriverApiParameters(values, direction, driver) {
|
|||||||
return _.fromPairs(pairs);
|
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) {
|
async function getConnection(extensions, storageType, conid, database) {
|
||||||
if (storageType == 'database' || storageType == 'query') {
|
if (storageType == 'database' || storageType == 'query') {
|
||||||
const conn = await getConnectionInfo({ conid });
|
const conn = await getConnectionInfo({ conid });
|
||||||
const driver = findEngineDriver(conn, extensions);
|
const driver = findEngineDriver(conn, extensions);
|
||||||
return [
|
const connection = extractShellConnection(conn, database);
|
||||||
{
|
return [connection, driver];
|
||||||
..._.omit(conn, ['_id', 'displayName']),
|
|
||||||
database,
|
|
||||||
},
|
|
||||||
driver,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
return [null, null];
|
return [null, null];
|
||||||
}
|
}
|
||||||
@@ -201,7 +212,7 @@ export default async function createImpExpScript(extensions, values, addEditorIn
|
|||||||
// @ts-ignore
|
// @ts-ignore
|
||||||
script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver));
|
script.assign(targetVar, ...getTargetExpr(extensions, sourceName, values, targetConnection, targetDriver));
|
||||||
|
|
||||||
const colmap = normalizeExportColumnMap(values[`columns_${sourceName}`] );
|
const colmap = normalizeExportColumnMap(values[`columns_${sourceName}`]);
|
||||||
|
|
||||||
let colmapVar = null;
|
let colmapVar = null;
|
||||||
if (colmap) {
|
if (colmap) {
|
||||||
|
|||||||
Reference in New Issue
Block a user