You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@metron.apache.org by rm...@apache.org on 2018/08/06 14:15:18 UTC
metron git commit: METRON-1676 PCAP UI - Add data range selector to
the filter bar (tiborm via merrimanr) closes apache/metron#1119
Repository: metron
Updated Branches:
refs/heads/feature/METRON-1554-pcap-query-panel b445bfe24 -> 09a7f1899
METRON-1676 PCAP UI - Add data range selector to the filter bar (tiborm via merrimanr) closes apache/metron#1119
Project: http://git-wip-us.apache.org/repos/asf/metron/repo
Commit: http://git-wip-us.apache.org/repos/asf/metron/commit/09a7f189
Tree: http://git-wip-us.apache.org/repos/asf/metron/tree/09a7f189
Diff: http://git-wip-us.apache.org/repos/asf/metron/diff/09a7f189
Branch: refs/heads/feature/METRON-1554-pcap-query-panel
Commit: 09a7f18994dc8254ca158139c44258cb7f1107ec
Parents: b445bfe
Author: tiborm <ti...@gmail.com>
Authored: Mon Aug 6 09:14:54 2018 -0500
Committer: rmerriman <me...@gmail.com>
Committed: Mon Aug 6 09:14:54 2018 -0500
----------------------------------------------------------------------
.../pcap-filters/pcap-filters.component.html | 30 ++--
.../pcap-filters/pcap-filters.component.scss | 2 +-
.../pcap-filters/pcap-filters.component.spec.ts | 156 ++++++++++++++++++-
.../pcap/pcap-filters/pcap-filters.component.ts | 19 ++-
.../metron-alerts/src/app/pcap/pcap.module.ts | 6 +-
.../src/app/pcap/service/pcap.service.ts | 4 +-
.../shared/directives/alert-search.directive.ts | 2 +-
7 files changed, 195 insertions(+), 24 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.html
----------------------------------------------------------------------
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 abc4cf0..f4133df 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
@@ -12,23 +12,33 @@
the specific language governing permissions and limitations under the License.
-->
<form (ngSubmit)="onSubmit()" #f="ngForm" class="form-inline pcap-search">
+
+ <div class="form-group">
+ <label>From</label>
+ <app-date-picker id="startTime" [(date)]="startTimeStr"> </app-date-picker>
+ </div>
+ <div class="form-group">
+ <label>To</label>
+ <app-date-picker id="endTime" [(date)]="endTimeStr"> </app-date-picker>
+ </div>
+
<div class="form-group">
- <label for="ip_src_addr">IP Source Address</label>
- <input name="ip_src_addr" #ip_src_addr="ngModel" class="form-control" pattern="^(?:\d{1,3}\.){3}\d{1,3}(.\d{1,2})?$" [(ngModel)]="model.ipSrcAddr">
+ <label for="ipSrcAddr">IP Source Address</label>
+ <input name="ipSrcAddr" #ipSrcAddr="ngModel" class="form-control" pattern="^(?:\d{1,3}\.){3}\d{1,3}(.\d{1,2})?$" [(ngModel)]="model.ipSrcAddr">
</div>
<div class="form-group">
- <label for="ip_src_port">IP Source Port</label>
- <input name="ip_src_port" #ip_src_port="ngModel" class="form-control" type="number" [(ngModel)]="model.ipSrcPort">
+ <label for="ipSrcPort">IP Source Port</label>
+ <input name="ipSrcPort" #ipSrcPort="ngModel" class="form-control" type="number" [(ngModel)]="model.ipSrcPort">
</div>
- <div class="form-group"><label for="ip_dest_addr">IP Dest Address</label>
- <input name="ip_dest_addr" #ip_dest_addr="ngModel" class="form-control" pattern="^(?:\d{1,3}\.){3}\d{1,3}(.\d{1,2})?$" [(ngModel)]="model.ipDstAddr">
+ <div class="form-group"><label for="ipDstAddr">IP Dest Address</label>
+ <input name="ipDstAddr" #ipDstAddr="ngModel" class="form-control" pattern="^(?:\d{1,3}\.){3}\d{1,3}(.\d{1,2})?$" [(ngModel)]="model.ipDstAddr">
</div>
<div class="form-group">
- <label for="ip_dest_port">IP Dest Port</label>
- <input id="ip_dest_port" name="ip_dest_port" #ip_dest_port="ngModel" class="form-control" type="number" [(ngModel)]="model.ipDstPort">
+ <label for="ipDstPort">IP Dest Port</label>
+ <input id="ipDstPort" name="ipDstPort" #ipDstPort="ngModel" class="form-control" type="number" [(ngModel)]="model.ipDstPort">
</div>
<div class="form-group">
@@ -37,8 +47,8 @@
</div>
<div class="form-group">
- <label for="includeReverseTraffic">Include Reverse Traffic</label>
- <input id="includeReverseTraffic" name="includeReverseTraffic" #includeReverseTraffic="ngModel" class="form-control" type="checkbox" [(ngModel)]="model.includeReverse">
+ <label for="includeReverse">Include Reverse Traffic</label>
+ <input id="includeReverse" name="includeReverse" #includeReverse="ngModel" class="form-control" type="checkbox" [(ngModel)]="model.includeReverse">
</div>
<div class="form-group">
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.scss
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.scss b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.scss
index 80bac08..b33e804 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.scss
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.scss
@@ -28,7 +28,7 @@
}
.form-group {
- padding-right: 0.75em;
+ padding: 0 0.75em 0.75em 0;
label {
margin-right: 1em;
}
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.spec.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.spec.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.spec.ts
index 8134f1d..c0f9c3b 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.spec.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.spec.ts
@@ -1,3 +1,4 @@
+
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
@@ -15,10 +16,23 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { async, ComponentFixture, TestBed } from '@angular/core/testing';
+import { async, ComponentFixture, TestBed, fakeAsync, tick } from '@angular/core/testing';
+import { By } from '@angular/platform-browser';
import { PcapFiltersComponent } from './pcap-filters.component';
import { FormsModule } from '../../../../node_modules/@angular/forms';
+import { Component, Input, Output, EventEmitter } from '@angular/core';
+import { PcapRequest } from '../model/pcap.request';
+import { emit } from 'cluster';
+
+@Component({
+ selector: 'app-date-picker',
+ template: '<input type="text" [(value)]="date">',
+})
+class FakeDatePicker {
+ @Input() date: string;
+ @Output() dateChange = new EventEmitter<string>();
+}
describe('PcapFiltersComponent', () => {
let component: PcapFiltersComponent;
@@ -29,18 +43,148 @@ describe('PcapFiltersComponent', () => {
imports: [
FormsModule
],
- declarations: [ PcapFiltersComponent ]
+ declarations: [
+ FakeDatePicker,
+ PcapFiltersComponent,
+ ]
})
.compileComponents();
- }));
- beforeEach(() => {
fixture = TestBed.createComponent(PcapFiltersComponent);
component = fixture.componentInstance;
fixture.detectChanges();
- });
+ }));
- it('should create', () => {
+ it('should be created', () => {
expect(component).toBeTruthy();
});
+
+ it('From date should be bound to the component', () => {
+ let input = fixture.debugElement.query(By.css('#startTime'));
+ const dateString = '2020-11-11 11:11:11';
+ input.componentInstance.dateChange.emit(dateString);
+ fixture.detectChanges();
+
+ expect(component.startTimeStr).toBe(dateString);
+ });
+
+ it('To date should be bound to the component', () => {
+ let input = fixture.debugElement.query(By.css('#endTime'));
+ const dateString = '2030-11-11 11:11:11';
+ input.componentInstance.dateChange.emit(dateString);
+ fixture.detectChanges();
+
+ expect(component.endTimeStr).toBe(dateString);
+ });
+
+ it('IP Source Address should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="ipSrcAddr"]');
+ input.value = '192.168.0.1';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.ipSrcAddr).toBe('192.168.0.1');
+ });
+
+ it('IP Source Port should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="ipSrcPort"]');
+ input.value = '9345';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.ipSrcPort).toBe(9345);
+ });
+
+ it('IP Dest Address should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="ipDstAddr"]');
+ input.value = '256.0.0.7';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.ipDstAddr).toBe('256.0.0.7');
+ });
+
+ it('IP Dest Port should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="ipDstPort"]');
+ input.value = '8989';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.ipDstPort).toBe(8989);
+ });
+
+ it('Protocol should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="protocol"]');
+ input.value = 'TCP';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.protocol).toBe('TCP');
+ });
+
+ it('Include Reverse Traffic should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="includeReverse"]');
+ input.click();
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.includeReverse).toBe(true);
+ });
+
+ it('Text filter should be bound to the model', () => {
+ let input: HTMLInputElement = fixture.nativeElement.querySelector('[name="protocol"]');
+ input.value = 'TestStringFilter';
+ input.dispatchEvent(new Event('input'));
+ fixture.detectChanges();
+
+ expect(component.model.protocol).toBe('TestStringFilter');
+ });
+
+ it('From date should be converted to timestamp on submit', () => {
+ component.startTimeStr = '2220-12-12 12:12:12';
+ component.search.emit = (model: PcapRequest) => {
+ expect(model.startTimeMs).toBe(new Date(component.startTimeStr).getTime());
+ }
+ component.onSubmit();
+ });
+
+ it('To date should be converted to timestamp on submit', () => {
+ component.endTimeStr = '2320-03-13 13:13:13';
+ component.search.emit = (model: PcapRequest) => {
+ expect(model.endTimeMs).toBe(new Date(component.endTimeStr).getTime());
+ }
+ component.onSubmit();
+ });
+
+ it('Filter should have an output called search', () => {
+ component.search.subscribe((filterModel) => {
+ expect(filterModel).toBeDefined();
+ });
+ component.onSubmit();
+ });
+
+ it('Filter should emit search event on submit', () => {
+ spyOn(component.search, 'emit');
+ component.onSubmit();
+ expect(component.search.emit).toHaveBeenCalled();
+ });
+
+ it('Search event should contains the filter model', () => {
+ spyOn(component.search, 'emit');
+ component.onSubmit();
+ expect(component.search.emit).toHaveBeenCalledWith(component.model);
+ });
+
+ it('Filter model structure aka PcapRequest', () => {
+ expect(fixture.componentInstance.model.hasOwnProperty('startTimeMs')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('endTimeMs')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('ipSrcAddr')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('ipSrcPort')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('ipDstAddr')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('ipDstPort')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('protocol')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('packetFilter')).toBeTruthy();
+ expect(fixture.componentInstance.model.hasOwnProperty('includeReverse')).toBeTruthy();
+ });
+
});
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.ts b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.ts
index e16d71b..4f6a3dd 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap-filters/pcap-filters.component.ts
@@ -15,8 +15,11 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import { Component, OnInit, Input, Output, EventEmitter } from '@angular/core';
-import { PcapRequest } from '../model/pcap.request'
+import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';
+import * as moment from 'moment/moment';
+import { DEFAULT_TIMESTAMP_FORMAT } from '../../utils/constants';
+
+import { PcapRequest } from '../model/pcap.request';
@Component({
selector: 'app-pcap-filters',
@@ -28,14 +31,24 @@ export class PcapFiltersComponent implements OnInit {
@Input() queryRunning: boolean = true;
@Output() search: EventEmitter<PcapRequest> = new EventEmitter<PcapRequest>();
+ startTimeStr: string;
+ endTimeStr: string;
+
model = new PcapRequest();
constructor() { }
ngOnInit() {
+ const endTime = new Date();
+ const startTime = new Date().setDate(endTime.getDate() - 5);
+
+ this.startTimeStr = moment(startTime).format(DEFAULT_TIMESTAMP_FORMAT);
+ this.endTimeStr = moment(endTime).format(DEFAULT_TIMESTAMP_FORMAT);
}
onSubmit() {
- this.search.emit(this.model)
+ this.model.startTimeMs = new Date(this.startTimeStr).getTime();
+ this.model.endTimeMs = new Date(this.endTimeStr).getTime();
+ this.search.emit(this.model);
}
}
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts
----------------------------------------------------------------------
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 c66b965..ef5c6c0 100644
--- a/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/pcap.module.ts
@@ -22,6 +22,8 @@ import { HttpModule } from '@angular/http';
import { routing } from './pcap.routing';
+import { DatePickerModule } from '../shared/date-picker/date-picker.module';
+
import { PcapListComponent } from './pcap-list/pcap-list.component';
import { PcapPacketComponent } from './pcap-packet/pcap-packet.component';
import { PcapFiltersComponent } from './pcap-filters/pcap-filters.component';
@@ -29,13 +31,15 @@ import { PcapPanelComponent } from './pcap-panel/pcap-panel.component';
import { PcapPacketLineComponent } from './pcap-packet-line/pcap-packet-line.component';
import { PcapService } from './service/pcap.service'
+
@NgModule({
imports: [
routing,
CommonModule,
FormsModule,
- HttpModule
+ HttpModule,
+ DatePickerModule,
],
declarations: [
PcapListComponent,
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts b/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
index ba209c4..6fd3e62 100644
--- a/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
+++ b/metron-interface/metron-alerts/src/app/pcap/service/pcap.service.ts
@@ -67,7 +67,7 @@ export class PcapService {
.onErrorResumeNext();
}
- public getDownloadUrl(id: string, pageNo: number) {
- return `/api/v1/pcap/${id}/raw?page=${pageNo}`;
+ public getDownloadUrl(id: string, pageId: number) {
+ return `/api/v1/pcap/${id}/raw?page=${pageId}`;
}
}
http://git-wip-us.apache.org/repos/asf/metron/blob/09a7f189/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
----------------------------------------------------------------------
diff --git a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
index c512233..eb69b56 100644
--- a/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
+++ b/metron-interface/metron-alerts/src/app/shared/directives/alert-search.directive.ts
@@ -130,7 +130,7 @@ export class AlertSearchDirective implements AfterViewInit, OnChanges {
private handleMouseEvent (callback: Function) {
clearTimeout(this.mouseEventTimer);
- this.mouseEventTimer = setTimeout(() => { callback(); }, 100);
+ this.mouseEventTimer = window.setTimeout(() => { callback(); }, 100);
}
private mouseover($event) {