dbgate-api-premium 6.7.3 → 6.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +6 -5
- package/src/auth/storageAuthProvider.js +9 -0
- package/src/controllers/connections.js +11 -49
- package/src/controllers/storage.js +20 -3
- package/src/currentVersion.js +2 -2
- package/src/shell/copyStream.js +2 -2
- package/src/shell/dataReplicator.js +1 -0
- package/src/storageModel.js +171 -2
- package/src/utility/auditlog.js +8 -3
- package/src/utility/envtools.js +445 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dbgate-api-premium",
|
|
3
3
|
"main": "src/index.js",
|
|
4
|
-
"version": "6.
|
|
4
|
+
"version": "6.8.1",
|
|
5
5
|
"homepage": "https://dbgate.org/",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -30,10 +30,10 @@
|
|
|
30
30
|
"compare-versions": "^3.6.0",
|
|
31
31
|
"cors": "^2.8.5",
|
|
32
32
|
"cross-env": "^6.0.3",
|
|
33
|
-
"dbgate-datalib": "^6.
|
|
33
|
+
"dbgate-datalib": "^6.8.1",
|
|
34
34
|
"dbgate-query-splitter": "^4.11.9",
|
|
35
|
-
"dbgate-sqltree": "^6.
|
|
36
|
-
"dbgate-tools": "^6.
|
|
35
|
+
"dbgate-sqltree": "^6.8.1",
|
|
36
|
+
"dbgate-tools": "^6.8.1",
|
|
37
37
|
"debug": "^4.3.4",
|
|
38
38
|
"diff": "^5.0.0",
|
|
39
39
|
"diff2html": "^3.4.13",
|
|
@@ -75,6 +75,7 @@
|
|
|
75
75
|
"start:dblogin": "env-cmd -f env/dblogin/.env node src/index.js --listen-api",
|
|
76
76
|
"start:filedb": "env-cmd node src/index.js /home/jena/test/chinook/Chinook.db --listen-api",
|
|
77
77
|
"start:storage": "env-cmd -f env/storage/.env node src/index.js --listen-api",
|
|
78
|
+
"start:sfill": "env-cmd -f env/sfill/.env node src/index.js --listen-api",
|
|
78
79
|
"start:storage:built": "env-cmd -f env/storage/.env cross-env DEVMODE= BUILTWEBMODE=1 node dist/bundle.js --listen-api",
|
|
79
80
|
"start:singleconn": "env-cmd node src/index.js --server localhost --user root --port 3307 --engine mysql@dbgate-plugin-mysql --password test --listen-api",
|
|
80
81
|
"start:azure": "env-cmd -f env/azure/.env node src/index.js --listen-api",
|
|
@@ -86,7 +87,7 @@
|
|
|
86
87
|
"devDependencies": {
|
|
87
88
|
"@types/fs-extra": "^9.0.11",
|
|
88
89
|
"@types/lodash": "^4.14.149",
|
|
89
|
-
"dbgate-types": "^6.
|
|
90
|
+
"dbgate-types": "^6.8.1",
|
|
90
91
|
"env-cmd": "^10.1.0",
|
|
91
92
|
"jsdoc-to-markdown": "^9.0.5",
|
|
92
93
|
"node-loader": "^1.0.2",
|
|
@@ -316,6 +316,15 @@ class OauthProvider extends StorageProviderBase {
|
|
|
316
316
|
if (this.config.oauthSaveNotDefinedLogins == 1 && loginRows.length == 0) {
|
|
317
317
|
const email = payload[this.config.oauthEmailField || 'email'] ?? null;
|
|
318
318
|
await storageSqlCommandFmt('insert into ~users (~login, ~email) values (%v, %v)', login, email);
|
|
319
|
+
sendToAuditLog(req, {
|
|
320
|
+
category: 'auth',
|
|
321
|
+
component: 'OauthProvider',
|
|
322
|
+
action: 'userCreated',
|
|
323
|
+
event: 'user.oauthAutoCreated',
|
|
324
|
+
severity: 'info',
|
|
325
|
+
detail: { login, email },
|
|
326
|
+
message: `New user ${login} automatically created from OAuth login`,
|
|
327
|
+
});
|
|
319
328
|
}
|
|
320
329
|
|
|
321
330
|
let groups =
|
|
@@ -23,6 +23,7 @@ const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
|
23
23
|
const requireEngineDriver = require('../utility/requireEngineDriver');
|
|
24
24
|
const { getAuthProviderById } = require('../auth/authProvider');
|
|
25
25
|
const { startTokenChecking } = require('../utility/authProxy');
|
|
26
|
+
const { extractConnectionsFromEnv } = require('../utility/envtools');
|
|
26
27
|
|
|
27
28
|
const logger = getLogger('connections');
|
|
28
29
|
|
|
@@ -61,55 +62,7 @@ function getDatabaseFileLabel(databaseFile) {
|
|
|
61
62
|
|
|
62
63
|
function getPortalCollections() {
|
|
63
64
|
if (process.env.CONNECTIONS) {
|
|
64
|
-
const connections =
|
|
65
|
-
_id: id,
|
|
66
|
-
engine: process.env[`ENGINE_${id}`],
|
|
67
|
-
server: process.env[`SERVER_${id}`],
|
|
68
|
-
user: process.env[`USER_${id}`],
|
|
69
|
-
password: process.env[`PASSWORD_${id}`],
|
|
70
|
-
passwordMode: process.env[`PASSWORD_MODE_${id}`],
|
|
71
|
-
port: process.env[`PORT_${id}`],
|
|
72
|
-
databaseUrl: process.env[`URL_${id}`],
|
|
73
|
-
useDatabaseUrl: !!process.env[`URL_${id}`],
|
|
74
|
-
databaseFile: process.env[`FILE_${id}`]?.replace(
|
|
75
|
-
'%%E2E_TEST_DATA_DIRECTORY%%',
|
|
76
|
-
path.join(path.dirname(path.dirname(__dirname)), 'e2e-tests', 'tmpdata')
|
|
77
|
-
),
|
|
78
|
-
socketPath: process.env[`SOCKET_PATH_${id}`],
|
|
79
|
-
serviceName: process.env[`SERVICE_NAME_${id}`],
|
|
80
|
-
authType: process.env[`AUTH_TYPE_${id}`] || (process.env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
|
|
81
|
-
defaultDatabase:
|
|
82
|
-
process.env[`DATABASE_${id}`] ||
|
|
83
|
-
(process.env[`FILE_${id}`] ? getDatabaseFileLabel(process.env[`FILE_${id}`]) : null),
|
|
84
|
-
singleDatabase: !!process.env[`DATABASE_${id}`] || !!process.env[`FILE_${id}`],
|
|
85
|
-
displayName: process.env[`LABEL_${id}`],
|
|
86
|
-
isReadOnly: process.env[`READONLY_${id}`],
|
|
87
|
-
databases: process.env[`DBCONFIG_${id}`] ? safeJsonParse(process.env[`DBCONFIG_${id}`]) : null,
|
|
88
|
-
allowedDatabases: process.env[`ALLOWED_DATABASES_${id}`]?.replace(/\|/g, '\n'),
|
|
89
|
-
allowedDatabasesRegex: process.env[`ALLOWED_DATABASES_REGEX_${id}`],
|
|
90
|
-
parent: process.env[`PARENT_${id}`] || undefined,
|
|
91
|
-
useSeparateSchemas: !!process.env[`USE_SEPARATE_SCHEMAS_${id}`],
|
|
92
|
-
localDataCenter: process.env[`LOCAL_DATA_CENTER_${id}`],
|
|
93
|
-
|
|
94
|
-
// SSH tunnel
|
|
95
|
-
useSshTunnel: process.env[`USE_SSH_${id}`],
|
|
96
|
-
sshHost: process.env[`SSH_HOST_${id}`],
|
|
97
|
-
sshPort: process.env[`SSH_PORT_${id}`],
|
|
98
|
-
sshMode: process.env[`SSH_MODE_${id}`],
|
|
99
|
-
sshLogin: process.env[`SSH_LOGIN_${id}`],
|
|
100
|
-
sshPassword: process.env[`SSH_PASSWORD_${id}`],
|
|
101
|
-
sshKeyfile: process.env[`SSH_KEY_FILE_${id}`],
|
|
102
|
-
sshKeyfilePassword: process.env[`SSH_KEY_FILE_PASSWORD_${id}`],
|
|
103
|
-
|
|
104
|
-
// SSL
|
|
105
|
-
useSsl: process.env[`USE_SSL_${id}`],
|
|
106
|
-
sslCaFile: process.env[`SSL_CA_FILE_${id}`],
|
|
107
|
-
sslCertFile: process.env[`SSL_CERT_FILE_${id}`],
|
|
108
|
-
sslCertFilePassword: process.env[`SSL_CERT_FILE_PASSWORD_${id}`],
|
|
109
|
-
sslKeyFile: process.env[`SSL_KEY_FILE_${id}`],
|
|
110
|
-
sslRejectUnauthorized: process.env[`SSL_REJECT_UNAUTHORIZED_${id}`],
|
|
111
|
-
trustServerCertificate: process.env[`SSL_TRUST_CERTIFICATE_${id}`],
|
|
112
|
-
}));
|
|
65
|
+
const connections = extractConnectionsFromEnv(process.env);
|
|
113
66
|
|
|
114
67
|
for (const conn of connections) {
|
|
115
68
|
for (const prop in process.env) {
|
|
@@ -229,6 +182,15 @@ module.exports = {
|
|
|
229
182
|
);
|
|
230
183
|
}
|
|
231
184
|
await this.checkUnsavedConnectionsLimit();
|
|
185
|
+
|
|
186
|
+
if (process.env.STORAGE_DATABASE && process.env.CONNECTIONS) {
|
|
187
|
+
const storage = require('./storage');
|
|
188
|
+
try {
|
|
189
|
+
await storage.fillStorageConnectionsFromEnv();
|
|
190
|
+
} catch (err) {
|
|
191
|
+
logger.error(extractErrorLogData(err), 'DBGM-00268 Error filling storage connections from env');
|
|
192
|
+
}
|
|
193
|
+
}
|
|
232
194
|
},
|
|
233
195
|
|
|
234
196
|
list_meta: true,
|
|
@@ -41,6 +41,7 @@ const crypto = require('crypto');
|
|
|
41
41
|
const dataReplicator = require('../shell/dataReplicator');
|
|
42
42
|
const storageReplicatorItems = require('../utility/storageReplicatorItems');
|
|
43
43
|
const { sendToAuditLog } = require('../utility/auditlog');
|
|
44
|
+
const { extractImportEntitiesFromEnv, createStorageFromEnvReplicatorItems } = require('../utility/envtools');
|
|
44
45
|
|
|
45
46
|
const logger = getLogger('storage');
|
|
46
47
|
|
|
@@ -642,7 +643,7 @@ module.exports = {
|
|
|
642
643
|
getConnectionList_meta: true,
|
|
643
644
|
async getConnectionList() {
|
|
644
645
|
const resp = await storageSelectFmt(
|
|
645
|
-
`select ~connections.~id,~connections.~engine,~connections.~displayName,~connections.~server,~connections.~user from ~connections`
|
|
646
|
+
`select ~connections.~id,~connections.~engine,~connections.~displayName,~connections.~server,~connections.~user,~connections.~import_source_id from ~connections`
|
|
646
647
|
);
|
|
647
648
|
return resp;
|
|
648
649
|
},
|
|
@@ -739,7 +740,7 @@ module.exports = {
|
|
|
739
740
|
|
|
740
741
|
getRoleList_meta: true,
|
|
741
742
|
async getRoleList() {
|
|
742
|
-
const resp = await storageSelectFmt(`select ~roles.~id,~roles.~name from ~roles`);
|
|
743
|
+
const resp = await storageSelectFmt(`select ~roles.~id,~roles.~name,~roles.~import_source_id from ~roles`);
|
|
743
744
|
const usedPermissions = await storageSelectFmt(`select * from ~role_permissions`);
|
|
744
745
|
return resp.map(x => ({
|
|
745
746
|
...x,
|
|
@@ -750,7 +751,7 @@ module.exports = {
|
|
|
750
751
|
getRoleDetail_meta: true,
|
|
751
752
|
async getRoleDetail({ id }) {
|
|
752
753
|
const resp =
|
|
753
|
-
id == 'new' ? {} : await storageSelectFmt(`select ~roles.~id,~roles.~name from ~roles where ~roles.~id = %v`, id);
|
|
754
|
+
id == 'new' ? {} : await storageSelectFmt(`select ~roles.~id,~roles.~name,~roles.~import_source_id from ~roles where ~roles.~id = %v`, id);
|
|
754
755
|
|
|
755
756
|
const basePermissions = getPredefinedPermissions(id < 0 && resp[0]?.name ? resp[0]?.name : 'logged-user');
|
|
756
757
|
const permissions =
|
|
@@ -1034,4 +1035,20 @@ module.exports = {
|
|
|
1034
1035
|
sendToAuditLog(req, props);
|
|
1035
1036
|
return null;
|
|
1036
1037
|
},
|
|
1038
|
+
|
|
1039
|
+
async fillStorageConnectionsFromEnv() {
|
|
1040
|
+
const importEntities = extractImportEntitiesFromEnv(process.env);
|
|
1041
|
+
if (!importEntities) {
|
|
1042
|
+
return;
|
|
1043
|
+
}
|
|
1044
|
+
|
|
1045
|
+
const [conn, driver] = await getStorageConnection();
|
|
1046
|
+
// @ts-ignore
|
|
1047
|
+
await dataReplicator({
|
|
1048
|
+
systemConnection: conn,
|
|
1049
|
+
driver,
|
|
1050
|
+
items: createStorageFromEnvReplicatorItems(importEntities),
|
|
1051
|
+
});
|
|
1052
|
+
socket.emitChanged('connection-list-changed');
|
|
1053
|
+
},
|
|
1037
1054
|
};
|
package/src/currentVersion.js
CHANGED
package/src/shell/copyStream.js
CHANGED
|
@@ -65,6 +65,8 @@ async function copyStream(input, output, options) {
|
|
|
65
65
|
});
|
|
66
66
|
}
|
|
67
67
|
} catch (err) {
|
|
68
|
+
logger.error(extractErrorLogData(err, { progressName }), 'DBGM-00157 Import/export job failed');
|
|
69
|
+
|
|
68
70
|
process.send({
|
|
69
71
|
msgtype: 'copyStreamError',
|
|
70
72
|
copyStreamError: {
|
|
@@ -82,8 +84,6 @@ async function copyStream(input, output, options) {
|
|
|
82
84
|
errorMessage: extractErrorMessage(err),
|
|
83
85
|
});
|
|
84
86
|
}
|
|
85
|
-
|
|
86
|
-
logger.error(extractErrorLogData(err, { progressName }), 'DBGM-00157 Import/export job failed');
|
|
87
87
|
// throw err;
|
|
88
88
|
}
|
|
89
89
|
}
|
|
@@ -64,6 +64,7 @@ async function dataReplicator({
|
|
|
64
64
|
createNew: compileOperationFunction(item.createNew, item.createCondition),
|
|
65
65
|
updateExisting: compileOperationFunction(item.updateExisting, item.updateCondition),
|
|
66
66
|
deleteMissing: !!item.deleteMissing,
|
|
67
|
+
skipUpdateColumns: item.skipUpdateColumns,
|
|
67
68
|
deleteRestrictionColumns: item.deleteRestrictionColumns ?? [],
|
|
68
69
|
openStream: item.openStream
|
|
69
70
|
? item.openStream
|
package/src/storageModel.js
CHANGED
|
@@ -686,9 +686,34 @@ module.exports = {
|
|
|
686
686
|
"columnName": "connectionDefinition",
|
|
687
687
|
"dataType": "text",
|
|
688
688
|
"notNull": false
|
|
689
|
+
},
|
|
690
|
+
{
|
|
691
|
+
"pureName": "connections",
|
|
692
|
+
"columnName": "import_source_id",
|
|
693
|
+
"dataType": "int",
|
|
694
|
+
"notNull": false
|
|
695
|
+
},
|
|
696
|
+
{
|
|
697
|
+
"pureName": "connections",
|
|
698
|
+
"columnName": "id_original",
|
|
699
|
+
"dataType": "varchar(250)",
|
|
700
|
+
"notNull": false
|
|
701
|
+
}
|
|
702
|
+
],
|
|
703
|
+
"foreignKeys": [
|
|
704
|
+
{
|
|
705
|
+
"constraintType": "foreignKey",
|
|
706
|
+
"constraintName": "FK_connections_import_source_id",
|
|
707
|
+
"pureName": "connections",
|
|
708
|
+
"refTableName": "import_sources",
|
|
709
|
+
"columns": [
|
|
710
|
+
{
|
|
711
|
+
"columnName": "import_source_id",
|
|
712
|
+
"refColumnName": "id"
|
|
713
|
+
}
|
|
714
|
+
]
|
|
689
715
|
}
|
|
690
716
|
],
|
|
691
|
-
"foreignKeys": [],
|
|
692
717
|
"primaryKey": {
|
|
693
718
|
"pureName": "connections",
|
|
694
719
|
"constraintType": "primaryKey",
|
|
@@ -790,6 +815,41 @@ module.exports = {
|
|
|
790
815
|
}
|
|
791
816
|
]
|
|
792
817
|
},
|
|
818
|
+
{
|
|
819
|
+
"pureName": "import_sources",
|
|
820
|
+
"columns": [
|
|
821
|
+
{
|
|
822
|
+
"pureName": "import_sources",
|
|
823
|
+
"columnName": "id",
|
|
824
|
+
"dataType": "int",
|
|
825
|
+
"autoIncrement": true,
|
|
826
|
+
"notNull": true
|
|
827
|
+
},
|
|
828
|
+
{
|
|
829
|
+
"pureName": "import_sources",
|
|
830
|
+
"columnName": "name",
|
|
831
|
+
"dataType": "varchar(250)",
|
|
832
|
+
"notNull": true
|
|
833
|
+
}
|
|
834
|
+
],
|
|
835
|
+
"foreignKeys": [],
|
|
836
|
+
"primaryKey": {
|
|
837
|
+
"pureName": "import_sources",
|
|
838
|
+
"constraintType": "primaryKey",
|
|
839
|
+
"constraintName": "PK_import_sources",
|
|
840
|
+
"columns": [
|
|
841
|
+
{
|
|
842
|
+
"columnName": "id"
|
|
843
|
+
}
|
|
844
|
+
]
|
|
845
|
+
},
|
|
846
|
+
"preloadedRows": [
|
|
847
|
+
{
|
|
848
|
+
"id": -1,
|
|
849
|
+
"name": "env"
|
|
850
|
+
}
|
|
851
|
+
]
|
|
852
|
+
},
|
|
793
853
|
{
|
|
794
854
|
"pureName": "roles",
|
|
795
855
|
"columns": [
|
|
@@ -805,9 +865,34 @@ module.exports = {
|
|
|
805
865
|
"columnName": "name",
|
|
806
866
|
"dataType": "varchar(250)",
|
|
807
867
|
"notNull": false
|
|
868
|
+
},
|
|
869
|
+
{
|
|
870
|
+
"pureName": "roles",
|
|
871
|
+
"columnName": "import_source_id",
|
|
872
|
+
"dataType": "int",
|
|
873
|
+
"notNull": false
|
|
874
|
+
},
|
|
875
|
+
{
|
|
876
|
+
"pureName": "roles",
|
|
877
|
+
"columnName": "id_original",
|
|
878
|
+
"dataType": "varchar(250)",
|
|
879
|
+
"notNull": false
|
|
880
|
+
}
|
|
881
|
+
],
|
|
882
|
+
"foreignKeys": [
|
|
883
|
+
{
|
|
884
|
+
"constraintType": "foreignKey",
|
|
885
|
+
"constraintName": "FK_roles_import_source_id",
|
|
886
|
+
"pureName": "roles",
|
|
887
|
+
"refTableName": "import_sources",
|
|
888
|
+
"columns": [
|
|
889
|
+
{
|
|
890
|
+
"columnName": "import_source_id",
|
|
891
|
+
"refColumnName": "id"
|
|
892
|
+
}
|
|
893
|
+
]
|
|
808
894
|
}
|
|
809
895
|
],
|
|
810
|
-
"foreignKeys": [],
|
|
811
896
|
"primaryKey": {
|
|
812
897
|
"pureName": "roles",
|
|
813
898
|
"constraintType": "primaryKey",
|
|
@@ -854,6 +939,12 @@ module.exports = {
|
|
|
854
939
|
"columnName": "connection_id",
|
|
855
940
|
"dataType": "int",
|
|
856
941
|
"notNull": true
|
|
942
|
+
},
|
|
943
|
+
{
|
|
944
|
+
"pureName": "role_connections",
|
|
945
|
+
"columnName": "import_source_id",
|
|
946
|
+
"dataType": "int",
|
|
947
|
+
"notNull": false
|
|
857
948
|
}
|
|
858
949
|
],
|
|
859
950
|
"foreignKeys": [
|
|
@@ -882,6 +973,18 @@ module.exports = {
|
|
|
882
973
|
"refColumnName": "id"
|
|
883
974
|
}
|
|
884
975
|
]
|
|
976
|
+
},
|
|
977
|
+
{
|
|
978
|
+
"constraintType": "foreignKey",
|
|
979
|
+
"constraintName": "FK_role_connections_import_source_id",
|
|
980
|
+
"pureName": "role_connections",
|
|
981
|
+
"refTableName": "import_sources",
|
|
982
|
+
"columns": [
|
|
983
|
+
{
|
|
984
|
+
"columnName": "import_source_id",
|
|
985
|
+
"refColumnName": "id"
|
|
986
|
+
}
|
|
987
|
+
]
|
|
885
988
|
}
|
|
886
989
|
],
|
|
887
990
|
"primaryKey": {
|
|
@@ -934,6 +1037,18 @@ module.exports = {
|
|
|
934
1037
|
"columnName": "database_permission_role_id",
|
|
935
1038
|
"dataType": "int",
|
|
936
1039
|
"notNull": true
|
|
1040
|
+
},
|
|
1041
|
+
{
|
|
1042
|
+
"pureName": "role_databases",
|
|
1043
|
+
"columnName": "import_source_id",
|
|
1044
|
+
"dataType": "int",
|
|
1045
|
+
"notNull": false
|
|
1046
|
+
},
|
|
1047
|
+
{
|
|
1048
|
+
"pureName": "role_databases",
|
|
1049
|
+
"columnName": "id_original",
|
|
1050
|
+
"dataType": "varchar(250)",
|
|
1051
|
+
"notNull": false
|
|
937
1052
|
}
|
|
938
1053
|
],
|
|
939
1054
|
"foreignKeys": [
|
|
@@ -974,6 +1089,18 @@ module.exports = {
|
|
|
974
1089
|
"refColumnName": "id"
|
|
975
1090
|
}
|
|
976
1091
|
]
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"constraintType": "foreignKey",
|
|
1095
|
+
"constraintName": "FK_role_databases_import_source_id",
|
|
1096
|
+
"pureName": "role_databases",
|
|
1097
|
+
"refTableName": "import_sources",
|
|
1098
|
+
"columns": [
|
|
1099
|
+
{
|
|
1100
|
+
"columnName": "import_source_id",
|
|
1101
|
+
"refColumnName": "id"
|
|
1102
|
+
}
|
|
1103
|
+
]
|
|
977
1104
|
}
|
|
978
1105
|
],
|
|
979
1106
|
"primaryKey": {
|
|
@@ -1087,6 +1214,12 @@ module.exports = {
|
|
|
1087
1214
|
"columnName": "permission",
|
|
1088
1215
|
"dataType": "varchar(250)",
|
|
1089
1216
|
"notNull": true
|
|
1217
|
+
},
|
|
1218
|
+
{
|
|
1219
|
+
"pureName": "role_permissions",
|
|
1220
|
+
"columnName": "import_source_id",
|
|
1221
|
+
"dataType": "int",
|
|
1222
|
+
"notNull": false
|
|
1090
1223
|
}
|
|
1091
1224
|
],
|
|
1092
1225
|
"foreignKeys": [
|
|
@@ -1102,6 +1235,18 @@ module.exports = {
|
|
|
1102
1235
|
"refColumnName": "id"
|
|
1103
1236
|
}
|
|
1104
1237
|
]
|
|
1238
|
+
},
|
|
1239
|
+
{
|
|
1240
|
+
"constraintType": "foreignKey",
|
|
1241
|
+
"constraintName": "FK_role_permissions_import_source_id",
|
|
1242
|
+
"pureName": "role_permissions",
|
|
1243
|
+
"refTableName": "import_sources",
|
|
1244
|
+
"columns": [
|
|
1245
|
+
{
|
|
1246
|
+
"columnName": "import_source_id",
|
|
1247
|
+
"refColumnName": "id"
|
|
1248
|
+
}
|
|
1249
|
+
]
|
|
1105
1250
|
}
|
|
1106
1251
|
],
|
|
1107
1252
|
"primaryKey": {
|
|
@@ -1184,6 +1329,18 @@ module.exports = {
|
|
|
1184
1329
|
"columnName": "table_permission_scope_id",
|
|
1185
1330
|
"dataType": "int",
|
|
1186
1331
|
"notNull": true
|
|
1332
|
+
},
|
|
1333
|
+
{
|
|
1334
|
+
"pureName": "role_tables",
|
|
1335
|
+
"columnName": "import_source_id",
|
|
1336
|
+
"dataType": "int",
|
|
1337
|
+
"notNull": false
|
|
1338
|
+
},
|
|
1339
|
+
{
|
|
1340
|
+
"pureName": "role_tables",
|
|
1341
|
+
"columnName": "id_original",
|
|
1342
|
+
"dataType": "varchar(250)",
|
|
1343
|
+
"notNull": false
|
|
1187
1344
|
}
|
|
1188
1345
|
],
|
|
1189
1346
|
"foreignKeys": [
|
|
@@ -1236,6 +1393,18 @@ module.exports = {
|
|
|
1236
1393
|
"refColumnName": "id"
|
|
1237
1394
|
}
|
|
1238
1395
|
]
|
|
1396
|
+
},
|
|
1397
|
+
{
|
|
1398
|
+
"constraintType": "foreignKey",
|
|
1399
|
+
"constraintName": "FK_role_tables_import_source_id",
|
|
1400
|
+
"pureName": "role_tables",
|
|
1401
|
+
"refTableName": "import_sources",
|
|
1402
|
+
"columns": [
|
|
1403
|
+
{
|
|
1404
|
+
"columnName": "import_source_id",
|
|
1405
|
+
"refColumnName": "id"
|
|
1406
|
+
}
|
|
1407
|
+
]
|
|
1239
1408
|
}
|
|
1240
1409
|
],
|
|
1241
1410
|
"primaryKey": {
|
package/src/utility/auditlog.js
CHANGED
|
@@ -132,11 +132,9 @@ async function sendToAuditLog(
|
|
|
132
132
|
|
|
133
133
|
const { login, userId } = req?.user || {};
|
|
134
134
|
const sessionId = req?.headers?.['x-api-session-id'];
|
|
135
|
-
|
|
136
|
-
auditLogQueue.push({
|
|
135
|
+
const logData = {
|
|
137
136
|
userId,
|
|
138
137
|
login,
|
|
139
|
-
created: new Date().getTime(),
|
|
140
138
|
category,
|
|
141
139
|
component,
|
|
142
140
|
event,
|
|
@@ -153,7 +151,14 @@ async function sendToAuditLog(
|
|
|
153
151
|
sessionGroup,
|
|
154
152
|
sessionParam,
|
|
155
153
|
message,
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
auditLogQueue.push({ ...logData,
|
|
157
|
+
created: new Date().getTime(),
|
|
156
158
|
});
|
|
159
|
+
|
|
160
|
+
logger.info(_.omitBy(logData, _.isNil), `DBGM-00269 Audit log: ${message}`);
|
|
161
|
+
|
|
157
162
|
if (!isProcessing && !isPlanned) {
|
|
158
163
|
setTimeout(() => {
|
|
159
164
|
isPlanned = true;
|
|
@@ -0,0 +1,445 @@
|
|
|
1
|
+
const path = require('path');
|
|
2
|
+
const _ = require('lodash');
|
|
3
|
+
const { safeJsonParse, getDatabaseFileLabel } = require('dbgate-tools');
|
|
4
|
+
const crypto = require('crypto');
|
|
5
|
+
|
|
6
|
+
function extractConnectionsFromEnv(env) {
|
|
7
|
+
if (!env?.CONNECTIONS) {
|
|
8
|
+
return null;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const connections = _.compact(env.CONNECTIONS.split(',')).map(id => ({
|
|
12
|
+
_id: id,
|
|
13
|
+
engine: env[`ENGINE_${id}`],
|
|
14
|
+
server: env[`SERVER_${id}`],
|
|
15
|
+
user: env[`USER_${id}`],
|
|
16
|
+
password: env[`PASSWORD_${id}`],
|
|
17
|
+
passwordMode: env[`PASSWORD_MODE_${id}`],
|
|
18
|
+
port: env[`PORT_${id}`],
|
|
19
|
+
databaseUrl: env[`URL_${id}`],
|
|
20
|
+
useDatabaseUrl: !!env[`URL_${id}`],
|
|
21
|
+
databaseFile: env[`FILE_${id}`]?.replace(
|
|
22
|
+
'%%E2E_TEST_DATA_DIRECTORY%%',
|
|
23
|
+
path.join(path.dirname(path.dirname(__dirname)), 'e2e-tests', 'tmpdata')
|
|
24
|
+
),
|
|
25
|
+
socketPath: env[`SOCKET_PATH_${id}`],
|
|
26
|
+
serviceName: env[`SERVICE_NAME_${id}`],
|
|
27
|
+
authType: env[`AUTH_TYPE_${id}`] || (env[`SOCKET_PATH_${id}`] ? 'socket' : undefined),
|
|
28
|
+
defaultDatabase: env[`DATABASE_${id}`] || (env[`FILE_${id}`] ? getDatabaseFileLabel(env[`FILE_${id}`]) : null),
|
|
29
|
+
singleDatabase: !!env[`DATABASE_${id}`] || !!env[`FILE_${id}`],
|
|
30
|
+
displayName: env[`LABEL_${id}`],
|
|
31
|
+
isReadOnly: env[`READONLY_${id}`],
|
|
32
|
+
databases: env[`DBCONFIG_${id}`] ? safeJsonParse(env[`DBCONFIG_${id}`]) : null,
|
|
33
|
+
allowedDatabases: env[`ALLOWED_DATABASES_${id}`]?.replace(/\|/g, '\n'),
|
|
34
|
+
allowedDatabasesRegex: env[`ALLOWED_DATABASES_REGEX_${id}`],
|
|
35
|
+
parent: env[`PARENT_${id}`] || undefined,
|
|
36
|
+
useSeparateSchemas: !!env[`USE_SEPARATE_SCHEMAS_${id}`],
|
|
37
|
+
localDataCenter: env[`LOCAL_DATA_CENTER_${id}`],
|
|
38
|
+
|
|
39
|
+
// SSH tunnel
|
|
40
|
+
useSshTunnel: env[`USE_SSH_${id}`],
|
|
41
|
+
sshHost: env[`SSH_HOST_${id}`],
|
|
42
|
+
sshPort: env[`SSH_PORT_${id}`],
|
|
43
|
+
sshMode: env[`SSH_MODE_${id}`],
|
|
44
|
+
sshLogin: env[`SSH_LOGIN_${id}`],
|
|
45
|
+
sshPassword: env[`SSH_PASSWORD_${id}`],
|
|
46
|
+
sshKeyfile: env[`SSH_KEY_FILE_${id}`],
|
|
47
|
+
sshKeyfilePassword: env[`SSH_KEY_FILE_PASSWORD_${id}`],
|
|
48
|
+
|
|
49
|
+
// SSL
|
|
50
|
+
useSsl: env[`USE_SSL_${id}`],
|
|
51
|
+
sslCaFile: env[`SSL_CA_FILE_${id}`],
|
|
52
|
+
sslCertFile: env[`SSL_CERT_FILE_${id}`],
|
|
53
|
+
sslCertFilePassword: env[`SSL_CERT_FILE_PASSWORD_${id}`],
|
|
54
|
+
sslKeyFile: env[`SSL_KEY_FILE_${id}`],
|
|
55
|
+
sslRejectUnauthorized: env[`SSL_REJECT_UNAUTHORIZED_${id}`],
|
|
56
|
+
trustServerCertificate: env[`SSL_TRUST_CERTIFICATE_${id}`],
|
|
57
|
+
}));
|
|
58
|
+
|
|
59
|
+
return connections;
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
function extractImportEntitiesFromEnv(env) {
|
|
63
|
+
const portalConnections = extractConnectionsFromEnv(env) || [];
|
|
64
|
+
|
|
65
|
+
const connections = portalConnections.map((conn, index) => ({
|
|
66
|
+
...conn,
|
|
67
|
+
id_original: conn._id,
|
|
68
|
+
import_source_id: -1,
|
|
69
|
+
conid: crypto.randomUUID(),
|
|
70
|
+
_id: undefined,
|
|
71
|
+
id: index + 1, // autoincrement id
|
|
72
|
+
}));
|
|
73
|
+
|
|
74
|
+
const connectionEnvIdToDbId = {};
|
|
75
|
+
for (const conn of connections) {
|
|
76
|
+
connectionEnvIdToDbId[conn.id_original] = conn.id;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const connectionsRegex = /^ROLE_(.+)_CONNECTIONS$/;
|
|
80
|
+
const permissionsRegex = /^ROLE_(.+)_PERMISSIONS$/;
|
|
81
|
+
|
|
82
|
+
const dbConnectionRegex = /^ROLE_(.+)_DATABASES_(.+)_CONNECTION$/;
|
|
83
|
+
const dbDatabasesRegex = /^ROLE_(.+)_DATABASES_(.+)_DATABASES$/;
|
|
84
|
+
const dbDatabasesRegexRegex = /^ROLE_(.+)_DATABASES_(.+)_DATABASES_REGEX$/;
|
|
85
|
+
const dbPermissionRegex = /^ROLE_(.+)_DATABASES_(.+)_PERMISSION$/;
|
|
86
|
+
|
|
87
|
+
const tableConnectionRegex = /^ROLE_(.+)_TABLES_(.+)_CONNECTION$/;
|
|
88
|
+
const tableDatabasesRegex = /^ROLE_(.+)_TABLES_(.+)_DATABASES$/;
|
|
89
|
+
const tableDatabasesRegexRegex = /^ROLE_(.+)_TABLES_(.+)_DATABASES_REGEX$/;
|
|
90
|
+
const tableSchemasRegex = /^ROLE_(.+)_TABLES_(.+)_SCHEMAS$/;
|
|
91
|
+
const tableSchemasRegexRegex = /^ROLE_(.+)_TABLES_(.+)_SCHEMAS_REGEX$/;
|
|
92
|
+
const tableTablesRegex = /^ROLE_(.+)_TABLES_(.+)_TABLES$/;
|
|
93
|
+
const tableTablesRegexRegex = /^ROLE_(.+)_TABLES_(.+)_TABLES_REGEX$/;
|
|
94
|
+
const tablePermissionRegex = /^ROLE_(.+)_TABLES_(.+)_PERMISSION$/;
|
|
95
|
+
const tableScopeRegex = /^ROLE_(.+)_TABLES_(.+)_SCOPE$/;
|
|
96
|
+
|
|
97
|
+
const roles = [];
|
|
98
|
+
const role_connections = [];
|
|
99
|
+
const role_permissions = [];
|
|
100
|
+
const role_databases = [];
|
|
101
|
+
const role_tables = [];
|
|
102
|
+
|
|
103
|
+
// Permission name to ID mappings
|
|
104
|
+
const databasePermissionMap = {
|
|
105
|
+
view: -1,
|
|
106
|
+
read_content: -2,
|
|
107
|
+
write_data: -3,
|
|
108
|
+
run_script: -4,
|
|
109
|
+
deny: -5,
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const tablePermissionMap = {
|
|
113
|
+
read: -1,
|
|
114
|
+
update_only: -2,
|
|
115
|
+
create_update_delete: -3,
|
|
116
|
+
run_script: -4,
|
|
117
|
+
deny: -5,
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
const tableScopeMap = {
|
|
121
|
+
all_objects: -1,
|
|
122
|
+
tables: -2,
|
|
123
|
+
views: -3,
|
|
124
|
+
tables_views_collections: -4,
|
|
125
|
+
procedures: -5,
|
|
126
|
+
functions: -6,
|
|
127
|
+
triggers: -7,
|
|
128
|
+
sql_objects: -8,
|
|
129
|
+
collections: -9,
|
|
130
|
+
};
|
|
131
|
+
|
|
132
|
+
// Collect database and table permissions data
|
|
133
|
+
const databasePermissions = {};
|
|
134
|
+
const tablePermissions = {};
|
|
135
|
+
|
|
136
|
+
// First pass: collect all database and table permission data
|
|
137
|
+
for (const key in env) {
|
|
138
|
+
const dbConnMatch = key.match(dbConnectionRegex);
|
|
139
|
+
const dbDatabasesMatch = key.match(dbDatabasesRegex);
|
|
140
|
+
const dbDatabasesRegexMatch = key.match(dbDatabasesRegexRegex);
|
|
141
|
+
const dbPermMatch = key.match(dbPermissionRegex);
|
|
142
|
+
|
|
143
|
+
const tableConnMatch = key.match(tableConnectionRegex);
|
|
144
|
+
const tableDatabasesMatch = key.match(tableDatabasesRegex);
|
|
145
|
+
const tableDatabasesRegexMatch = key.match(tableDatabasesRegexRegex);
|
|
146
|
+
const tableSchemasMatch = key.match(tableSchemasRegex);
|
|
147
|
+
const tableSchemasRegexMatch = key.match(tableSchemasRegexRegex);
|
|
148
|
+
const tableTablesMatch = key.match(tableTablesRegex);
|
|
149
|
+
const tableTablesRegexMatch = key.match(tableTablesRegexRegex);
|
|
150
|
+
const tablePermMatch = key.match(tablePermissionRegex);
|
|
151
|
+
const tableScopeMatch = key.match(tableScopeRegex);
|
|
152
|
+
|
|
153
|
+
// Database permissions
|
|
154
|
+
if (dbConnMatch) {
|
|
155
|
+
const [, roleName, permId] = dbConnMatch;
|
|
156
|
+
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
|
|
157
|
+
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
|
|
158
|
+
databasePermissions[roleName][permId].connection = env[key];
|
|
159
|
+
}
|
|
160
|
+
if (dbDatabasesMatch) {
|
|
161
|
+
const [, roleName, permId] = dbDatabasesMatch;
|
|
162
|
+
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
|
|
163
|
+
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
|
|
164
|
+
databasePermissions[roleName][permId].databases = env[key]?.replace(/\|/g, '\n');
|
|
165
|
+
}
|
|
166
|
+
if (dbDatabasesRegexMatch) {
|
|
167
|
+
const [, roleName, permId] = dbDatabasesRegexMatch;
|
|
168
|
+
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
|
|
169
|
+
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
|
|
170
|
+
databasePermissions[roleName][permId].databasesRegex = env[key];
|
|
171
|
+
}
|
|
172
|
+
if (dbPermMatch) {
|
|
173
|
+
const [, roleName, permId] = dbPermMatch;
|
|
174
|
+
if (!databasePermissions[roleName]) databasePermissions[roleName] = {};
|
|
175
|
+
if (!databasePermissions[roleName][permId]) databasePermissions[roleName][permId] = {};
|
|
176
|
+
databasePermissions[roleName][permId].permission = env[key];
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
// Table permissions
|
|
180
|
+
if (tableConnMatch) {
|
|
181
|
+
const [, roleName, permId] = tableConnMatch;
|
|
182
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
183
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
184
|
+
tablePermissions[roleName][permId].connection = env[key];
|
|
185
|
+
}
|
|
186
|
+
if (tableDatabasesMatch) {
|
|
187
|
+
const [, roleName, permId] = tableDatabasesMatch;
|
|
188
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
189
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
190
|
+
tablePermissions[roleName][permId].databases = env[key]?.replace(/\|/g, '\n');
|
|
191
|
+
}
|
|
192
|
+
if (tableDatabasesRegexMatch) {
|
|
193
|
+
const [, roleName, permId] = tableDatabasesRegexMatch;
|
|
194
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
195
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
196
|
+
tablePermissions[roleName][permId].databasesRegex = env[key];
|
|
197
|
+
}
|
|
198
|
+
if (tableSchemasMatch) {
|
|
199
|
+
const [, roleName, permId] = tableSchemasMatch;
|
|
200
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
201
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
202
|
+
tablePermissions[roleName][permId].schemas = env[key];
|
|
203
|
+
}
|
|
204
|
+
if (tableSchemasRegexMatch) {
|
|
205
|
+
const [, roleName, permId] = tableSchemasRegexMatch;
|
|
206
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
207
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
208
|
+
tablePermissions[roleName][permId].schemasRegex = env[key];
|
|
209
|
+
}
|
|
210
|
+
if (tableTablesMatch) {
|
|
211
|
+
const [, roleName, permId] = tableTablesMatch;
|
|
212
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
213
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
214
|
+
tablePermissions[roleName][permId].tables = env[key]?.replace(/\|/g, '\n');
|
|
215
|
+
}
|
|
216
|
+
if (tableTablesRegexMatch) {
|
|
217
|
+
const [, roleName, permId] = tableTablesRegexMatch;
|
|
218
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
219
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
220
|
+
tablePermissions[roleName][permId].tablesRegex = env[key];
|
|
221
|
+
}
|
|
222
|
+
if (tablePermMatch) {
|
|
223
|
+
const [, roleName, permId] = tablePermMatch;
|
|
224
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
225
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
226
|
+
tablePermissions[roleName][permId].permission = env[key];
|
|
227
|
+
}
|
|
228
|
+
if (tableScopeMatch) {
|
|
229
|
+
const [, roleName, permId] = tableScopeMatch;
|
|
230
|
+
if (!tablePermissions[roleName]) tablePermissions[roleName] = {};
|
|
231
|
+
if (!tablePermissions[roleName][permId]) tablePermissions[roleName][permId] = {};
|
|
232
|
+
tablePermissions[roleName][permId].scope = env[key];
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
// Second pass: process roles, connections, and permissions
|
|
237
|
+
for (const key in env) {
|
|
238
|
+
const connMatch = key.match(connectionsRegex);
|
|
239
|
+
const permMatch = key.match(permissionsRegex);
|
|
240
|
+
if (connMatch) {
|
|
241
|
+
const roleName = connMatch[1];
|
|
242
|
+
let role = roles.find(r => r.name === roleName);
|
|
243
|
+
if (!role) {
|
|
244
|
+
role = {
|
|
245
|
+
id: roles.length + 1,
|
|
246
|
+
name: roleName,
|
|
247
|
+
import_source_id: -1,
|
|
248
|
+
};
|
|
249
|
+
roles.push(role);
|
|
250
|
+
}
|
|
251
|
+
const connIds = env[key]
|
|
252
|
+
.split(',')
|
|
253
|
+
.map(id => id.trim())
|
|
254
|
+
.filter(id => id.length > 0);
|
|
255
|
+
for (const connId of connIds) {
|
|
256
|
+
const dbId = connectionEnvIdToDbId[connId];
|
|
257
|
+
if (dbId) {
|
|
258
|
+
role_connections.push({
|
|
259
|
+
role_id: role.id,
|
|
260
|
+
connection_id: dbId,
|
|
261
|
+
import_source_id: -1,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
if (permMatch) {
|
|
267
|
+
const roleName = permMatch[1];
|
|
268
|
+
let role = roles.find(r => r.name === roleName);
|
|
269
|
+
if (!role) {
|
|
270
|
+
role = {
|
|
271
|
+
id: roles.length + 1,
|
|
272
|
+
name: roleName,
|
|
273
|
+
import_source_id: -1,
|
|
274
|
+
};
|
|
275
|
+
roles.push(role);
|
|
276
|
+
}
|
|
277
|
+
const permissions = env[key]
|
|
278
|
+
.split(',')
|
|
279
|
+
.map(p => p.trim())
|
|
280
|
+
.filter(p => p.length > 0);
|
|
281
|
+
for (const permission of permissions) {
|
|
282
|
+
role_permissions.push({
|
|
283
|
+
role_id: role.id,
|
|
284
|
+
permission,
|
|
285
|
+
import_source_id: -1,
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Process database permissions
|
|
292
|
+
for (const roleName in databasePermissions) {
|
|
293
|
+
let role = roles.find(r => r.name === roleName);
|
|
294
|
+
if (!role) {
|
|
295
|
+
role = {
|
|
296
|
+
id: roles.length + 1,
|
|
297
|
+
name: roleName,
|
|
298
|
+
import_source_id: -1,
|
|
299
|
+
};
|
|
300
|
+
roles.push(role);
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
for (const permId in databasePermissions[roleName]) {
|
|
304
|
+
const perm = databasePermissions[roleName][permId];
|
|
305
|
+
if (perm.connection && perm.permission) {
|
|
306
|
+
const dbId = connectionEnvIdToDbId[perm.connection];
|
|
307
|
+
const permissionId = databasePermissionMap[perm.permission];
|
|
308
|
+
if (dbId && permissionId) {
|
|
309
|
+
role_databases.push({
|
|
310
|
+
role_id: role.id,
|
|
311
|
+
connection_id: dbId,
|
|
312
|
+
database_names_list: perm.databases || null,
|
|
313
|
+
database_names_regex: perm.databasesRegex || null,
|
|
314
|
+
database_permission_role_id: permissionId,
|
|
315
|
+
id_original: permId,
|
|
316
|
+
import_source_id: -1,
|
|
317
|
+
});
|
|
318
|
+
}
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
// Process table permissions
|
|
324
|
+
for (const roleName in tablePermissions) {
|
|
325
|
+
let role = roles.find(r => r.name === roleName);
|
|
326
|
+
if (!role) {
|
|
327
|
+
role = {
|
|
328
|
+
id: roles.length + 1,
|
|
329
|
+
name: roleName,
|
|
330
|
+
import_source_id: -1,
|
|
331
|
+
};
|
|
332
|
+
roles.push(role);
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
for (const permId in tablePermissions[roleName]) {
|
|
336
|
+
const perm = tablePermissions[roleName][permId];
|
|
337
|
+
if (perm.connection && perm.permission) {
|
|
338
|
+
const dbId = connectionEnvIdToDbId[perm.connection];
|
|
339
|
+
const permissionId = tablePermissionMap[perm.permission];
|
|
340
|
+
const scopeId = tableScopeMap[perm.scope || 'all_objects'];
|
|
341
|
+
if (dbId && permissionId && scopeId) {
|
|
342
|
+
role_tables.push({
|
|
343
|
+
role_id: role.id,
|
|
344
|
+
connection_id: dbId,
|
|
345
|
+
database_names_list: perm.databases || null,
|
|
346
|
+
database_names_regex: perm.databasesRegex || null,
|
|
347
|
+
schema_names_list: perm.schemas || null,
|
|
348
|
+
schema_names_regex: perm.schemasRegex || null,
|
|
349
|
+
table_names_list: perm.tables || null,
|
|
350
|
+
table_names_regex: perm.tablesRegex || null,
|
|
351
|
+
table_permission_role_id: permissionId,
|
|
352
|
+
table_permission_scope_id: scopeId,
|
|
353
|
+
id_original: permId,
|
|
354
|
+
import_source_id: -1,
|
|
355
|
+
});
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
if (connections.length == 0 && roles.length == 0) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
return {
|
|
366
|
+
connections,
|
|
367
|
+
roles,
|
|
368
|
+
role_connections,
|
|
369
|
+
role_permissions,
|
|
370
|
+
role_databases,
|
|
371
|
+
role_tables,
|
|
372
|
+
};
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
function createStorageFromEnvReplicatorItems(importEntities) {
|
|
376
|
+
return [
|
|
377
|
+
{
|
|
378
|
+
name: 'connections',
|
|
379
|
+
findExisting: true,
|
|
380
|
+
createNew: true,
|
|
381
|
+
updateExisting: true,
|
|
382
|
+
matchColumns: ['id_original', 'import_source_id'],
|
|
383
|
+
deleteMissing: true,
|
|
384
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
385
|
+
skipUpdateColumns: ['conid'],
|
|
386
|
+
jsonArray: importEntities.connections,
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
name: 'roles',
|
|
390
|
+
findExisting: true,
|
|
391
|
+
createNew: true,
|
|
392
|
+
updateExisting: true,
|
|
393
|
+
matchColumns: ['name', 'import_source_id'],
|
|
394
|
+
deleteMissing: true,
|
|
395
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
396
|
+
jsonArray: importEntities.roles,
|
|
397
|
+
},
|
|
398
|
+
{
|
|
399
|
+
name: 'role_connections',
|
|
400
|
+
findExisting: true,
|
|
401
|
+
createNew: true,
|
|
402
|
+
updateExisting: false,
|
|
403
|
+
deleteMissing: true,
|
|
404
|
+
matchColumns: ['role_id', 'connection_id', 'import_source_id'],
|
|
405
|
+
jsonArray: importEntities.role_connections,
|
|
406
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
407
|
+
},
|
|
408
|
+
{
|
|
409
|
+
name: 'role_permissions',
|
|
410
|
+
findExisting: true,
|
|
411
|
+
createNew: true,
|
|
412
|
+
updateExisting: false,
|
|
413
|
+
deleteMissing: true,
|
|
414
|
+
matchColumns: ['role_id', 'permission', 'import_source_id'],
|
|
415
|
+
jsonArray: importEntities.role_permissions,
|
|
416
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
417
|
+
},
|
|
418
|
+
{
|
|
419
|
+
name: 'role_databases',
|
|
420
|
+
findExisting: true,
|
|
421
|
+
createNew: true,
|
|
422
|
+
updateExisting: true,
|
|
423
|
+
deleteMissing: true,
|
|
424
|
+
matchColumns: ['role_id', 'id_original', 'import_source_id'],
|
|
425
|
+
jsonArray: importEntities.role_databases,
|
|
426
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
427
|
+
},
|
|
428
|
+
{
|
|
429
|
+
name: 'role_tables',
|
|
430
|
+
findExisting: true,
|
|
431
|
+
createNew: true,
|
|
432
|
+
updateExisting: true,
|
|
433
|
+
deleteMissing: true,
|
|
434
|
+
matchColumns: ['role_id', 'id_original', 'import_source_id'],
|
|
435
|
+
jsonArray: importEntities.role_tables,
|
|
436
|
+
deleteRestrictionColumns: ['import_source_id'],
|
|
437
|
+
},
|
|
438
|
+
];
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
module.exports = {
|
|
442
|
+
extractConnectionsFromEnv,
|
|
443
|
+
extractImportEntitiesFromEnv,
|
|
444
|
+
createStorageFromEnvReplicatorItems,
|
|
445
|
+
};
|