mirror of
https://github.com/overcuriousity/autopsy-flatpak.git
synced 2025-07-14 17:06:16 +00:00
more WIP to group bins by range in UI and also some bug fixes for when there is more than one valid BIN in a keyword search snippet
This commit is contained in:
parent
1c12218cdf
commit
72b3078d71
@ -43,6 +43,7 @@ import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.concurrent.GuardedBy;
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.Action;
|
||||
@ -933,9 +934,15 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
}
|
||||
|
||||
private void updateDisplayName() {
|
||||
ArrayList<Long> keys = new ArrayList<>();
|
||||
accountFactory.createKeys(keys);
|
||||
setDisplayName(bin.getBIN().toString() + " (" + keys.size() + ")"); //NON-NLS
|
||||
setDisplayName(getBinRangeString() + " (" + bin.getCount() + ")"); //NON-NLS
|
||||
}
|
||||
|
||||
private String getBinRangeString() {
|
||||
if (bin.getIINStart() == bin.getIINEnd()) {
|
||||
return Integer.toString(bin.getIINStart());
|
||||
} else {
|
||||
return bin.getIINStart() + "-" + StringUtils.difference(bin.getIINStart() + "", bin.getIINEnd() + "");
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -977,7 +984,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
properties.put(new NodeProperty<>(Bundle.Accounts_BINNode_binProperty_displayName(),
|
||||
Bundle.Accounts_BINNode_binProperty_displayName(),
|
||||
Bundle.Accounts_BINNode_noDescription(),
|
||||
bin.getBIN()));
|
||||
getBinRangeString()));
|
||||
properties.put(new NodeProperty<>(Bundle.Accounts_BINNode_accountsProperty_displayName(),
|
||||
Bundle.Accounts_BINNode_accountsProperty_displayName(), Bundle.Accounts_BINNode_noDescription(),
|
||||
bin.getCount()));
|
||||
@ -1020,6 +1027,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<BinResult> list) {
|
||||
RangeMap<Integer, BinResult> presentRanges = TreeRangeMap.create();
|
||||
|
||||
String query
|
||||
= "SELECT SUBSTR(blackboard_attributes.value_text,1,8) AS BIN, " //NON-NLS
|
||||
@ -1034,9 +1042,27 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query)) {
|
||||
ResultSet resultSet = results.getResultSet();
|
||||
while (resultSet.next()) {
|
||||
list.add(new BinResult(Integer.valueOf(resultSet.getString("BIN")), //NON-NLS
|
||||
resultSet.getLong("count"))); //NON-NLS
|
||||
final Integer bin = Integer.valueOf(resultSet.getString("BIN"));
|
||||
final long count = resultSet.getLong("count");
|
||||
IINRange iinRange = (IINRange) getIINInfo(bin);
|
||||
|
||||
BinResult previousResult = presentRanges.get(bin);
|
||||
|
||||
if (previousResult != null) {
|
||||
presentRanges.remove(Range.closed(previousResult.getIINStart(), previousResult.getIINEnd()));
|
||||
BinResult merged = new BinResult(previousResult.getCount() + count, previousResult.getIINRange());
|
||||
presentRanges.put(Range.closed(merged.getIINStart(), merged.getIINEnd()), merged);
|
||||
} else if (iinRange == null) {
|
||||
BinResult merged = new BinResult(count, bin, bin);
|
||||
if (merged.hasDetails()) {
|
||||
presentRanges.put(Range.closed(iinRange.getIINstart(), iinRange.getIINend()), merged);
|
||||
} else {
|
||||
presentRanges.put(Range.closed(bin, bin), merged);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
presentRanges.asMapOfRanges().values().forEach(list::add);
|
||||
} catch (TskCoreException | SQLException ex) {
|
||||
LOGGER.log(Level.SEVERE, "Error querying for BINs.", ex); //NON-NLS
|
||||
return false;
|
||||
@ -1059,88 +1085,89 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
/**
|
||||
* The number of accounts with this BIN
|
||||
*/
|
||||
private Long count;
|
||||
private final Long count;
|
||||
|
||||
private final IINInfo iinInfo;
|
||||
private Range<Integer> iinRange;
|
||||
private final IINRange iinRange;
|
||||
private final int iinEnd;
|
||||
private final int iinStart;
|
||||
|
||||
private BinResult(int start, int end, Long count, IINInfo iinInfo) {
|
||||
this.iinRange = Range.closed(start, end);
|
||||
private BinResult(Long count, @Nonnull IINRange iinRange) {
|
||||
this.count = count;
|
||||
this.iinInfo = iinInfo;
|
||||
}
|
||||
public void setIINStart(int IINStart) {
|
||||
this.IINStart = IINStart;
|
||||
this.iinRange = iinRange;
|
||||
iinStart = iinRange.getIINstart();
|
||||
iinEnd = iinRange.getIINend();
|
||||
}
|
||||
|
||||
public void setIINEnd(int IINEnd) {
|
||||
this.IINEnd = IINEnd;
|
||||
}
|
||||
|
||||
public void setCount(Long count) {
|
||||
private BinResult(Long count, int start, int end) {
|
||||
this.count = count;
|
||||
this.iinRange = null;
|
||||
iinStart = start;
|
||||
iinEnd = end;
|
||||
}
|
||||
|
||||
int getIINstart() {
|
||||
return IINStart;
|
||||
int getIINStart() {
|
||||
return iinStart;
|
||||
}
|
||||
|
||||
int getIINend() {
|
||||
return IINEnd;
|
||||
int getIINEnd() {
|
||||
return iinEnd;
|
||||
}
|
||||
|
||||
|
||||
public Long getCount() {
|
||||
return count;
|
||||
}
|
||||
|
||||
boolean hasDetails() {
|
||||
return iinInfo != null;
|
||||
return iinRange != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<Integer> getNumberLength() {
|
||||
return iinInfo.getNumberLength();
|
||||
return iinRange.getNumberLength();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankCity() {
|
||||
return iinInfo.getBankCity();
|
||||
return iinRange.getBankCity();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankName() {
|
||||
return iinInfo.getBankName();
|
||||
return iinRange.getBankName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankPhoneNumber() {
|
||||
return iinInfo.getBankPhoneNumber();
|
||||
return iinRange.getBankPhoneNumber();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBankURL() {
|
||||
return iinInfo.getBankURL();
|
||||
return iinRange.getBankURL();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getBrand() {
|
||||
return iinInfo.getBrand();
|
||||
return iinRange.getBrand();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getCardType() {
|
||||
return iinInfo.getCardType();
|
||||
return iinRange.getCardType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getCountry() {
|
||||
return iinInfo.getCountry();
|
||||
return iinRange.getCountry();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Optional<String> getScheme() {
|
||||
return iinInfo.getScheme();
|
||||
return iinRange.getScheme();
|
||||
}
|
||||
|
||||
private IINRange getIINRange() {
|
||||
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
|
||||
}
|
||||
}
|
||||
|
||||
@ -1157,7 +1184,6 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
|
||||
@Override
|
||||
protected boolean createKeys(List<Long> list) {
|
||||
private final static RangeMap<Integer, BinResult> presentRanges = TreeRangeMap.create();
|
||||
|
||||
String query
|
||||
= "SELECT blackboard_artifacts.artifact_id " //NON-NLS
|
||||
@ -1165,7 +1191,7 @@ public class Accounts extends Observable implements AutopsyVisitableItem {
|
||||
+ " JOIN blackboard_attributes ON blackboard_artifacts.artifact_id = blackboard_attributes.artifact_id " //NON-NLS
|
||||
+ " WHERE blackboard_artifacts.artifact_type_id = " + BlackboardArtifact.ARTIFACT_TYPE.TSK_CREDIT_CARD_ACCOUNT.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.attribute_type_id = " + BlackboardAttribute.ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER.getTypeID() //NON-NLS
|
||||
+ " AND blackboard_attributes.value_text BETWEEN " + bin.getIINstart() + " AND " + bin.getIINend() //NON-NLS
|
||||
+ " AND blackboard_attributes.value_text >= \"" + bin.getIINStart() + "\" AND blackboard_attributes.value_text < \"" + (bin.getIINEnd() + 1) + "\"" //NON-NLS
|
||||
+ getRejectedArtifactFilterClause()
|
||||
+ " ORDER BY blackboard_attributes.value_text"; //NON-NLS
|
||||
try (SleuthkitCase.CaseDbQuery results = skCase.executeQuery(query);
|
||||
|
@ -19,6 +19,7 @@
|
||||
//
|
||||
package org.sleuthkit.autopsy.keywordsearch;
|
||||
|
||||
import com.google.common.base.CharMatcher;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.HashSet;
|
||||
@ -181,21 +182,30 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
||||
@Override
|
||||
public KeywordCachedArtifact writeSingleFileHitsToBlackBoard(String termHit, KeywordHit hit, String snippet, String listName) {
|
||||
BlackboardArtifact newArtifact;
|
||||
|
||||
Collection<BlackboardAttribute> attributes = new ArrayList<>();
|
||||
try {
|
||||
//if the keyword hit matched the credit card number keyword/regex...
|
||||
if (keyword.getType() == ATTRIBUTE_TYPE.TSK_ACCOUNT_NUMBER) {
|
||||
termHit = CharMatcher.inRange('0', '9').negate().trimFrom(termHit);
|
||||
newArtifact = hit.getContent().newArtifact(ARTIFACT_TYPE.TSK_CREDIT_CARD_ACCOUNT);
|
||||
// make account artifact
|
||||
//try to match it against the track 1 regex
|
||||
Matcher matcher = TRACK1_PATTERN.matcher(hit.getSnippet());
|
||||
if (matcher.find()) {
|
||||
parseTrack1Data(newArtifact, matcher);
|
||||
while (matcher.find()) {
|
||||
if (termHit.equals(matcher.group("accountNumber"))) {
|
||||
parseTrack1Data(newArtifact, matcher);
|
||||
break;
|
||||
}
|
||||
}
|
||||
//then try to match it against the track 2 regex
|
||||
matcher = TRACK2_PATTERN.matcher(hit.getSnippet());
|
||||
if (matcher.find()) {
|
||||
parseTrack2Data(newArtifact, matcher);
|
||||
while (matcher.find()) {
|
||||
final String group = matcher.group("accountNumber");
|
||||
if (termHit.equals(group)) {
|
||||
parseTrack2Data(newArtifact, matcher);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (hit.getContent() instanceof AbstractFile) {
|
||||
AbstractFile file = (AbstractFile) hit.getContent();
|
||||
@ -329,9 +339,9 @@ final class TermComponentQuery implements KeywordSearchQuery {
|
||||
continue; //if the hit does not pass the luhn check, skip it.
|
||||
}
|
||||
final int iin = Integer.parseInt(ccn.substring(0, 8));
|
||||
if (false == Accounts.isIINKnown(iin)) {
|
||||
continue;
|
||||
}
|
||||
// if (false == Accounts.isIINKnown(iin)) {
|
||||
// continue;
|
||||
// }
|
||||
}
|
||||
|
||||
/*
|
||||
|
Loading…
x
Reference in New Issue
Block a user