SYNC: Merge pull request #12 from dbgate/feature/team-files

This commit is contained in:
Jan Prochazka
2025-09-26 12:44:08 +02:00
committed by Diflow
parent 925e3a67da
commit 494b33bd7a
15 changed files with 510 additions and 104 deletions

View File

@@ -10,7 +10,13 @@ function getTokenSecret() {
return tokenSecret;
}
function getStaticTokenSecret() {
// TODO static not fixed
return '14813c43-a91b-4ad1-9dcd-a81bd7dbb05f';
}
module.exports = {
getTokenLifetime,
getTokenSecret,
getStaticTokenSecret,
};

View File

@@ -21,7 +21,7 @@ module.exports = {
const filePermissions = await loadFilePermissionsFromRequest(req);
for (const file of await fs.readdir(dir)) {
if (!hasPermission(`all-files`, loadedPermissions)) {
if (!hasPermission(`all-disk-files`, loadedPermissions)) {
const role = getFilePermissionRole('apps', file, filePermissions);
if (role == 'deny') continue;
}

View File

@@ -8,11 +8,13 @@ const path = require('path');
const { handleProcessCommunication } = require('../utility/processComm');
const processArgs = require('../utility/processArgs');
const { appdir } = require('../utility/directories');
const { getLogger, extractErrorLogData } = require('dbgate-tools');
const { getLogger, extractErrorLogData, removeSqlFrontMatter } = require('dbgate-tools');
const pipeForkLogs = require('../utility/pipeForkLogs');
const config = require('./config');
const { sendToAuditLog } = require('../utility/auditlog');
const { testStandardPermission, testDatabaseRolePermission } = require('../utility/hasPermission');
const { getStaticTokenSecret } = require('../auth/authCommon');
const jwt = require('jsonwebtoken');
const logger = getLogger('sessions');
@@ -95,7 +97,7 @@ module.exports = {
socket.emit(`session-initialize-file-${jslid}`);
},
handle_ping() { },
handle_ping() {},
create_meta: true,
async create({ conid, database }) {
@@ -149,12 +151,23 @@ module.exports = {
executeQuery_meta: true,
async executeQuery({ sesid, sql, autoCommit, autoDetectCharts, limitRows, frontMatter }, req) {
await testStandardPermission('dbops/query', req);
let useTokenIsOk = false;
if (frontMatter?.useToken) {
const decoded = jwt.verify(frontMatter.useToken, getStaticTokenSecret());
if (decoded?.['contentHash'] == crypto.createHash('md5').update(removeSqlFrontMatter(sql)).digest('hex')) {
useTokenIsOk = true;
}
}
if (!useTokenIsOk) {
await testStandardPermission('dbops/query', req);
}
const session = this.opened.find(x => x.sesid == sesid);
if (!session) {
throw new Error('Invalid session');
}
await testDatabaseRolePermission(session.conid, session.database, 'run_script', req);
if (!useTokenIsOk) {
await testDatabaseRolePermission(session.conid, session.database, 'run_script', req);
}
sendToAuditLog(req, {
category: 'dbop',

View File

@@ -29,6 +29,8 @@ const files = require('./controllers/files');
const scheduler = require('./controllers/scheduler');
const queryHistory = require('./controllers/queryHistory');
const cloud = require('./controllers/cloud');
const teamFiles = require('./controllers/teamFiles');
const onFinished = require('on-finished');
const processArgs = require('./utility/processArgs');
@@ -264,6 +266,7 @@ function useAllControllers(app, electron) {
useController(app, electron, '/apps', apps);
useController(app, electron, '/auth', auth);
useController(app, electron, '/cloud', cloud);
useController(app, electron, '/team-files', teamFiles);
}
function setElectronSender(electronSender) {

View File

@@ -784,49 +784,6 @@ module.exports = {
}
]
},
{
"pureName": "roles",
"columns": [
{
"pureName": "roles",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "roles",
"columnName": "name",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "roles",
"constraintType": "primaryKey",
"constraintName": "PK_roles",
"columns": [
{
"columnName": "id"
}
]
},
"preloadedRows": [
{
"id": -1,
"name": "anonymous-user"
},
{
"id": -2,
"name": "logged-user"
},
{
"id": -3,
"name": "superadmin"
}
]
},
{
"pureName": "role_connections",
"columns": [
@@ -1243,6 +1200,129 @@ module.exports = {
]
}
},
{
"pureName": "role_team_files",
"columns": [
{
"pureName": "role_team_files",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "role_team_files",
"columnName": "role_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_team_files",
"columnName": "team_file_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "role_team_files",
"columnName": "allow_read",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_team_files",
"columnName": "allow_write",
"dataType": "int",
"notNull": false
},
{
"pureName": "role_team_files",
"columnName": "allow_use",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_role_team_files_role_id",
"pureName": "role_team_files",
"refTableName": "roles",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "role_id",
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_role_team_files_team_file_id",
"pureName": "role_team_files",
"refTableName": "team_files",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "team_file_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
"pureName": "role_team_files",
"constraintType": "primaryKey",
"constraintName": "PK_role_team_files",
"columns": [
{
"columnName": "id"
}
]
}
},
{
"pureName": "roles",
"columns": [
{
"pureName": "roles",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "roles",
"columnName": "name",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "roles",
"constraintType": "primaryKey",
"constraintName": "PK_roles",
"columns": [
{
"columnName": "id"
}
]
},
"preloadedRows": [
{
"id": -1,
"name": "anonymous-user"
},
{
"id": -2,
"name": "logged-user"
},
{
"id": -3,
"name": "superadmin"
}
]
},
{
"pureName": "table_permission_roles",
"columns": [
@@ -1362,39 +1442,111 @@ module.exports = {
]
},
{
"pureName": "users",
"pureName": "team_file_types",
"columns": [
{
"pureName": "users",
"pureName": "team_file_types",
"columnName": "id",
"dataType": "int",
"notNull": true
},
{
"pureName": "team_file_types",
"columnName": "name",
"dataType": "varchar(250)",
"notNull": true
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "team_file_types",
"constraintType": "primaryKey",
"constraintName": "PK_team_file_types",
"columns": [
{
"columnName": "id"
}
]
},
"preloadedRows": [
{
"id": -1,
"name": "sql"
}
]
},
{
"pureName": "team_files",
"columns": [
{
"pureName": "team_files",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "users",
"columnName": "login",
"pureName": "team_files",
"columnName": "file_name",
"dataType": "varchar(250)",
"notNull": false
},
{
"pureName": "users",
"columnName": "password",
"dataType": "varchar(250)",
"pureName": "team_files",
"columnName": "file_content",
"dataType": "text",
"notNull": false
},
{
"pureName": "users",
"columnName": "email",
"dataType": "varchar(250)",
"pureName": "team_files",
"columnName": "file_type_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "team_files",
"columnName": "owner_user_id",
"dataType": "int",
"notNull": false
},
{
"pureName": "team_files",
"columnName": "metadata",
"dataType": "varchar(1000)",
"notNull": false
}
],
"foreignKeys": [],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_team_files_file_type_id",
"pureName": "team_files",
"refTableName": "team_file_types",
"columns": [
{
"columnName": "file_type_id",
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_team_files_owner_user_id",
"pureName": "team_files",
"refTableName": "users",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "owner_user_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
"pureName": "users",
"pureName": "team_files",
"constraintType": "primaryKey",
"constraintName": "PK_users",
"constraintName": "PK_team_files",
"columns": [
{
"columnName": "id"
@@ -1879,6 +2031,127 @@ module.exports = {
}
]
}
},
{
"pureName": "user_team_files",
"columns": [
{
"pureName": "user_team_files",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "user_team_files",
"columnName": "user_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "user_team_files",
"columnName": "team_file_id",
"dataType": "int",
"notNull": true
},
{
"pureName": "user_team_files",
"columnName": "allow_read",
"dataType": "int",
"notNull": false
},
{
"pureName": "user_team_files",
"columnName": "allow_write",
"dataType": "int",
"notNull": false
},
{
"pureName": "user_team_files",
"columnName": "allow_use",
"dataType": "int",
"notNull": false
}
],
"foreignKeys": [
{
"constraintType": "foreignKey",
"constraintName": "FK_user_team_files_user_id",
"pureName": "user_team_files",
"refTableName": "users",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "user_id",
"refColumnName": "id"
}
]
},
{
"constraintType": "foreignKey",
"constraintName": "FK_user_team_files_team_file_id",
"pureName": "user_team_files",
"refTableName": "team_files",
"deleteAction": "CASCADE",
"columns": [
{
"columnName": "team_file_id",
"refColumnName": "id"
}
]
}
],
"primaryKey": {
"pureName": "user_team_files",
"constraintType": "primaryKey",
"constraintName": "PK_user_team_files",
"columns": [
{
"columnName": "id"
}
]
}
},
{
"pureName": "users",
"columns": [
{
"pureName": "users",
"columnName": "id",
"dataType": "int",
"autoIncrement": true,
"notNull": true
},
{
"pureName": "users",
"columnName": "login",
"dataType": "varchar(250)",
"notNull": false
},
{
"pureName": "users",
"columnName": "password",
"dataType": "varchar(250)",
"notNull": false
},
{
"pureName": "users",
"columnName": "email",
"dataType": "varchar(250)",
"notNull": false
}
],
"foreignKeys": [],
"primaryKey": {
"pureName": "users",
"constraintType": "primaryKey",
"constraintName": "PK_users",
"columns": [
{
"columnName": "id"
}
]
}
}
],
"collections": [],

View File

@@ -327,7 +327,7 @@ async function testStandardPermission(permission, req, loadedPermissions) {
loadedPermissions = await loadPermissionsFromRequest(req);
}
if (!hasPermission(permission, loadedPermissions)) {
throw new Error('DBGM-00265 Permission not granted');
throw new Error(`DBGM-00265 Permission ${permission} not granted`);
}
}
@@ -344,7 +344,7 @@ async function testDatabaseRolePermission(conid, database, requiredRole, req) {
const requiredIndex = getDatabaseRoleLevelIndex(requiredRole);
const roleIndex = getDatabaseRoleLevelIndex(role);
if (roleIndex < requiredIndex) {
throw new Error('DBGM-00266 Permission not granted');
throw new Error(`DBGM-00266 Permission ${requiredRole} not granted`);
}
}