package com.threatconnect.sdk.app;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.threatconnect.app.apps.App;
import com.threatconnect.app.apps.AppConfig;
import com.threatconnect.sdk.client.fluent.AdversaryBuilder;
import com.threatconnect.sdk.client.fluent.AttributeBuilder;
import com.threatconnect.sdk.client.fluent.TagBuilder;
import com.threatconnect.sdk.client.fluent.ThreatBuilder;
import com.threatconnect.sdk.client.reader.AbstractGroupReaderAdapter;
import com.threatconnect.sdk.client.reader.AbstractIndicatorReaderAdapter;
import com.threatconnect.sdk.client.reader.DataStoreReaderAdapter;
import com.threatconnect.sdk.client.reader.ReaderAdapterFactory;
import com.threatconnect.sdk.client.reader.TagReaderAdapter;
import com.threatconnect.sdk.client.response.IterableResponse;
import com.threatconnect.sdk.client.writer.AbstractGroupWriterAdapter;
import com.threatconnect.sdk.client.writer.AbstractIndicatorWriterAdapter;
import com.threatconnect.sdk.client.writer.DataStoreWriterAdapter;
import com.threatconnect.sdk.client.writer.TagWriterAdapter;
import com.threatconnect.sdk.client.writer.WriterAdapterFactory;
import com.threatconnect.sdk.config.Configuration;
import com.threatconnect.sdk.conn.Connection;
import com.threatconnect.sdk.exception.FailedResponseException;
import com.threatconnect.sdk.server.entity.Adversary;
import com.threatconnect.sdk.server.entity.Attribute;
import com.threatconnect.sdk.server.entity.Group;
import com.threatconnect.sdk.server.entity.Indicator;
import com.threatconnect.sdk.server.entity.Tag;
import com.threatconnect.sdk.server.entity.Threat;
import com.threatconnect.sdk.server.response.entity.ApiEntitySingleResponse;
import com.threatconnect.sdk.util.IndicatorUtil;
import com.threatconnect.sdk.util.StringUtil;
import org.apache.http.Header;
import org.apache.http.HttpEntityEnclosingRequest;
import org.apache.http.HttpRequest;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpRequestBase;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import static com.threatconnect.sdk.app.AppUtil.createClientBuilder;
import static com.threatconnect.sdk.util.IndicatorUtil.getUniqueId;
import static com.threatconnect.sdk.util.IndicatorUtil.setUniqueId;
/**
* Created by dtineo on 5/15/15.
*/
public abstract class EnhancedApp extends App
{
private static final Logger logger = LoggerFactory.getLogger(EnhancedApp.class);
private Connection conn;
private String owner;
private int resultLimit = 500;
private Map<Indicator.Type, AbstractIndicatorReaderAdapter> indReaderMap = new HashMap<>();
private Map<Indicator.Type, AbstractIndicatorWriterAdapter> indWriterMap = new HashMap<>();
private Map<Group.Type, AbstractGroupReaderAdapter> groupReaderMap = new HashMap<>();
private Map<Group.Type, AbstractGroupWriterAdapter> groupWriterMap = new HashMap<>();
private int maxRetries = 3;
private int retrySleepMs = 5000;
private int requestTimerCounter = 0;
private long requestLimitResetTimeMs = 0;
private Map<String, Threat> threatMap;
private Map<String, Adversary> adversaryMap;
private TagWriterAdapter tagWriter;
private Map<String, Tag> tagMap;
private TagReaderAdapter tagReader;
private DataStoreReaderAdapter dataStoreReader;
private DataStoreWriterAdapter dataStoreWriter;
private HttpClient externalClient;
private List<String> cookies = new ArrayList();
protected Integer getRateLimit()
{
return Integer.MAX_VALUE;
}
protected Long getRateLimitIntervalMs()
{
return 60 * 1000L;
}
public EnhancedApp()
{
this(new SdkAppConfig());
}
public EnhancedApp(AppConfig appConfig)
{
Configuration config;
if (appConfig.getTcToken() != null)
{
info("Connecting using API Token");
config = new Configuration(appConfig.getTcApiPath(), appConfig.getTcApiAccessID(),
appConfig.getTcApiUserSecretKey(), appConfig.getApiDefaultOrg(),
appConfig.getApiMaxResults(getResultLimit()), appConfig.getTcToken(), appConfig.getTcTokenExpires());
}
else
{
info("Connecting using API Key");
config = new Configuration(appConfig.getTcApiPath(), appConfig.getTcApiAccessID(),
appConfig.getTcApiUserSecretKey(), appConfig.getApiDefaultOrg(),
appConfig.getApiMaxResults(getResultLimit()));
}
this.owner = appConfig.getApiDefaultOrg();
try
{
conn = new Connection(config);
}
catch (IOException e)
{
e.printStackTrace();
}
}
protected void debug(String msg, Object... fmtArgs)
{
logger.debug(String.format(msg, fmtArgs));
}
protected void warn(String msg, Object... fmtArgs)
{
logger.warn(String.format(msg, fmtArgs) );
}
protected void info(String msg, Object... fmtArgs)
{
logger.info(String.format(msg, fmtArgs) );
}
protected void error(Exception e, String msg, Object... fmtArgs)
{
logger.error(e.getMessage(), msg, fmtArgs);
}
protected void sleep(long millis)
{
try
{
Thread.sleep(millis);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
public String getOwner()
{
return owner;
}
public void setOwner(String owner)
{
this.owner = owner;
}
public Connection getConn()
{
return conn;
}
public void setConn(Connection conn)
{
this.conn = conn;
}
public AbstractIndicatorReaderAdapter getReader(Indicator.Type type)
{
AbstractIndicatorReaderAdapter reader = indReaderMap.get(type);
if (reader == null)
{
reader = ReaderAdapterFactory.createIndicatorReader(type, getConn());
indReaderMap.put(type, reader);
}
return reader;
}
public AbstractIndicatorWriterAdapter getWriter(Indicator.Type type)
{
AbstractIndicatorWriterAdapter writer = indWriterMap.get(type);
if (writer == null)
{
writer = WriterAdapterFactory.createIndicatorWriter(type, getConn());
indWriterMap.put(type, writer);
}
return writer;
}
public AbstractGroupReaderAdapter getReader(Group.Type type)
{
AbstractGroupReaderAdapter reader = groupReaderMap.get(type);
if (reader == null)
{
reader = ReaderAdapterFactory.createGroupReader(type, getConn());
groupReaderMap.put(type, reader);
}
return reader;
}
public AbstractGroupWriterAdapter getWriter(Group.Type type)
{
AbstractGroupWriterAdapter writer = groupWriterMap.get(type);
if (writer == null)
{
writer = WriterAdapterFactory.createGroupWriter(type, getConn());
groupWriterMap.put(type, writer);
}
return writer;
}
public TagReaderAdapter getTagReader()
{
if (this.tagReader == null)
{
this.tagReader = ReaderAdapterFactory.createTagReader(conn);
}
return this.tagReader;
}
public DataStoreReaderAdapter getDataStoreReader()
{
if (this.dataStoreReader == null)
{
this.dataStoreReader = ReaderAdapterFactory.createDataStoreReaderAdapter(conn);
}
return this.dataStoreReader;
}
public DataStoreWriterAdapter getDataStoreWriter()
{
if (this.dataStoreWriter == null)
{
this.dataStoreWriter = WriterAdapterFactory.createDataStoreWriterAdapter(conn);
}
return this.dataStoreWriter;
}
public int getMaxRetries()
{
return maxRetries;
}
public void setMaxRetries(int maxRetries)
{
this.maxRetries = maxRetries;
}
public int getRetrySleepMs()
{
return retrySleepMs;
}
public void setRetrySleepMs(int retrySleepMs)
{
this.retrySleepMs = retrySleepMs;
}
public int getResultLimit()
{
return resultLimit;
}
public void setResultLimit(int resultLimit)
{
this.resultLimit = resultLimit;
}
public HttpResponse getHttpResponse(String url)
{
return getHttpResponse(url, new HashMap<String, String>(), getMaxRetries(), 0);
}
public HttpResponse getHttpResponse(String url, Map<String, String> headerMap)
{
return getHttpResponse(url, headerMap, getMaxRetries(), 0);
}
public HttpResponse getHttpResponse(String url, Map<String, String> headerMap, Object entity)
{
return getHttpResponse(url, headerMap, getMaxRetries(), 0, entity);
}
public HttpResponse getHttpResponse(String url, Map<String, String> headerMap, int retryNum)
{
return getHttpResponse(url, headerMap, getMaxRetries(), retryNum);
}
protected void addHeaders(HttpRequest request, Map<String, String> headerMap)
{
if (request instanceof HttpEntityEnclosingRequest)
{
request.addHeader("Accept", ContentType.APPLICATION_JSON.toString());
}
for (Map.Entry<String, String> entry : headerMap.entrySet())
{
request.setHeader(entry.getKey(), entry.getValue());
}
//now add in any cookies saved from the last request
for (int i = 0; i < cookies.size(); i++)
{
String cookie = cookies.get(i);
request.setHeader("cookie", cookie);
}
}
protected HttpResponse getHttpResponse(String url, Map<String, String> headerMap, int maxRetries, int retryNum)
{
HttpRequestBase request = new HttpGet(url);
return getHttpResponse(url, headerMap, maxRetries, retryNum, request);
}
protected HttpResponse getHttpResponse(String url, Map<String, String> headerMap, int maxRetries, int retryNum,
Object entity)
{
if (entity != null)
{
HttpEntityEnclosingRequestBase request = new HttpPost(url);
String jsonData;
try
{
jsonData = StringUtil.toJSON(entity);
debug("jsonEntity=%s", jsonData);
}
catch (JsonProcessingException e)
{
error(e, "Failed to convert entity to JSON: %s", entity);
throw new RuntimeException("Failed to convert entity to JSON: %s" + entity);
}
request.setEntity(new StringEntity(jsonData, ContentType.APPLICATION_JSON));
return getHttpResponse(url, headerMap, maxRetries, retryNum, request);
}
else
{
return getHttpResponse(url, headerMap, maxRetries, retryNum);
}
}
private HttpResponse getHttpResponse(String url, Map<String, String> headerMap, int maxRetries, int retryNum,
HttpRequestBase request)
{
MetricUtil.tick("getResponse");
debug("getResponse.URL=%s, retryNum=%d", url, retryNum);
// debug("getResponse.headers=%s", headerMap);
HttpClient client = getExternalClient();
addHeaders(request, headerMap);
HttpResponse response;
checkRateLimit();
try
{
response = client.execute(request);
}
catch (IOException e)
{
MetricUtil.tockUpdate("getResponse");
error(e, "URL Failed to return data: %s", url);
throw new RuntimeException("URL failed to return data: " + url);
}
if (response.getStatusLine().getStatusCode() == HttpStatus.SC_OK)
{
MetricUtil.tockUpdate("getResponse");
//save any cookies that are set.
Header[] headers = response.getAllHeaders();
for (Header header : headers) {
if (header.getName().equals("Set-Cookie"))
{
cookies.add(header.getValue());
debug("Cookie to be saved: Key : " + header.getName() + " ,Value : " + header.getValue());
}
}
return response;
}
else if (response.getStatusLine().getStatusCode() == HttpStatus.SC_SERVICE_UNAVAILABLE)
{
if (retryNum < maxRetries)
{
sleep(getRetrySleepMs());
return getHttpResponse(url, headerMap, maxRetries, retryNum + 1);
}
}
MetricUtil.tockUpdate("getResponse");
debug("URL failed to return data: response_code=" + response.getStatusLine().getStatusCode()
+ " response=" + response.toString());
throw new RuntimeException(
"URL failed to return data: response_code=" + response.getStatusLine().getStatusCode()
+ "reason=" + response.getStatusLine().getReasonPhrase());
}
protected HttpClient getExternalClient()
{
if (externalClient == null)
{
externalClient = createClientBuilder(getAppConfig().isProxyExternal(),
getAppConfig().isVerifySSL()).build();
}
return externalClient;
}
private void checkRateLimit()
{
requestTimerCounter++;
info("Request counter=%d", requestTimerCounter);
if (requestTimerCounter == 1)
{
requestLimitResetTimeMs = System.currentTimeMillis() + getRateLimitIntervalMs();
info("On first counter, set request expire to: %s", new Date(requestLimitResetTimeMs));
return;
}
if (requestTimerCounter >= getRateLimit())
{
long sleepMs = requestLimitResetTimeMs - System.currentTimeMillis() + getRateLimitIntervalMs();
if (sleepMs >= 0)
{
info("RequestTimer hit rate limit, throttling requests. Limit=%d, Now=%s, ResetTime=%s, SleepMs=%d",
getRateLimit(), new Date(), new Date(requestLimitResetTimeMs), sleepMs);
sleep(sleepMs);
}
requestTimerCounter = 0;
}
}
public void dissociateTags(AbstractIndicatorReaderAdapter reader, AbstractIndicatorWriterAdapter writer,
Indicator indicator)
{
String uniqueId = getUniqueId(indicator);
if (uniqueId == null)
{
return;
}
IterableResponse<Tag> associatedTags;
try
{
associatedTags = reader.getAssociatedTags(uniqueId, getOwner());
}
catch (IOException | FailedResponseException e)
{
return;
}
for (Tag tag : associatedTags)
{
try
{
writer.dissociateTag(uniqueId, tag.getName());
}
catch (IOException | FailedResponseException e)
{
e.printStackTrace();
}
}
}
private void deleteAttributes(AbstractIndicatorReaderAdapter reader, AbstractIndicatorWriterAdapter writer,
Indicator indicator)
{
IterableResponse<Attribute> attributes;
try
{
attributes = reader.getAttributes(getUniqueId(indicator), this.owner);
}
catch (IOException | FailedResponseException e)
{
return;
}
debug("Removing attributes for indicator %s", getUniqueId(indicator));
List<Attribute> list = new ArrayList<>();
for (Attribute a : attributes)
{
list.add(a);
}
try
{
writer.deleteAttributes(getUniqueId(indicator), list, this.owner);
}
catch (IOException e)
{
e.printStackTrace();
}
}
public Attribute setAttribute(AbstractIndicatorWriterAdapter writer, Indicator indicator,
Attribute currentAttribute,
String type, String value)
{
if (currentAttribute == null)
{
info("CREATE attribute: %s=%s", type, value);
return addAttribute(writer, indicator, type, value);
}
else
{
currentAttribute.setValue(value);
info("UPDATE attribute: %s", currentAttribute);
return updateAttribute(writer, indicator, currentAttribute);
}
}
public Attribute setAttribute(AbstractGroupWriterAdapter writer, Group group, Attribute currentAttribute,
String type, String value)
{
if (currentAttribute == null)
{
info("CREATE attribute: %s=%s", type, value);
return addAttribute(writer, group, type, value);
}
else
{
currentAttribute.setValue(value);
info("UPDATE attribute: %s", currentAttribute);
return updateAttribute(writer, group, currentAttribute);
}
}
public Attribute updateAttribute(AbstractIndicatorWriterAdapter writer, Indicator indicator,
Attribute currentAttribute)
{
try
{
String uniqueId = getUniqueId(indicator);
if (uniqueId != null)
{
return (Attribute) writer.updateAttribute(uniqueId, currentAttribute).getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Failed to add attribute: %s, error: %s", currentAttribute.getType(), e.toString());
e.printStackTrace();
}
return null;
}
public Attribute updateAttribute(AbstractGroupWriterAdapter writer, Group group, Attribute currentAttribute)
{
try
{
Integer uniqueId = group.getId();
if (uniqueId != null)
{
return (Attribute) writer.updateAttribute(uniqueId, currentAttribute).getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Failed to add attribute: %s, error: %s", currentAttribute.getType(), e.toString());
e.printStackTrace();
}
return null;
}
public Attribute addAttribute(AbstractGroupWriterAdapter writer, Group group, String type, String value)
{
Attribute attribute = new AttributeBuilder()
.withDisplayed(true)
.withType(type)
.withDateAdded(new Date())
.withLastModified(new Date())
.withValue(value)
.createAttribute();
try
{
Integer uniqueId = group.getId();
if (uniqueId != null)
{
return (Attribute) writer.addAttribute(uniqueId, attribute, getOwner()).getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Failed to add attribute: %s, error: %s", attribute.getType(), e.toString());
e.printStackTrace();
}
return null;
}
public Attribute addAttribute(AbstractIndicatorWriterAdapter writer, Indicator indicator, String type, String value)
{
Attribute attribute = new AttributeBuilder()
.withDisplayed(true)
.withType(type)
.withDateAdded(new Date())
.withLastModified(new Date())
.withValue(value)
.createAttribute();
try
{
String uniqueId = getUniqueId(indicator);
if (uniqueId != null)
{
return (Attribute) writer.addAttribute(uniqueId, attribute, getOwner()).getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Failed to add attribute: %s, error: %s", attribute.getType(), e.toString());
e.printStackTrace();
}
return null;
}
public Indicator getIndicator(AbstractIndicatorReaderAdapter reader, String indText)
{
try
{
Indicator indicator = (Indicator) reader.getById(indText, getOwner());
info("Found indicator: text=%s, ind=%s", indText, indicator);
return indicator;
}
catch (IOException | FailedResponseException e)
{
e.printStackTrace();
}
return null;
}
public Indicator createIndicator(Indicator.Type type, String indText, double rating)
{
Indicator ind = IndicatorUtil.createIndicator(type);
setUniqueId(ind, indText);
ind.setType(type.toString());
ind.setRating(rating);
ind.setSummary(indText);
return ind;
}
public void addTags(AbstractGroupWriterAdapter<Group> writer, Integer groupId, List<String> tagLabels)
{
List<Tag> tags = new ArrayList<>();
for (String label : tagLabels)
{
Tag tag = new Tag();
tag.setName(label);
tags.add(tag);
}
addFullTags(writer, groupId, tags);
}
public void addFullTags(AbstractGroupWriterAdapter<Group> writer, Integer groupId, List<Tag> tags)
{
if (tagMap == null)
{
loadTagMap();
}
for (Tag tag : tags)
{
if (tag.getName().toLowerCase().contains("unknown"))
{
continue;
}
tag.setName(tag.getName().replace("/", "-"));
Tag oldTag = tagMap.get(tag.getName());
if (oldTag == null)
{
createTag(tag);
tagMap.put(tag.getName(), tag);
}
try
{
writer.associateTag(groupId, tag.getName(), getOwner());
}
catch (IOException | FailedResponseException e)
{
warn("Failed to associate tag %s to group id %d", tag.getName(), groupId);
e.printStackTrace();
}
}
}
public void addTags(AbstractIndicatorWriterAdapter<Indicator> writer, Indicator indicator, List<String> tagLabels)
{
if (tagMap == null)
{
loadTagMap();
}
String uniqueId = getUniqueId(indicator);
for (String tagLabel : tagLabels)
{
if (tagLabel.toLowerCase().contains("unknown"))
{
continue;
}
tagLabel = tagLabel.replace("/", "-");
Tag tag = tagMap.get(tagLabel);
if (tag == null)
{
createTag(tagLabel);
tagMap.put(tagLabel, tag);
}
try
{
if (uniqueId != null)
{
debug("Associating uniqueId " + uniqueId + " to tag: " + tagLabel);
writer.associateTag(uniqueId, tagLabel, getOwner());
}
}
catch (IOException | FailedResponseException e)
{
warn("Failed to associate tag %s to indicator %s", tagLabel, uniqueId);
e.printStackTrace();
}
}
}
public boolean deleteTag(String tagLabel)
{
try
{
ApiEntitySingleResponse response = getTagWriter().delete(tagLabel, getOwner());
if (response.isSuccess())
{
return true;
}
}
catch (IOException | FailedResponseException e)
{
// ignore
}
return false;
}
public Tag createTag(String tagLabel)
{
Tag tag = new TagBuilder().withName(tagLabel).createTag();
return createTag(tag);
}
public TagWriterAdapter getTagWriter()
{
if (tagWriter == null)
{
tagWriter = WriterAdapterFactory.createTagWriter(getConn());
}
return tagWriter;
}
public Tag createTag(Tag tag)
{
ApiEntitySingleResponse response;
try
{
if (getTagMap().containsKey(tag.getName()))
{
response = getTagWriter().update(tag, getOwner());
}
else
{
response = getTagWriter().create(tag, getOwner());
}
if (response.isSuccess())
{
getTagMap().put(tag.getName(), tag);
return (Tag) response.getItem();
}
}
catch (IOException | FailedResponseException e)
{
e.printStackTrace();
}
return null;
}
private void loadTagMap()
{
tagMap = new HashMap<>();
TagReaderAdapter tagReader = getTagReader();
try
{
for (Tag t : tagReader.getAll(getOwner()))
{
tagMap.put(t.getName(), t);
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to cache tagMap");
}
}
protected void associateThreat(AbstractIndicatorReaderAdapter<Indicator> reader,
AbstractIndicatorWriterAdapter<Indicator> writer, Indicator indicator, List<String> actors)
{
if (threatMap == null)
{
loadThreatMap();
}
String uniqueId = getUniqueId(indicator);
for (String actor : actors)
{
if (actor == null || actor.equalsIgnoreCase("unknown"))
{
continue;
}
Threat threat = threatMap.get(actor);
if (threat == null)
{
threat = createThreat(actor);
if (threat == null)
{
continue;
}
threatMap.put(threat.getName(), threat);
}
try
{
if (uniqueId != null)
{
info("Associating threat %s [id=%d] to indicator %s", threat.getName(), threat.getId(), uniqueId);
writer.associateGroupThreat(uniqueId, threat.getId());
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to associate threat %s to indicator %s", threat.getName(), uniqueId);
}
}
}
protected Threat createThreat(String actor)
{
AbstractGroupWriterAdapter threatWriter = getWriter(Group.Type.Threat);
if (threatWriter == null)
{
threatWriter = WriterAdapterFactory.createThreatGroupWriter(getConn());
}
Threat threat =
new ThreatBuilder().withOwnerName(getOwner()).withName(actor).withDateAdded(new Date()).createThreat();
try
{
ApiEntitySingleResponse response = threatWriter.create(threat, getOwner());
threat = null;
if (response.isSuccess())
{
threat = (Threat) response.getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to create threat %s", actor);
return null;
}
return threat;
}
private void loadThreatMap()
{
threatMap = new HashMap<>();
AbstractGroupReaderAdapter<Threat> threatReader = ReaderAdapterFactory.createThreatGroupReader(getConn());
try
{
for (Threat t : threatReader.getAll(getOwner()))
{
threatMap.put(t.getName(), t);
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to cache threatMap");
}
}
protected void associateThreat(AbstractGroupReaderAdapter<Group> reader, AbstractGroupWriterAdapter<Group> writer,
Integer groupId, List<String> actors)
{
if (threatMap == null)
{
loadThreatMap();
}
for (String actor : actors)
{
if (actor == null || actor.equalsIgnoreCase("unknown"))
{
continue;
}
Threat threat = threatMap.get(actor);
if (threat == null)
{
threat = createThreat(actor);
if (threat == null)
{
continue;
}
threatMap.put(threat.getName(), threat);
}
try
{
info("Associating threat %s [id=%d] to group id %d", threat.getName(), threat.getId(), groupId);
writer.associateGroupThreat(groupId, threat.getId());
}
catch (IOException | FailedResponseException e)
{
warn("Unable to associate threat %s to group id %d", threat.getName(), groupId);
}
}
}
protected Adversary createAdversary(String actor)
{
AbstractGroupWriterAdapter adversaryWriter = getWriter(Group.Type.Adversary);
if (adversaryWriter == null)
{
adversaryWriter = WriterAdapterFactory.createAdversaryGroupWriter(getConn());
}
Adversary adversary = new AdversaryBuilder()
.withOwnerName(getOwner())
.withName(actor)
.withDateAdded(new Date())
.createAdversary();
try
{
ApiEntitySingleResponse response = adversaryWriter.create(adversary, getOwner());
adversary = null;
if (response.isSuccess())
{
adversary = (Adversary) response.getItem();
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to create adversary %s", actor);
return null;
}
return adversary;
}
private void loadAdversaryMap()
{
adversaryMap = new HashMap<>();
AbstractGroupReaderAdapter<Adversary> adversaryReader =
ReaderAdapterFactory.createAdversaryGroupReader(getConn());
try
{
for (Adversary a : adversaryReader.getAll(getOwner()))
{
adversaryMap.put(a.getName(), a);
}
}
catch (IOException | FailedResponseException e)
{
warn("Unable to cache adversaryMap");
}
}
protected void associateAdversary(AbstractGroupReaderAdapter<Group> reader,
AbstractGroupWriterAdapter<Group> writer, Integer groupId, List<String> actors)
{
if (adversaryMap == null)
{
loadAdversaryMap();
}
for (String actor : actors)
{
if (actor == null || actor.equalsIgnoreCase("unknown"))
{
continue;
}
Adversary adversary = adversaryMap.get(actor);
if (adversary == null)
{
adversary = createAdversary(actor);
if (adversary == null)
{
continue;
}
adversaryMap.put(adversary.getName(), adversary);
}
try
{
info("Associating adversary %s [id=%d] to group id %d", adversary.getName(), adversary.getId(),
groupId);
writer.associateGroupAdversary(groupId, adversary.getId());
}
catch (IOException | FailedResponseException e)
{
warn("Unable to associate adversary %s to group id %d", adversary.getName(), groupId);
}
}
}
public Map<String, Threat> getThreatMap()
{
if (threatMap == null)
{
loadThreatMap();
}
return threatMap;
}
public void setThreatMap(Map<String, Threat> threatMap)
{
this.threatMap = threatMap;
}
public Map<String, Adversary> getAdversaryMap()
{
if (adversaryMap == null)
{
loadAdversaryMap();
}
return adversaryMap;
}
public void setAdversaryMap(Map<String, Adversary> adversaryMap)
{
this.adversaryMap = adversaryMap;
}
public String basicEncoded(String user, String password)
{
String encoded = new sun.misc.BASE64Encoder().encode(String.format("%s:%s", user, password).getBytes());
return "Basic " + encoded;
}
public Map<String, Tag> getTagMap()
{
return tagMap;
}
}