/*
* SoapUI, Copyright (C) 2004-2016 SmartBear Software
*
* Licensed under the EUPL, Version 1.1 or - as soon as they will be approved by the European Commission - subsequent
* versions of the EUPL (the "Licence");
* You may not use this work except in compliance with the Licence.
* You may obtain a copy of the Licence at:
*
* http://ec.europa.eu/idabc/eupl
*
* Unless required by applicable law or agreed to in writing, software distributed under the Licence is
* distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the Licence for the specific language governing permissions and limitations
* under the Licence.
*/
package com.eviware.soapui.security.log;
import com.eviware.soapui.model.security.SecurityScan;
import com.eviware.soapui.model.testsuite.TestStep;
import com.eviware.soapui.security.result.SecurityResult;
import com.eviware.soapui.security.result.SecurityResult.ResultStatus;
import com.eviware.soapui.security.result.SecurityScanRequestResult;
import com.eviware.soapui.security.result.SecurityScanResult;
import com.eviware.soapui.security.result.SecurityTestStepResult;
import com.eviware.soapui.security.scan.AbstractSecurityScan;
import org.apache.commons.collections.list.TreeList;
import javax.swing.AbstractListModel;
import java.lang.ref.SoftReference;
import java.util.Collections;
import java.util.List;
/**
* SecurityTestLog
*
* @author SoapUI team
*/
@SuppressWarnings({"serial", "unchecked"})
public class SecurityTestLogModel extends AbstractListModel {
private List<Object> items = Collections.synchronizedList(new TreeList());
private List<SoftReference<SecurityResult>> results = Collections.synchronizedList(new TreeList());
private int maxSize = 100;
private int stepCount;
private int checkCount;
private int requestCount;
private int currentCheckEntriesCount;
private int currentStepEntriesCount;
public synchronized Object getElementAt(int arg0) {
try {
return items.get(arg0);
} catch (Throwable e) {
return null;
}
}
@Override
public int getSize() {
return items.size();
}
public synchronized void addText(String msg) {
items.add(msg);
results.add(null);
fireIntervalAdded(this, items.size() - 1, items.size() - 1);
enforceMaxSize();
}
public synchronized SecurityResult getTestStepResultAt(int index) {
if (index >= results.size()) {
return null;
}
SoftReference<SecurityResult> result = results.get(index);
return result == null ? null : result.get();
}
/**
* called before TestStep SecurityScans just to mark beginning of TestStep
* SecurityLog part to be updated after step scans finish with proper values
*
* @return true - if added, false - otherwise
*/
public synchronized boolean addSecurityTestStepResult(TestStep testStep) {
stepCount++;
checkCount = 0;
currentStepEntriesCount = 1;
int size = items.size();
if (AbstractSecurityScan.isSecurable(testStep)) {
SecurityTestStepResult result = new SecurityTestStepResult(testStep, null);
SoftReference<SecurityResult> stepResultRef = new SoftReference<SecurityResult>(result);
items.add("Step " + stepCount + " [" + result.getTestStep().getName() + "] ");
results.add(stepResultRef);
fireIntervalAdded(this, size, items.size() - 1);
enforceMaxSize();
return true;
} else {
return false;
}
}
// called after whole security teststep finished to delete start line in case
// only errors are beeing displayed
public synchronized void updateSecurityTestStepResult(SecurityTestStepResult result, boolean errorsOnly,
boolean hasChecksToProcess, boolean startStepLogEntryAdded) {
int startStepIndex = 0;
if (items.size() > currentStepEntriesCount) {
if (currentStepEntriesCount > 0) {
startStepIndex = items.size() - currentStepEntriesCount;
} else {
startStepIndex = items.size();
}
}
if ((errorsOnly && !result.isHasScansWithWarnings()) || (startStepLogEntryAdded && !hasChecksToProcess)) {
// stepCount-- ;
int size = items.size() - 1;
while (size >= startStepIndex) {
items.remove(size);
results.remove(size);
size--;
}
if (startStepIndex > 0 && size > 0) {
fireIntervalRemoved(this, startStepIndex, size);
} else {
fireIntervalRemoved(this, 0, size);
}
} else if (startStepLogEntryAdded) {
try {
if (startStepIndex > 0 && startStepIndex < maxSize) {
String statusToDisplay = getStatusToDisplay(result.getExecutionProgressStatus());
items.set(startStepIndex, "Step " + stepCount + " [" + result.getTestStep().getName() + "] "
+ statusToDisplay + ": took " + result.getTimeTaken() + " ms");
SoftReference<SecurityResult> stepResultRef = new SoftReference<SecurityResult>(result);
results.set(startStepIndex, stepResultRef);
fireContentsChanged(this, startStepIndex, startStepIndex);
}
} catch (IndexOutOfBoundsException e) {
// when log max size is exceeded skip updating the raw since it
// won't be visible anyway
}
}
currentStepEntriesCount = 0;
}
private String getStatusToDisplay(ResultStatus result) {
String statusToDisplay = "";
switch (result) {
case FAILED:
statusToDisplay = "Alerts";
break;
case OK:
statusToDisplay = "No Alerts";
break;
case SKIPPED:
statusToDisplay = "Skipped";
break;
case MISSING_ASSERTIONS:
statusToDisplay = "Missing Assertions";
break;
case MISSING_PARAMETERS:
statusToDisplay = "Missing Parameters";
break;
}
return statusToDisplay;
}
public synchronized void addSecurityScanResult(SecurityScan securityCheck) {
int size = items.size();
checkCount++;
requestCount = 0;
SecurityScanResult securityCheckResult = securityCheck.getSecurityScanResult();
SoftReference<SecurityResult> checkResultRef = new SoftReference<SecurityResult>(securityCheckResult);
items.add("SecurityScan " + checkCount + " [" + securityCheck.getName() + "] ");
results.add(checkResultRef);
currentCheckEntriesCount = 1;
currentStepEntriesCount++;
fireIntervalAdded(this, size, items.size() - 1);
enforceMaxSize();
}
// updates log entry for security scan with the status, time taken, and
// similar info known only after finished
public synchronized void updateSecurityScanResult(SecurityScanResult securityCheckResult, boolean errorsOnly) {
int startCheckIndex = 0;
if (items.size() > currentCheckEntriesCount) {
if (currentCheckEntriesCount > 0) {
startCheckIndex = items.size() - currentCheckEntriesCount;
} else {
startCheckIndex = items.size();
}
}
if (errorsOnly && !securityCheckResult.isHasRequestsWithWarnings()) {
// remove all entries for the securityCheck that had no warnings
checkCount--;
int size = items.size() - 1;
while (size >= startCheckIndex) {
items.remove(size);
results.remove(size);
size--;
}
if (startCheckIndex > 0) {
fireIntervalRemoved(this, startCheckIndex, size);
} else {
fireIntervalRemoved(this, startCheckIndex, size);
}
} else {
SecurityScan securityCheck = securityCheckResult.getSecurityScan();
securityCheckResult.detectMissingItems();
StringBuilder outStr = new StringBuilder("SecurityScan ");
String statusToDisplay = getStatusToDisplay(securityCheckResult.getExecutionProgressStatus());
outStr.append(checkCount).append(" [").append(securityCheck.getName()).append("] ").append(
statusToDisplay).append(", took = ").append(securityCheckResult.getTimeTaken());
try {
if (startCheckIndex > 0 && startCheckIndex < maxSize) {
items.set(startCheckIndex, outStr.toString());
SoftReference<SecurityResult> checkResultRef = new SoftReference<SecurityResult>(securityCheckResult);
results.set(startCheckIndex, checkResultRef);
currentCheckEntriesCount = 0;
fireContentsChanged(this, startCheckIndex, startCheckIndex);
}
} catch (IndexOutOfBoundsException e) {
// when log max size is exceeded skip updating the raw since it
// won't be visible anyway
}
}
}
public synchronized void addSecurityScanRequestResult(SecurityScanRequestResult securityCheckRequestResult) {
int size = items.size();
requestCount++;
SoftReference<SecurityResult> checkReqResultRef = new SoftReference<SecurityResult>(securityCheckRequestResult);
items.add(securityCheckRequestResult.getChangedParamsInfo(requestCount));
results.add(checkReqResultRef);
currentCheckEntriesCount++;
currentStepEntriesCount++;
for (String msg : securityCheckRequestResult.getMessages()) {
items.add(" -> " + msg);
results.add(checkReqResultRef);
currentCheckEntriesCount++;
currentStepEntriesCount++;
}
fireIntervalAdded(this, size, items.size() - 1);
enforceMaxSize();
}
public synchronized void clear() {
int sz = items.size();
items.clear();
results.clear();
stepCount = 0;
fireIntervalRemoved(this, 0, sz);
}
public int getMaxSize() {
return maxSize;
}
public void setMaxSize(int maxSize) {
this.maxSize = maxSize;
enforceMaxSize();
}
private synchronized void enforceMaxSize() {
while (items.size() > maxSize) {
items.remove(0);
results.remove(0);
fireIntervalRemoved(this, 0, 0);
}
}
public synchronized int getIndexOfSecurityScan(SecurityScan check) {
for (int i = 0; i < results.size(); i++) {
SoftReference<SecurityResult> result = results.get(i);
if (result != null) {
SecurityResult referent = result.get();
if (referent instanceof SecurityScanResult) {
if (((SecurityScanResult) referent).getSecurityScan() == check) {
return i;
}
}
}
}
return -1;
}
}