Skip to content

Commit

Permalink
AB#814 Set confidentiality label on NVG points
Browse files Browse the repository at this point in the history
  • Loading branch information
gjvoosten committed Nov 28, 2024
1 parent 39a9a72 commit 2a860b7
Showing 1 changed file with 115 additions and 6 deletions.
121 changes: 115 additions & 6 deletions src/main/java/mil/dds/anet/ws/Nvg20WebService.java
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
import java.util.Map;
import java.util.Set;
import java.util.TimeZone;
import java.util.regex.Pattern;
import javax.xml.datatype.DatatypeFactory;
import mil.dds.anet.beans.AccessToken;
import mil.dds.anet.beans.Location;
Expand All @@ -23,12 +24,19 @@
import mil.dds.anet.beans.search.ISearchQuery;
import mil.dds.anet.beans.search.ReportSearchSortBy;
import mil.dds.anet.config.AnetConfig;
import mil.dds.anet.config.AnetDictionary;
import mil.dds.anet.database.AccessTokenDao;
import mil.dds.anet.database.AdminDao;
import mil.dds.anet.database.mappers.MapperUtils;
import mil.dds.anet.resources.GraphQLResource;
import mil.dds.anet.utils.DaoUtils;
import mil.dds.anet.utils.Utils;
import nato.act.tide.wsdl.nvg20.CapabilityItemType;
import nato.act.tide.wsdl.nvg20.CategoryType;
import nato.act.tide.wsdl.nvg20.ClassificationType;
import nato.act.tide.wsdl.nvg20.ConfidentialityInformationType;
import nato.act.tide.wsdl.nvg20.ContentType;
import nato.act.tide.wsdl.nvg20.ExtensionType;
import nato.act.tide.wsdl.nvg20.GetCapabilities;
import nato.act.tide.wsdl.nvg20.GetCapabilitiesResponse;
import nato.act.tide.wsdl.nvg20.GetNvg;
Expand All @@ -43,8 +51,10 @@
import nato.act.tide.wsdl.nvg20.NvgType;
import nato.act.tide.wsdl.nvg20.ObjectFactory;
import nato.act.tide.wsdl.nvg20.PointType;
import nato.act.tide.wsdl.nvg20.PolicyIdentifierType;
import nato.act.tide.wsdl.nvg20.SelectType;
import nato.act.tide.wsdl.nvg20.SelectValueType;
import org.apache.commons.lang3.RegExUtils;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ResponseStatusException;
Expand Down Expand Up @@ -130,7 +140,7 @@ static String getApp6Symbol(String app6Version, boolean isPlanned) {
private static final String REPORT_QUERY = "query ($reportQuery: ReportSearchQueryInput) {" // -
+ " reportList(query: $reportQuery) {" // -
+ " totalCount list {" // -
+ " uuid intent engagementDate duration keyOutcomes nextSteps" // -
+ " uuid intent engagementDate duration keyOutcomes nextSteps classification" // -
+ " primaryAdvisor { uuid name rank }" // -
+ " primaryInterlocutor { uuid name rank }" // -
+ " advisorOrg { uuid shortName longName identificationCode }" // -
Expand All @@ -144,14 +154,18 @@ static String getApp6Symbol(String app6Version, boolean isPlanned) {
"sortOrder", ISearchQuery.SortOrder.DESC);

private final AnetConfig config;
private final AnetDictionary dict;
private final GraphQLResource graphQLResource;
private final AccessTokenDao accessTokenDao;
private final AdminDao adminDao;

public Nvg20WebService(AnetConfig config, GraphQLResource graphQLResource,
AccessTokenDao accessTokenDao) {
public Nvg20WebService(AnetConfig config, AnetDictionary dict, GraphQLResource graphQLResource,
AccessTokenDao accessTokenDao, AdminDao adminDao) {
this.config = config;
this.dict = dict;
this.graphQLResource = graphQLResource;
this.accessTokenDao = accessTokenDao;
this.adminDao = adminDao;
}

@Override
Expand Down Expand Up @@ -220,14 +234,18 @@ private NvgType makeNvg(String app6Version, int pastDays, int futureDays) {
// Calculate end of period
final Instant end = now.plus(futureDays, ChronoUnit.DAYS);

final ConfidentialityRecord defaultConfidentiality = ConfidentialityRecord.create(
adminDao.getSetting(AdminDao.AdminSettingKeys.SECURITY_BANNER_CLASSIFICATION),
adminDao.getSetting(AdminDao.AdminSettingKeys.SECURITY_BANNER_RELEASABILITY));
final List<Report> reports = getReportsByPeriod(start, end);
contentTypeList
.addAll(reports.stream().map(r -> reportToNvgPoint(app6Version, now, r)).toList());
contentTypeList.addAll(reports.stream()
.map(r -> reportToNvgPoint(app6Version, defaultConfidentiality, now, r)).toList());

return nvgType;
}

private PointType reportToNvgPoint(String app6Version, Instant reportingTime, Report report) {
private PointType reportToNvgPoint(String app6Version,
ConfidentialityRecord defaultConfidentiality, Instant reportingTime, Report report) {
final PointType nvgPoint = NVG_OF.createPointType();
nvgPoint.setLabel(report.getIntent());
nvgPoint.setUri(String.format("urn:anet:reports:%1$s", report.getUuid()));
Expand All @@ -236,9 +254,42 @@ private PointType reportToNvgPoint(String app6Version, Instant reportingTime, Re
setSymbol(app6Version, reportingTime, report, nvgPoint);
nvgPoint.setHref(String.format("%s/reports/%s", config.getServerUrl(), report.getUuid()));
setTextInfo(report, nvgPoint);
setConfidentialityInformation(determineConfidentiality(defaultConfidentiality, report),
nvgPoint);
return nvgPoint;
}

private void setConfidentialityInformation(ConfidentialityRecord confidentiality,
PointType nvgPoint) {
if (!Utils.isEmptyOrNull(confidentiality.policy())) {
final ConfidentialityInformationType confidentialityInformationType =
NVG_OF.createConfidentialityInformationType();
final PolicyIdentifierType policyIdentifierType = NVG_OF.createPolicyIdentifierType();
policyIdentifierType.setValue(confidentiality.policy);
confidentialityInformationType.setPolicyIdentifier(policyIdentifierType);

if (!Utils.isEmptyOrNull(confidentiality.classification())) {
final ClassificationType classificationType = NVG_OF.createClassificationType();
classificationType.setValue(confidentiality.classification());
confidentialityInformationType.setClassification(classificationType);
}

if (!Utils.isEmptyOrNull(confidentiality.releasableTo())) {
final CategoryType categoryType = NVG_OF.createCategoryType();
categoryType.setTagName("Releasable to");
categoryType.setType("PERMISSIVE");
categoryType.getCategoryValue()
.add(NVG_OF.createGenericValue(confidentiality.releasableTo()));
confidentialityInformationType.getCategory().add(categoryType);
}

final ExtensionType extensionType = NVG_OF.createExtensionType();
extensionType.getAny()
.add(NVG_OF.createConfidentialityInformation(confidentialityInformationType));
nvgPoint.setExtension(extensionType);
}
}

private void setSymbol(String app6Version, Instant reportingTime, Report report,
PointType nvgPoint) {
nvgPoint.setSymbol(App6Symbology.getApp6Symbol(app6Version,
Expand Down Expand Up @@ -366,4 +417,62 @@ private List<Report> getReportsByPeriod(final Instant start, final Instant end)
return anetBeanList.getList();
}

private ConfidentialityRecord determineConfidentiality(
ConfidentialityRecord defaultConfidentiality, Report report) {
@SuppressWarnings("unchecked")
final Map<String, String> classificationChoices =
(Map<String, String>) dict.getDictionaryEntry("classification.choices");
final String reportClassification = classificationChoices.get(report.getClassification());
return reportClassification == null ? defaultConfidentiality
: ConfidentialityRecord.create(reportClassification);
}

private record ConfidentialityRecord(String policy, String classification, String releasableTo) {

static ConfidentialityRecord create(
String siteClassification, String siteReleasability) {
// Try to split site classification
final String[] policyAndClassification = siteClassification.trim().split("\\s+", 2);
final String releasableTo;
if ( Utils.isEmptyOrNull(siteReleasability)) {
releasableTo = null;
} else {
releasableTo = getReleasableTo(siteReleasability);
}
return new ConfidentialityRecord(
toUpper(policyAndClassification[0]), toUpper(policyAndClassification[1]), toUpper(releasableTo));
}

static ConfidentialityRecord create(String reportClassification) {
// Try to split report classification
final String[] policyAndRest = reportClassification.trim().split("\\s+", 2);
final String classification;
final String releasableTo;
if (policyAndRest.length < 2) {
classification = null;
releasableTo = null;
} else {
final String[] classificationAndReleasability = policyAndRest[1].split("\\s+", 2);
classification = classificationAndReleasability[0];
if (classificationAndReleasability.length < 2) {
releasableTo = null;
} else {
releasableTo = getReleasableTo(classificationAndReleasability[1]);
}
}
return new ConfidentialityRecord(toUpper(policyAndRest[0]), toUpper(classification), toUpper(releasableTo));
}

private static String getReleasableTo(String releasability) {
// Try to strip off "releasable to"
return RegExUtils.removeFirst(
releasability, Pattern.compile("^releasable to\\s+", Pattern.CASE_INSENSITIVE));
}

private static String toUpper(String s) {
return s == null ? null : s.toUpperCase();
}

}

}

0 comments on commit 2a860b7

Please sign in to comment.