From 79b327fa96d6be8aea0f9bcf07f3f58ccd699581 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:17:12 +0200 Subject: [PATCH 01/17] making date picker compatible with ReactiveFormsModule --- .../date-picker/date-picker.component.scss | 14 +++++++- .../date-picker/date-picker.component.ts | 34 ++++++++++++++++--- .../shared/date-picker/date-picker.module.ts | 3 +- 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.scss b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.scss index 813b6a5a03..f46599ab5f 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.scss +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.scss @@ -28,4 +28,16 @@ font-family: "FontAwesome"; content: '\f073'; } -} \ No newline at end of file +} + +:host(.ng-invalid):not(form) { + border-left: none !important; +} + +:host(.ng-invalid) input { + border-left: 5px solid #a94442; /* red */ + + &:focus { + border-color: #4D4D4D; + } +} diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts index d58bb5f50a..9014058d0c 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.component.ts @@ -15,21 +15,29 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - import { Component, OnInit, ViewChild, ElementRef, OnChanges, SimpleChanges, Input, Output, EventEmitter } from '@angular/core'; +import { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms'; import * as moment from 'moment/moment'; -import * as Pikaday from "pikaday-time"; +import * as Pikaday from 'pikaday-time'; @Component({ selector: 'app-date-picker', templateUrl: './date-picker.component.html', + providers : [{ + provide : NG_VALUE_ACCESSOR, + useExisting: DatePickerComponent, + multi: true, + }], styleUrls: ['./date-picker.component.scss'] }) -export class DatePickerComponent implements OnInit, OnChanges { +export class DatePickerComponent implements OnInit, OnChanges, ControlValueAccessor { defaultDateStr = 'now'; picker: Pikaday; dateStr = this.defaultDateStr; + private onChange: Function; + private onTouched: Function; + @Input() date = ''; @Input() minDate = ''; @Output() dateChange = new EventEmitter(); @@ -45,7 +53,12 @@ export class DatePickerComponent implements OnInit, OnChanges { use24hour: true, onSelect: function() { _datePickerComponent.dateStr = this.getMoment().format('YYYY-MM-DD HH:mm:ss'); - setTimeout(() => _datePickerComponent.dateChange.emit(_datePickerComponent.dateStr), 0); + setTimeout(() => { + _datePickerComponent.dateChange.emit(_datePickerComponent.dateStr); + if (_datePickerComponent.onChange) { + _datePickerComponent.onChange(_datePickerComponent.dateStr); + } + }, 0); } }; this.picker = new Pikaday(pikadayConfig); @@ -62,6 +75,19 @@ export class DatePickerComponent implements OnInit, OnChanges { } } + writeValue(value) { + this.date = value; + this.setDate(); + } + + registerOnChange(fn) { + this.onChange = fn; + } + + registerOnTouched(fn) { + this.onTouched = fn; + } + setDate() { if (this.date === '') { this.dateStr = this.defaultDateStr; diff --git a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.module.ts b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.module.ts index d59d566881..e5dfd6c182 100644 --- a/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.module.ts +++ b/metron-interface/metron-alerts/src/app/shared/date-picker/date-picker.module.ts @@ -19,8 +19,7 @@ import { NgModule } from '@angular/core'; import { CommonModule } from '@angular/common'; import { FormsModule } from '@angular/forms'; -import {DatePickerComponent} from './date-picker.component'; -import {SharedModule} from '../shared.module'; +import { DatePickerComponent } from './date-picker.component'; @NgModule({ imports: [ From 89310c608ba1c2354aea74c946aa94c9f15b4978 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:18:01 +0200 Subject: [PATCH 02/17] fixing tslint warnings --- .../src/app/pcap/pcap-panel/pcap-panel.component.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts index 7c880072c4..4a017dbb5b 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.ts @@ -23,7 +23,7 @@ import { PcapRequest } from '../model/pcap.request'; import { Pdml } from '../model/pdml'; import { Subscription } from 'rxjs/Rx'; import { PcapPagination } from '../model/pcap-pagination'; -import { RestError } from "../../model/rest-error"; +import { RestError } from '../../model/rest-error'; @Component({ selector: 'app-pcap-panel', @@ -40,9 +40,9 @@ export class PcapPanelComponent implements OnInit, OnDestroy { cancelSubscription: Subscription; submitSubscription: Subscription; getSubscription: Subscription; - queryRunning: boolean = false; + queryRunning = false; queryId: string; - progressWidth: number = 0; + progressWidth = 0; pagination: PcapPagination = new PcapPagination(); savedPcapRequest: {}; errorMsg: string; From cf3b1a7e802aaa803efe97b3df239f539c9d44e9 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:27:24 +0200 Subject: [PATCH 03/17] merging udpPort handlig and tslint fixes togheter --- .../pcap-packet-line.component.spec.ts | 53 ++----------------- .../pcap-packet-line.component.ts | 22 ++++---- 2 files changed, 15 insertions(+), 60 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.spec.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.spec.ts index 00f081f365..d01c0cbc59 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.spec.ts +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.spec.ts @@ -17,7 +17,6 @@ */ import { async, ComponentFixture, TestBed } from '@angular/core/testing'; import { fakePacket } from '../model/pdml.mock'; -import { fakeUdpPacket } from '../model/pdml.mock'; import { PcapPacketLineComponent } from './pcap-packet-line.component'; @@ -35,6 +34,8 @@ describe('PcapPacketLineComponent', () => { beforeEach(() => { fixture = TestBed.createComponent(PcapPacketLineComponent); component = fixture.componentInstance; + component.packet = fakePacket; + fixture.detectChanges(); }); it('should be created', () => { @@ -42,8 +43,6 @@ describe('PcapPacketLineComponent', () => { }); it('should extract timestamp fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); expect(component.ip.timestamp).toEqual({ "name": "timestamp", "pos": "0", @@ -60,8 +59,6 @@ describe('PcapPacketLineComponent', () => { }); it('should extract ipSrcAddr fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); expect(component.ip.ipSrcAddr).toEqual({ "name": "ip.src", "pos": "26", @@ -77,8 +74,6 @@ describe('PcapPacketLineComponent', () => { }); it('should extract ipSrcPort fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); expect(component.ip.ipSrcPort).toEqual({ "name": "tcp.srcport", "pos": "34", @@ -93,9 +88,7 @@ describe('PcapPacketLineComponent', () => { }); }); - it('should extract TCP ipDestAddr fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); + it('should extract ipDestAddr fields', () => { expect(component.ip.ipDestAddr).toEqual({ "name": "ip.dst", "pos": "30", @@ -110,9 +103,7 @@ describe('PcapPacketLineComponent', () => { }); }); - it('should extract TCP ipDestPort fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); + it('should extract ipDestPort fields', () => { expect(component.ip.ipDestPort).toEqual({ "name": "tcp.dstport", "pos": "36", @@ -128,8 +119,6 @@ describe('PcapPacketLineComponent', () => { }); it('should extract protocol fields', () => { - component.packet = fakePacket; - fixture.detectChanges(); expect(component.ip.protocol).toEqual({ "name": "ip.proto", "pos": "23", @@ -143,38 +132,4 @@ describe('PcapPacketLineComponent', () => { "protos": null }); }); - - it('should extract UDP ipSrcPort fields', () => { - component.packet = fakeUdpPacket; - fixture.detectChanges(); - expect(component.ip.ipSrcPort).toEqual({ - "name": "udp.srcport", - "pos": "34", - "showname": "Source port: bootpc (68)", - "size": "2", - "value": "0044", - "show": "68", - "unmaskedvalue": null, - "hide": null, - "fields": null, - "protos": null - }); - }); - - it('should extract UDP ipDestPort fields', () => { - component.packet = fakeUdpPacket; - fixture.detectChanges(); - expect(component.ip.ipDestPort).toEqual({ - "name": "udp.dstport", - "pos": "36", - "showname": "Destination port: bootps (67)", - "size": "2", - "value": "0043", - "show": "67", - "unmaskedvalue": null, - "hide": null, - "fields": null, - "protos": null - }); - }); }); diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.ts index b1546affc5..913aff9252 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.ts +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-packet-line/pcap-packet-line.component.ts @@ -16,7 +16,7 @@ * limitations under the License. */ import { Component, OnInit, Input } from '@angular/core'; -import { PdmlPacket, PdmlProto, PdmlField } from '../model/pdml' +import { PdmlPacket, PdmlProto, PdmlField } from '../model/pdml'; @Component({ selector: '[app-pcap-packet-line]', @@ -37,18 +37,18 @@ export class PcapPacketLineComponent implements OnInit { constructor() { } ngOnInit() { - const genProto: PdmlProto = this.packet.protos.filter(p => p.name == "geninfo")[0]; - const ipProto: PdmlProto = this.packet.protos.filter(p => p.name == "ip")[0]; - const tcpProto: PdmlProto = this.packet.protos.filter(p => p.name == "tcp")[0]; - const udpProto: PdmlProto = this.packet.protos.filter(p => p.name == "udp")[0]; + const genProto: PdmlProto = this.packet.protos.filter(p => p.name === 'geninfo')[0]; + const ipProto: PdmlProto = this.packet.protos.filter(p => p.name === 'ip')[0]; + const tcpProto: PdmlProto = this.packet.protos.filter(p => p.name === 'tcp')[0]; + const udpProto: PdmlProto = this.packet.protos.filter(p => p.name === 'udp')[0]; this.ip = { - timestamp: PdmlProto.findField(genProto,'timestamp'), - ipSrcAddr: PdmlProto.findField(ipProto,'ip.src'), - ipSrcPort: tcpProto ? PdmlProto.findField(tcpProto,'tcp.srcport') : PdmlProto.findField(udpProto,'udp.srcport'), - ipDestAddr: PdmlProto.findField(ipProto,'ip.dst'), - ipDestPort: tcpProto ? PdmlProto.findField(tcpProto,'tcp.dstport') : PdmlProto.findField(udpProto,'udp.dstport'), - protocol: PdmlProto.findField(ipProto,'ip.proto') + timestamp: PdmlProto.findField(genProto, 'timestamp'), + ipSrcAddr: PdmlProto.findField(ipProto, 'ip.src'), + ipSrcPort: tcpProto ? PdmlProto.findField(tcpProto, 'tcp.srcport') : PdmlProto.findField(udpProto, 'udp.srcport'), + ipDestAddr: PdmlProto.findField(ipProto, 'ip.dst'), + ipDestPort: tcpProto ? PdmlProto.findField(tcpProto, 'tcp.dstport') : PdmlProto.findField(udpProto, 'udp.dstport'), + protocol: PdmlProto.findField(ipProto, 'ip.proto') }; } From 3394575f4ec110c884b0ef825bed8c5a70a47749 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:27:46 +0200 Subject: [PATCH 04/17] adding ReactiveFormsModule --- metron-interface/metron-alerts/src/app/pcap/pcap.module.ts | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts b/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts index 8c0db02c42..784bc93154 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts +++ b/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts @@ -17,7 +17,7 @@ */ import {NgModule} from '@angular/core'; import { CommonModule } from '@angular/common'; -import { FormsModule } from '@angular/forms'; +import { FormsModule, ReactiveFormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { routing } from './pcap.routing'; @@ -29,7 +29,7 @@ import { PcapPacketComponent } from './pcap-packet/pcap-packet.component'; import { PcapFiltersComponent } from './pcap-filters/pcap-filters.component'; import { PcapPanelComponent } from './pcap-panel/pcap-panel.component'; import { PcapPacketLineComponent } from './pcap-packet-line/pcap-packet-line.component'; -import { PcapPaginationComponent } from './pcap-pagination/pcap-pagination.component' +import { PcapPaginationComponent } from './pcap-pagination/pcap-pagination.component'; import { PcapService } from './service/pcap.service'; @NgModule({ @@ -37,6 +37,7 @@ import { PcapService } from './service/pcap.service'; routing, CommonModule, FormsModule, + ReactiveFormsModule, HttpModule, DatePickerModule, ], From 6670581654f04f340f01cddb65022ef147eb6afd Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:28:08 +0200 Subject: [PATCH 05/17] extending pcap-panel tests --- .../pcap/pcap-panel/pcap-panel.component.spec.ts | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts index fe4df1e569..2ebf8840b5 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-panel/pcap-panel.component.spec.ts @@ -26,8 +26,8 @@ import { PcapPagination } from '../model/pcap-pagination'; import { By } from '../../../../node_modules/@angular/platform-browser'; import { PcapRequest } from '../model/pcap.request'; import { defer } from 'rxjs/observable/defer'; -import {Observable} from "rxjs/Observable"; -import {RestError} from "../../model/rest-error"; +import { Observable } from 'rxjs/Observable'; +import { RestError } from '../../model/rest-error'; @Component({ selector: 'app-pcap-filters', @@ -349,7 +349,7 @@ describe('PcapPanelComponent', () => { it('should hide the progress bar if the user clicks on the cancel button', fakeAsync(() => { component.queryRunning = true; - component.queryId = 'testid'; + component.queryId = '42'; fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeDefined(); @@ -360,7 +360,7 @@ describe('PcapPanelComponent', () => { tick(); fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('.pcap-progress')) == null).toBe(true); })); it('should hide the progress bar if the cancellation request fails', fakeAsync(() => { @@ -370,7 +370,7 @@ describe('PcapPanelComponent', () => { ); component.queryRunning = true; - component.queryId = 'testid'; + component.queryId = '42'; fixture.detectChanges(); expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeDefined(); @@ -381,7 +381,7 @@ describe('PcapPanelComponent', () => { tick(); fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('.pcap-progress'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('.pcap-progress')) == null).toBe(true); })); it('should show an error message if the cancellation request fails', fakeAsync(() => { @@ -392,9 +392,9 @@ describe('PcapPanelComponent', () => { ); component.queryRunning = true; - component.queryId = 'testid'; + component.queryId = '42'; fixture.detectChanges(); - expect(fixture.debugElement.query(By.css('[data-qe-id="error"]'))).toBeFalsy(); + expect(fixture.debugElement.query(By.css('[data-qe-id="error"]')) == null).toBe(true); const cancelBtn = fixture.debugElement.query(By.css('[data-qe-id="pcap-cancel-query-button"]')); const cancelBtnEl = cancelBtn.nativeElement; From e0a1b25db93f475a918c8b1b4e4b71f692c8effc Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:28:29 +0200 Subject: [PATCH 06/17] fixing result table typo --- .../src/app/pcap/pcap-list/pcap-list.component.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-list/pcap-list.component.html b/metron-interface/metron-alerts/src/app/pcap/pcap-list/pcap-list.component.html index 5337935ea9..10b7be2092 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-list/pcap-list.component.html +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-list/pcap-list.component.html @@ -16,9 +16,9 @@ Timestamp - Source Addr + Source Address Source Port - Dest Addr + Dest Address Dest Port Protocol From 0b9cde57c40203bf5ee3de880085f5c28d665730 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:34:59 +0200 Subject: [PATCH 07/17] fixing PcapRequest types --- .../src/app/pcap/model/pcap.mock.ts | 4 ++-- .../src/app/pcap/model/pcap.request.ts | 18 +++++++++--------- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/model/pcap.mock.ts b/metron-interface/metron-alerts/src/app/pcap/model/pcap.mock.ts index bf02da8dd2..c867fe99fa 100644 --- a/metron-interface/metron-alerts/src/app/pcap/model/pcap.mock.ts +++ b/metron-interface/metron-alerts/src/app/pcap/model/pcap.mock.ts @@ -22,9 +22,9 @@ export const fakePcapRequest = { startTimeMs: 0, endTimeMs: 0, ipSrcAddr: '0.0.0.0', - ipSrcPort: 80, + ipSrcPort: '80', ipDstAddr: '0.0.0.0', - ipDstPort: 80, + ipDstPort: '80', protocol: '*', packetFilter: '*', includeReverse: false diff --git a/metron-interface/metron-alerts/src/app/pcap/model/pcap.request.ts b/metron-interface/metron-alerts/src/app/pcap/model/pcap.request.ts index 8afc9636f6..4ba80b1567 100644 --- a/metron-interface/metron-alerts/src/app/pcap/model/pcap.request.ts +++ b/metron-interface/metron-alerts/src/app/pcap/model/pcap.request.ts @@ -17,13 +17,13 @@ */ export class PcapRequest { - startTimeMs: number = 0; - endTimeMs: number = 150000000000000000; - ipSrcAddr: string = ''; - ipSrcPort: number; - ipDstAddr: string = ''; - ipDstPort: number; - protocol: string = ''; - packetFilter: string = ''; - includeReverse: boolean = false; + startTimeMs = 0; + endTimeMs = 150000000000000000; + ipSrcAddr = ''; + ipSrcPort = ''; + ipDstAddr = ''; + ipDstPort = ''; + protocol = ''; + packetFilter = ''; + includeReverse = false; } From e2a70a16ae9c9e575ee9fa328bdf912f87ab5f75 Mon Sep 17 00:00:00 2001 From: tiborm Date: Wed, 22 Aug 2018 12:38:57 +0200 Subject: [PATCH 08/17] refactroring filtering, adding date range validation and validation messages --- .../pcap-filters/pcap-filters.component.html | 55 +++--- .../pcap-filters/pcap-filters.component.scss | 13 +- .../pcap-filters.component.spec.ts | 163 +++++++----------- .../pcap-filters/pcap-filters.component.ts | 125 ++++++++++---- 4 files changed, 188 insertions(+), 168 deletions(-) diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.html b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.html index 039307a99b..c7a4db558b 100644 --- a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.html +++ b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.html @@ -11,52 +11,63 @@ OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. --> -