dbgate-api-premium 6.6.3 → 6.6.5
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 -6
- package/src/auth/authCommon.js +6 -0
- package/src/auth/authProvider.js +6 -1
- package/src/auth/storageAuthProvider.js +51 -6
- package/src/controllers/apps.js +342 -220
- package/src/controllers/auth.js +3 -1
- package/src/controllers/databaseConnections.js +1 -1
- package/src/controllers/files.js +6 -1
- package/src/controllers/serverConnections.js +2 -2
- package/src/controllers/sessions.js +17 -4
- package/src/controllers/storage.js +128 -4
- package/src/controllers/storageDb.js +331 -0
- package/src/controllers/teamFiles.js +250 -0
- package/src/controllers/uploads.js +66 -95
- package/src/currentVersion.js +2 -2
- package/src/main.js +3 -0
- package/src/proc/databaseConnectionProcess.js +0 -2
- package/src/storageModel.js +506 -37
- package/src/utility/getChartExport.js +1 -1
- package/src/utility/getMapExport.js +1 -1
- package/src/utility/hasPermission.js +51 -2
- package/src/gistSecret.js +0 -2
|
@@ -8,11 +8,13 @@ const path = require('path');
|
|
|
8
8
|
const { handleProcessCommunication } = require('../utility/processComm');
|
|
9
9
|
const processArgs = require('../utility/processArgs');
|
|
10
10
|
const { appdir } = require('../utility/directories');
|
|
11
|
-
const { getLogger, extractErrorLogData } = require('dbgate-tools');
|
|
11
|
+
const { getLogger, extractErrorLogData, removeSqlFrontMatter } = require('dbgate-tools');
|
|
12
12
|
const pipeForkLogs = require('../utility/pipeForkLogs');
|
|
13
13
|
const config = require('./config');
|
|
14
14
|
const { sendToAuditLog } = require('../utility/auditlog');
|
|
15
15
|
const { testStandardPermission, testDatabaseRolePermission } = require('../utility/hasPermission');
|
|
16
|
+
const { getStaticTokenSecret } = require('../auth/authCommon');
|
|
17
|
+
const jwt = require('jsonwebtoken');
|
|
16
18
|
|
|
17
19
|
const logger = getLogger('sessions');
|
|
18
20
|
|
|
@@ -95,7 +97,7 @@ module.exports = {
|
|
|
95
97
|
socket.emit(`session-initialize-file-${jslid}`);
|
|
96
98
|
},
|
|
97
99
|
|
|
98
|
-
handle_ping() {
|
|
100
|
+
handle_ping() {},
|
|
99
101
|
|
|
100
102
|
create_meta: true,
|
|
101
103
|
async create({ conid, database }) {
|
|
@@ -149,12 +151,23 @@ module.exports = {
|
|
|
149
151
|
|
|
150
152
|
executeQuery_meta: true,
|
|
151
153
|
async executeQuery({ sesid, sql, autoCommit, autoDetectCharts, limitRows, frontMatter }, req) {
|
|
152
|
-
|
|
154
|
+
let useTokenIsOk = false;
|
|
155
|
+
if (frontMatter?.useToken) {
|
|
156
|
+
const decoded = jwt.verify(frontMatter.useToken, getStaticTokenSecret());
|
|
157
|
+
if (decoded?.['contentHash'] == crypto.createHash('md5').update(removeSqlFrontMatter(sql)).digest('hex')) {
|
|
158
|
+
useTokenIsOk = true;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
if (!useTokenIsOk) {
|
|
162
|
+
await testStandardPermission('dbops/query', req);
|
|
163
|
+
}
|
|
153
164
|
const session = this.opened.find(x => x.sesid == sesid);
|
|
154
165
|
if (!session) {
|
|
155
166
|
throw new Error('Invalid session');
|
|
156
167
|
}
|
|
157
|
-
|
|
168
|
+
if (!useTokenIsOk) {
|
|
169
|
+
await testDatabaseRolePermission(session.conid, session.database, 'run_script', req);
|
|
170
|
+
}
|
|
158
171
|
|
|
159
172
|
sendToAuditLog(req, {
|
|
160
173
|
category: 'dbop',
|
|
@@ -14,6 +14,7 @@ const {
|
|
|
14
14
|
storageSaveRelationDiff,
|
|
15
15
|
selectStorageIdentity,
|
|
16
16
|
storageSaveDetailPermissionsDiff,
|
|
17
|
+
saveStorageTeamFilesPermissions,
|
|
17
18
|
} = require('./storageDb');
|
|
18
19
|
const { hasPermission, loadPermissionsFromRequest } = require('../utility/hasPermission');
|
|
19
20
|
const { changeSetToSql, removeSchemaFromChangeSet } = require('dbgate-datalib');
|
|
@@ -485,10 +486,39 @@ module.exports = {
|
|
|
485
486
|
: (await storageSelectFmt('select ~connection_id from ~user_connections where ~user_id = %v', id)).map(
|
|
486
487
|
x => x.connection_id
|
|
487
488
|
);
|
|
489
|
+
const usedTeamFilesRead =
|
|
490
|
+
id == 'new'
|
|
491
|
+
? []
|
|
492
|
+
: (
|
|
493
|
+
await storageSelectFmt(
|
|
494
|
+
'select ~team_file_id from ~user_team_files where ~user_id = %v and ~allow_read = 1',
|
|
495
|
+
id
|
|
496
|
+
)
|
|
497
|
+
).map(x => x.team_file_id);
|
|
498
|
+
const usedTeamFilesWrite =
|
|
499
|
+
id == 'new'
|
|
500
|
+
? []
|
|
501
|
+
: (
|
|
502
|
+
await storageSelectFmt(
|
|
503
|
+
'select ~team_file_id from ~user_team_files where ~user_id = %v and ~allow_write = 1',
|
|
504
|
+
id
|
|
505
|
+
)
|
|
506
|
+
).map(x => x.team_file_id);
|
|
507
|
+
const usedTeamFilesUse =
|
|
508
|
+
id == 'new'
|
|
509
|
+
? []
|
|
510
|
+
: (
|
|
511
|
+
await storageSelectFmt(
|
|
512
|
+
'select ~team_file_id from ~user_team_files where ~user_id = %v and ~allow_use = 1',
|
|
513
|
+
id
|
|
514
|
+
)
|
|
515
|
+
).map(x => x.team_file_id);
|
|
488
516
|
const databasePermissions =
|
|
489
517
|
id == 'new' ? [] : await storageSelectFmt('select * from ~user_databases where ~user_id = %v', id);
|
|
490
518
|
const tablePermissions =
|
|
491
519
|
id == 'new' ? [] : await storageSelectFmt('select * from ~user_tables where ~user_id = %v', id);
|
|
520
|
+
const filePermissions =
|
|
521
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~user_files where ~user_id = %v', id);
|
|
492
522
|
|
|
493
523
|
return {
|
|
494
524
|
...resp[0],
|
|
@@ -500,7 +530,11 @@ module.exports = {
|
|
|
500
530
|
usedConnections,
|
|
501
531
|
databasePermissions,
|
|
502
532
|
tablePermissions,
|
|
533
|
+
filePermissions,
|
|
503
534
|
encryptPassword: !!(resp[0]?.password?.startsWith('crypt:') || id == 'new'),
|
|
535
|
+
usedTeamFilesRead,
|
|
536
|
+
usedTeamFilesWrite,
|
|
537
|
+
usedTeamFilesUse,
|
|
504
538
|
};
|
|
505
539
|
},
|
|
506
540
|
|
|
@@ -508,8 +542,20 @@ module.exports = {
|
|
|
508
542
|
async saveUserDetail(user) {
|
|
509
543
|
const [conn, driver] = await getStorageConnection();
|
|
510
544
|
|
|
511
|
-
const {
|
|
512
|
-
|
|
545
|
+
const {
|
|
546
|
+
login,
|
|
547
|
+
password,
|
|
548
|
+
email,
|
|
549
|
+
usedRoles,
|
|
550
|
+
usedConnections,
|
|
551
|
+
usedTeamFilesRead,
|
|
552
|
+
usedTeamFilesWrite,
|
|
553
|
+
usedTeamFilesUse,
|
|
554
|
+
permissions,
|
|
555
|
+
databasePermissions,
|
|
556
|
+
tablePermissions,
|
|
557
|
+
filePermissions,
|
|
558
|
+
} = encryptUser(user);
|
|
513
559
|
let id = user.id;
|
|
514
560
|
|
|
515
561
|
if (id == null) {
|
|
@@ -538,6 +584,15 @@ module.exports = {
|
|
|
538
584
|
await storageSaveRelationDiff('user_roles', 'user_id', 'role_id', id, usedRoles);
|
|
539
585
|
await storageSaveRelationDiff('user_connections', 'user_id', 'connection_id', id, usedConnections);
|
|
540
586
|
|
|
587
|
+
await saveStorageTeamFilesPermissions(
|
|
588
|
+
'user_team_files',
|
|
589
|
+
'user_id',
|
|
590
|
+
id,
|
|
591
|
+
usedTeamFilesRead,
|
|
592
|
+
usedTeamFilesWrite,
|
|
593
|
+
usedTeamFilesUse
|
|
594
|
+
);
|
|
595
|
+
|
|
541
596
|
await storageSaveDetailPermissionsDiff(
|
|
542
597
|
'user_databases',
|
|
543
598
|
'user_id',
|
|
@@ -564,6 +619,14 @@ module.exports = {
|
|
|
564
619
|
tablePermissions
|
|
565
620
|
);
|
|
566
621
|
|
|
622
|
+
await storageSaveDetailPermissionsDiff(
|
|
623
|
+
'user_files',
|
|
624
|
+
'user_id',
|
|
625
|
+
id,
|
|
626
|
+
['folder_name', 'file_names_list', 'file_names_regex', 'file_permission_role_id'],
|
|
627
|
+
filePermissions
|
|
628
|
+
);
|
|
629
|
+
|
|
567
630
|
return true;
|
|
568
631
|
},
|
|
569
632
|
|
|
@@ -708,11 +771,39 @@ module.exports = {
|
|
|
708
771
|
: (await storageSelectFmt('select ~connection_id from ~role_connections where ~role_id = %v', id)).map(
|
|
709
772
|
x => x.connection_id
|
|
710
773
|
);
|
|
774
|
+
const usedTeamFilesRead =
|
|
775
|
+
id == 'new'
|
|
776
|
+
? []
|
|
777
|
+
: (
|
|
778
|
+
await storageSelectFmt(
|
|
779
|
+
'select ~team_file_id from ~role_team_files where ~role_id = %v and ~allow_read = 1',
|
|
780
|
+
id
|
|
781
|
+
)
|
|
782
|
+
).map(x => x.team_file_id);
|
|
783
|
+
const usedTeamFilesWrite =
|
|
784
|
+
id == 'new'
|
|
785
|
+
? []
|
|
786
|
+
: (
|
|
787
|
+
await storageSelectFmt(
|
|
788
|
+
'select ~team_file_id from ~role_team_files where ~role_id = %v and ~allow_write = 1',
|
|
789
|
+
id
|
|
790
|
+
)
|
|
791
|
+
).map(x => x.team_file_id);
|
|
792
|
+
const usedTeamFilesUse =
|
|
793
|
+
id == 'new'
|
|
794
|
+
? []
|
|
795
|
+
: (
|
|
796
|
+
await storageSelectFmt(
|
|
797
|
+
'select ~team_file_id from ~role_team_files where ~role_id = %v and ~allow_use = 1',
|
|
798
|
+
id
|
|
799
|
+
)
|
|
800
|
+
).map(x => x.team_file_id);
|
|
711
801
|
const databasePermissions =
|
|
712
802
|
id == 'new' ? [] : await storageSelectFmt('select * from ~role_databases where ~role_id = %v', id);
|
|
713
803
|
const tablePermissions =
|
|
714
804
|
id == 'new' ? [] : await storageSelectFmt('select * from ~role_tables where ~role_id = %v', id);
|
|
715
|
-
|
|
805
|
+
const filePermissions =
|
|
806
|
+
id == 'new' ? [] : await storageSelectFmt('select * from ~role_files where ~role_id = %v', id);
|
|
716
807
|
|
|
717
808
|
return {
|
|
718
809
|
...resp[0],
|
|
@@ -722,8 +813,12 @@ module.exports = {
|
|
|
722
813
|
usedUsers,
|
|
723
814
|
allConnections,
|
|
724
815
|
usedConnections,
|
|
816
|
+
usedTeamFilesRead,
|
|
817
|
+
usedTeamFilesWrite,
|
|
818
|
+
usedTeamFilesUse,
|
|
725
819
|
databasePermissions,
|
|
726
820
|
tablePermissions,
|
|
821
|
+
filePermissions,
|
|
727
822
|
};
|
|
728
823
|
},
|
|
729
824
|
|
|
@@ -743,7 +838,18 @@ module.exports = {
|
|
|
743
838
|
async saveRoleDetail(role) {
|
|
744
839
|
const [conn, driver] = await getStorageConnection();
|
|
745
840
|
|
|
746
|
-
const {
|
|
841
|
+
const {
|
|
842
|
+
name,
|
|
843
|
+
usedConnections,
|
|
844
|
+
usedUsers,
|
|
845
|
+
usedTeamFilesRead,
|
|
846
|
+
usedTeamFilesWrite,
|
|
847
|
+
usedTeamFilesUse,
|
|
848
|
+
permissions,
|
|
849
|
+
databasePermissions,
|
|
850
|
+
tablePermissions,
|
|
851
|
+
filePermissions,
|
|
852
|
+
} = role;
|
|
747
853
|
let id = role.id;
|
|
748
854
|
|
|
749
855
|
if (id == null) {
|
|
@@ -759,6 +865,16 @@ module.exports = {
|
|
|
759
865
|
await storageSaveRelationDiff('user_roles', 'role_id', 'user_id', id, usedUsers);
|
|
760
866
|
await storageSaveRelationDiff('role_connections', 'role_id', 'connection_id', id, usedConnections);
|
|
761
867
|
|
|
868
|
+
// await storageSaveRelationDiff('role_team_files', 'role_id', 'team_file_id', id, usedTeamFiles);
|
|
869
|
+
await saveStorageTeamFilesPermissions(
|
|
870
|
+
'role_team_files',
|
|
871
|
+
'role_id',
|
|
872
|
+
id,
|
|
873
|
+
usedTeamFilesRead,
|
|
874
|
+
usedTeamFilesWrite,
|
|
875
|
+
usedTeamFilesUse
|
|
876
|
+
);
|
|
877
|
+
|
|
762
878
|
await storageSaveDetailPermissionsDiff(
|
|
763
879
|
'role_databases',
|
|
764
880
|
'role_id',
|
|
@@ -785,6 +901,14 @@ module.exports = {
|
|
|
785
901
|
tablePermissions
|
|
786
902
|
);
|
|
787
903
|
|
|
904
|
+
await storageSaveDetailPermissionsDiff(
|
|
905
|
+
'role_files',
|
|
906
|
+
'role_id',
|
|
907
|
+
id,
|
|
908
|
+
['folder_name', 'file_names_list', 'file_names_regex', 'file_permission_role_id'],
|
|
909
|
+
filePermissions
|
|
910
|
+
);
|
|
911
|
+
|
|
788
912
|
return true;
|
|
789
913
|
},
|
|
790
914
|
|
|
@@ -365,6 +365,44 @@ async function storageSaveDetailPermissionsDiff(table, idColumn, idValue, valueC
|
|
|
365
365
|
}
|
|
366
366
|
}
|
|
367
367
|
|
|
368
|
+
async function saveStorageTeamFilesPermissions(
|
|
369
|
+
table,
|
|
370
|
+
idColumn,
|
|
371
|
+
idValue,
|
|
372
|
+
usedTeamFilesRead,
|
|
373
|
+
usedTeamFilesWrite,
|
|
374
|
+
usedTeamFilesUse
|
|
375
|
+
) {
|
|
376
|
+
const [conn, driver] = await getStorageConnection();
|
|
377
|
+
if (!conn) {
|
|
378
|
+
return null;
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
const records = _.uniq([...usedTeamFilesRead, ...usedTeamFilesWrite, ...usedTeamFilesUse]).map(teamFileId => ({
|
|
382
|
+
team_file_id: teamFileId,
|
|
383
|
+
allow_read: usedTeamFilesRead.includes(teamFileId) ? 1 : 0,
|
|
384
|
+
allow_write: usedTeamFilesWrite.includes(teamFileId) ? 1 : 0,
|
|
385
|
+
allow_use: usedTeamFilesUse.includes(teamFileId) ? 1 : 0,
|
|
386
|
+
}));
|
|
387
|
+
|
|
388
|
+
await runQueryFmt(driver, conn, 'delete from %i where %i = %v', table, idColumn, idValue);
|
|
389
|
+
|
|
390
|
+
for (const record of records) {
|
|
391
|
+
await runQueryFmt(
|
|
392
|
+
driver,
|
|
393
|
+
conn,
|
|
394
|
+
'insert into %i (%i, ~team_file_id, ~allow_read, ~allow_write, ~allow_use) values (%v, %v, %v, %v, %v)',
|
|
395
|
+
table,
|
|
396
|
+
idColumn,
|
|
397
|
+
idValue,
|
|
398
|
+
record.team_file_id,
|
|
399
|
+
record.allow_read,
|
|
400
|
+
record.allow_write,
|
|
401
|
+
record.allow_use
|
|
402
|
+
);
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
|
|
368
406
|
function getStorageConnectionError() {
|
|
369
407
|
return storageConnectionError;
|
|
370
408
|
}
|
|
@@ -409,6 +447,285 @@ async function storageCheckUserRoleConnectionAccess(userId, conid) {
|
|
|
409
447
|
return respByUser.length > 0 || respByRole.length > 0 || respByLogged.length > 0;
|
|
410
448
|
}
|
|
411
449
|
|
|
450
|
+
async function storageCreateTeamFile({ fileType, file, data, ownerUserId, metadata }) {
|
|
451
|
+
const [conn, driver] = await getStorageConnection();
|
|
452
|
+
if (!conn) {
|
|
453
|
+
return null;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
const typeIdRows = await storageSelectFmt('select ~id from ~team_file_types where ~name = %v', fileType);
|
|
457
|
+
const typeId = typeIdRows?.[0]?.id;
|
|
458
|
+
if (!typeId) {
|
|
459
|
+
return null;
|
|
460
|
+
}
|
|
461
|
+
await storageSqlCommandFmt(
|
|
462
|
+
'insert into ~team_files (~file_type_id, ~file_name, ~file_content, ~owner_user_id, ~metadata) values (%v, %v, %v, %v, %v)',
|
|
463
|
+
typeId,
|
|
464
|
+
file,
|
|
465
|
+
data,
|
|
466
|
+
ownerUserId ?? null,
|
|
467
|
+
metadata
|
|
468
|
+
);
|
|
469
|
+
const teamFileId = await selectStorageIdentity('team_files');
|
|
470
|
+
return { teamFileId };
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
async function storageListTeamFilesForUser(userId) {
|
|
474
|
+
const [conn, driver] = await getStorageConnection();
|
|
475
|
+
if (!conn) {
|
|
476
|
+
return null;
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
const sqlCond =
|
|
480
|
+
additionalCond => `exists (select 1 from ~user_team_files where ~user_team_files.~user_id = ${userId} and ~user_team_files.~team_file_id = ~team_files.~id ${additionalCond(
|
|
481
|
+
'user_team_files'
|
|
482
|
+
)}))
|
|
483
|
+
or (exists (select 1 from ~role_team_files where ~role_team_files.~role_id in (select ~role_id from ~user_roles where ~user_roles.~user_id = ${userId}) and ~role_team_files.~team_file_id = ~team_files.~id ${additionalCond(
|
|
484
|
+
'role_team_files'
|
|
485
|
+
)}))
|
|
486
|
+
or (exists (select 1 from ~role_team_files where ~role_team_files.~role_id = -2 and ~role_team_files.~team_file_id = ~team_files.~id ${additionalCond(
|
|
487
|
+
'role_team_files'
|
|
488
|
+
)})`;
|
|
489
|
+
|
|
490
|
+
const resp = await storageSelectFmt(
|
|
491
|
+
`
|
|
492
|
+
select ~team_files.~id, ~team_files.~file_name, ~team_files.~metadata, ~team_file_types.~name as ~type_name, ~team_files.~owner_user_id,
|
|
493
|
+
|
|
494
|
+
case when (
|
|
495
|
+
${sqlCond(table => `and ~${table}.~allow_read = 1`)}
|
|
496
|
+
) then 1 else 0 end as ~allow_read,
|
|
497
|
+
case when (
|
|
498
|
+
${sqlCond(table => `and ~${table}.~allow_write = 1`)}
|
|
499
|
+
) then 1 else 0 end as ~allow_write,
|
|
500
|
+
case when (
|
|
501
|
+
${sqlCond(table => `and ~${table}.~allow_use = 1`)}
|
|
502
|
+
) then 1 else 0 end as ~allow_use
|
|
503
|
+
|
|
504
|
+
from ~team_files
|
|
505
|
+
inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id
|
|
506
|
+
where ~team_files.~owner_user_id = ${userId}
|
|
507
|
+
or (exists (select 1 from ~user_team_files where ~user_team_files.~user_id = ${userId} and ~user_team_files.~team_file_id = ~team_files.~id))
|
|
508
|
+
or (exists (select 1 from ~role_team_files where ~role_team_files.~role_id in (select ~role_id from ~user_roles where ~user_roles.~user_id = ${userId}) and ~role_team_files.~team_file_id = ~team_files.~id))
|
|
509
|
+
or (exists (select 1 from ~role_team_files where ~role_team_files.~role_id = -2 and ~role_team_files.~team_file_id = ~team_files.~id))`
|
|
510
|
+
);
|
|
511
|
+
return resp;
|
|
512
|
+
}
|
|
513
|
+
|
|
514
|
+
async function storageListAllTeamFiles() {
|
|
515
|
+
const [conn, driver] = await getStorageConnection();
|
|
516
|
+
if (!conn) {
|
|
517
|
+
return null;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const resp =
|
|
521
|
+
await storageSelectFmt(`select ~team_files.~id, ~team_files.~file_name, ~team_files.~metadata, ~team_file_types.~name as ~type_name, ~team_files.~owner_user_id
|
|
522
|
+
from ~team_files inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id`);
|
|
523
|
+
return resp;
|
|
524
|
+
}
|
|
525
|
+
|
|
526
|
+
async function storageListTeamFilesForRole(roleId) {
|
|
527
|
+
const [conn, driver] = await getStorageConnection();
|
|
528
|
+
if (!conn) {
|
|
529
|
+
return null;
|
|
530
|
+
}
|
|
531
|
+
const sqlCond = additionalCond =>
|
|
532
|
+
`exists (select 1 from ~role_team_files where ~role_team_files.~role_id = ${roleId} and ~role_team_files.~team_file_id = ~team_files.~id ${additionalCond(
|
|
533
|
+
'role_team_files'
|
|
534
|
+
)})`;
|
|
535
|
+
|
|
536
|
+
const resp = await storageSelectFmt(
|
|
537
|
+
`
|
|
538
|
+
select ~team_files.~id, ~team_files.~file_name, ~team_files.~metadata, ~team_file_types.~name as ~type_name, ~team_files.~owner_user_id,
|
|
539
|
+
case when (
|
|
540
|
+
${sqlCond(table => `and ~${table}.~allow_read = 1`)}
|
|
541
|
+
) then 1 else 0 end as ~allow_read,
|
|
542
|
+
case when (
|
|
543
|
+
${sqlCond(table => `and ~${table}.~allow_write = 1`)}
|
|
544
|
+
) then 1 else 0 end as ~allow_write,
|
|
545
|
+
case when (
|
|
546
|
+
${sqlCond(table => `and ~${table}.~allow_use = 1`)}
|
|
547
|
+
) then 1 else 0 end as ~allow_use
|
|
548
|
+
from ~team_files
|
|
549
|
+
inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id
|
|
550
|
+
where ~team_files.~owner_user_id = ${roleId}
|
|
551
|
+
or (${sqlCond(() => '')})`
|
|
552
|
+
);
|
|
553
|
+
return resp;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
async function storageGetTeamFileUserAccess(teamFileId, userId) {
|
|
557
|
+
const [conn, driver] = await getStorageConnection();
|
|
558
|
+
if (!conn) {
|
|
559
|
+
return null;
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
const respUser = await storageSelectFmt(
|
|
563
|
+
'select allow_read, allow_write, allow_use from ~user_team_files where ~user_team_files.~user_id = %v and ~user_team_files.~team_file_id = %v',
|
|
564
|
+
userId,
|
|
565
|
+
teamFileId
|
|
566
|
+
);
|
|
567
|
+
const respRole = await storageSelectFmt(
|
|
568
|
+
'select allow_read, allow_write, allow_use from ~role_team_files where ~role_team_files.~role_id in (select ~role_id from ~user_roles where ~user_roles.~user_id = %v) and ~role_team_files.~team_file_id = %v',
|
|
569
|
+
userId,
|
|
570
|
+
teamFileId
|
|
571
|
+
);
|
|
572
|
+
const respFile = await storageSelectFmt(
|
|
573
|
+
'select owner_user_id from ~team_files where ~team_files.~id = %v',
|
|
574
|
+
teamFileId
|
|
575
|
+
);
|
|
576
|
+
|
|
577
|
+
const resp = {
|
|
578
|
+
allowRead: false,
|
|
579
|
+
allowWrite: false,
|
|
580
|
+
allowUse: false,
|
|
581
|
+
owner: false,
|
|
582
|
+
};
|
|
583
|
+
|
|
584
|
+
resp.owner = respFile?.[0]?.owner_user_id == userId;
|
|
585
|
+
|
|
586
|
+
for (const row of respUser) {
|
|
587
|
+
resp.allowRead ||= row.allow_read;
|
|
588
|
+
resp.allowWrite ||= row.allow_write;
|
|
589
|
+
resp.allowUse ||= row.allow_use;
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
for (const row of respRole) {
|
|
593
|
+
resp.allowRead ||= row.allow_read;
|
|
594
|
+
resp.allowWrite ||= row.allow_write;
|
|
595
|
+
resp.allowUse ||= row.allow_use;
|
|
596
|
+
}
|
|
597
|
+
|
|
598
|
+
return resp;
|
|
599
|
+
}
|
|
600
|
+
|
|
601
|
+
async function storageGetTeamFileRoleAccess(teamFileId, roleId) {
|
|
602
|
+
const [conn, driver] = await getStorageConnection();
|
|
603
|
+
if (!conn) {
|
|
604
|
+
return null;
|
|
605
|
+
}
|
|
606
|
+
const respRole = await storageSelectFmt(
|
|
607
|
+
'select allow_read, allow_write, allow_use from ~role_team_files where ~role_team_files.~role_id = %v and ~role_team_files.~team_file_id = %v',
|
|
608
|
+
roleId,
|
|
609
|
+
teamFileId
|
|
610
|
+
);
|
|
611
|
+
const resp = {
|
|
612
|
+
allowRead: false,
|
|
613
|
+
allowWrite: false,
|
|
614
|
+
allowUse: false,
|
|
615
|
+
};
|
|
616
|
+
|
|
617
|
+
for (const row of respRole) {
|
|
618
|
+
resp.allowRead ||= row.allow_read;
|
|
619
|
+
resp.allowWrite ||= row.allow_write;
|
|
620
|
+
resp.allowUse ||= row.allow_use;
|
|
621
|
+
}
|
|
622
|
+
|
|
623
|
+
return resp;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
async function storageGetExistingFile(teamFileId) {
|
|
627
|
+
const [conn, driver] = await getStorageConnection();
|
|
628
|
+
if (!conn) {
|
|
629
|
+
return null;
|
|
630
|
+
}
|
|
631
|
+
const resp = await storageSelectFmt(
|
|
632
|
+
`select ~team_files.~id, ~team_files.~owner_user_id, ~team_file_types.~name as ~type_name
|
|
633
|
+
from ~team_files inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id where ~team_files.~id = %v`,
|
|
634
|
+
teamFileId
|
|
635
|
+
);
|
|
636
|
+
return resp?.[0];
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
async function storageGetExistingFileWithContent(teamFileId) {
|
|
640
|
+
const [conn, driver] = await getStorageConnection();
|
|
641
|
+
if (!conn) {
|
|
642
|
+
return null;
|
|
643
|
+
}
|
|
644
|
+
const resp = await storageSelectFmt(
|
|
645
|
+
`select ~team_files.~id, ~team_files.~file_name, ~team_files.~owner_user_id, ~team_file_types.~name as ~type_name, ~team_files.~file_content,
|
|
646
|
+
~users.login as ~owner_login, ~users.~email as ~owner_email
|
|
647
|
+
from ~team_files inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id
|
|
648
|
+
left join ~users on ~team_files.~owner_user_id = ~users.~id
|
|
649
|
+
where ~team_files.~id = %v`,
|
|
650
|
+
teamFileId
|
|
651
|
+
);
|
|
652
|
+
return resp?.[0];
|
|
653
|
+
}
|
|
654
|
+
|
|
655
|
+
async function storageUpdateTeamFile({ teamFileId, data, name, metadata }) {
|
|
656
|
+
const [conn, driver] = await getStorageConnection();
|
|
657
|
+
if (!conn) {
|
|
658
|
+
return null;
|
|
659
|
+
}
|
|
660
|
+
if (data != null) {
|
|
661
|
+
await storageSqlCommandFmt(
|
|
662
|
+
'update ~team_files set ~file_content = %v, metadata = %v where ~id = %v',
|
|
663
|
+
data,
|
|
664
|
+
metadata,
|
|
665
|
+
teamFileId
|
|
666
|
+
);
|
|
667
|
+
}
|
|
668
|
+
if (name != null) {
|
|
669
|
+
await storageSqlCommandFmt('update ~team_files set ~file_name = %v where ~id = %v', name, teamFileId);
|
|
670
|
+
}
|
|
671
|
+
return true;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
async function storageUpdateTeamFileAdmin({ teamFileId, name }) {
|
|
675
|
+
const [conn, driver] = await getStorageConnection();
|
|
676
|
+
if (!conn) {
|
|
677
|
+
return null;
|
|
678
|
+
}
|
|
679
|
+
await storageSqlCommandFmt('update ~team_files set ~file_name = %v where ~id = %v', name, teamFileId);
|
|
680
|
+
return true;
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
async function storageListAllAdminFiles() {
|
|
684
|
+
const [conn, driver] = await getStorageConnection();
|
|
685
|
+
if (!conn) {
|
|
686
|
+
return null;
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const resp =
|
|
690
|
+
await storageSelectFmt(`select ~team_files.~id, ~team_files.~file_name, ~team_files.~metadata, ~team_file_types.~name as ~type_name
|
|
691
|
+
from ~team_files inner join ~team_file_types on ~team_files.~file_type_id = ~team_file_types.~id`);
|
|
692
|
+
return resp;
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
async function storageDeleteFile(id) {
|
|
696
|
+
const [conn, driver] = await getStorageConnection();
|
|
697
|
+
if (!conn) {
|
|
698
|
+
return null;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
await storageSqlCommandFmt('delete from ~team_files where ~id = %v', id);
|
|
702
|
+
return true;
|
|
703
|
+
}
|
|
704
|
+
|
|
705
|
+
async function storageCopyFile(id, newName, userId) {
|
|
706
|
+
const [conn, driver] = await getStorageConnection();
|
|
707
|
+
if (!conn) {
|
|
708
|
+
return null;
|
|
709
|
+
}
|
|
710
|
+
const resp = await storageSelectFmt(`select * from ~team_files where ~team_files.~id = %v`, id);
|
|
711
|
+
|
|
712
|
+
const existingFile = resp?.[0];
|
|
713
|
+
if (!existingFile) {
|
|
714
|
+
return null;
|
|
715
|
+
}
|
|
716
|
+
|
|
717
|
+
await storageSqlCommandFmt(
|
|
718
|
+
'insert into ~team_files (~file_type_id, ~file_name, ~file_content, ~owner_user_id, ~metadata) values (%v, %v, %v, %v, %v)',
|
|
719
|
+
existingFile.file_type_id,
|
|
720
|
+
newName,
|
|
721
|
+
existingFile.file_content,
|
|
722
|
+
userId,
|
|
723
|
+
existingFile.metadata
|
|
724
|
+
);
|
|
725
|
+
const teamFileId = await selectStorageIdentity('team_files');
|
|
726
|
+
return { teamFileId };
|
|
727
|
+
}
|
|
728
|
+
|
|
412
729
|
module.exports = {
|
|
413
730
|
getStorageConnection,
|
|
414
731
|
storageSelectFmt,
|
|
@@ -416,6 +733,7 @@ module.exports = {
|
|
|
416
733
|
storageReadUserRolePermissions,
|
|
417
734
|
storageReadUserPermissions,
|
|
418
735
|
storageReadRolePermissions,
|
|
736
|
+
storageGetTeamFileUserAccess,
|
|
419
737
|
loadSuperadminPermissions,
|
|
420
738
|
storageReadConfig,
|
|
421
739
|
storageWriteConfig,
|
|
@@ -428,4 +746,17 @@ module.exports = {
|
|
|
428
746
|
readComplexRolePermissions,
|
|
429
747
|
storageCheckRoleConnectionAccess,
|
|
430
748
|
storageCheckUserRoleConnectionAccess,
|
|
749
|
+
storageCreateTeamFile,
|
|
750
|
+
storageGetExistingFile,
|
|
751
|
+
storageGetTeamFileRoleAccess,
|
|
752
|
+
storageListTeamFilesForUser,
|
|
753
|
+
storageListTeamFilesForRole,
|
|
754
|
+
storageUpdateTeamFile,
|
|
755
|
+
storageListAllTeamFiles,
|
|
756
|
+
storageGetExistingFileWithContent,
|
|
757
|
+
storageListAllAdminFiles,
|
|
758
|
+
storageUpdateTeamFileAdmin,
|
|
759
|
+
storageDeleteFile,
|
|
760
|
+
saveStorageTeamFilesPermissions,
|
|
761
|
+
storageCopyFile,
|
|
431
762
|
};
|