member_webapp/@overflow/discovery/component/search-config.component.ts
2018-06-14 12:11:56 +09:00

312 lines
7.8 KiB
TypeScript

import {
Component, EventEmitter, Input,
Output, OnChanges, SimpleChanges
} from '@angular/core';
import { ProbeHost } from '@overflow/commons-typescript/model/probe';
import * as CIDR from 'ip-cidr';
import * as ipRangeCheck from 'ip-range-check';
import { DiscoverPort, DiscoverService, DiscoverZone } from '@overflow/commons-typescript/model/discovery';
import { Checkbox } from 'primeng/primeng';
import { MetaIPTypeEnum, toMetaIPType } from '@overflow/commons-typescript/model/meta';
@Component({
selector: 'of-discovery-search-config',
templateUrl: './search-config.component.html',
})
export class SearchConfigComponent implements OnChanges {
SUPPORT_V6 = false;
@Input() probeHost: ProbeHost;
@Output() requestDiscovery = new EventEmitter<DiscoverZone>();
ipType: MetaIPTypeEnum;
startIP: string;
endIP: string;
startPort: string;
endPort: string;
excludeIPs = [];
excludePorts = [];
includeServices = [];
hostChecked = true;
portChecked = true;
serviceChecked = true;
tcpChecked = true;
udpChecked = true;
validation = false;
ipErrMsg: string;
portErrMsg: string;
fixedIPrange: number;
ipArray = [];
portExcludeDisplay = false;
portChips = [];
constructor(
) {
}
ngOnChanges(changes: SimpleChanges): void {
if (changes['probeHost']) {
this.initByProbe();
}
this.validation = true;
}
initByProbe() {
const cidr = new CIDR(this.probeHost.probe.cidr);
if (!cidr.isValid()) {
return;
}
this.ipType = MetaIPTypeEnum.V4;
this.startIP = cidr.start();
this.endIP = cidr.end();
this.startPort = '1';
this.endPort = '1024';
// TODO: Initialize services
this.checkEditableIPrange(cidr);
}
onIPExcludeFocus() {
const cidr = new CIDR(this.probeHost.probe.cidr);
this.ipArray = cidr.toArray().filter((value) => {
return this.inRange(value) || this.excludeIPs.find(obj => obj.ip === value);
}).map(value => {
return { ip: value };
});
}
inRange(value) {
const min = this.startIP;
const max = this.endIP;
if (this.ipToNum(min) <= this.ipToNum(value) && this.ipToNum(max) >= this.ipToNum(value)) {
return true;
}
return false;
}
ipToNum(ip) {
return Number(
ip.split('.')
.map(d => ('000' + d).substr(-3))
.join('')
);
}
onRequestDiscovery() {
let discoverPort: DiscoverPort = null;
let discoverService: DiscoverService = null;
if (this.serviceChecked) {
const services = [];
for (const service of this.includeServices) {
services.push(service.description);
}
discoverService = {
includeServices: services,
};
}
if (this.portChecked) {
discoverPort = {
firstScanRange: Number(this.startPort),
lastScanRange: Number(this.endPort),
includeTCP: this.tcpChecked,
includeUDP: this.udpChecked,
excludePorts: this.excludePorts,
discoverService: discoverService
};
}
const discoverZone: DiscoverZone = {
discoverHost: {
metaIPType: toMetaIPType(this.ipType),
firstScanRange: this.startIP,
lastScanRange: this.endIP,
discoverPort: discoverPort,
excludeHosts: this.excludeIPs,
},
};
console.log(discoverZone);
this.requestDiscovery.emit(discoverZone);
}
checkEditableIPrange(cidr) {
const startIPArray = cidr.addressStart.parsedAddress;
const endIPArray = cidr.addressEnd.parsedAddress;
let count = 0;
endIPArray.forEach((element, idx) => {
if (element === startIPArray[idx]) {
count++;
}
});
this.fixedIPrange = count;
}
onPortCheckChange(serviceCheckbox: Checkbox, checked: boolean) {
if (!checked) {
serviceCheckbox.checked = false;
this.serviceChecked = false;
} else {
if (!this.tcpChecked && !this.udpChecked) {
this.tcpChecked = true;
this.udpChecked = true;
}
}
}
onServiceCheckChange(portCheckbox: Checkbox, checked: boolean) {
if (checked) {
portCheckbox.checked = true;
this.portChecked = true;
}
}
onPortTypeCheck(portCheckbox: Checkbox, serviceCheckbox: Checkbox): void {
if (!this.tcpChecked && !this.udpChecked) {
this.portChecked = false;
portCheckbox.checked = false;
this.serviceChecked = false;
serviceCheckbox.checked = false;
}
}
onInputIP(e, idx: number) {
const value = e.value;
if (idx === 0) {
this.startIP = value;
} else {
this.endIP = value;
}
this.ipErrMsg = this.validateIP(value, idx);
if (this.ipErrMsg) {
this.validation = false;
} else {
this.validation = true;
}
}
validateIP(value: string, idx): string {
if (!this.isValidIPregex(value)) {
return 'Not valid IP format.';
}
if (!ipRangeCheck(value, this.probeHost.probe.cidr)) {
return 'Not valid IP range.';
}
const ipArray = [this.startIP, this.endIP];
const sortedIpArray = this.sortIP([this.startIP, this.endIP]);
if (ipArray[0] !== sortedIpArray[0]) {
return 'Not valiad range';
}
return null;
}
isValidIPregex(ip: string): boolean {
if (this.ipType === MetaIPTypeEnum.V4) {
return /^(?=\d+\.\d+\.\d+\.\d+$)(?:(?:25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]|[0-9])\.?){4}$/.test(ip);
}
return false;
}
sortIP(ipAddressArray) {
return ipAddressArray.sort((a, b) => {
a = a.split('.');
b = b.split('.');
for (let i = 0; i < a.length; i++) {
// tslint:disable-next-line:radix
if ((a[i] = parseInt(a[i])) < (b[i] = parseInt(b[i]))) {
return -1;
} else if (a[i] > b[i]) {
return 1;
}
}
return 0;
});
}
onInputPort(portNum: string, idx: number) {
if (idx === 0) {
this.startPort = portNum;
} else {
this.endPort = portNum;
}
this.portErrMsg = this.validatePort(portNum);
if (this.portErrMsg) {
this.validation = false;
} else {
this.validation = true;
}
}
validatePort(portNum): string {
if (Number(this.startPort) > Number(this.endPort)) {
return 'Not valid port range.';
}
if (Number(portNum) <= 0 || Number(portNum) > 65535) {
return 'Not valid port range.';
}
return null;
}
onAddExcludePort(event) {
const port = event.value.replace(/\s/g, '');
if (port.indexOf('~') > 0) { // e.g. 1~3000
const splited = port.split('~');
this.portChips.pop();
const from = Number(splited[0]);
const to = Number(splited[1]);
if (this.checkInvalidPort(from)
|| this.checkInvalidPort(to)
|| !Number.isInteger(from)
|| !Number.isInteger(to)) {
return;
}
const chipItem = 'All ' + from + ' ~ ' + to;
this.portChips.push(chipItem);
for (let i = from; i <= to; i++) {
this.excludePorts.push(String(i));
}
} else {
const num = Number(event.value);
if (!Number.isInteger(num) || this.checkInvalidPort(num) || this.checkExistExcludePort(event.value)) {
this.portChips.pop();
return;
}
this.excludePorts.push(event.value);
}
}
onRemoveExcludePort(event) {
if (event.value.indexOf('~') > 0) {
// e.g. 'All 1 ~ 30'
const splited = event.value.replace(/\s/g, '').replace('All', '').split('~');
for (let i = Number(splited[0]); i <= Number(splited[1]); i++) {
console.log(String(i));
const index = this.excludePorts.indexOf(String(i));
this.excludePorts.splice(index, 1);
}
return;
}
const idx = this.excludePorts.indexOf(event.value);
this.excludePorts.splice(idx, 1);
}
checkExistExcludePort(portNum) {
return this.excludePorts.find((value) => {
return value === portNum;
});
}
checkInvalidPort(port) {
return port <= 0 || port > 65535;
}
}