mirror of
https://github.com/DeNNiiInc/dbgate.git
synced 2026-04-26 09:56:00 +00:00
azure auth WIP
This commit is contained in:
@@ -16,6 +16,7 @@ const { safeJsonParse, getLogger } = require('dbgate-tools');
|
|||||||
const platformInfo = require('../utility/platformInfo');
|
const platformInfo = require('../utility/platformInfo');
|
||||||
const { connectionHasPermission, testConnectionPermission } = require('../utility/hasPermission');
|
const { connectionHasPermission, testConnectionPermission } = require('../utility/hasPermission');
|
||||||
const pipeForkLogs = require('../utility/pipeForkLogs');
|
const pipeForkLogs = require('../utility/pipeForkLogs');
|
||||||
|
const requireEngineDriver = require('../utility/requireEngineDriver');
|
||||||
|
|
||||||
const logger = getLogger('connections');
|
const logger = getLogger('connections');
|
||||||
|
|
||||||
@@ -345,7 +346,7 @@ module.exports = {
|
|||||||
|
|
||||||
const storage = require('./storage');
|
const storage = require('./storage');
|
||||||
|
|
||||||
const storageConnection = await storage.getConnection({conid});
|
const storageConnection = await storage.getConnection({ conid });
|
||||||
if (storageConnection) {
|
if (storageConnection) {
|
||||||
return storageConnection;
|
return storageConnection;
|
||||||
}
|
}
|
||||||
@@ -379,4 +380,16 @@ module.exports = {
|
|||||||
});
|
});
|
||||||
return res;
|
return res;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
dblogin_meta: {
|
||||||
|
raw: true,
|
||||||
|
method: 'get',
|
||||||
|
},
|
||||||
|
async dblogin(req, res) {
|
||||||
|
const { conid } = req.query;
|
||||||
|
const connection = await this.getCore({ conid });
|
||||||
|
const driver = requireEngineDriver(connection);
|
||||||
|
const authUrl = driver.getRedirectAuthUrl(connection);
|
||||||
|
res.redirect(authUrl);
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -89,6 +89,9 @@ module.exports = {
|
|||||||
if (connection.passwordMode == 'askPassword' || connection.passwordMode == 'askUser') {
|
if (connection.passwordMode == 'askPassword' || connection.passwordMode == 'askUser') {
|
||||||
throw new MissingCredentialsError({ conid, passwordMode: connection.passwordMode });
|
throw new MissingCredentialsError({ conid, passwordMode: connection.passwordMode });
|
||||||
}
|
}
|
||||||
|
if (connection.useRedirectDbLogin) {
|
||||||
|
throw new MissingCredentialsError({ conid, redirectToDbLogin: true });
|
||||||
|
}
|
||||||
const subprocess = fork(
|
const subprocess = fork(
|
||||||
global['API_PACKAGE'] || process.argv[1],
|
global['API_PACKAGE'] || process.argv[1],
|
||||||
[
|
[
|
||||||
|
|||||||
1
packages/types/engines.d.ts
vendored
1
packages/types/engines.d.ts
vendored
@@ -149,6 +149,7 @@ export interface EngineDriver {
|
|||||||
summaryCommand(pool, command, row): Promise<void>;
|
summaryCommand(pool, command, row): Promise<void>;
|
||||||
startProfiler(pool, options): Promise<any>;
|
startProfiler(pool, options): Promise<any>;
|
||||||
stopProfiler(pool, profiler): Promise<void>;
|
stopProfiler(pool, profiler): Promise<void>;
|
||||||
|
getRedirectAuthUrl(connection): Promise<string>;
|
||||||
|
|
||||||
analyserClass?: any;
|
analyserClass?: any;
|
||||||
dumperClass?: any;
|
dumperClass?: any;
|
||||||
|
|||||||
@@ -31,7 +31,8 @@
|
|||||||
|
|
||||||
$: showConnectionFieldArgs = { config: $config };
|
$: showConnectionFieldArgs = { config: $config };
|
||||||
|
|
||||||
$: showUser = driver?.showConnectionField('user', $values, showConnectionFieldArgs) && $values.passwordMode != 'askUser';
|
$: showUser =
|
||||||
|
driver?.showConnectionField('user', $values, showConnectionFieldArgs) && $values.passwordMode != 'askUser';
|
||||||
$: showPassword =
|
$: showPassword =
|
||||||
driver?.showConnectionField('password', $values, showConnectionFieldArgs) &&
|
driver?.showConnectionField('password', $values, showConnectionFieldArgs) &&
|
||||||
$values.passwordMode != 'askPassword' &&
|
$values.passwordMode != 'askPassword' &&
|
||||||
@@ -83,17 +84,19 @@
|
|||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if $authTypes && driver?.showConnectionField('authType', $values, showConnectionFieldArgs)}
|
{#if $authTypes && driver?.showConnectionField('authType', $values, showConnectionFieldArgs)}
|
||||||
<FormSelectField
|
{#key $authTypes}
|
||||||
label={driver?.authTypeLabel ?? 'Authentication'}
|
<FormSelectField
|
||||||
name="authType"
|
label={driver?.authTypeLabel ?? 'Authentication'}
|
||||||
isNative
|
name="authType"
|
||||||
disabled={isConnected}
|
isNative
|
||||||
defaultValue={driver?.defaultAuthTypeName}
|
disabled={isConnected}
|
||||||
options={$authTypes.map(auth => ({
|
defaultValue={driver?.defaultAuthTypeName}
|
||||||
value: auth.name,
|
options={$authTypes.map(auth => ({
|
||||||
label: auth.title,
|
value: auth.name,
|
||||||
}))}
|
label: auth.title,
|
||||||
/>
|
}))}
|
||||||
|
/>
|
||||||
|
{/key}
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if driver?.showConnectionField('clientLibraryPath', $values, showConnectionFieldArgs)}
|
{#if driver?.showConnectionField('clientLibraryPath', $values, showConnectionFieldArgs)}
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import { showModal } from '../modals/modalTools';
|
|||||||
import DatabaseLoginModal, { isDatabaseLoginVisible } from '../modals/DatabaseLoginModal.svelte';
|
import DatabaseLoginModal, { isDatabaseLoginVisible } from '../modals/DatabaseLoginModal.svelte';
|
||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import uuidv1 from 'uuid/v1';
|
import uuidv1 from 'uuid/v1';
|
||||||
|
import { openWebLink } from './exportFileTools';
|
||||||
|
|
||||||
export const strmid = uuidv1();
|
export const strmid = uuidv1();
|
||||||
|
|
||||||
@@ -63,7 +64,9 @@ function processApiResponse(route, args, resp) {
|
|||||||
// }
|
// }
|
||||||
|
|
||||||
if (resp?.missingCredentials) {
|
if (resp?.missingCredentials) {
|
||||||
if (!isDatabaseLoginVisible()) {
|
if (resp.detail.redirectToDbLogin) {
|
||||||
|
openWebLink('connections/dblogin');
|
||||||
|
} else if (!isDatabaseLoginVisible()) {
|
||||||
showModal(DatabaseLoginModal, resp.detail);
|
showModal(DatabaseLoginModal, resp.detail);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
|||||||
@@ -31,12 +31,13 @@
|
|||||||
"plugout": "dbgate-plugout dbgate-plugin-mssql"
|
"plugout": "dbgate-plugout dbgate-plugin-mssql"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"async-lock": "^1.2.6",
|
||||||
|
"@azure/msal-node": "^2.12.0",
|
||||||
"dbgate-plugin-tools": "^1.0.7",
|
"dbgate-plugin-tools": "^1.0.7",
|
||||||
"dbgate-query-splitter": "^4.10.1",
|
"dbgate-query-splitter": "^4.10.1",
|
||||||
"webpack": "^5.91.0",
|
|
||||||
"webpack-cli": "^5.1.4",
|
|
||||||
"dbgate-tools": "^5.0.0-alpha.1",
|
"dbgate-tools": "^5.0.0-alpha.1",
|
||||||
"tedious": "^18.2.0",
|
"tedious": "^18.2.0",
|
||||||
"async-lock": "^1.2.6"
|
"webpack": "^5.91.0",
|
||||||
|
"webpack-cli": "^5.1.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
12
plugins/dbgate-plugin-mssql/src/backend/azureAuth.js
Normal file
12
plugins/dbgate-plugin-mssql/src/backend/azureAuth.js
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
function getAzureAuthTypes(platformInfo) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function azureGetRedirectAuthUrl(connection) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = {
|
||||||
|
getAzureAuthTypes,
|
||||||
|
azureGetRedirectAuthUrl,
|
||||||
|
};
|
||||||
@@ -8,8 +8,11 @@ const AsyncLock = require('async-lock');
|
|||||||
const nativeDriver = require('./nativeDriver');
|
const nativeDriver = require('./nativeDriver');
|
||||||
const lock = new AsyncLock();
|
const lock = new AsyncLock();
|
||||||
const { tediousConnect, tediousQueryCore, tediousReadQuery, tediousStream } = require('./tediousDriver');
|
const { tediousConnect, tediousQueryCore, tediousReadQuery, tediousStream } = require('./tediousDriver');
|
||||||
|
const { getAzureAuthTypes } = require('./azureAuth');
|
||||||
const { nativeConnect, nativeQueryCore, nativeReadQuery, nativeStream } = nativeDriver;
|
const { nativeConnect, nativeQueryCore, nativeReadQuery, nativeStream } = nativeDriver;
|
||||||
|
|
||||||
let requireMsnodesqlv8;
|
let requireMsnodesqlv8;
|
||||||
|
let platformInfo;
|
||||||
|
|
||||||
const versionQuery = `
|
const versionQuery = `
|
||||||
SELECT
|
SELECT
|
||||||
@@ -52,7 +55,14 @@ const driver = {
|
|||||||
analyserClass: MsSqlAnalyser,
|
analyserClass: MsSqlAnalyser,
|
||||||
|
|
||||||
getAuthTypes() {
|
getAuthTypes() {
|
||||||
return requireMsnodesqlv8 ? windowsAuthTypes : null;
|
const res = [];
|
||||||
|
if (requireMsnodesqlv8) res.push(...windowsAuthTypes);
|
||||||
|
const azureAuthTypes = getAzureAuthTypes(platformInfo);
|
||||||
|
if (azureAuthTypes) res.push(...azureAuthTypes);
|
||||||
|
if (res.length > 0) {
|
||||||
|
return _.uniqBy(res, 'name');
|
||||||
|
}
|
||||||
|
return null;
|
||||||
},
|
},
|
||||||
|
|
||||||
async connect(conn) {
|
async connect(conn) {
|
||||||
@@ -115,12 +125,16 @@ const driver = {
|
|||||||
const { rows } = await this.query(pool, 'SELECT name FROM sys.databases order by name');
|
const { rows } = await this.query(pool, 'SELECT name FROM sys.databases order by name');
|
||||||
return rows;
|
return rows;
|
||||||
},
|
},
|
||||||
|
getRedirectAuthUrl(connection) {
|
||||||
|
return azureGetRedirectAuthUrl(connection);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
driver.initialize = dbgateEnv => {
|
driver.initialize = dbgateEnv => {
|
||||||
if (dbgateEnv.nativeModules && dbgateEnv.nativeModules.msnodesqlv8) {
|
if (dbgateEnv.nativeModules && dbgateEnv.nativeModules.msnodesqlv8) {
|
||||||
requireMsnodesqlv8 = dbgateEnv.nativeModules.msnodesqlv8;
|
requireMsnodesqlv8 = dbgateEnv.nativeModules.msnodesqlv8;
|
||||||
}
|
}
|
||||||
|
platformInfo = dbgateEnv.platformInfo;
|
||||||
nativeDriver.initialize(dbgateEnv);
|
nativeDriver.initialize(dbgateEnv);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ const driver = {
|
|||||||
field
|
field
|
||||||
) ||
|
) ||
|
||||||
(field == 'trustServerCertificate' && values.authType != 'sql' && values.authType != 'sspi') ||
|
(field == 'trustServerCertificate' && values.authType != 'sql' && values.authType != 'sspi') ||
|
||||||
(field == 'windowsDomain' && values.authType != 'sql' && values.authType != 'sspi'),
|
(field == 'windowsDomain' && values.authType != 'sql' && values.authType != 'sspi' && values.authType != 'msentra'),
|
||||||
// (field == 'useDatabaseUrl' && values.authType != 'sql' && values.authType != 'sspi')
|
// (field == 'useDatabaseUrl' && values.authType != 'sql' && values.authType != 'sspi')
|
||||||
getQuerySplitterOptions: usage =>
|
getQuerySplitterOptions: usage =>
|
||||||
usage == 'editor'
|
usage == 'editor'
|
||||||
@@ -154,6 +154,13 @@ const driver = {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
},
|
},
|
||||||
|
|
||||||
|
beforeConnectionSave: connection => {
|
||||||
|
return {
|
||||||
|
...connection,
|
||||||
|
useRedirectDbLogin: connection.authType == 'msentra' ? 1 : 0,
|
||||||
|
};
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = driver;
|
module.exports = driver;
|
||||||
|
|||||||
14
yarn.lock
14
yarn.lock
@@ -164,6 +164,20 @@
|
|||||||
resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.10.0.tgz#215449726717b53d549953db77562cad6cb8421c"
|
resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.10.0.tgz#215449726717b53d549953db77562cad6cb8421c"
|
||||||
integrity sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==
|
integrity sha512-Zk6DPDz7e1wPgLoLgAp0349Yay9RvcjPM5We/ehuenDNsz/t9QEFI7tRoHpp/e47I4p20XE3FiDlhKwAo3utDA==
|
||||||
|
|
||||||
|
"@azure/msal-common@14.14.0":
|
||||||
|
version "14.14.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@azure/msal-common/-/msal-common-14.14.0.tgz#31a015070d5864ebcf9ebb988fcbc5c5536f22d1"
|
||||||
|
integrity sha512-OxcOk9H1/1fktHh6//VCORgSNJc2dCQObTm6JNmL824Z6iZSO6eFo/Bttxe0hETn9B+cr7gDouTQtsRq3YPuSQ==
|
||||||
|
|
||||||
|
"@azure/msal-node@^2.12.0":
|
||||||
|
version "2.12.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.12.0.tgz#57ee6b6011a320046d72dc0828fec46278f2ab2c"
|
||||||
|
integrity sha512-jmk5Im5KujRA2AcyCb0awA3buV8niSrwXZs+NBJWIvxOz76RvNlusGIqi43A0h45BPUy93Qb+CPdpJn82NFTIg==
|
||||||
|
dependencies:
|
||||||
|
"@azure/msal-common" "14.14.0"
|
||||||
|
jsonwebtoken "^9.0.0"
|
||||||
|
uuid "^8.3.0"
|
||||||
|
|
||||||
"@azure/msal-node@^2.5.1":
|
"@azure/msal-node@^2.5.1":
|
||||||
version "2.8.0"
|
version "2.8.0"
|
||||||
resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.8.0.tgz#ef6e4a76bcd0851f7b1240d94b00fe1f9a52d559"
|
resolved "https://registry.yarnpkg.com/@azure/msal-node/-/msal-node-2.8.0.tgz#ef6e4a76bcd0851f7b1240d94b00fe1f9a52d559"
|
||||||
|
|||||||
Reference in New Issue
Block a user