From 6d973e8ac1fd6fbe948838d2981914062dbdc689 Mon Sep 17 00:00:00 2001 From: Zachary Priest Date: Fri, 7 Aug 2020 14:23:49 -0600 Subject: [PATCH] fixing commit_all bug #32 --- src/db/db.ts | 20 +++-- src/ui/ipc-render-handlers.ts | 140 ++++++++++++++++++++++++++-------- src/ui/main-window-menu.ts | 97 +++++++++++++---------- 3 files changed, 179 insertions(+), 78 deletions(-) diff --git a/src/db/db.ts b/src/db/db.ts index 9627902d..1d4a2b02 100644 --- a/src/db/db.ts +++ b/src/db/db.ts @@ -310,13 +310,16 @@ export class StigDB { public async getRID(identifier: Identifier): Promise { let rid: Rid; let query; + let result: StixObject[]; try { if (identifier.startsWith('relationship') || identifier.startsWith('sighting')) { query = "select from E where id_=:id order by modified desc limit 1"; } else { query = "select from V where id_=:id order by modified desc limit 1"; } - const result = await this.ojs.query(query, { params: { id: identifier } }); + + result = await this.ojs.query(query, { params: { id: identifier } }).all(); + if (result && result.length > 0) { rid = result[0]['@rid']; return rid; @@ -787,17 +790,18 @@ export class StigDB { from_RID = from_node; to_RID = to_node; } + if (to_RID === undefined) { + const node_data = window.cycore.getElementById(to_node); + to_RID = await this.createVertex(node_data.data('raw_data'))[0]; + } if (from_RID === undefined) { console.debug(`createEdge saving ${from_node} to database`); const node_data = window.cycore.getElementById(from_node); - from_RID = await this.createVertex(node_data.data('raw_data'))[0].Rid; + // from_RID = await this.createVertex(node_data.data('raw_data'))[0]; // isnt created + from_RID = await this.createVertex(node_data.data('raw_data'))[0]; } - if (to_RID === undefined) { - console.debug(`createEdge saving ${to_node} to database`); - const node_data = window.cycore.getElementById(to_node); - to_RID = await this.createVertex(node_data.data('raw_data'))[0].Rid; - } - result = this.createEdgeRID(from_RID, to_RID, data); + + result = await this.createEdgeRID(from_RID, to_RID, data); return result; } catch (e) { e.stack += (new Error()).stack; diff --git a/src/ui/ipc-render-handlers.ts b/src/ui/ipc-render-handlers.ts index 2be56638..abccf00c 100644 --- a/src/ui/ipc-render-handlers.ts +++ b/src/ui/ipc-render-handlers.ts @@ -7,48 +7,70 @@ ALL RIGHTS RESERVED import { ipcRenderer, dialog } from "electron"; import { CollectionReturnValue, NodeSingular} from 'cytoscape'; import { StigDB } from '../db'; -import { StixObject } from '../stix'; +import { StixObject, BundleType } from '../stix'; import { DatabaseConfigurationStorage } from '../storage'; import { open } from 'fs'; import { openDatabaseConfiguration } from './database-config-widget'; import { newDatabaseConfiguration } from './new-database-widget'; +import * as fileSaver from 'file-saver'; +import * as uuid from 'uuid'; -export function setHandlers() { +export async function setHandlers() { ipcRenderer.on("commit_all", () => { const db = new StigDB(DatabaseConfigurationStorage.Instance.current); const to_save: CollectionReturnValue = window.cycore.$('[!saved]'); const results: StixObject[] = []; const edges: StixObject[] = []; - to_save.forEach((ele: NodeSingular, _i: number, _eles: CollectionReturnValue) => { + let numObjects = to_save.size(); + let itemsProcessed = 0; + + async function saveEdges (edges: StixObject[]) { + //do the edges + edges.forEach((stix_obj: StixObject, _i: number, _eles: StixObject[]) => { + db.updateDB(stix_obj) + .then((result) => { + results.push(...result); + }) + .catch((e) => { + // tslint:disable-next-line:no-console + console.error(e); + }, + ); + }) + } + + async function saveVertex(stix_obj: StixObject) { + await db.updateDB(stix_obj) + .then((result) => { + results.push(...result); + }) + .catch((e) => { + // tslint:disable-next-line:no-console + console.error(e); + }); + } + + to_save.forEach(async (ele: NodeSingular, _i: number, _eles: CollectionReturnValue) => { const stix_obj = ele.data('raw_data'); if (stix_obj === undefined) { return; } if (stix_obj['type'] === 'relationship') { // save edges for after all the nodes are done edges.push(stix_obj); + itemsProcessed++; return; } - db.updateDB(stix_obj) - .then((result) => { - results.push(...result); - }) - .catch((e) => { - // tslint:disable-next-line:no-console - console.error(e); - }, - ); + + await saveVertex(stix_obj); + + itemsProcessed++; + //wait for all vertex to step through before saving edges + if (itemsProcessed === numObjects){ + saveEdges(edges); + } }); - //do the edges - edges.forEach((stix_obj: StixObject, _i: number, _eles: StixObject[]) => { - db.updateDB(stix_obj) - .then((result) => { - results.push(...result); - }) - .catch((e) => { - // tslint:disable-next-line:no-console - console.error(e); - }, - ); - }) + + $('.message-status').html(`Committed ${numObjects} objects`); + }); ipcRenderer.on("invert_selected", () => { @@ -58,14 +80,49 @@ export function setHandlers() { unselected.select(); }); + ipcRenderer.on("export_selected", () => { + const bundle_id = 'bundle--' + uuid.v4(); + const bundle = { type: 'bundle', id: bundle_id, objects: [] } as BundleType; + + let nodes = window.cycore.$(':selected'); + nodes.each((ele) => { + if (ele.length === 0) { + return; + } + //logic to remove null on json export + if(ele.data('raw_data')!==undefined){ + bundle.objects.push(ele.data('raw_data')); + } + }); + + const jsonToSave = JSON.stringify(bundle); + const jsonBundleSave = new Blob([jsonToSave], { type: "application/json" }); + fileSaver.saveAs(jsonBundleSave, "bundle.json"); + $('.message-status').html(`Exported ${bundle.objects.length} objects`); + + }); + ipcRenderer.on("export_all", async () => { - const filename = await dialog.showSaveDialog({title: 'Export All as JSON'}); - if (filename) { - open(filename, 'w', (err, fd) => { - if (err) { throw err; } - if (!fd) { return; } - }); - } + + const bundle_id = 'bundle--' + uuid.v4(); + const bundle = { type: 'bundle', id: bundle_id, objects: [] } as BundleType; + let nodes = window.cycore.$(':visible'); + nodes = nodes.union(nodes.connectedEdges()); + nodes.each((ele) => { + if (ele.length === 0) { + return; + } + //logic to remove null on json export + if(ele.data('raw_data')!==undefined){ + bundle.objects.push(ele.data('raw_data')); + } + }); + + // Convert to JSON and save + const jsonToSave = JSON.stringify(bundle); + const jsonBundleSave = new Blob([jsonToSave], { type: "application/json" }); + fileSaver.saveAs(jsonBundleSave, "bundle.json"); + $('.message-status').html(`Exported ${bundle.objects.length} objects`); }); ipcRenderer.on("select_all", () => { @@ -80,3 +137,24 @@ export function setHandlers() { newDatabaseConfiguration(); }); } +// export function saveFile(CollectionReturnValue node){ +// const bundle_id = 'bundle--' + uuid.v4(); +// const bundle = { type: 'bundle', id: bundle_id, objects: [] } as BundleType; +// let nodesToSave = node; +// nodesToSave = nodesToSave.union(nodesToSave.connectedEdges()); +// nodesToSave.each((ele) => { +// if (ele.length === 0) { +// return; +// } +// //logic to remove null on json export +// if(ele.data('raw_data')!==undefined){ +// bundle.objects.push(ele.data('raw_data')); +// } +// }); + +// // Convert to JSON and save +// const jsonToSave = JSON.stringify(bundle); +// const jsonBundleSave = new Blob([jsonToSave], { type: "application/json" }); +// fileSaver.saveAs(jsonBundleSave, "bundle.json"); +// $('.message-status').html(`Exported ${bundle.objects.length} objects`); +// } diff --git a/src/ui/main-window-menu.ts b/src/ui/main-window-menu.ts index 36e05a41..7f6f5de1 100644 --- a/src/ui/main-window-menu.ts +++ b/src/ui/main-window-menu.ts @@ -37,11 +37,11 @@ function commit_all(item: MenuItem, focusedWindow: BrowserWindow) { } } -function export_selected(item: MenuItem, focusedWindow: BrowserWindow) { - if (focusedWindow) { - focusedWindow.webContents.send("export_selected", item.label); - } -} +// function commit_selected(item: MenuItem, focusedWindow: BrowserWindow) { +// if (focusedWindow) { +// focusedWindow.webContents.send("commit_selected", item.label); +// } +// } function invert_selection(item: MenuItem, focusedWindow: BrowserWindow) { if (focusedWindow) { @@ -55,12 +55,21 @@ function export_all(item: MenuItem, focusedWindow: BrowserWindow) { } } -function export_graph(item: MenuItem, focusedWindow: BrowserWindow) { +function export_selected(item: MenuItem, focusedWindow: BrowserWindow) { if (focusedWindow) { - focusedWindow.webContents.send("export_graph", item.label); + focusedWindow.webContents.send("export_selected", item.label); } } +function select_all(item: MenuItem, focusedWindow: BrowserWindow) { + if (focusedWindow) { focusedWindow.webContents.send("select_all", item.label); } +} +// function export_graph(item: MenuItem, focusedWindow: BrowserWindow) { +// if (focusedWindow) { +// focusedWindow.webContents.send("export_graph", item.label); +// } +// } + // const db = new StigDB(ConfigurationStorageService.Instance.get().host, ConfigurationStorageService.Instance.get().name, window.cycore); // const to_save: CollectionElements = window.cycore.$('[!saved]'); // const results:StixObject[] = [] @@ -75,9 +84,6 @@ function export_graph(item: MenuItem, focusedWindow: BrowserWindow) { // ); // }); -function select_all(item: MenuItem, focusedWindow: BrowserWindow) { - if (focusedWindow) { focusedWindow.webContents.send("select_all", item.label); } -} const template: MenuItemConstructorOptions[] = [ // { @@ -111,34 +117,11 @@ const template: MenuItemConstructorOptions[] = [ // }, { // type: 'separator' // }, - // { - // label: 'Cut', - // accelerator: 'CmdOrCtrl+X', - // role: 'cut', - // }, - // { - // label: 'Copy', - // accelerator: 'CmdOrCtrl+C', - // role: 'copy', - // }, - // { - // label: 'Paste', - // accelerator: 'CmdOrCtrl+V', - // role: 'paste', - // }, - // { - // label: 'Select All', - // accelerator: 'CmdOrCtrl+A', - // role: 'selectall', - // }, - // { - // type: 'separator', - // }, { label: 'Configure Database', submenu: [ { - label: 'Database connection...', + label: 'Database Connection...', accelerator: 'CmdOrCtrl+,', click: (_, focusedWindow) => { if (focusedWindow) { @@ -156,6 +139,29 @@ const template: MenuItemConstructorOptions[] = [ // }, ], }, + { + type: 'separator', + }, + { + label: 'Select All', + accelerator: 'CmdOrCtrl+A', + role: 'selectall', + }, + { + label: 'Copy Text', + accelerator: 'CmdOrCtrl+C', + role: 'copy', + }, + { + label: 'Cut Text', + accelerator: 'CmdOrCtrl+X', + role: 'cut', + }, + { + label: 'Paste Text', + accelerator: 'CmdOrCtrl+V', + role: 'paste', + }, ], }, { @@ -172,7 +178,7 @@ const template: MenuItemConstructorOptions[] = [ accelerator: 'Shift+CmdOrCtrl+X', }, { - label: 'Paste elements', + label: 'Paste Elements', click: paste_elements, accelerator: 'Shift+CmdOrCtrl+V', }, @@ -201,12 +207,25 @@ const template: MenuItemConstructorOptions[] = [ label: 'All Elements...', click: export_all, }, - { - label: 'Export graph...', - click: export_graph, - }, + // { + // label: 'Export graph...', + // click: export_graph, + // }, ], }, + // { + // label: 'Commit...', + // submenu: [ + // { + // label: 'Selected Elements...', + // click: commit_selected, + // }, + // { + // label: 'All Elements...', + // click: commit_all, + // }, + // ], + // }, ], }, {