Skip to content

Commit

Permalink
Merge pull request #3715 from cisagov/feature/uk-language
Browse files Browse the repository at this point in the history
Finished SAL page updates for language support
  • Loading branch information
jekuipers authored Jan 30, 2024
2 parents bc2c7f2 + a2fdce3 commit 40ab7c2
Show file tree
Hide file tree
Showing 19 changed files with 876 additions and 311 deletions.

Large diffs are not rendered by default.

Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
{
"pairs": [
{
"key": "16338",
"value": "[UK]Does aggregation of information on this system reveal sensitive patterns and plans, or facilitate access to sensitive or critical systems?"
},
{
"key": "16342",
"value": "[UK]Does/could access to this system result in some form of access to other more sensitive or critical systems (e.g., over a network)?"
},
{
"key": "16346",
"value": "[UK]Are there extenuating circumstances such as: The system provides critical process flow or security capability, the public visibility of the system, the sheer number of other systems reliant on its operation, or the overall cost of the systems replacement?"
},
{
"key": "16350",
"value": "[UK]Would unauthorized modification or destruction of information affecting external communications (e.g., web pages, electronic mail) adversely affect operations or seriously damage mission function and/or public confidence?"
},
{
"key": "16354",
"value": "[UK]Would either physical or logical destruction of the system result in very large expenditures to restore the system and/or require a long period of time for recovery?"
},
{
"key": "16358",
"value": "[UK]Does the mission served by the system, or the information that the system processes, affect the security of critical infrastructures and key resources?"
},
{
"key": "16362",
"value": "[UK]Does the system store, communicate, or process any privacy act information?"
},
{
"key": "16366",
"value": "[UK]Does the systems store, communicate, or process any trade secrets information?"
}
]
}
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,12 @@
<None Update="App_Data\LanguagePacks\UK\NEW_REQUIREMENT.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="App_Data\LanguagePacks\UK\NIST_SAL_INFO_TYPES_DEFAULTS.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="App_Data\LanguagePacks\UK\NIST_SAL_QUESTIONS.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Update="App_Data\LanguagePacks\UK\SECTORS.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1265,7 +1265,7 @@ public List<DocumentLibraryTable> GetDocumentLibrary()

public BasicReportData.OverallSALTable GetNistSals()
{
var manager = new NistSalBusiness(_context, _assessmentUtil);
var manager = new NistSalBusiness(_context, _assessmentUtil, _tokenManager);
var sals = manager.CalculatedNist(_assessmentId);
List<BasicReportData.CNSSSALJustificationsTable> list = new List<BasicReportData.CNSSSALJustificationsTable>();
var infos = _context.CNSS_CIA_JUSTIFICATIONS.Where(x => x.Assessment_Id == _assessmentId).ToList();
Expand Down
98 changes: 86 additions & 12 deletions CSETWebApi/CSETWeb_Api/CSETWebCore.Business/Sal/NistSalBusiness.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,20 +15,26 @@
using CSETWebCore.Model.Sal;
using Microsoft.EntityFrameworkCore;


namespace CSETWebCore.Business.Sal
{
public class NistSalBusiness
{
private CSETContext _context;
private readonly IAssessmentUtil _assessmentUtil;
private readonly ITokenManager _tokenManager;
private readonly TranslationOverlay _overlay;

/// <summary>
///
/// </summary>
public NistSalBusiness(CSETContext context, IAssessmentUtil assessmentUtil)
public NistSalBusiness(CSETContext context, IAssessmentUtil assessmentUtil, ITokenManager tokenManager)
{
_context = context;
_assessmentUtil = assessmentUtil;
_tokenManager = tokenManager;

_overlay = new TranslationOverlay();
}


Expand Down Expand Up @@ -71,29 +77,78 @@ internal void CreateInitialList(object assessmentId)
new SqlParameter("@Id", assessmentId));
}


/// <summary>
///
/// </summary>
public List<NistSalModel> GetInformationTypes(int assessmentId)
{
TinyMapper.Bind<NIST_SAL_INFO_TYPES, NistSalModel>();
CreateInitialList(assessmentId);
List<NistSalModel> rlist = new List<NistSalModel>();
foreach (NIST_SAL_INFO_TYPES t in _context.NIST_SAL_INFO_TYPES.Where(x => x.Assessment_Id == assessmentId))

List<NistSalModel> list = new List<NistSalModel>();

var q = from n1 in _context.NIST_SAL_INFO_TYPES
join n2 in _context.NIST_SAL_INFO_TYPES_DEFAULTS on n1.Type_Value equals n2.Type_Value
where n1.Assessment_Id == assessmentId
select new { n1, n2 };

var qqq = q.ToList();


foreach (var t in qqq)
{
rlist.Add(TinyMapper.Map<NistSalModel>(t));
var j = TinyMapper.Map<NistSalModel>(t.n1);
j.Type_Id = t.n2.Type_Id;

list.Add(j);
}


// overlay question text for language
var lang = _tokenManager.GetCurrentLanguage();
if (lang != "en")
{
list.ForEach(x =>
{
var val = _overlay.GetJObject("NIST_SAL_INFO_TYPES_DEFAULTS", "typeId", x.Type_Id.ToString(), lang);
if (val != null)
{
x.Type_Value = val.Value<string>("typeValue");
x.Confidentiality_Special_Factor = val.Value<string>("specialFactorC");
x.Integrity_Special_Factor = val.Value<string>("specialFactorI");
x.Availability_Special_Factor = val.Value<string>("specialFactorA");
}
});
}
return rlist;

return list;
}

public Sals UpdateSalValue(NistSalModel updateValue, int assessmentid)

public Sals UpdateSalValue(NistSalModel updateValue, int assessmentId)
{
TinyMapper.Bind<NistSalModel, NIST_SAL_INFO_TYPES>(config =>
{
config.Ignore(x => x.Assessment_Id);
config.Ignore(x => x.Type_Value);
config.Ignore(x => x.Confidentiality_Special_Factor);
config.Ignore(x => x.Integrity_Special_Factor);
config.Ignore(x => x.Availability_Special_Factor);
});

NIST_SAL_INFO_TYPES update = _context.NIST_SAL_INFO_TYPES.Where(x => x.Assessment_Id == assessmentid && x.Type_Value == updateValue.Type_Value).FirstOrDefault();
TinyMapper.Map<NistSalModel, NIST_SAL_INFO_TYPES>(updateValue, update);
_context.SaveChanges();
return CalculateOveralls(assessmentid);
var dbInfoDefault = _context.NIST_SAL_INFO_TYPES_DEFAULTS.Where(x => x.Type_Id == updateValue.Type_Id).FirstOrDefault();
if (dbInfoDefault != null)
{
var dbInfoType = _context.NIST_SAL_INFO_TYPES.Where(x => x.Assessment_Id == assessmentId
&& x.Type_Value == dbInfoDefault.Type_Value).FirstOrDefault();

TinyMapper.Map<NistSalModel, NIST_SAL_INFO_TYPES>(updateValue, dbInfoType);

_context.SaveChanges();
}

return CalculateOveralls(assessmentId);
}


Expand Down Expand Up @@ -125,12 +180,30 @@ public List<NistQuestionsAnswers> GetNistQuestions(int assessmentId)
_context.SaveChanges();
}

