From d4bac2d6741f7a291522c29c9ecc87c3e32e21d4 Mon Sep 17 00:00:00 2001 From: Emiliano Ciavatta Date: Fri, 16 Oct 2020 14:16:44 +0200 Subject: Add notification when pcap have been processed --- frontend/src/components/objects/CopyLinkPopover.js | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 frontend/src/components/objects/CopyLinkPopover.js (limited to 'frontend/src/components/objects/CopyLinkPopover.js') diff --git a/frontend/src/components/objects/CopyLinkPopover.js b/frontend/src/components/objects/CopyLinkPopover.js new file mode 100644 index 0000000..fa9266f --- /dev/null +++ b/frontend/src/components/objects/CopyLinkPopover.js @@ -0,0 +1,54 @@ +/* + * This file is part of caronte (https://github.com/eciavatta/caronte). + * Copyright (c) 2020 Emiliano Ciavatta. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, version 3. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +import React, {Component} from "react"; +import TextField from "../fields/TextField"; +import LinkPopover from "./LinkPopover"; + +class CopyLinkPopover extends Component { + + state = {}; + + constructor(props) { + super(props); + + this.copyTextarea = React.createRef(); + } + + handleClick = () => { + this.copyTextarea.current.select(); + document.execCommand("copy"); + this.setState({copiedMessage: true}); + setTimeout(() => this.setState({copiedMessage: false}), 3000); + }; + + render() { + const copyPopoverContent =
+ {this.state.copiedMessage ? Copied! : + Click to copy} + +
; + + return ( + {this.props.text}} + content={copyPopoverContent} placement="right"/> + ); + } +} + +export default CopyLinkPopover; -- cgit v1.2.3-70-g09d2 From 79b8b2fa3e8563c986da8baa3a761f2d4f0c6f47 Mon Sep 17 00:00:00 2001 From: Emiliano Ciavatta Date: Fri, 16 Oct 2020 19:05:44 +0200 Subject: Minor improvements --- application_router.go | 2 +- frontend/src/components/App.js | 29 ++++++++----- frontend/src/components/Header.js | 12 +++--- frontend/src/components/fields/InputField.js | 2 +- frontend/src/components/objects/CopyLinkPopover.js | 4 +- frontend/src/components/pages/ConfigurationPage.js | 12 ++++-- .../src/components/pages/ConfigurationPage.scss | 30 +++++++++---- frontend/src/components/pages/MainPage.js | 50 +++++++++++----------- frontend/src/components/panels/ConnectionsPane.js | 4 +- frontend/src/components/panels/SearchPane.js | 6 +-- rules_manager.go | 5 +++ 11 files changed, 93 insertions(+), 63 deletions(-) (limited to 'frontend/src/components/objects/CopyLinkPopover.js') diff --git a/application_router.go b/application_router.go index 656b63e..4048dc5 100644 --- a/application_router.go +++ b/application_router.go @@ -39,7 +39,7 @@ func CreateApplicationRouter(applicationContext *ApplicationContext, router.Use(static.Serve("/", static.LocalFile("./frontend/build", true))) - for _, path := range []string{"/connections/:id", "/pcaps", "/rules", "/services", "/config"} { + for _, path := range []string{"/connections/:id", "/pcaps", "/rules", "/services", "/config", "/searches"} { router.GET(path, func(c *gin.Context) { c.File("./frontend/build/index.html") }) diff --git a/frontend/src/components/App.js b/frontend/src/components/App.js index e12a99d..96083cd 100644 --- a/frontend/src/components/App.js +++ b/frontend/src/components/App.js @@ -16,6 +16,7 @@ */ import React, {Component} from "react"; +import {BrowserRouter as Router} from "react-router-dom"; import dispatcher from "../dispatcher"; import Notifications from "./Notifications"; import ConfigurationPage from "./pages/ConfigurationPage"; @@ -27,15 +28,7 @@ class App extends Component { state = {}; componentDidMount() { - dispatcher.register("notifications", (payload) => { - if (payload.event === "connected") { - this.setState({ - connected: true, - configured: payload.message["is_configured"], - version: payload.message["version"] - }); - } - }); + dispatcher.register("notifications", this.handleNotifications); setInterval(() => { if (document.title.endsWith("❚")) { @@ -46,16 +39,30 @@ class App extends Component { }, 500); } + componentWillUnmount() { + dispatcher.unregister(this.handleNotifications); + } + + handleNotifications = (payload) => { + if (payload.event === "connected") { + this.setState({ + connected: true, + configured: payload.message["is_configured"], + version: payload.message["version"] + }); + } + }; + render() { return ( - <> + {this.state.connected ? (this.state.configured ? : this.setState({configured: true})}/>) : } - + ); } } diff --git a/frontend/src/components/Header.js b/frontend/src/components/Header.js index ab16dd1..c46d768 100644 --- a/frontend/src/components/Header.js +++ b/frontend/src/components/Header.js @@ -27,6 +27,8 @@ import RulesConnectionsFilter from "./filters/RulesConnectionsFilter"; import StringConnectionsFilter from "./filters/StringConnectionsFilter"; import "./Header.scss"; +const classNames = require("classnames"); + class Header extends Component { componentDidMount() { @@ -46,7 +48,7 @@ class Header extends Component { return (
-
+

{ @@ -56,7 +58,7 @@ class Header extends Component {

-
+ {this.props.configured &&
-
+
} -
+ {this.props.configured &&
@@ -89,7 +91,7 @@ class Header extends Component {
-
+
}
); diff --git a/frontend/src/components/fields/InputField.js b/frontend/src/components/fields/InputField.js index 823989d..e2ea020 100644 --- a/frontend/src/components/fields/InputField.js +++ b/frontend/src/components/fields/InputField.js @@ -75,7 +75,7 @@ class InputField extends Component { aria-describedby={this.id} onChange={handler} {...inputProps} readOnly={this.props.readonly}/> - {type !== "file" && value !== "" && + {type !== "file" && value !== "" && !this.props.readonly &&
handler(null)}>del
diff --git a/frontend/src/components/objects/CopyLinkPopover.js b/frontend/src/components/objects/CopyLinkPopover.js index fa9266f..b951603 100644 --- a/frontend/src/components/objects/CopyLinkPopover.js +++ b/frontend/src/components/objects/CopyLinkPopover.js @@ -37,10 +37,10 @@ class CopyLinkPopover extends Component { }; render() { - const copyPopoverContent =
+ const copyPopoverContent =
{this.state.copiedMessage ? Copied! : Click to copy} - +
; return ( diff --git a/frontend/src/components/pages/ConfigurationPage.js b/frontend/src/components/pages/ConfigurationPage.js index 4f0ce21..8f9b68b 100644 --- a/frontend/src/components/pages/ConfigurationPage.js +++ b/frontend/src/components/pages/ConfigurationPage.js @@ -25,8 +25,10 @@ import ButtonField from "../fields/ButtonField"; import CheckField from "../fields/CheckField"; import InputField from "../fields/InputField"; import TextField from "../fields/TextField"; +import Header from "../Header"; import LinkPopover from "../objects/LinkPopover"; import "../panels/common.scss"; +import "./common.scss"; import "./ConfigurationPage.scss"; class ConfigurationPage extends Component { @@ -113,9 +115,13 @@ class ConfigurationPage extends Component { ); return ( -
-
-
+
+
+
+
+ +
+
POST /setup diff --git a/frontend/src/components/pages/ConfigurationPage.scss b/frontend/src/components/pages/ConfigurationPage.scss index 4509865..4254547 100644 --- a/frontend/src/components/pages/ConfigurationPage.scss +++ b/frontend/src/components/pages/ConfigurationPage.scss @@ -1,18 +1,30 @@ @import "../../colors"; .configuration-page { - display: flex; - align-items: center; - justify-content: center; - height: 100%; background-color: $color-primary-0; - .pane { - flex-basis: 900px; - margin-bottom: 200px; + .header-title { + margin: 50px auto; } - .pane-container { - padding-bottom: 1px; + .configuration-pane { + display: flex; + justify-content: center; + height: 100%; + padding-top: 100px; + + .section-content { + background-color: $color-primary-3; + margin-top: 15px; + } + + .section-table table { + background-color: red !important; + } + + .section-footer { + background-color: $color-primary-3; + } } } + diff --git a/frontend/src/components/pages/MainPage.js b/frontend/src/components/pages/MainPage.js index a542e3f..c4dcd20 100644 --- a/frontend/src/components/pages/MainPage.js +++ b/frontend/src/components/pages/MainPage.js @@ -16,7 +16,7 @@ */ import React, {Component} from "react"; -import {BrowserRouter as Router, Route, Switch} from "react-router-dom"; +import {Route, Switch} from "react-router-dom"; import Filters from "../dialogs/Filters"; import Header from "../Header"; import Connections from "../panels/ConnectionsPane"; @@ -42,34 +42,32 @@ class MainPage extends Component { return (
- -
-
this.setState({filterWindowOpen: true})}/> -
- -
-
- this.setState({selectedConnection: c})}/> -
-
- - }/> - }/> - }/> - }/> - }/> - }/> - -
+
+
this.setState({filterWindowOpen: true})} configured={true}/> +
- {modal} +
+
+ this.setState({selectedConnection: c})}/>
- -
- +
+ + }/> + }/> + }/> + }/> + }/> + }/> +
- + + {modal} +
+ +
+ +
); } diff --git a/frontend/src/components/panels/ConnectionsPane.js b/frontend/src/components/panels/ConnectionsPane.js index 457c249..6418b3e 100644 --- a/frontend/src/components/panels/ConnectionsPane.js +++ b/frontend/src/components/panels/ConnectionsPane.js @@ -226,11 +226,11 @@ class ConnectionsPane extends Component { } loadRules = async () => { - return backend.get("/api/rules").then(res => this.setState({rules: res.json})); + return backend.get("/api/rules").then((res) => this.setState({rules: res.json})); }; loadServices = async () => { - return backend.get("/api/services").then(res => this.setState({services: res.json})); + return backend.get("/api/services").then((res) => this.setState({services: res.json})); }; render() { diff --git a/frontend/src/components/panels/SearchPane.js b/frontend/src/components/panels/SearchPane.js index 4c9f229..4ef5632 100644 --- a/frontend/src/components/panels/SearchPane.js +++ b/frontend/src/components/panels/SearchPane.js @@ -236,13 +236,13 @@ class SearchPane extends Component { })} name="terms" min={3} inline allowNew={true} readonly={regexOptionsModified || options["text_search"]["exact_phrase"]} - onChange={(tags) => this.updateParam((s) => s["text_search"].terms = tags.map(t => t.name))}/> - { + onChange={(tags) => this.updateParam((s) => s["text_search"].terms = tags.map((t) => t.name))}/> + { return {name: t}; })} name="excluded_terms" min={3} inline allowNew={true} readonly={regexOptionsModified || options["text_search"]["exact_phrase"]} - onChange={(tags) => this.updateParam((s) => s["text_search"]["excluded_terms"] = tags.map(t => t.name))}/> + onChange={(tags) => this.updateParam((s) => s["text_search"]["excluded_terms"] = tags.map((t) => t.name))}/> or diff --git a/rules_manager.go b/rules_manager.go index a6d969f..5d6cded 100644 --- a/rules_manager.go +++ b/rules_manager.go @@ -24,6 +24,7 @@ import ( "github.com/flier/gohs/hyperscan" "github.com/go-playground/validator/v10" log "github.com/sirupsen/logrus" + "sort" "sync" "time" ) @@ -213,6 +214,10 @@ func (rm *rulesManagerImpl) GetRules() []Rule { rules = append(rules, rule) } + sort.Slice(rules, func(i, j int) bool { + return rules[i].ID.Timestamp().Before(rules[j].ID.Timestamp()) + }) + return rules } -- cgit v1.2.3-70-g09d2