var rlist = from a in _context.NIST_SAL_QUESTIONS
var qList = from a in _context.NIST_SAL_QUESTIONS
join b in _context.NIST_SAL_QUESTION_ANSWERS on a.Question_Id equals b.Question_Id
where b.Assessment_Id == assessmentId
orderby a.Question_Number
select new NistQuestionsAnswers() { Assessment_Id = b.Assessment_Id, Question_Id = b.Question_Id, Question_Answer = b.Question_Answer, Question_Number = a.Question_Number, Question_Text = a.Question_Text };
return rlist.ToList();

var list = qList.ToList();


// overlay question text for language
var lang = _tokenManager.GetCurrentLanguage();
if (lang != "en")
{
list.ForEach(x =>
{
var val = _overlay.GetValue("NIST_SAL_QUESTIONS", x.Question_Id.ToString(), lang)?.Value;
if (val != null)
{
x.Question_Text = val;
}
});
}

return list;
}


Expand Down Expand Up @@ -240,6 +313,7 @@ public class NistQuestionsAnswers
public class NistSalModel
{
public int Assessment_Id { get; set; }
public int Type_Id { get; set; }
public string Type_Value { get; set; }
public bool Selected { get; set; }
public string Confidentiality_Value { get; set; }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,34 +81,26 @@ public void SaveToDb(int id, CSETContext context, IAssessmentUtil assessmentUtil
CNSS_CIA_JUSTIFICATIONS cnvalu;

// Availability
if (!String.IsNullOrWhiteSpace(this.Availability_Special_Factor))
{
cnvalu = getOrCreateNew("availability", id, dbValues, context);
cnvalu.Justification = this.Availability_Special_Factor == null ? String.Empty : this.Availability_Special_Factor;
cnvalu.DropDownValueLevel = this.Availability_Value.SALName;
}
cnvalu = GetOrCreateNew("availability", id, dbValues, context);
cnvalu.Justification = this.Availability_Special_Factor == null ? String.Empty : this.Availability_Special_Factor;
cnvalu.DropDownValueLevel = this.Availability_Value.SALName;

// Confidentiality
if (!String.IsNullOrWhiteSpace(this.Confidentiality_Special_Factor))
{
cnvalu = getOrCreateNew("confidentiality", id, dbValues, context);
cnvalu.Justification = this.Confidentiality_Special_Factor == null ? string.Empty : this.Confidentiality_Special_Factor;
cnvalu.DropDownValueLevel = this.Confidentiality_Value.SALName;
}
cnvalu = GetOrCreateNew("confidentiality", id, dbValues, context);
cnvalu.Justification = this.Confidentiality_Special_Factor == null ? string.Empty : this.Confidentiality_Special_Factor;
cnvalu.DropDownValueLevel = this.Confidentiality_Value.SALName;

// Integrity
if (!String.IsNullOrWhiteSpace(this.Integrity_Special_Factor))
{
cnvalu = getOrCreateNew("integrity", id, dbValues, context);
cnvalu.Justification = this.Integrity_Special_Factor == null ? String.Empty : this.Integrity_Special_Factor;
cnvalu.DropDownValueLevel = this.Integrity_Value.SALName;
}
cnvalu = GetOrCreateNew("integrity", id, dbValues, context);
cnvalu.Justification = this.Integrity_Special_Factor == null ? String.Empty : this.Integrity_Special_Factor;
cnvalu.DropDownValueLevel = this.Integrity_Value.SALName;

context.SaveChanges();
assessmentUtils.TouchAssessment(id);
}

private CNSS_CIA_JUSTIFICATIONS getOrCreateNew(String ciaType, int id, Dictionary<String, CNSS_CIA_JUSTIFICATIONS> dbValues, CSETContext context)

private CNSS_CIA_JUSTIFICATIONS GetOrCreateNew(String ciaType, int id, Dictionary<String, CNSS_CIA_JUSTIFICATIONS> dbValues, CSETContext context)
{
CNSS_CIA_JUSTIFICATIONS cnvalu;
if (dbValues.TryGetValue(ciaType, out cnvalu))
Expand All @@ -123,6 +115,7 @@ private CNSS_CIA_JUSTIFICATIONS getOrCreateNew(String ciaType, int id, Dictionar
}
}


/// <summary>
/// Upper Case the First Letter (UCF)
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ namespace CSETWebCore.DataLayer.Model;
/// </summary>
public partial class NIST_SAL_INFO_TYPES_DEFAULTS
{
public int Type_Id { get; set; }

[Key]
[StringLength(50)]
public string Type_Value { get; set; }
Expand Down
59 changes: 58 additions & 1 deletion CSETWebApi/CSETWeb_Api/CSETWebCore.Helpers/TranslationOverlay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
using CSETWebCore.Model.Question;
using CSETWebCore.Model.Set;
using Microsoft.EntityFrameworkCore;
using Newtonsoft.Json.Linq;
using Org.BouncyCastle.Asn1.Pkcs;
using System;
using System.Collections.Generic;
Expand All @@ -18,12 +19,55 @@ namespace CSETWebCore.Helpers
/// </summary>
public class TranslationOverlay
{
private Dictionary<string, JArray> dict = new Dictionary<string, JArray>();
private Dictionary<string, RequirementTranslations> dReq = new Dictionary<string, RequirementTranslations>();
private Dictionary<string, CategoryTranslation> dCat = new Dictionary<string, CategoryTranslation>();

private Dictionary<string, GenericTranslation> dKVP = new Dictionary<string, GenericTranslation>();


/// <summary>
/// Intended to return a JObject so that it is very generic.
/// The caller supplies the key field name and the key value. A JObject or null is returned.
/// </summary>
public JObject GetJObject(string collection, string keyFieldName, string key, string lang)
{
JArray langPack = null;

if (lang == "en")
{
return null;
}

lang = lang.ToLower();
collection = collection.ToLower();

var kvpKey = $"{lang}|{collection}";

if (!dict.ContainsKey(kvpKey))
{
var rh = new ResourceHelper();
var json = rh.GetCopiedResource(System.IO.Path.Combine("app_data", "LanguagePacks", lang, $"{collection}.json"));

if (json == null)
{
return null;
}

langPack = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(json);

dict.Add(kvpKey, langPack);
}
else
{
langPack = dict[kvpKey];
}

var target = langPack.Children().FirstOrDefault(x => x.SelectToken(keyFieldName).Value<string>().Equals(key, StringComparison.InvariantCultureIgnoreCase));

return (JObject)target;
}


/// <summary>
/// Generically gets a value for the specified key and collection.
/// Collection indicates the name of the JSON file.
Expand Down Expand Up @@ -87,6 +131,13 @@ public Model.Question.KeyValuePair GetCat(string category, string lang)
var rh = new ResourceHelper();
var json = rh.GetCopiedResource(System.IO.Path.Combine("app_data", "LanguagePacks", lang, "CATEGORIES.json"));

// safety in case the language pack doesn't exist
if (json == null)
{
return null;
}


langPack = Newtonsoft.Json.JsonConvert.DeserializeObject<CategoryTranslation>(json);

dCat.Add(lang, langPack);
Expand Down Expand Up @@ -118,6 +169,12 @@ public RequirementTranslation GetReq(int requirementId, string lang)
var rh = new ResourceHelper();
var json = rh.GetCopiedResource(System.IO.Path.Combine("app_data", "LanguagePacks", lang, "NEW_REQUIREMENT.json"));

// safety in case the language pack doesn't exist
if (json == null)
{
return null;
}

langPack = Newtonsoft.Json.JsonConvert.DeserializeObject<RequirementTranslations>(json);

dReq.Add(lang, langPack);
Expand Down
Loading

0 comments on commit 40ab7c2

Please sign in to comment.