diff --git a/Samples/SampleExtensions/ExtensionLibrary.cs b/Samples/SampleExtensions/ExtensionLibrary.cs index da315bc4..374e9255 100644 --- a/Samples/SampleExtensions/ExtensionLibrary.cs +++ b/Samples/SampleExtensions/ExtensionLibrary.cs @@ -1,3 +1,3 @@ using ThreatsManager.Interfaces; -[assembly: ExtensionsContainer("1.3.1")] \ No newline at end of file +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Samples/SampleExtensions/SampleExtensions.csproj b/Samples/SampleExtensions/SampleExtensions.csproj index e3d9dd23..079c71d9 100644 --- a/Samples/SampleExtensions/SampleExtensions.csproj +++ b/Samples/SampleExtensions/SampleExtensions.csproj @@ -72,16 +72,16 @@ - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Icons.dll + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Icons.dll - - ..\packages\ThreatsManager.Interfaces.1.3.1\lib\net472\ThreatsManager.Interfaces.dll + + ..\packages\ThreatsManager.Interfaces.1.3.3\lib\net472\ThreatsManager.Interfaces.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Packaging.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Packaging.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Utilities.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Utilities.dll diff --git a/Samples/SampleExtensions/packages.config b/Samples/SampleExtensions/packages.config index 203ba1fc..72b88b71 100644 --- a/Samples/SampleExtensions/packages.config +++ b/Samples/SampleExtensions/packages.config @@ -8,6 +8,6 @@ - - + + \ No newline at end of file diff --git a/Samples/SampleWinFormExtensions/ExtensionLibrary.cs b/Samples/SampleWinFormExtensions/ExtensionLibrary.cs index da315bc4..374e9255 100644 --- a/Samples/SampleWinFormExtensions/ExtensionLibrary.cs +++ b/Samples/SampleWinFormExtensions/ExtensionLibrary.cs @@ -1,3 +1,3 @@ using ThreatsManager.Interfaces; -[assembly: ExtensionsContainer("1.3.1")] \ No newline at end of file +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Samples/SampleWinFormExtensions/SampleWinFormExtensions.csproj b/Samples/SampleWinFormExtensions/SampleWinFormExtensions.csproj index 5625ccd1..38f1a350 100644 --- a/Samples/SampleWinFormExtensions/SampleWinFormExtensions.csproj +++ b/Samples/SampleWinFormExtensions/SampleWinFormExtensions.csproj @@ -42,7 +42,7 @@ ..\packages\Fizzler.1.2.0\lib\netstandard2.0\Fizzler.dll - ..\packages\ThreatsManager.Utilities.WinForms.1.3.1\lib\net472\Keyoti.RapidSpell.NET4.dll + ..\packages\ThreatsManager.Utilities.WinForms.1.3.3\lib\net472\Keyoti.RapidSpell.NET4.dll @@ -87,19 +87,19 @@ - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Icons.dll + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Icons.dll - - ..\packages\ThreatsManager.Interfaces.1.3.1\lib\net472\ThreatsManager.Interfaces.dll + + ..\packages\ThreatsManager.Interfaces.1.3.3\lib\net472\ThreatsManager.Interfaces.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Packaging.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Packaging.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Utilities.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Utilities.dll - - ..\packages\ThreatsManager.Utilities.WinForms.1.3.1\lib\net472\ThreatsManager.Utilities.WinForms.dll + + ..\packages\ThreatsManager.Utilities.WinForms.1.3.3\lib\net472\ThreatsManager.Utilities.WinForms.dll diff --git a/Samples/SampleWinFormExtensions/packages.config b/Samples/SampleWinFormExtensions/packages.config index 467be7f9..ea50483b 100644 --- a/Samples/SampleWinFormExtensions/packages.config +++ b/Samples/SampleWinFormExtensions/packages.config @@ -10,7 +10,7 @@ - - - + + + \ No newline at end of file diff --git a/Samples/SimpleThreatModelAnalyzer/ExtensionLibrary.cs b/Samples/SimpleThreatModelAnalyzer/ExtensionLibrary.cs index da315bc4..374e9255 100644 --- a/Samples/SimpleThreatModelAnalyzer/ExtensionLibrary.cs +++ b/Samples/SimpleThreatModelAnalyzer/ExtensionLibrary.cs @@ -1,3 +1,3 @@ using ThreatsManager.Interfaces; -[assembly: ExtensionsContainer("1.3.1")] \ No newline at end of file +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Samples/SimpleThreatModelAnalyzer/SimpleThreatModelAnalyzer.csproj b/Samples/SimpleThreatModelAnalyzer/SimpleThreatModelAnalyzer.csproj index aa3802f6..11f3562b 100644 --- a/Samples/SimpleThreatModelAnalyzer/SimpleThreatModelAnalyzer.csproj +++ b/Samples/SimpleThreatModelAnalyzer/SimpleThreatModelAnalyzer.csproj @@ -89,20 +89,20 @@ - - ..\packages\ThreatsManager.Engine.1.3.1\lib\net472\ThreatsManager.Engine.dll + + ..\packages\ThreatsManager.Engine.1.3.3\lib\net472\ThreatsManager.Engine.dll - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Icons.dll + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Icons.dll - - ..\packages\ThreatsManager.Interfaces.1.3.1\lib\net472\ThreatsManager.Interfaces.dll + + ..\packages\ThreatsManager.Interfaces.1.3.3\lib\net472\ThreatsManager.Interfaces.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Packaging.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Packaging.dll - - ..\packages\ThreatsManager.Utilities.1.3.1\lib\net472\ThreatsManager.Utilities.dll + + ..\packages\ThreatsManager.Utilities.1.3.3\lib\net472\ThreatsManager.Utilities.dll diff --git a/Samples/SimpleThreatModelAnalyzer/packages.config b/Samples/SimpleThreatModelAnalyzer/packages.config index c5cd9db2..7cc20ed7 100644 --- a/Samples/SimpleThreatModelAnalyzer/packages.config +++ b/Samples/SimpleThreatModelAnalyzer/packages.config @@ -13,7 +13,7 @@ - - - + + + \ No newline at end of file diff --git a/Sources/Extensions/Extensions.sln b/Sources/Extensions/Extensions.sln new file mode 100644 index 00000000..ceee3439 --- /dev/null +++ b/Sources/Extensions/Extensions.sln @@ -0,0 +1,67 @@ + +Microsoft Visual Studio Solution File, Format Version 12.00 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30413.136 +MinimumVisualStudioVersion = 10.0.40219.1 +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.AutoThreatGeneration", "ThreatsManager.AutoThreatGeneration\ThreatsManager.AutoThreatGeneration.csproj", "{C96D95AE-1081-4BD8-9004-0D34574FDC9B}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Interfaces", "..\ThreatsManager.Interfaces\ThreatsManager.Interfaces.csproj", "{F6685B01-5E85-4DFE-AD30-DC7226326A88}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Utilities", "..\ThreatsManager.Utilities\ThreatsManager.Utilities.csproj", "{C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Extensions", "ThreatsManager.Extensions\ThreatsManager.Extensions.csproj", "{3CABCB35-25FF-440A-9226-C9E881C8636F}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.MsTmt", "ThreatsManager.MsTmt\ThreatsManager.MsTmt.csproj", "{8ACF0B4D-F9F9-4AA5-A5E0-72A700C890FC}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.PackageManagers", "ThreatsManager.PackageManagers\ThreatsManager.PackageManagers.csproj", "{8D599C3D-E2E2-49CD-A597-A0B0247CDBA4}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.DevOps", "ThreatsManager.DevOps\ThreatsManager.DevOps.csproj", "{E545F770-9A4B-41BC-91D6-4456AF295DFE}" +EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Quality", "ThreatsManager.Quality\ThreatsManager.Quality.csproj", "{26BBE943-E47E-49AC-9C27-CA88166F46FE}" +EndProject +Global + GlobalSection(SolutionConfigurationPlatforms) = preSolution + Debug|Any CPU = Debug|Any CPU + Release|Any CPU = Release|Any CPU + EndGlobalSection + GlobalSection(ProjectConfigurationPlatforms) = postSolution + {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Release|Any CPU.Build.0 = Release|Any CPU + {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Debug|Any CPU.Build.0 = Debug|Any CPU + {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Release|Any CPU.ActiveCfg = Release|Any CPU + {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Release|Any CPU.Build.0 = Release|Any CPU + {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Release|Any CPU.Build.0 = Release|Any CPU + {3CABCB35-25FF-440A-9226-C9E881C8636F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {3CABCB35-25FF-440A-9226-C9E881C8636F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {3CABCB35-25FF-440A-9226-C9E881C8636F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {3CABCB35-25FF-440A-9226-C9E881C8636F}.Release|Any CPU.Build.0 = Release|Any CPU + {8ACF0B4D-F9F9-4AA5-A5E0-72A700C890FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8ACF0B4D-F9F9-4AA5-A5E0-72A700C890FC}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8ACF0B4D-F9F9-4AA5-A5E0-72A700C890FC}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8ACF0B4D-F9F9-4AA5-A5E0-72A700C890FC}.Release|Any CPU.Build.0 = Release|Any CPU + {8D599C3D-E2E2-49CD-A597-A0B0247CDBA4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {8D599C3D-E2E2-49CD-A597-A0B0247CDBA4}.Debug|Any CPU.Build.0 = Debug|Any CPU + {8D599C3D-E2E2-49CD-A597-A0B0247CDBA4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {8D599C3D-E2E2-49CD-A597-A0B0247CDBA4}.Release|Any CPU.Build.0 = Release|Any CPU + {E545F770-9A4B-41BC-91D6-4456AF295DFE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {E545F770-9A4B-41BC-91D6-4456AF295DFE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {E545F770-9A4B-41BC-91D6-4456AF295DFE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {E545F770-9A4B-41BC-91D6-4456AF295DFE}.Release|Any CPU.Build.0 = Release|Any CPU + {26BBE943-E47E-49AC-9C27-CA88166F46FE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {26BBE943-E47E-49AC-9C27-CA88166F46FE}.Debug|Any CPU.Build.0 = Debug|Any CPU + {26BBE943-E47E-49AC-9C27-CA88166F46FE}.Release|Any CPU.ActiveCfg = Release|Any CPU + {26BBE943-E47E-49AC-9C27-CA88166F46FE}.Release|Any CPU.Build.0 = Release|Any CPU + EndGlobalSection + GlobalSection(SolutionProperties) = preSolution + HideSolutionNode = FALSE + EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {87B3BA26-85AC-46C6-84AF-183918DE3412} + EndGlobalSection +EndGlobal diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ActionsHelper.cs b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ActionsHelper.cs new file mode 100644 index 00000000..73954f6f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ActionsHelper.cs @@ -0,0 +1,204 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.AutoThreatGeneration.Engine; +using ThreatsManager.AutoThreatGeneration.Schemas; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.AutoThreatGeneration.Actions +{ + public static class ActionsHelper + { + public static bool GenerateThreatEvents(this IThreatModel model) + { + bool result = false; + + var schemaManager = new AutoThreatGenPropertySchemaManager(model); + var propertyType = schemaManager.GetPropertyType(); + if (propertyType is IJsonSerializableObjectPropertyType jsonPropertyType) + { + var threatTypes = model.ThreatTypes?.Where(x => x.HasProperty(jsonPropertyType)).ToArray(); + if (threatTypes?.Any() ?? false) + { + ApplyThreatTypes(model, threatTypes, jsonPropertyType); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + ApplyThreatTypes(entity, threatTypes, jsonPropertyType); + } + } + var dataFlows = model.DataFlows?.ToArray(); + if (dataFlows?.Any() ?? false) + { + foreach (var dataFlow in dataFlows) + { + ApplyThreatTypes(dataFlow, threatTypes, jsonPropertyType); + } + } + + result = true; + } + } + + return result; + } + + public static bool GenerateThreatEvents(this IEntity entity) + { + bool result = false; + + if (entity.Model is IThreatModel model) + { + var schemaManager = new AutoThreatGenPropertySchemaManager(model); + var propertyType = schemaManager.GetPropertyType(); + if (propertyType is IJsonSerializableObjectPropertyType jsonPropertyType) + { + var threatTypes = model.ThreatTypes?.Where(x => x.HasProperty(jsonPropertyType)).ToArray(); + if (threatTypes?.Any() ?? false) + { + ApplyThreatTypes(entity, threatTypes, jsonPropertyType); + + result = true; + } + } + } + + return result; + } + + public static bool GenerateThreatEvents(this IDataFlow flow) + { + bool result = false; + + if (flow.Model is IThreatModel model) + { + var schemaManager = new AutoThreatGenPropertySchemaManager(model); + var propertyType = schemaManager.GetPropertyType(); + if (propertyType is IJsonSerializableObjectPropertyType jsonPropertyType) + { + var threatTypes = model.ThreatTypes?.Where(x => x.HasProperty(jsonPropertyType)).ToArray(); + if (threatTypes?.Any() ?? false) + { + ApplyThreatTypes(flow, threatTypes, jsonPropertyType); + + result = true; + } + } + } + + return result; + } + + private static bool ApplyThreatTypes([NotNull] IIdentity identity, + [NotNull] IEnumerable threatTypes, + [NotNull] IJsonSerializableObjectPropertyType propertyType) + { + bool result = false; + + foreach (var threatType in threatTypes) + { + result |= ApplyThreatType(identity, threatType, propertyType); + } + + return result; + } + + private static bool ApplyThreatType([NotNull] IIdentity identity, + [NotNull] IThreatType threatType, [NotNull] IJsonSerializableObjectPropertyType propertyType) + { + bool result = false; + + var property = threatType.GetProperty(propertyType); + if (property is IPropertyJsonSerializableObject jsonProperty && + jsonProperty.Value is SelectionRule rule && rule.Evaluate(identity) && + identity is IThreatEventsContainer container) + { + var threatEvent = container.AddThreatEvent(threatType); + if (threatEvent == null) + { + threatEvent = container.ThreatEvents.FirstOrDefault(x => x.ThreatTypeId == threatType.Id); + } + else + { + result = true; + } + + if (threatEvent != null) + { + result |= threatEvent.ApplyMitigations(propertyType); + } + } + + return result; + } + + public static bool ApplyMitigations(this IThreatEvent threatEvent, + IJsonSerializableObjectPropertyType propertyType = null) + { + bool result = false; + + if (threatEvent.ThreatType is IThreatType threatType && threatEvent.Model is IThreatModel model && + threatEvent.Parent is IIdentity identity) + { + if (propertyType == null) + { + var schemaManager = new AutoThreatGenPropertySchemaManager(model); + propertyType = schemaManager.GetPropertyType() as IJsonSerializableObjectPropertyType; + } + + if (propertyType != null) + { + var mitigations = threatType.Mitigations?.ToArray(); + if (mitigations?.Any() ?? false) + { + ISeverity maximumSeverity = null; + var generated = false; + + foreach (var mitigation in mitigations) + { + var mProperty = mitigation.GetProperty(propertyType); + if (mProperty is IPropertyJsonSerializableObject jsonMProperty && + jsonMProperty.Value is MitigationSelectionRule mRule && mRule.Evaluate(identity)) + { + var strength = mitigation.Strength; + if (mRule.StrengthId.HasValue && + model.GetStrength(mRule.StrengthId.Value) is IStrength strengthOverride) + strength = strengthOverride; + + if (mRule.Status.HasValue) + generated = (threatEvent.AddMitigation(mitigation.Mitigation, strength, + mRule.Status.Value) != + null); + else + generated = (threatEvent.AddMitigation(mitigation.Mitigation, strength) != + null); + result |= generated; + + if (generated && mRule.SeverityId.HasValue && + model.GetSeverity(mRule.SeverityId.Value) is ISeverity severity && + (maximumSeverity == null || maximumSeverity.Id > severity.Id)) + { + maximumSeverity = severity; + } + } + } + + if (maximumSeverity != null && maximumSeverity.Id < threatEvent.SeverityId) + { + threatEvent.Severity = maximumSeverity; + } + } + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyAutoGenRulesToItem.cs b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyAutoGenRulesToItem.cs new file mode 100644 index 00000000..dc69cd40 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyAutoGenRulesToItem.cs @@ -0,0 +1,66 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.AutoThreatGeneration.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "FC9151DF-D604-4B88-A529-6418495FA5C8")] + [ExportMetadata("Label", "Apply Auto Gen Rules to Item Context Aware Action")] + [ExportMetadata("Priority", 35)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ApplyAutoGenRulesToItem : IIdentityContextAwareAction, IDesktopAlertAwareExtension + { + public Scope Scope => Scope.Entity | Scope.DataFlow; + public string Label => "Apply Auto Gen Rules"; + public string Group => "ItemActions"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action ShowMessage; + public event Action ShowWarning; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + if (identity is IEntity entity) + { + if (entity.GenerateThreatEvents()) + ShowMessage?.Invoke("Threat Events generated successfully."); + else + { + ShowWarning?.Invoke("No Threat Event or Mitigation has been generated."); + } + + } + else if (identity is IDataFlow flow) + { + if (flow.GenerateThreatEvents()) + ShowMessage?.Invoke("Threat Events generated successfully."); + else + { + ShowWarning?.Invoke("No Threat Event or Mitigation has been generated."); + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyMitigationAssociationRules.cs b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyMitigationAssociationRules.cs new file mode 100644 index 00000000..c6848ec5 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/Actions/ApplyMitigationAssociationRules.cs @@ -0,0 +1,57 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.AutoThreatGeneration.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "C2029A88-0E8E-49F1-A9DF-3FEFAF5582CB")] + [ExportMetadata("Label", "Apply Mitigation Association Rule to Threat Event Context Aware Action")] + [ExportMetadata("Priority", 35)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ApplyMitigationAssociationRules : IIdentityContextAwareAction, IDesktopAlertAwareExtension + { + public Scope Scope => Scope.ThreatEvent; + public string Label => "Apply Mitigation Association Rules"; + public string Group => "ItemActions"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action ShowMessage; + public event Action ShowWarning; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + if (identity is IThreatEvent threatEvent) + { + if (threatEvent.ApplyMitigations()) + ShowMessage?.Invoke("Mitigations associated successfully."); + else + { + ShowWarning?.Invoke("No Mitigation has been associated."); + } + + } + + return true; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ExtensionsContainer.cs index 111b7431..b8227c8a 100644 --- a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ExtensionsContainer.cs +++ b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ExtensionsContainer.cs @@ -1,3 +1,3 @@ using ThreatsManager.Interfaces; -[assembly: ExtensionsContainer("1.3.1")] \ No newline at end of file +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.csproj b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.csproj index b590ff8c..3149d31a 100644 --- a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.csproj +++ b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.csproj @@ -3,15 +3,15 @@ netcoreapp3.1;net472 Threats Manager Platform Auto Threat Generation library. - 1.3.1.0 + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Engine/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 true ..\..\ThreatsManager.Engine\ThreatsManager.snk diff --git a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.sln b/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.sln deleted file mode 100644 index 2d4b87b5..00000000 --- a/Sources/Extensions/ThreatsManager.AutoThreatGeneration/ThreatsManager.AutoThreatGeneration.sln +++ /dev/null @@ -1,37 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30413.136 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.AutoThreatGeneration", "ThreatsManager.AutoThreatGeneration.csproj", "{C96D95AE-1081-4BD8-9004-0D34574FDC9B}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Interfaces", "..\..\ThreatsManager.Interfaces\ThreatsManager.Interfaces.csproj", "{F6685B01-5E85-4DFE-AD30-DC7226326A88}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Utilities", "..\..\ThreatsManager.Utilities\ThreatsManager.Utilities.csproj", "{C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C96D95AE-1081-4BD8-9004-0D34574FDC9B}.Release|Any CPU.Build.0 = Release|Any CPU - {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Debug|Any CPU.Build.0 = Debug|Any CPU - {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Release|Any CPU.ActiveCfg = Release|Any CPU - {F6685B01-5E85-4DFE-AD30-DC7226326A88}.Release|Any CPU.Build.0 = Release|Any CPU - {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C598DBFD-D401-4B5D-BD6A-7D13BB1A964F}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {87B3BA26-85AC-46C6-84AF-183918DE3412} - EndGlobalSection -EndGlobal diff --git a/Sources/Extensions/ThreatsManager.DevOps/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.DevOps/ExtensionsContainer.cs new file mode 100644 index 00000000..b8227c8a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.DevOps/ExtensionsContainer.cs @@ -0,0 +1,3 @@ +using ThreatsManager.Interfaces; + +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.Designer.cs b/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.Designer.cs new file mode 100644 index 00000000..ab286405 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.Designer.cs @@ -0,0 +1,153 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ThreatsManager.DevOps.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ThreatsManager.DevOps.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to https://www.simoneonsecurity.com/tm/2018. + /// + internal static string DefaultNamespace { + get { + return ResourceManager.GetString("DefaultNamespace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Config. + /// + internal static string DevOpsConfig { + get { + return ResourceManager.GetString("DevOpsConfig", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Type containing the metadata with the information related to the connection to the DevOps system.. + /// + internal static string DevOpsConfigDescription { + get { + return ResourceManager.GetString("DevOpsConfigDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DevOpsConfig. + /// + internal static string DevOpsConfigPropertySchema { + get { + return ResourceManager.GetString("DevOpsConfigPropertySchema", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema used to store configuration info for the connection to the DevOps system.. + /// + internal static string DevOpsConfigPropertySchemaDescription { + get { + return ResourceManager.GetString("DevOpsConfigPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Info. + /// + internal static string DevOpsInfo { + get { + return ResourceManager.GetString("DevOpsInfo", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Type containing the metadata with the information related to the associated item in a connected DevOps system.. + /// + internal static string DevOpsInfoDescription { + get { + return ResourceManager.GetString("DevOpsInfoDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to DevOps. + /// + internal static string DevOpsPropertySchema { + get { + return ResourceManager.GetString("DevOpsPropertySchema", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema used to enrich object metadata with information related to the associated item in a connected DevOps system.. + /// + internal static string DevOpsPropertySchemaDescription { + get { + return ResourceManager.GetString("DevOpsPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status of the Mitigation for the Roadmap.. + /// + internal static string PropertyRoadmap { + get { + return ResourceManager.GetString("PropertyRoadmap", resourceCulture); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.resx b/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.resx new file mode 100644 index 00000000..9c5b98f5 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.DevOps/Properties/Resources.resx @@ -0,0 +1,150 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + https://www.simoneonsecurity.com/tm/2018 + + + Config + + + Property Type containing the metadata with the information related to the connection to the DevOps system. + + + DevOpsConfig + + + Property Schema used to store configuration info for the connection to the DevOps system. + + + Info + + + Property Type containing the metadata with the information related to the associated item in a connected DevOps system. + + + DevOps + + + Property Schema used to enrich object metadata with information related to the associated item in a connected DevOps system. + + + Status of the Mitigation for the Roadmap. + + \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.DevOps/ThreatsManager.DevOps.csproj b/Sources/Extensions/ThreatsManager.DevOps/ThreatsManager.DevOps.csproj new file mode 100644 index 00000000..8cf53991 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.DevOps/ThreatsManager.DevOps.csproj @@ -0,0 +1,44 @@ + + + + netcoreapp3.1;net472 + Threats Manager Platform DevOps Integration library. + 1.3.3.0 + Simone Curzi + Simone Curzi + Threats Manager Platform + Copyright © Simone Curzi, 2018-2020. All Rights Reserved. + https://www.nuget.org/packages/ThreatsManager.Engine/ + https://github.com/simonec73/threatsmanager + 1.3.3.0 + 1.3.3 + true + ..\..\ThreatsManager.Engine\ThreatsManager.snk + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateDataStore.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateDataStore.cs new file mode 100644 index 00000000..660c7c9b --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateDataStore.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "D6B01BC8-E72A-400C-88C9-6EB83B41D936")] + [ExportMetadata("Label", "Create a Data Store Context Aware Action")] + [ExportMetadata("Priority", 17)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CreateDataStore : IIdentityContextAwareAction, IIdentityAddingRequiredAction + { + public Scope Scope => Scope.Diagram | Scope.ThreatModel; + public string Label => "Create a Data Store..."; + public string Group => "EntityCreation"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action IdentityAddingRequired; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + bool result = false; + + // ReSharper disable once SuspiciousTypeConversion.Global + if (identity is IDiagram diagram) + { + var dataStore = diagram.Model?.AddEntity(); + IdentityAddingRequired?.Invoke(diagram, dataStore, PointF.Empty, SizeF.Empty); + result = true; + } + else if (identity is IThreatModel threatModel) + { + threatModel.AddEntity(); + result = true; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateExternalInteractor.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateExternalInteractor.cs new file mode 100644 index 00000000..5a6a4d04 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateExternalInteractor.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "2F7A97D4-D5EE-4DF8-A467-EE7F22B451F1")] + [ExportMetadata("Label", "Create an External Interactor Context Aware Action")] + [ExportMetadata("Priority", 15)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CreateExternalInteractor : IIdentityContextAwareAction, IIdentityAddingRequiredAction + { + public Scope Scope => Scope.Diagram | Scope.ThreatModel; + public string Label => "Create an External Interactor..."; + public string Group => "EntityCreation"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action IdentityAddingRequired; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + bool result = false; + + // ReSharper disable once SuspiciousTypeConversion.Global + if (identity is IDiagram diagram) + { + var interactor = diagram.Model?.AddEntity(); + IdentityAddingRequired?.Invoke(diagram, interactor, PointF.Empty, SizeF.Empty); + result = true; + } + else if (identity is IThreatModel threatModel) + { + threatModel.AddEntity(); + result = true; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateGlobalThreatEvent.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateGlobalThreatEvent.cs new file mode 100644 index 00000000..4015de61 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateGlobalThreatEvent.cs @@ -0,0 +1,56 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ +#pragma warning disable CS0067 + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "7FCCFBE8-A4DF-4004-A192-CD223AC6F187")] + [ExportMetadata("Label", "Create Global Threat Event Context Aware Action")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CreateGlobalThreatEvent : IIdentityContextAwareAction, IDesktopAlertAwareExtension + { + public Scope Scope => Scope.ThreatType; + public string Label => "Create Global Threat Event"; + public string Group => "ThreatTypesActions"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action ShowMessage; + public event Action ShowWarning; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + bool result = false; + + if (identity is IThreatType threatType) + { + threatType.Model?.AddThreatEvent(threatType); + ShowMessage?.Invoke("Add Global Threat Event has been executed successfully."); + result = true; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateProcess.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateProcess.cs new file mode 100644 index 00000000..d5c9aa6a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateProcess.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "E10940D4-952E-4E47-B9F6-4404E58878F4")] + [ExportMetadata("Label", "Create a Process Context Aware Action")] + [ExportMetadata("Priority", 16)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CreateProcess : IIdentityContextAwareAction, IIdentityAddingRequiredAction + { + public Scope Scope => Scope.Diagram | Scope.ThreatModel; + public string Label => "Create a Process..."; + public string Group => "EntityCreation"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action IdentityAddingRequired; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + bool result = false; + + // ReSharper disable once SuspiciousTypeConversion.Global + if (identity is IDiagram diagram) + { + var process = diagram.Model?.AddEntity(); + IdentityAddingRequired?.Invoke(diagram, process, PointF.Empty, SizeF.Empty); + result = true; + } + else if (identity is IThreatModel threatModel) + { + threatModel.AddEntity(); + result = true; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateTrustBoundary.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateTrustBoundary.cs new file mode 100644 index 00000000..8c99986e --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/CreateTrustBoundary.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "E6BA9412-00C0-4547-9D62-A55BF881F3E7")] + [ExportMetadata("Label", "Create a Trust Boundary Context Aware Action")] + [ExportMetadata("Priority", 18)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CreateTrustBoundary : IIdentityContextAwareAction, IIdentityAddingRequiredAction + { + public Scope Scope => Scope.Diagram | Scope.ThreatModel; + public string Label => "Create a Trust Boundary..."; + public string Group => "EntityCreation"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action IdentityAddingRequired; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + bool result = false; + + // ReSharper disable once SuspiciousTypeConversion.Global + if (identity is IDiagram diagram) + { + var trustBoundary = diagram.Model?.AddGroup(); + IdentityAddingRequired?.Invoke(diagram, trustBoundary, PointF.Empty, new SizeF(600, 300)); + result = true; + } + else if (identity is IThreatModel threatModel) + { + threatModel.AddGroup(); + result = true; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatEvent.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatEvent.cs new file mode 100644 index 00000000..b21f10d6 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatEvent.cs @@ -0,0 +1,81 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "606CDD2C-8811-47D2-87DE-7BAE808146B3")] + [ExportMetadata("Label", "Propagate Threat Event Name and Description Context Aware Action")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PropagateThreatEvent : IIdentityContextAwareAction, IAsker + { + public Scope Scope => Scope.ThreatEvent; + public string Label => "Propagate Threat Event Info"; + public string Group => "Propagate"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action Ask; + + public bool Execute([NotNull] object item) + { + bool result = false; + + if (item is IIdentity identity) + { + result = Execute(identity); + } + + return result; + } + + public bool Execute([NotNull] IIdentity identity) + { + if (identity is IThreatEvent threatEvent) + { + Ask?.Invoke(this, threatEvent, "Copy Threat Event Info", + $"You are about to copy Name and Description of Threat Event '{threatEvent.Name}' to the associated Threat Type and to its sibling Threat Events. Are you sure?", + false, RequestOptions.YesNo); + } + + return true; + } + + public void Answer(object context, AnswerType answer) + { + if (answer == AnswerType.Yes && context is IThreatEvent threatEvent && + threatEvent.Model is IThreatModel model) + { + var threatType = threatEvent.ThreatType; + if (threatType != null) + { + threatType.Name = threatEvent.Name; + threatType.Description = threatEvent.Description; + var threatEvents = model.GetThreatEvents(threatType)?.ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var t in threatEvents) + { + if (t != threatEvent) + { + t.Name = threatEvent.Name; + t.Description = threatEvent.Description; + } + } + } + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatType.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatType.cs new file mode 100644 index 00000000..9123635b --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/PropagateThreatType.cs @@ -0,0 +1,72 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "FA566F92-541F-4817-B53B-199C4BA098D6")] + [ExportMetadata("Label", "Propagate Threat Type Name and Description Context Aware Action")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PropagateThreatType : IIdentityContextAwareAction, IAsker + { + public Scope Scope => Scope.ThreatType; + public string Label => "Propagate Threat Type Info"; + public string Group => "Propagate"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action Ask; + + public bool Execute([NotNull] object item) + { + bool result = false; + + if (item is IIdentity identity) + { + result = Execute(identity); + } + + return result; + } + + public bool Execute([NotNull] IIdentity identity) + { + if (identity is IThreatType threatType) + { + Ask?.Invoke(this, threatType, "Copy Threat Type Info", + $"You are about to copy Name and Description of Threat Type '{threatType.Name}' to the associated Threat Events. Are you sure?", + false, RequestOptions.YesNo); + } + + return true; + } + + public void Answer(object context, AnswerType answer) + { + if (answer == AnswerType.Yes && context is IThreatType threatType && + threatType.Model is IThreatModel model) + { + var threatEvents = model.GetThreatEvents(threatType)?.ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var t in threatEvents) + { + t.Name = threatType.Name; + t.Description = threatType.Description; + } + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromDiagram.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromDiagram.cs new file mode 100644 index 00000000..31a42a6d --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromDiagram.cs @@ -0,0 +1,73 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Drawing; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "140EA130-FA6C-4745-B609-28B5A47AF834")] + [ExportMetadata("Label", "Remove from Diagram Context Aware Action")] + [ExportMetadata("Priority", 50)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class RemoveFromDiagram : IShapesContextAwareAction, + IShapeContextAwareAction, ILinkContextAwareAction, + IEntityGroupRemovingRequiredAction, IDataFlowRemovingRequiredAction + { + public Scope Scope => Scope.Entity | Scope.Group | Scope.DataFlow; + public string Label => "Remove from Diagram"; + public string Group => "Remove"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action EntityGroupRemovingRequired; + public event Action DataFlowRemovingRequired; + + public bool Execute([NotNull] object item) + { + return false; + } + + public bool Execute([NotNull] ILink link) + { + return Execute(null, new[] {link}); + } + + public bool Execute([NotNull] IShape shape) + { + return Execute(new[] {shape}, null); + } + + public bool Execute(IEnumerable shapes, IEnumerable links) + { + var shapesArray = shapes?.ToArray(); + var linksArray = links?.ToArray(); + + if (linksArray?.Any() ?? false) + { + foreach (var link in linksArray) + { + DataFlowRemovingRequired?.Invoke(link); + } + } + + if (shapesArray?.Any() ?? false) + { + foreach (var shape in shapesArray) + { + EntityGroupRemovingRequired?.Invoke(shape); + } + } + + return true; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromModel.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromModel.cs new file mode 100644 index 00000000..50915235 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveFromModel.cs @@ -0,0 +1,55 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "4CB5F79B-189F-499F-AC63-ABF4EEFB462F")] + [ExportMetadata("Label", "Remove from Model Context Aware Action")] + [ExportMetadata("Priority", 51)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class RemoveFromModel : IIdentityContextAwareAction, IRemoveIdentityFromModelRequiredAction, IAsker + { + public Scope Scope => Scope.Entity | Scope.DataFlow | Scope.Group; + public string Label => "Remove from Model"; + public string Group => "Remove"; + public Bitmap Icon => null; + public Bitmap SmallIcon => null; + public Shortcut Shortcut => Shortcut.None; + + public event Action IdentityRemovingRequired; + public event Action Ask; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + Ask?.Invoke(this, identity, Resources.DeleteFromModel, + string.Format(Resources.RemoveIdentityFromModel, identity.Name), + false, RequestOptions.YesNo); + + return true; + } + + public void Answer(object context, AnswerType answer) + { + if (answer == AnswerType.Yes && context is IIdentity identity) + IdentityRemovingRequired?.Invoke(identity); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatEvent.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatEvent.cs new file mode 100644 index 00000000..99066c1a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatEvent.cs @@ -0,0 +1,71 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Icons; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "D252EAFC-8F07-4D35-900D-981A96D5779F")] + [ExportMetadata("Label", "Remove Threat Event Context Aware Action")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class RemoveThreatEvent : IIdentityContextAwareAction, IDesktopAlertAwareExtension, IAsker + { + public Scope Scope => Scope.ThreatEvent; + public string Label => "Remove Threat Event"; + public string Group => "ObjectRemoval"; + public Bitmap Icon => Resources.threat_event_big_delete; + public Bitmap SmallIcon => Resources.threat_event_delete; + public Shortcut Shortcut => Shortcut.None; + + public event Action ShowMessage; + public event Action ShowWarning; + public event Action Ask; + + public bool Execute([NotNull] object item) + { + bool result = false; + + if (item is IIdentity identity) + { + result = Execute(identity); + } + + return result; + } + + public bool Execute([NotNull] IIdentity identity) + { + if (identity is IThreatEvent threatEvent) + { + Ask?.Invoke(this, threatEvent, "Remove Threat Event", + $"You are about to remove Threat Event '{threatEvent.Name}' associated to '{threatEvent.Parent.Name}'. Are you sure?", + false, RequestOptions.YesNo); + } + + return true; + } + + public void Answer(object context, AnswerType answer) + { + if (answer == AnswerType.Yes && context is IThreatEvent threatEvent && + threatEvent.Parent is IThreatEventsContainer container) + { + var result = container.RemoveThreatEvent(threatEvent.Id); + if (result) + ShowMessage?.Invoke("Remove Threat Event has been executed successfully."); + else + ShowWarning?.Invoke("Remove Threat Event has failed."); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatType.cs b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatType.cs new file mode 100644 index 00000000..654e1a0c --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Actions/RemoveThreatType.cs @@ -0,0 +1,68 @@ +using System; +using System.ComponentModel.Composition; +using System.Drawing; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.Extensions.Actions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using Shortcut = ThreatsManager.Interfaces.Extensions.Shortcut; + +namespace ThreatsManager.Extensions.Actions +{ +#pragma warning disable CS0067 + [Export(typeof(IContextAwareAction))] + [ExportMetadata("Id", "8CB90E20-19C5-43C1-A79A-C10794FE014E")] + [ExportMetadata("Label", "Remove Threat Type Context Aware Action")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class RemoveThreatType : IIdentityContextAwareAction, IDesktopAlertAwareExtension, IAsker + { + public Scope Scope => Scope.ThreatType; + public string Label => "Remove Threat Type"; + public string Group => "ObjectRemoval"; + public Bitmap Icon => Icons.Resources.threat_type_big_delete; + public Bitmap SmallIcon => Icons.Resources.threat_type_delete; + public Shortcut Shortcut => Shortcut.None; + + public event Action ShowMessage; + public event Action ShowWarning; + public event Action Ask; + + public bool Execute(object item) + { + bool result = false; + + if (item is IIdentity identity) + result = Execute(identity); + + return result; + } + + public bool Execute(IIdentity identity) + { + if (identity is IThreatType threatType) + { + Ask?.Invoke(this, threatType, "Remove Threat Type", + $"You are about to remove Threat Type '{threatType.Name}'. Are you sure?", + false, RequestOptions.YesNo); + } + + return true; + } + + public void Answer(object context, AnswerType answer) + { + if (answer == AnswerType.Yes && context is IThreatType threatType && + threatType.Model is IThreatModel model) + { + var result = model.RemoveThreatType(threatType.Id); + if (result) + ShowMessage?.Invoke("Remove Threat Type has been executed successfully."); + else + ShowWarning?.Invoke("Remove Threat Type has failed."); + } + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.Extensions/ExtensionsContainer.cs new file mode 100644 index 00000000..b8227c8a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/ExtensionsContainer.cs @@ -0,0 +1,3 @@ +using ThreatsManager.Interfaces; + +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/ActorsInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ActorsInitializer.cs new file mode 100644 index 00000000..bdab066c --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ActorsInitializer.cs @@ -0,0 +1,32 @@ +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IInitializer))] + [ExportMetadata("Id", "30530FE5-9EC2-40DD-9DFF-9482096E51C6")] + [ExportMetadata("Label", "Standard Actors Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ActorsInitializer : IInitializer + { + public void Initialize([NotNull] IThreatModel model) + { + var values = EnumExtensions.GetUIVisible()?.ToArray(); + if (values?.Any() ?? false) + { + foreach (var value in values) + { + model.AddThreatActor(value); + } + } + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/KnownTypesInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/KnownTypesInitializer.cs new file mode 100644 index 00000000..cb14c41a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/KnownTypesInitializer.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.Composition; +using ThreatsManager.Extensions.Schemas; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IExtensionInitializer))] + [ExportMetadata("Id", "1B861078-A088-4368-8A19-B96585BF7158")] + [ExportMetadata("Label", "Known Types Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Business)] + public class KnownTypesInitializer : IExtensionInitializer + { + public void Initialize() + { + KnownTypesBinder.AddKnownType(typeof(ResidualRiskEstimatorConfiguration)); + KnownTypesBinder.AddKnownType(typeof(ResidualRiskEstimatorParameter)); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/ModelConfigSchemaInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ModelConfigSchemaInitializer.cs new file mode 100644 index 00000000..b13f2766 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ModelConfigSchemaInitializer.cs @@ -0,0 +1,48 @@ +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Schemas; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IInitializer))] + [ExportMetadata("Id", "6E637EFC-7AFC-4895-8794-F650DA4ED2FF")] + [ExportMetadata("Label", "Threat Model Configuration Schema Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ModelConfigSchemaInitializer : IInitializer + { + public void Initialize([NotNull] IThreatModel model) + { + var schemaManager = new ModelConfigPropertySchemaManager(model); + var schema = schemaManager.GetSchema(); + + var horizontalPT = schema.GetPropertyType("Diagram Layout Horizontal Spacing"); + var horizontal = model.GetProperty(horizontalPT); + if (horizontal == null) + { + model.AddProperty(horizontalPT, "200"); + } + else + { + if (string.IsNullOrWhiteSpace(horizontal.StringValue)) + horizontal.StringValue = "200"; + } + + var verticalPT = schema.GetPropertyType("Diagram Layout Vertical Spacing"); + var vertical = model.GetProperty(verticalPT); + if (vertical == null) + { + model.AddProperty(verticalPT, "100"); + } + else + { + if (string.IsNullOrWhiteSpace(vertical.StringValue)) + vertical.StringValue = "100"; + } + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/SeveritiesInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/SeveritiesInitializer.cs new file mode 100644 index 00000000..78ade4ba --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/SeveritiesInitializer.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IInitializer))] + [ExportMetadata("Id", "389FA3FA-C263-4B4C-8B8F-0266E553D261")] + [ExportMetadata("Label", "Standard Severities Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class SeveritiesInitializer : IInitializer + { + public void Initialize([NotNull] IThreatModel model) + { + model.InitializeStandardSeverities(); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/StrengthsInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/StrengthsInitializer.cs new file mode 100644 index 00000000..7228c447 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/StrengthsInitializer.cs @@ -0,0 +1,22 @@ +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IInitializer))] + [ExportMetadata("Id", "C7EE5AE4-3DD0-4CD1-8CAD-AC3D21BF8F5D")] + [ExportMetadata("Label", "Standard Strengths Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class StrengthInitializer : IInitializer + { + public void Initialize([NotNull] IThreatModel model) + { + model.InitializeStandardStrengths(); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Initializers/ThreatsSchemaInitializer.cs b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ThreatsSchemaInitializer.cs new file mode 100644 index 00000000..1a9a4758 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Initializers/ThreatsSchemaInitializer.cs @@ -0,0 +1,24 @@ +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Schemas; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; + +namespace ThreatsManager.Extensions.Initializers +{ + [Export(typeof(IInitializer))] + [ExportMetadata("Id", "3FCE7492-5173-451B-90AD-4AB51EF8D1D4")] + [ExportMetadata("Label", "Threats Schema Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ThreatsSchemaInitializer : IInitializer + { + public void Initialize([NotNull] IThreatModel model) + { + var schemaManager = new ThreatsPropertySchemaManager(model); + schemaManager.GetSchema(); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.Designer.cs b/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.Designer.cs new file mode 100644 index 00000000..62c4f9b3 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.Designer.cs @@ -0,0 +1,3728 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ThreatsManager.Extensions.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ThreatsManager.Extensions.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap arrows_merge { + get { + object obj = ResourceManager.GetObject("arrows_merge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap arrows_merge_big { + get { + object obj = ResourceManager.GetObject("arrows_merge_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap arrows_merge_huge { + get { + object obj = ResourceManager.GetObject("arrows_merge_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap arrows_merge_small { + get { + object obj = ResourceManager.GetObject("arrows_merge_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Identifier of the Diagram associated to the Entity.. + /// + internal static string AssociatedDiagram { + get { + return ResourceManager.GetString("AssociatedDiagram", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties to manage Diagrams associated to Entities.. + /// + internal static string AssociatedDiagramPropertySchemaDescription { + get { + return ResourceManager.GetString("AssociatedDiagramPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Identifier of the Entity associated to the Diagram.. + /// + internal static string AssociatedEntity { + get { + return ResourceManager.GetString("AssociatedEntity", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties to manage Entities associated to Diagrams.. + /// + internal static string AssociatedEntityPropertySchemaDescription { + get { + return ResourceManager.GetString("AssociatedEntityPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap astrologer { + get { + object obj = ResourceManager.GetObject("astrologer", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap astrologer_big { + get { + object obj = ResourceManager.GetObject("astrologer_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap astrologer_huge { + get { + object obj = ResourceManager.GetObject("astrologer_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap astrologer_small { + get { + object obj = ResourceManager.GetObject("astrologer_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book { + get { + object obj = ResourceManager.GetObject("book", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_big { + get { + object obj = ResourceManager.GetObject("book_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_huge { + get { + object obj = ResourceManager.GetObject("book_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open { + get { + object obj = ResourceManager.GetObject("book_open", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_big { + get { + object obj = ResourceManager.GetObject("book_open_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_huge { + get { + object obj = ResourceManager.GetObject("book_open_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_selected { + get { + object obj = ResourceManager.GetObject("book_open_selected", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_selected_big { + get { + object obj = ResourceManager.GetObject("book_open_selected_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_selected_huge { + get { + object obj = ResourceManager.GetObject("book_open_selected_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_selected_small { + get { + object obj = ResourceManager.GetObject("book_open_selected_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_open_small { + get { + object obj = ResourceManager.GetObject("book_open_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_selected { + get { + object obj = ResourceManager.GetObject("book_selected", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_selected_big { + get { + object obj = ResourceManager.GetObject("book_selected_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_selected_huge { + get { + object obj = ResourceManager.GetObject("book_selected_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_selected_small { + get { + object obj = ResourceManager.GetObject("book_selected_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap book_small { + get { + object obj = ResourceManager.GetObject("book_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap businesspeople_alt { + get { + object obj = ResourceManager.GetObject("businesspeople_alt", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap businesspeople_alt_big { + get { + object obj = ResourceManager.GetObject("businesspeople_alt_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap businesspeople_alt_huge { + get { + object obj = ResourceManager.GetObject("businesspeople_alt_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap businesspeople_alt_small { + get { + object obj = ResourceManager.GetObject("businesspeople_alt_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap caesar { + get { + object obj = ResourceManager.GetObject("caesar", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap caesar_big { + get { + object obj = ResourceManager.GetObject("caesar_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap caesar_huge { + get { + object obj = ResourceManager.GetObject("caesar_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap caesar_small { + get { + object obj = ResourceManager.GetObject("caesar_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap camera { + get { + object obj = ResourceManager.GetObject("camera", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap camera_big { + get { + object obj = ResourceManager.GetObject("camera_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap camera_huge { + get { + object obj = ResourceManager.GetObject("camera_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap camera_small { + get { + object obj = ResourceManager.GetObject("camera_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties to configure Capec. It is dynamically generated based on the selected properties from Capec data source.. + /// + internal static string CapecConfigPropertySchemaDescription { + get { + return ResourceManager.GetString("CapecConfigPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to http://capec.mitre.org/data/xml/capec_v2.10.xml. + /// + internal static string CapecDefaultUrl { + get { + return ResourceManager.GetString("CapecDefaultUrl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects the properties returned by Capec and applies to Threat Types and Events.. + /// + internal static string CapecPropertySchemaDescription { + get { + return ResourceManager.GetString("CapecPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap chart_pie { + get { + object obj = ResourceManager.GetObject("chart_pie", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap chart_pie_big { + get { + object obj = ResourceManager.GetObject("chart_pie_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap chart_pie_huge { + get { + object obj = ResourceManager.GetObject("chart_pie_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap chart_pie_small { + get { + object obj = ResourceManager.GetObject("chart_pie_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox { + get { + object obj = ResourceManager.GetObject("checkbox", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_big { + get { + object obj = ResourceManager.GetObject("checkbox_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_huge { + get { + object obj = ResourceManager.GetObject("checkbox_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_small { + get { + object obj = ResourceManager.GetObject("checkbox_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_unchecked { + get { + object obj = ResourceManager.GetObject("checkbox_unchecked", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_unchecked_big { + get { + object obj = ResourceManager.GetObject("checkbox_unchecked_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_unchecked_huge { + get { + object obj = ResourceManager.GetObject("checkbox_unchecked_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap checkbox_unchecked_small { + get { + object obj = ResourceManager.GetObject("checkbox_unchecked_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clear { + get { + object obj = ResourceManager.GetObject("clear", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clear_big { + get { + object obj = ResourceManager.GetObject("clear_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clear_huge { + get { + object obj = ResourceManager.GetObject("clear_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clear_small { + get { + object obj = ResourceManager.GetObject("clear_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clipboard { + get { + object obj = ResourceManager.GetObject("clipboard", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clipboard_big { + get { + object obj = ResourceManager.GetObject("clipboard_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clipboard_huge { + get { + object obj = ResourceManager.GetObject("clipboard_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap clipboard_small { + get { + object obj = ResourceManager.GetObject("clipboard_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cloud_computing_download { + get { + object obj = ResourceManager.GetObject("cloud_computing_download", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap copy { + get { + object obj = ResourceManager.GetObject("copy", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap copy_big { + get { + object obj = ResourceManager.GetObject("copy_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap copy_huge { + get { + object obj = ResourceManager.GetObject("copy_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap copy_small { + get { + object obj = ResourceManager.GetObject("copy_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cubes { + get { + object obj = ResourceManager.GetObject("cubes", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cubes_big { + get { + object obj = ResourceManager.GetObject("cubes_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cubes_huge { + get { + object obj = ResourceManager.GetObject("cubes_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cubes_small { + get { + object obj = ResourceManager.GetObject("cubes_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cut { + get { + object obj = ResourceManager.GetObject("cut", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cut_big { + get { + object obj = ResourceManager.GetObject("cut_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cut_huge { + get { + object obj = ResourceManager.GetObject("cut_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap cut_small { + get { + object obj = ResourceManager.GetObject("cut_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to http://cwe.mitre.org/data/xml/cwec_v2.10.xml.zip. + /// + internal static string CweDefaultUrl { + get { + return ResourceManager.GetString("CweDefaultUrl", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to https://www.simoneonsecurity.com/tm/2018. + /// + internal static string DefaultNamespace { + get { + return ResourceManager.GetString("DefaultNamespace", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Delete from Model. + /// + internal static string DeleteFromModel { + get { + return ResourceManager.GetString("DeleteFromModel", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dependencies { + get { + object obj = ResourceManager.GetObject("dependencies", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dependencies_big { + get { + object obj = ResourceManager.GetObject("dependencies_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dependencies_huge { + get { + object obj = ResourceManager.GetObject("dependencies_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap dependencies_small { + get { + object obj = ResourceManager.GetObject("dependencies_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Diagram is not associated to a Model.. + /// + internal static string DiagramNoModelError { + get { + return ResourceManager.GetString("DiagramNoModelError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties to be assigned to the Diagrams.. + /// + internal static string DiagramPropertySchemaDescription { + get { + return ResourceManager.GetString("DiagramPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_empty { + get { + object obj = ResourceManager.GetObject("document_empty", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_empty_big { + get { + object obj = ResourceManager.GetObject("document_empty_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_empty_huge { + get { + object obj = ResourceManager.GetObject("document_empty_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_empty_small { + get { + object obj = ResourceManager.GetObject("document_empty_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_text { + get { + object obj = ResourceManager.GetObject("document_text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_text_big { + get { + object obj = ResourceManager.GetObject("document_text_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_text_huge { + get { + object obj = ResourceManager.GetObject("document_text_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap document_text_small { + get { + object obj = ResourceManager.GetObject("document_text_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap docx { + get { + object obj = ResourceManager.GetObject("docx", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap docx_big { + get { + object obj = ResourceManager.GetObject("docx_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap docx_huge { + get { + object obj = ResourceManager.GetObject("docx_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap docx_small { + get { + object obj = ResourceManager.GetObject("docx_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema to represent the Effort required to implement mitigations.. + /// + internal static string EffortPropertySchemaDescription { + get { + return ResourceManager.GetString("EffortPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap element { + get { + object obj = ResourceManager.GetObject("element", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap element_big { + get { + object obj = ResourceManager.GetObject("element_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap element_huge { + get { + object obj = ResourceManager.GetObject("element_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap element_small { + get { + object obj = ResourceManager.GetObject("element_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_cascade { + get { + object obj = ResourceManager.GetObject("elements_cascade", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_cascade_big { + get { + object obj = ResourceManager.GetObject("elements_cascade_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_cascade_huge { + get { + object obj = ResourceManager.GetObject("elements_cascade_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_cascade_small { + get { + object obj = ResourceManager.GetObject("elements_cascade_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_tree { + get { + object obj = ResourceManager.GetObject("elements_tree", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_tree_big { + get { + object obj = ResourceManager.GetObject("elements_tree_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_tree_huge { + get { + object obj = ResourceManager.GetObject("elements_tree_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_tree_small { + get { + object obj = ResourceManager.GetObject("elements_tree_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_two { + get { + object obj = ResourceManager.GetObject("elements_two", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_two_big { + get { + object obj = ResourceManager.GetObject("elements_two_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_two_huge { + get { + object obj = ResourceManager.GetObject("elements_two_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap elements_two_small { + get { + object obj = ResourceManager.GetObject("elements_two_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap export_template { + get { + object obj = ResourceManager.GetObject("export_template", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap export_template_big { + get { + object obj = ResourceManager.GetObject("export_template_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap export_template_huge { + get { + object obj = ResourceManager.GetObject("export_template_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap export_template_small { + get { + object obj = ResourceManager.GetObject("export_template_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap firewall { + get { + object obj = ResourceManager.GetObject("firewall", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap firewall_big { + get { + object obj = ResourceManager.GetObject("firewall_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap firewall_huge { + get { + object obj = ResourceManager.GetObject("firewall_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap firewall_small { + get { + object obj = ResourceManager.GetObject("firewall_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap floppy_disk { + get { + object obj = ResourceManager.GetObject("floppy_disk", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap floppy_disk_big { + get { + object obj = ResourceManager.GetObject("floppy_disk_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap floppy_disk_huge { + get { + object obj = ResourceManager.GetObject("floppy_disk_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap floppy_disk_small { + get { + object obj = ResourceManager.GetObject("floppy_disk_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder_open_document { + get { + object obj = ResourceManager.GetObject("folder_open_document", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder_open_document_big { + get { + object obj = ResourceManager.GetObject("folder_open_document_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder_open_document_huge { + get { + object obj = ResourceManager.GetObject("folder_open_document_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap folder_open_document_small { + get { + object obj = ResourceManager.GetObject("folder_open_document_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap gauge { + get { + object obj = ResourceManager.GetObject("gauge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap gauge_big { + get { + object obj = ResourceManager.GetObject("gauge_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap gauge_huge { + get { + object obj = ResourceManager.GetObject("gauge_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap gauge_small { + get { + object obj = ResourceManager.GetObject("gauge_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap graph_star { + get { + object obj = ResourceManager.GetObject("graph_star", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap graph_star_big { + get { + object obj = ResourceManager.GetObject("graph_star_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap graph_star_huge { + get { + object obj = ResourceManager.GetObject("graph_star_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap graph_star_small { + get { + object obj = ResourceManager.GetObject("graph_star_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Deleting objects. + /// + internal static string GraphDeletionCaption { + get { + return ResourceManager.GetString("GraphDeletionCaption", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are about to delete {0} objects. Do you confirm?. + /// + internal static string GraphDeletionConfirmation { + get { + return ResourceManager.GetString("GraphDeletionConfirmation", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hint { + get { + object obj = ResourceManager.GetObject("hint", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hint_big { + get { + object obj = ResourceManager.GetObject("hint_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hint_huge { + get { + object obj = ResourceManager.GetObject("hint_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hint_small { + get { + object obj = ResourceManager.GetObject("hint_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import { + get { + object obj = ResourceManager.GetObject("import", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_big { + get { + object obj = ResourceManager.GetObject("import_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_huge { + get { + object obj = ResourceManager.GetObject("import_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_small { + get { + object obj = ResourceManager.GetObject("import_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_template { + get { + object obj = ResourceManager.GetObject("import_template", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_template_big { + get { + object obj = ResourceManager.GetObject("import_template_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_template_huge { + get { + object obj = ResourceManager.GetObject("import_template_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap import_template_small { + get { + object obj = ResourceManager.GetObject("import_template_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_bottom { + get { + object obj = ResourceManager.GetObject("layout_bottom", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_bottom_big { + get { + object obj = ResourceManager.GetObject("layout_bottom_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_bottom_huge { + get { + object obj = ResourceManager.GetObject("layout_bottom_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_bottom_small { + get { + object obj = ResourceManager.GetObject("layout_bottom_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_horizontal { + get { + object obj = ResourceManager.GetObject("layout_horizontal", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_horizontal_big { + get { + object obj = ResourceManager.GetObject("layout_horizontal_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_horizontal_small { + get { + object obj = ResourceManager.GetObject("layout_horizontal_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_left { + get { + object obj = ResourceManager.GetObject("layout_left", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_left_big { + get { + object obj = ResourceManager.GetObject("layout_left_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_left_huge { + get { + object obj = ResourceManager.GetObject("layout_left_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_left_small { + get { + object obj = ResourceManager.GetObject("layout_left_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_right { + get { + object obj = ResourceManager.GetObject("layout_right", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_right_big { + get { + object obj = ResourceManager.GetObject("layout_right_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_right_huge { + get { + object obj = ResourceManager.GetObject("layout_right_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_right_small { + get { + object obj = ResourceManager.GetObject("layout_right_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_top { + get { + object obj = ResourceManager.GetObject("layout_top", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_top_big { + get { + object obj = ResourceManager.GetObject("layout_top_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_top_huge { + get { + object obj = ResourceManager.GetObject("layout_top_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_top_small { + get { + object obj = ResourceManager.GetObject("layout_top_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_vertical { + get { + object obj = ResourceManager.GetObject("layout_vertical", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_vertical_big { + get { + object obj = ResourceManager.GetObject("layout_vertical_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap layout_vertical_small { + get { + object obj = ResourceManager.GetObject("layout_vertical_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties to be assigned to the Links within Diagrams.. + /// + internal static string LinksPropertySchemaDescription { + get { + return ResourceManager.GetString("LinksPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap list_style_numbered { + get { + object obj = ResourceManager.GetObject("list_style_numbered", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap list_style_numbered_big { + get { + object obj = ResourceManager.GetObject("list_style_numbered_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap list_style_numbered_huge { + get { + object obj = ResourceManager.GetObject("list_style_numbered_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap list_style_numbered_small { + get { + object obj = ResourceManager.GetObject("list_style_numbered_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap magic_wand { + get { + object obj = ResourceManager.GetObject("magic_wand", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap magic_wand_big { + get { + object obj = ResourceManager.GetObject("magic_wand_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap magic_wand_huge { + get { + object obj = ResourceManager.GetObject("magic_wand_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap magic_wand_small { + get { + object obj = ResourceManager.GetObject("magic_wand_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap map_roads { + get { + object obj = ResourceManager.GetObject("map_roads", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap map_roads_big { + get { + object obj = ResourceManager.GetObject("map_roads_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap map_roads_huge { + get { + object obj = ResourceManager.GetObject("map_roads_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap map_roads_small { + get { + object obj = ResourceManager.GetObject("map_roads_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to You are requesting to get full edit access to the Property Schemas. + ///Please note that editing System Property Schemas is a risky action and is not supported: you may cause your Threat Model to become unreadable. + ///It is recommended to create backup of the Threat Model before proceeding further. + /// + ///Are you sure you want still to get full access rights? . + /// + internal static string MessagePromote { + get { + return ResourceManager.GetString("MessagePromote", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to You are requesting to get full edit access to Severities. + ///Please note that removing Severities is a risky action and is not supported: you may even compromise your Threat Model's integrity. + ///It is recommended to create backup of the Threat Model before proceeding further. + /// + ///Are you sure you want still to get full access rights? . + /// + internal static string MessagePromoteSeverities { + get { + return ResourceManager.GetString("MessagePromoteSeverities", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Parameter '{0}' is missing.. + /// + internal static string MissingParameterError { + get { + return ResourceManager.GetString("MissingParameterError", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap model_big_up { + get { + object obj = ResourceManager.GetObject("model_big_up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap model_huge_up { + get { + object obj = ResourceManager.GetObject("model_huge_up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap model_small_up { + get { + object obj = ResourceManager.GetObject("model_small_up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap model_up { + get { + object obj = ResourceManager.GetObject("model_up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap money_bill_fire { + get { + object obj = ResourceManager.GetObject("money_bill_fire", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap money_bill_fire_big { + get { + object obj = ResourceManager.GetObject("money_bill_fire_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap money_bill_fire_huge { + get { + object obj = ResourceManager.GetObject("money_bill_fire_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap money_bill_fire_small { + get { + object obj = ResourceManager.GetObject("money_bill_fire_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap nav_refresh { + get { + object obj = ResourceManager.GetObject("nav_refresh", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap nav_refresh_big { + get { + object obj = ResourceManager.GetObject("nav_refresh_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap nav_refresh_huge { + get { + object obj = ResourceManager.GetObject("nav_refresh_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap nav_refresh_small { + get { + object obj = ResourceManager.GetObject("nav_refresh_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap note_text { + get { + object obj = ResourceManager.GetObject("note_text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap note_text_big { + get { + object obj = ResourceManager.GetObject("note_text_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap note_text_huge { + get { + object obj = ResourceManager.GetObject("note_text_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap note_text_small { + get { + object obj = ResourceManager.GetObject("note_text_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap odometer { + get { + object obj = ResourceManager.GetObject("odometer", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap odometer_big { + get { + object obj = ResourceManager.GetObject("odometer_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap odometer_huge { + get { + object obj = ResourceManager.GetObject("odometer_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap odometer_small { + get { + object obj = ResourceManager.GetObject("odometer_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Parent is not aligned. Please move the shape to the correct parent.. + /// + internal static string ParentAlignmentWarning { + get { + return ResourceManager.GetString("ParentAlignmentWarning", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap paste { + get { + object obj = ResourceManager.GetObject("paste", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap paste_big { + get { + object obj = ResourceManager.GetObject("paste_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap paste_huge { + get { + object obj = ResourceManager.GetObject("paste_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap paste_small { + get { + object obj = ResourceManager.GetObject("paste_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf { + get { + object obj = ResourceManager.GetObject("pdf", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_big { + get { + object obj = ResourceManager.GetObject("pdf_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_huge { + get { + object obj = ResourceManager.GetObject("pdf_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_small { + get { + object obj = ResourceManager.GetObject("pdf_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap presentation_pie_chart { + get { + object obj = ResourceManager.GetObject("presentation_pie_chart", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap presentation_pie_chart_big { + get { + object obj = ResourceManager.GetObject("presentation_pie_chart_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap presentation_pie_chart_huge { + get { + object obj = ResourceManager.GetObject("presentation_pie_chart_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap presentation_pie_chart_small { + get { + object obj = ResourceManager.GetObject("presentation_pie_chart_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties { + get { + object obj = ResourceManager.GetObject("properties", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_big { + get { + object obj = ResourceManager.GetObject("properties_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_big_delete { + get { + object obj = ResourceManager.GetObject("properties_big_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_big_new { + get { + object obj = ResourceManager.GetObject("properties_big_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_delete { + get { + object obj = ResourceManager.GetObject("properties_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_huge { + get { + object obj = ResourceManager.GetObject("properties_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_huge_delete { + get { + object obj = ResourceManager.GetObject("properties_huge_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_huge_new { + get { + object obj = ResourceManager.GetObject("properties_huge_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_new { + get { + object obj = ResourceManager.GetObject("properties_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_small { + get { + object obj = ResourceManager.GetObject("properties_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_small_delete { + get { + object obj = ResourceManager.GetObject("properties_small_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap properties_small_new { + get { + object obj = ResourceManager.GetObject("properties_small_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property { + get { + object obj = ResourceManager.GetObject("property", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_big { + get { + object obj = ResourceManager.GetObject("property_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_big_delete { + get { + object obj = ResourceManager.GetObject("property_big_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_big_new { + get { + object obj = ResourceManager.GetObject("property_big_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_delete { + get { + object obj = ResourceManager.GetObject("property_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_huge { + get { + object obj = ResourceManager.GetObject("property_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_huge_delete { + get { + object obj = ResourceManager.GetObject("property_huge_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_huge_new { + get { + object obj = ResourceManager.GetObject("property_huge_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_new { + get { + object obj = ResourceManager.GetObject("property_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_small { + get { + object obj = ResourceManager.GetObject("property_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_small_delete { + get { + object obj = ResourceManager.GetObject("property_small_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap property_small_new { + get { + object obj = ResourceManager.GetObject("property_small_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Widths of the Columns. It applies to Word Reporting.. + /// + internal static string PropertyColumnWidths { + get { + return ResourceManager.GetString("PropertyColumnWidths", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reference Dpi factor for the Diagram.. + /// + internal static string PropertyDpiFactor { + get { + return ResourceManager.GetString("PropertyDpiFactor", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Estimated effort for implementing the Mitigation.. + /// + internal static string PropertyEffort { + get { + return ResourceManager.GetString("PropertyEffort", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Selected fields for the Excel reporting Extension.. + /// + internal static string PropertyExcelSelectedFields { + get { + return ResourceManager.GetString("PropertyExcelSelectedFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to List of hidden properties, not to be created in the Capec Property Schema. . + /// + internal static string PropertyHiddenProperties { + get { + return ResourceManager.GetString("PropertyHiddenProperties", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Horizontal spacing to use for the Diagram automatic layout function.. + /// + internal static string PropertyHorizontalSpacing { + get { + return ResourceManager.GetString("PropertyHorizontalSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Fields to be ignored for the Lists. It applies to Word Reporting.. + /// + internal static string PropertyIgnoredListFields { + get { + return ResourceManager.GetString("PropertyIgnoredListFields", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Keywords associated to the Threat Type or Event. This is used to improve the results while Searching for Threats.. + /// + internal static string PropertyKeywords { + get { + return ResourceManager.GetString("PropertyKeywords", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Reference points for the link.. + /// + internal static string PropertyPoints { + get { + return ResourceManager.GetString("PropertyPoints", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Status of the Mitigation for the Roadmap.. + /// + internal static string PropertyRoadmap { + get { + return ResourceManager.GetString("PropertyRoadmap", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Vertical spacing to use for the Diagram automatic layout function.. + /// + internal static string PropertyVerticalSpacing { + get { + return ResourceManager.GetString("PropertyVerticalSpacing", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Path name of the file used as seed for Word Report generation.. + /// + internal static string PropertyWordDocumentPath { + get { + return ResourceManager.GetString("PropertyWordDocumentPath", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Configuration of the Sections for Word Report generation.. + /// + internal static string PropertyWordSections { + get { + return ResourceManager.GetString("PropertyWordSections", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap question_and_answer { + get { + object obj = ResourceManager.GetObject("question_and_answer", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap question_and_answer_big { + get { + object obj = ResourceManager.GetObject("question_and_answer_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap question_and_answer_huge { + get { + object obj = ResourceManager.GetObject("question_and_answer_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap question_and_answer_small { + get { + object obj = ResourceManager.GetObject("question_and_answer_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap red_chart_pie { + get { + object obj = ResourceManager.GetObject("red_chart_pie", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap red_chart_pie_big { + get { + object obj = ResourceManager.GetObject("red_chart_pie_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap red_chart_pie_huge { + get { + object obj = ResourceManager.GetObject("red_chart_pie_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap red_chart_pie_small { + get { + object obj = ResourceManager.GetObject("red_chart_pie_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to You are about to remove '{0}' from the Threat Model. Are you sure?. + /// + internal static string RemoveIdentityFromModel { + get { + return ResourceManager.GetString("RemoveIdentityFromModel", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap report_problem { + get { + object obj = ResourceManager.GetObject("report_problem", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap report_problem_big { + get { + object obj = ResourceManager.GetObject("report_problem_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap report_problem_huge { + get { + object obj = ResourceManager.GetObject("report_problem_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap report_problem_small { + get { + object obj = ResourceManager.GetObject("report_problem_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties used to configure the Reporting Extensions.. + /// + internal static string ReportingConfigPropertySchemaDescription { + get { + return ResourceManager.GetString("ReportingConfigPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects the configuration of the selected Residual Risk Estimator.. + /// + internal static string ResidualRiskEstimatorConfigurationPropertySchemaDescription { + get { + return ResourceManager.GetString("ResidualRiskEstimatorConfigurationPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Property Schema to store the Roadmap Status for Mitigations.. + /// + internal static string RoadmapPropertySchemaDescription { + get { + return ResourceManager.GetString("RoadmapPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp { + get { + object obj = ResourceManager.GetObject("rubber_stamp", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_big { + get { + object obj = ResourceManager.GetObject("rubber_stamp_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_big_delete { + get { + object obj = ResourceManager.GetObject("rubber_stamp_big_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_big_new { + get { + object obj = ResourceManager.GetObject("rubber_stamp_big_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_delete { + get { + object obj = ResourceManager.GetObject("rubber_stamp_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_huge { + get { + object obj = ResourceManager.GetObject("rubber_stamp_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_huge_delete { + get { + object obj = ResourceManager.GetObject("rubber_stamp_huge_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_huge_new { + get { + object obj = ResourceManager.GetObject("rubber_stamp_huge_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_new { + get { + object obj = ResourceManager.GetObject("rubber_stamp_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_small { + get { + object obj = ResourceManager.GetObject("rubber_stamp_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_small_delete { + get { + object obj = ResourceManager.GetObject("rubber_stamp_small_delete", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap rubber_stamp_small_new { + get { + object obj = ResourceManager.GetObject("rubber_stamp_small_new", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap school { + get { + object obj = ResourceManager.GetObject("school", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap school_big { + get { + object obj = ResourceManager.GetObject("school_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap school_huge { + get { + object obj = ResourceManager.GetObject("school_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap school_small { + get { + object obj = ResourceManager.GetObject("school_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap selected_graph_star { + get { + object obj = ResourceManager.GetObject("selected_graph_star", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap selected_graph_star_big { + get { + object obj = ResourceManager.GetObject("selected_graph_star_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap selected_graph_star_huge { + get { + object obj = ResourceManager.GetObject("selected_graph_star_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap selected_graph_star_small { + get { + object obj = ResourceManager.GetObject("selected_graph_star_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Shape does not refer to an Entity.. + /// + internal static string ShapeNotEntityError { + get { + return ResourceManager.GetString("ShapeNotEntityError", resourceCulture); + } + } + + /// + /// Looks up a localized string similar to Shape does not refer to a Group.. + /// + internal static string ShapeNotGroupError { + get { + return ResourceManager.GetString("ShapeNotGroupError", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shapes { + get { + object obj = ResourceManager.GetObject("shapes", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shapes_big { + get { + object obj = ResourceManager.GetObject("shapes_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shapes_huge { + get { + object obj = ResourceManager.GetObject("shapes_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shapes_small { + get { + object obj = ResourceManager.GetObject("shapes_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shelf_full { + get { + object obj = ResourceManager.GetObject("shelf_full", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shelf_full_big { + get { + object obj = ResourceManager.GetObject("shelf_full_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shelf_full_huge { + get { + object obj = ResourceManager.GetObject("shelf_full_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap shelf_full_small { + get { + object obj = ResourceManager.GetObject("shelf_full_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap signpost_two { + get { + object obj = ResourceManager.GetObject("signpost_two", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap signpost_two_big { + get { + object obj = ResourceManager.GetObject("signpost_two_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap signpost_two_huge { + get { + object obj = ResourceManager.GetObject("signpost_two_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap signpost_two_small { + get { + object obj = ResourceManager.GetObject("signpost_two_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap table { + get { + object obj = ResourceManager.GetObject("table", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap table_big { + get { + object obj = ResourceManager.GetObject("table_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap table_huge { + get { + object obj = ResourceManager.GetObject("table_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap table_small { + get { + object obj = ResourceManager.GetObject("table_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tag { + get { + object obj = ResourceManager.GetObject("tag", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tag_big { + get { + object obj = ResourceManager.GetObject("tag_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tag_huge { + get { + object obj = ResourceManager.GetObject("tag_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tag_small { + get { + object obj = ResourceManager.GetObject("tag_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text { + get { + object obj = ResourceManager.GetObject("text", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text_big { + get { + object obj = ResourceManager.GetObject("text_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text_huge { + get { + object obj = ResourceManager.GetObject("text_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap text_small { + get { + object obj = ResourceManager.GetObject("text_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threat_selection { + get { + object obj = ResourceManager.GetObject("threat_selection", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threat_selection_big { + get { + object obj = ResourceManager.GetObject("threat_selection_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threat_selection_huge { + get { + object obj = ResourceManager.GetObject("threat_selection_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threat_selection_small { + get { + object obj = ResourceManager.GetObject("threat_selection_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties used to configure the standard Extensions within the Threat Model. . + /// + internal static string ThreatModelConfigPropertySchemaDescription { + get { + return ResourceManager.GetString("ThreatModelConfigPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threats_selection { + get { + object obj = ResourceManager.GetObject("threats_selection", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threats_selection_big { + get { + object obj = ResourceManager.GetObject("threats_selection_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threats_selection_huge { + get { + object obj = ResourceManager.GetObject("threats_selection_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap threats_selection_small { + get { + object obj = ResourceManager.GetObject("threats_selection_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects additional generic properties for Threat Types and Events.. + /// + internal static string ThreatsPropertySchemaDescription { + get { + return ResourceManager.GetString("ThreatsPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane { + get { + object obj = ResourceManager.GetObject("tower_crane", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_big { + get { + object obj = ResourceManager.GetObject("tower_crane_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_huge { + get { + object obj = ResourceManager.GetObject("tower_crane_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_small { + get { + object obj = ResourceManager.GetObject("tower_crane_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_stop { + get { + object obj = ResourceManager.GetObject("tower_crane_stop", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_stop_big { + get { + object obj = ResourceManager.GetObject("tower_crane_stop_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_stop_huge { + get { + object obj = ResourceManager.GetObject("tower_crane_stop_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tower_crane_stop_small { + get { + object obj = ResourceManager.GetObject("tower_crane_stop_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tt_chart_pie { + get { + object obj = ResourceManager.GetObject("tt_chart_pie", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tt_chart_pie_big { + get { + object obj = ResourceManager.GetObject("tt_chart_pie_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tt_chart_pie_huge { + get { + object obj = ResourceManager.GetObject("tt_chart_pie_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap tt_chart_pie_small { + get { + object obj = ResourceManager.GetObject("tt_chart_pie_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap undo { + get { + object obj = ResourceManager.GetObject("undo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap undo_big { + get { + object obj = ResourceManager.GetObject("undo_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap undo_huge { + get { + object obj = ResourceManager.GetObject("undo_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap undo_small { + get { + object obj = ResourceManager.GetObject("undo_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to File '{0}' has an unsupported type.. + /// + internal static string UnsupportedFileTypeError { + get { + return ResourceManager.GetString("UnsupportedFileTypeError", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_1_1 { + get { + object obj = ResourceManager.GetObject("view_1_1", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_1_1_big { + get { + object obj = ResourceManager.GetObject("view_1_1_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_1_1_huge { + get { + object obj = ResourceManager.GetObject("view_1_1_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap view_1_1_small { + get { + object obj = ResourceManager.GetObject("view_1_1_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap window_size { + get { + object obj = ResourceManager.GetObject("window_size", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap window_size_big { + get { + object obj = ResourceManager.GetObject("window_size_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap window_size_huge { + get { + object obj = ResourceManager.GetObject("window_size_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap window_size_small { + get { + object obj = ResourceManager.GetObject("window_size_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Property Schema that collects properties required for the Word Reporting feature.. + /// + internal static string WordPropertySchemaDescription { + get { + return ResourceManager.GetString("WordPropertySchemaDescription", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx { + get { + object obj = ResourceManager.GetObject("xlsx", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_big { + get { + object obj = ResourceManager.GetObject("xlsx_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_huge { + get { + object obj = ResourceManager.GetObject("xlsx_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_small { + get { + object obj = ResourceManager.GetObject("xlsx_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_in { + get { + object obj = ResourceManager.GetObject("zoom_in", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_in_big { + get { + object obj = ResourceManager.GetObject("zoom_in_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_in_huge { + get { + object obj = ResourceManager.GetObject("zoom_in_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_in_small { + get { + object obj = ResourceManager.GetObject("zoom_in_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_out { + get { + object obj = ResourceManager.GetObject("zoom_out", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_out_big { + get { + object obj = ResourceManager.GetObject("zoom_out_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_out_huge { + get { + object obj = ResourceManager.GetObject("zoom_out_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap zoom_out_small { + get { + object obj = ResourceManager.GetObject("zoom_out_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.resx b/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.resx new file mode 100644 index 00000000..67eb580e --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Properties/Resources.resx @@ -0,0 +1,254 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + Shape does not refer to an Entity. + + + Shape does not refer to a Group. + + + Diagram is not associated to a Model. + + + http://capec.mitre.org/data/xml/capec_v2.10.xml + + + http://cwe.mitre.org/data/xml/cwec_v2.10.xml.zip + + + Parameter '{0}' is missing. + + + File '{0}' has an unsupported type. + + + Property Schema that collects the properties returned by Capec and applies to Threat Types and Events. + + + https://www.simoneonsecurity.com/tm/2018 + + + Property Schema that collects additional generic properties for Threat Types and Events. + + + You are about to delete {0} objects. Do you confirm? + + + Deleting objects + + + Property Schema that collects properties to configure Capec. It is dynamically generated based on the selected properties from Capec data source. + + + You are about to remove '{0}' from the Threat Model. Are you sure? + + + Delete from Model + + + Parent is not aligned. Please move the shape to the correct parent. + + + List of hidden properties, not to be created in the Capec Property Schema. + + + Property Schema that collects properties used to configure the standard Extensions within the Threat Model. + + + Horizontal spacing to use for the Diagram automatic layout function. + + + Vertical spacing to use for the Diagram automatic layout function. + + + Reference points for the link. + + + Selected fields for the Excel reporting Extension. + + + Property Schema that collects properties used to configure the Reporting Extensions. + + + Path name of the file used as seed for Word Report generation. + + + Configuration of the Sections for Word Report generation. + + + Property Schema that collects properties required for the Word Reporting feature. + + + Widths of the Columns. It applies to Word Reporting. + + + Fields to be ignored for the Lists. It applies to Word Reporting. + + + Identifier of the Diagram associated to the Entity. + + + Property Schema that collects properties to manage Diagrams associated to Entities. + + + Identifier of the Entity associated to the Diagram. + + + Property Schema that collects properties to manage Entities associated to Diagrams. + + + You are requesting to get full edit access to the Property Schemas. +Please note that editing System Property Schemas is a risky action and is not supported: you may cause your Threat Model to become unreadable. +It is recommended to create backup of the Threat Model before proceeding further. + +Are you sure you want still to get full access rights? + + + Property Schema to represent the Effort required to implement mitigations. + + + Estimated effort for implementing the Mitigation. + + + Status of the Mitigation for the Roadmap. + + + Property Schema to store the Roadmap Status for Mitigations. + + + Property Schema that collects the configuration of the selected Residual Risk Estimator. + + + Property Schema that collects properties to be assigned to the Diagrams. + + + Property Schema that collects properties to be assigned to the Links within Diagrams. + + + Reference Dpi factor for the Diagram. + + + You are requesting to get full edit access to Severities. +Please note that removing Severities is a risky action and is not supported: you may even compromise your Threat Model's integrity. +It is recommended to create backup of the Threat Model before proceeding further. + +Are you sure you want still to get full access rights? + + \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Properties/launchSettings.json b/Sources/Extensions/ThreatsManager.Extensions/Properties/launchSettings.json new file mode 100644 index 00000000..d26858e0 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ThreatsManager.Extensions": { + "commandName": "Executable", + "executablePath": "C:\\src\\Threats Manager Platform\\Dev\\ThreatsManager\\bin\\Debug\\ThreatsManager.exe" + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/ResidualRiskEstimators/BugBarResidualRiskEstimator.cs b/Sources/Extensions/ThreatsManager.Extensions/ResidualRiskEstimators/BugBarResidualRiskEstimator.cs new file mode 100644 index 00000000..7b3ab047 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/ResidualRiskEstimators/BugBarResidualRiskEstimator.cs @@ -0,0 +1,207 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using System.Text.RegularExpressions; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.ResidualRiskEstimators +{ + [Export(typeof(IResidualRiskEstimator))] + [ExportMetadata("Id", "C1F10EC7-FF20-4FE5-99EC-2DBF3C1BC216")] + [ExportMetadata("Label", "Bug Bar Residual Risk Estimator")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Business)] + public class BugBarResidualRiskEstimator : IResidualRiskEstimator + { + class MitigationWeight + { + public MitigationWeight(Guid mitigationId, int effectiveness) + { + MitigationId = mitigationId; + Effectiveness = effectiveness; + } + + public Guid MitigationId { get; private set; } + public int Effectiveness { get; set; } + } + + public float DefaultInfinite => 10f; + + public float Estimate([NotNull] IThreatModel model, IEnumerable mitigations, out float min, out float max) + { + float result = 0f; + + var threatEvents = model.GetThreatEvents()?.ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var threatEvent in threatEvents) + { + var risk = (float)threatEvent.SeverityId; + var mitigationsStrength = threatEvent.Mitigations? + .Where(x => (x.Status != MitigationStatus.Existing) && + (x.Status != MitigationStatus.Implemented) && + (mitigations?.Any(y => y == x.MitigationId) ?? false)) + .Sum(x => x.StrengthId); + result += risk * (100f - Math.Min((mitigationsStrength ?? 0), 100f)) / 100f; + } + } + + min = result * 0.9f; + max = result * 1.1f; + + return result; + } + + public IDictionary CategorizeMitigations([NotNull] IThreatModel model) + { + IDictionary result = null; + + var mitigations = model.GetUniqueMitigations()? + .Select(x => new MitigationWeight(x.Id, CalculateMitigationEffectiveness(model, x))) + .OrderByDescending(x => x.Effectiveness) + .ToArray(); + if (mitigations?.Any() ?? false) + { + var list = new Dictionary(); + + int count = mitigations.Length / 3; + int i = 0; + foreach (var mitigation in mitigations) + { + var pos = Math.DivRem(i, count, out var remainder); + i++; + Effectiveness effectiveness; + if (mitigation.Effectiveness == 0) + effectiveness = Effectiveness.Minor; + else + switch (pos) + { + case 0: + effectiveness = Effectiveness.Major; + break; + case 1: + effectiveness = Effectiveness.Average; + break; + default: + effectiveness = Effectiveness.Minor; + break; + } + + list.Add(mitigation.MitigationId, effectiveness); + } + + result = list; + } + + return result; + } + + public IDictionary GetProjectedThreatTypesResidualRisk(IThreatModel model, IEnumerable mitigations) + { + IDictionary result = null; + + var threatEvents = model.GetThreatEvents()?.ToArray(); + if (threatEvents?.Any() ?? false) + { + var dict = new Dictionary(); + + foreach (var threatEvent in threatEvents) + { + var mitigationsStrength = threatEvent.Mitigations? + .Where(x => (x.Status != MitigationStatus.Existing) && + (x.Status != MitigationStatus.Implemented) && + (mitigations?.Any(y => y == x.MitigationId) ?? false)) + .Sum(x => x.StrengthId); + var newSeverity = model.GetMappedSeverity( + Convert.ToInt32(((float)threatEvent.SeverityId) * + (100f - Math.Min((mitigationsStrength ?? 0), 100f)) / 100f)); + + if (newSeverity != null) + { + var newSeverityId = newSeverity.Id == 0 ? (int) DefaultSeverity.Info : newSeverity.Id; + if (dict.ContainsKey(threatEvent.ThreatTypeId)) + { + if (dict[threatEvent.ThreatTypeId] < newSeverityId) + dict[threatEvent.ThreatTypeId] = newSeverityId; + } + else + { + dict[threatEvent.ThreatTypeId] = newSeverityId; + } + } + } + + result = dict; + } + + return result; + } + + private int CalculateMitigationEffectiveness([NotNull] IThreatModel model, [NotNull] IMitigation mitigation) + { + int result = 0; + + var threats = model.GetThreatEvents()? + .Where(x => x.Mitigations?.Any(y => + y.MitigationId == mitigation.Id && y.Status != MitigationStatus.Implemented && + y.Status != MitigationStatus.Existing) ?? false) + .ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + var threatMitigation = threat.Mitigations.First(x => x.MitigationId == mitigation.Id); + result += threatMitigation.StrengthId * threat.SeverityId; + } + } + + return result; + } + + public IEnumerable GetAcceptableRiskParameters([NotNull] IThreatModel model) + { + return model.Severities?.Where(x => x.Visible && x.Id > 0) + .Select(x => $"Maximum {x.Name} Severity Threat Events count").ToArray(); + } + + public float GetAcceptableRisk([NotNull] IThreatModel model, + IDictionary parameters, float infinite) + { + float result = 0f; + + var severities = model.Severities?.ToArray(); + if ((parameters?.Any() ?? false) && (severities?.Any() ?? false)) + { + var regex = new Regex("Maximum (?'severity'.*) Severity Threat Events count"); + foreach (var parameter in parameters) + { + var match = regex.Match(parameter.Key); + if (match.Success) + { + var severityName = match.Groups["severity"].Value; + var severity = severities.FirstOrDefault(x => string.CompareOrdinal(x.Name, severityName) == 0); + if (severity != null) + { + result += severity.Id * + (parameter.Value < 0 ? infinite : Math.Min(parameter.Value, infinite)); + } + } + } + } + + return result; + } + + public override string ToString() + { + return this.GetExtensionLabel(); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/AssociatedDiagramPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/AssociatedDiagramPropertySchemaManager.cs new file mode 100644 index 00000000..e098ed8b --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/AssociatedDiagramPropertySchemaManager.cs @@ -0,0 +1,57 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class AssociatedDiagramPropertySchemaManager + { + private const string SchemaName = "Associated Diagram for Entities"; + + private readonly IThreatModel _model; + + public AssociatedDiagramPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.Entity; + result.AutoApply = true; + result.Priority = 10; + result.Visible = true; + result.System = true; + result.Description = Resources.AssociatedDiagramPropertySchemaDescription; + } + + return result; + } + + public IPropertyType GetAssociatedDiagramIdPropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType("Associated Diagram"); + if (result == null) + { + result = + schema.AddPropertyType("Associated Diagram", PropertyValueType.IdentityReference); + result.Visible = true; + result.Description = Resources.AssociatedDiagram; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ModelConfigPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ModelConfigPropertySchemaManager.cs new file mode 100644 index 00000000..53423a67 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ModelConfigPropertySchemaManager.cs @@ -0,0 +1,55 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class ModelConfigPropertySchemaManager + { + private const string SchemaName = "Standard Extensions Configuration"; + + private readonly IThreatModel _model; + + public ModelConfigPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.ThreatModel; + result.AutoApply = true; + result.Priority = 10; + result.Visible = false; + result.System = true; + result.Description = Resources.ThreatModelConfigPropertySchemaDescription; + } + + var horizontalSpacing = result.GetPropertyType("Diagram Layout Horizontal Spacing"); + if (horizontalSpacing == null) + { + horizontalSpacing = + result.AddPropertyType("Diagram Layout Horizontal Spacing", PropertyValueType.Integer); + horizontalSpacing.Visible = false; + horizontalSpacing.Description = Resources.PropertyHorizontalSpacing; + } + + var verticalSpacing = result.GetPropertyType("Diagram Layout Vertical Spacing"); + if (verticalSpacing == null) + { + verticalSpacing = + result.AddPropertyType("Diagram Layout Vertical Spacing", PropertyValueType.Integer); + verticalSpacing.Visible = false; + verticalSpacing.Description = Resources.PropertyVerticalSpacing; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ReportingConfigPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ReportingConfigPropertySchemaManager.cs new file mode 100644 index 00000000..1fc33234 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ReportingConfigPropertySchemaManager.cs @@ -0,0 +1,61 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class ReportingConfigPropertySchemaManager + { + private const string SchemaName = "Reporting Extensions Configuration"; + + private readonly IThreatModel _model; + + public ReportingConfigPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.ThreatModel; + result.AutoApply = true; + result.Priority = 10; + result.Visible = false; + result.System = true; + result.Description = Resources.ReportingConfigPropertySchemaDescription; + } + + var excelSelectedFields = result.GetPropertyType("ExcelSelectedFields"); + if (excelSelectedFields == null) + { + excelSelectedFields = result.AddPropertyType("ExcelSelectedFields", PropertyValueType.Array); + excelSelectedFields.Visible = false; + excelSelectedFields.Description = Resources.PropertyExcelSelectedFields; + } + + var wordDocumentPath = result.GetPropertyType("WordDocumentPath"); + if (wordDocumentPath == null) + { + wordDocumentPath = result.AddPropertyType("WordDocumentPath", PropertyValueType.SingleLineString); + wordDocumentPath.Visible = false; + wordDocumentPath.Description = Resources.PropertyWordDocumentPath; + } + + var wordSections = result.GetPropertyType("WordSections"); + if (wordSections == null) + { + wordSections = result.AddPropertyType("WordSections", PropertyValueType.JsonSerializableObject); + wordSections.Visible = false; + wordSections.Description = Resources.PropertyWordSections; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorConfiguration.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorConfiguration.cs new file mode 100644 index 00000000..8259f7fe --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorConfiguration.cs @@ -0,0 +1,15 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace ThreatsManager.Extensions.Schemas +{ + /// + /// Configuration of the Residual Risk Estimator. + /// + [JsonObject(MemberSerialization.OptIn)] + public class ResidualRiskEstimatorConfiguration + { + [JsonProperty("parameters")] + public List Parameters { get; set; } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorParameter.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorParameter.cs new file mode 100644 index 00000000..446b981a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorParameter.cs @@ -0,0 +1,17 @@ +using Newtonsoft.Json; + +namespace ThreatsManager.Extensions.Schemas +{ + /// + /// Residual Risk Estimator Configuration parameter. + /// + [JsonObject(MemberSerialization.OptIn)] + public class ResidualRiskEstimatorParameter + { + [JsonProperty("name")] + public string Name { get; set; } + + [JsonProperty("value")] + public float Value { get; set; } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorPropertySchemaManager.cs new file mode 100644 index 00000000..06944613 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ResidualRiskEstimatorPropertySchemaManager.cs @@ -0,0 +1,225 @@ +using System.Collections.Generic; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.Schemas +{ + public class ResidualRiskEstimatorPropertySchemaManager + { + private const string SchemaName = "Residual Risk Estimator Configuration"; + + private readonly IThreatModel _model; + + public ResidualRiskEstimatorPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.ThreatModel; + result.AutoApply = false; + result.Priority = 100; + result.Visible = false; + result.System = true; + result.Description = Resources.ResidualRiskEstimatorConfigurationPropertySchemaDescription; + } + + return result; + } + + public IPropertyType GetSelectedEstimatorIdPropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType("Selected Estimator"); + if (result == null) + { + result = + schema.AddPropertyType("Selected Estimator", PropertyValueType.SingleLineString); + result.Visible = false; + result.Description = "Extension Id of the Selected Residual Risk Estimator"; + } + } + + return result; + } + + public IPropertyType GetParametersPropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType("Estimator Parameters"); + if (result == null) + { + result = + schema.AddPropertyType("Estimator Parameters", PropertyValueType.JsonSerializableObject); + result.Visible = false; + result.Description = "Parameters of the Selected Residual Risk Estimator"; + } + } + + return result; + } + + public IPropertyType GetInfinitePropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType("Infinite Cap"); + if (result == null) + { + result = + schema.AddPropertyType("Infinite Cap", PropertyValueType.Decimal); + result.Visible = false; + result.Description = "Infinite Cap for the selected Residual Risk Estimator"; + } + } + + return result; + } + + public IResidualRiskEstimator SelectedEstimator + { + get + { + IResidualRiskEstimator result = null; + + var propertyType = GetSelectedEstimatorIdPropertyType(); + if (propertyType != null) + { + var property = _model.GetProperty(propertyType); + if (property != null) + result = ExtensionUtils.GetExtension(property.StringValue); + } + + return result; + } + + set + { + var propertyType = GetSelectedEstimatorIdPropertyType(); + if (propertyType != null) + { + var property = _model.GetProperty(propertyType); + + if (property == null) + { + if (value != null) + { + _model.AddProperty(propertyType, value.GetExtensionId()); + } + } + else + { + property.StringValue = value?.GetExtensionId(); + } + } + } + } + + public IEnumerable Parameters + { + get + { + IEnumerable result = null; + + var propertyType = GetParametersPropertyType(); + if (propertyType != null) + { + if (_model.GetProperty(propertyType) is IPropertyJsonSerializableObject jsonSerializableObject && + jsonSerializableObject.Value is ResidualRiskEstimatorConfiguration config) + { + result = config.Parameters; + } + } + + return result; + } + + set + { + var propertyType = GetParametersPropertyType(); + if (propertyType != null) + { + if (_model.GetProperty(propertyType) is IPropertyJsonSerializableObject property) + { + if (value == null) + property.Value = null; + else + { + property.Value = new ResidualRiskEstimatorConfiguration() + { + Parameters = new List(value) + }; + } + } + else + { + if (value != null) + { + if (_model.AddProperty(propertyType, null) is IPropertyJsonSerializableObject p) + { + p.Value = new ResidualRiskEstimatorConfiguration() + { + Parameters = new List(value) + }; + } + } + } + } + } + } + + public float Infinite + { + get + { + float result = -1f; + + var propertyType = GetInfinitePropertyType(); + if (propertyType != null) + { + var property = _model.GetProperty(propertyType); + if (property is IPropertyDecimal decimalProperty) + result = (float) decimalProperty.Value; + } + + return result; + } + + set + { + var propertyType = GetInfinitePropertyType(); + if (propertyType != null) + { + var property = _model.GetProperty(propertyType); + + if (property == null) + property = _model.AddProperty(propertyType, null); + + if (property is IPropertyDecimal decimalProperty) + decimalProperty.Value = (decimal) value; + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/RoadmapPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/RoadmapPropertySchemaManager.cs new file mode 100644 index 00000000..b4146ecf --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/RoadmapPropertySchemaManager.cs @@ -0,0 +1,56 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class RoadmapPropertySchemaManager + { + private const string SchemaName = "Roadmap"; + private const string PropertyName = "Status"; + + private readonly IThreatModel _model; + + public RoadmapPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.Description = Properties.Resources.RoadmapPropertySchemaDescription; + result.Visible = false; + result.System = true; + result.Priority = 10; + result.AutoApply = false; + result.AppliesTo = Scope.Mitigation; + } + + return result; + } + + public IPropertyType GetPropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType(PropertyName); + if (result == null) + { + result = schema.AddPropertyType(PropertyName, PropertyValueType.SingleLineString); + result.Description = Resources.PropertyRoadmap; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/ThreatsPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ThreatsPropertySchemaManager.cs new file mode 100644 index 00000000..0903bcb0 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/ThreatsPropertySchemaManager.cs @@ -0,0 +1,46 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class ThreatsPropertySchemaManager + { + private const string SchemaName = "Threats"; + + private readonly IThreatModel _model; + + public ThreatsPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.ThreatType | Scope.ThreatEvent; + result.AutoApply = true; + result.Priority = 10; + result.Visible = true; + result.System = true; + result.RequiredExecutionMode = ExecutionMode.Expert; + result.Description = Properties.Resources.ThreatsPropertySchemaDescription; + } + + var keywords = result.GetPropertyType("Keywords"); + if (keywords == null) + { + keywords = result.AddPropertyType("Keywords", PropertyValueType.Tokens); + keywords.Visible = true; + keywords.Description = Resources.PropertyKeywords; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/Schemas/WordPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Extensions/Schemas/WordPropertySchemaManager.cs new file mode 100644 index 00000000..62ed21e5 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/Schemas/WordPropertySchemaManager.cs @@ -0,0 +1,53 @@ +using PostSharp.Patterns.Contracts; +using ThreatsManager.Extensions.Properties; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Extensions.Schemas +{ + public class WordPropertySchemaManager + { + private const string SchemaName = "Word"; + + private readonly IThreatModel _model; + + public WordPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public IPropertySchema GetSchema() + { + var result = _model.GetSchema(SchemaName, Properties.Resources.DefaultNamespace); + if (result == null) + { + result = _model.AddSchema(SchemaName, Properties.Resources.DefaultNamespace); + result.AppliesTo = Scope.ThreatModel; + result.AutoApply = true; + result.Priority = 10; + result.Visible = false; + result.System = true; + result.Description = Properties.Resources.WordPropertySchemaDescription; + } + + var ignoredListFields = result.GetPropertyType("IgnoredListFields"); + if (ignoredListFields == null) + { + ignoredListFields = result.AddPropertyType("IgnoredListFields", PropertyValueType.Array); + ignoredListFields.Visible = false; + ignoredListFields.Description = Resources.PropertyIgnoredListFields; + } + + var columnWidth = result.GetPropertyType("ColumnWidth"); + if (columnWidth == null) + { + columnWidth = result.AddPropertyType("ColumnWidth", PropertyValueType.Array); + columnWidth.Visible = false; + columnWidth.Description = Resources.PropertyColumnWidths; + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/AssignedThreatTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/AssignedThreatTypeCounter.cs new file mode 100644 index 00000000..b45259bf --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/AssignedThreatTypeCounter.cs @@ -0,0 +1,66 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "DF5ECD98-CF04-45A8-8025-A08EA02FEDA8")] + [ExportMetadata("Label", "Assigned Threat Type Counter Status Info Provider")] + [ExportMetadata("Priority", 27)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class AssignedThreatTypeCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + } + + public string CurrentStatus => + $"Assigned Threat Types: {_model.AssignedThreatTypes}"; + + public string Description => "Counter of the Threat Types which are associated to at least a Threat Event."; + + private void Update(IThreatEventsContainer container, IThreatEvent mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Assigned Threat Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventByTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventByTypeCounter.cs new file mode 100644 index 00000000..ec5d4c88 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventByTypeCounter.cs @@ -0,0 +1,88 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "14A6D89E-7B01-4093-8915-7EF3D1430D6C")] + [ExportMetadata("Label", "Critical Severity Threat Event by Type Counter Status Info Provider")] + [ExportMetadata("Priority", 45)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CriticalByTypeThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Critical by Type: {_model.CountThreatEventsByType((int)DefaultSeverity.Critical)}"; + + public string Description => "Counter of the Threat Events by Type which have been categorized as Critical.\nThis counter counts as a single instance all Threat Events belonging to the same Threat Type having Critical as top Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Critical Severity Threat Event by Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventCounter.cs new file mode 100644 index 00000000..35269fe9 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/CriticalThreatEventCounter.cs @@ -0,0 +1,88 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "FA4E8CC1-4EB9-459F-A766-358423765B8A")] + [ExportMetadata("Label", "Critical Severity Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 40)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class CriticalThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Critical: {_model.CountThreatEvents((int)DefaultSeverity.Critical)}"; + + public string Description => "Counter of the Threat Events which have been categorized as Critical."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Critical Severity Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataFlowCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataFlowCounter.cs new file mode 100644 index 00000000..5669a738 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataFlowCounter.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "1F1A0EC1-C0F1-46DF-957E-FE2F3FC7D84A")] + [ExportMetadata("Label", "Flow Counter Status Info Provider")] + [ExportMetadata("Priority", 13)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class DataFlowCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Flows: {_model?.DataFlows?.Count() ?? 0}"; + + public string Description => "Counter of the Flows defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IDataFlow) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Flow Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataStoreCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataStoreCounter.cs new file mode 100644 index 00000000..74cb4b1f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/DataStoreCounter.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "050DF7F2-0AD0-4F28-BEF4-8393358EF165")] + [ExportMetadata("Label", "Data Store Counter Status Info Provider")] + [ExportMetadata("Priority", 12)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class DataStoreCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Data Stores: {_model?.Entities?.OfType().Count() ?? 0}"; + + public string Description => "Counter of the Data Stores defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IDataStore) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Data Store Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ExternalInteractorCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ExternalInteractorCounter.cs new file mode 100644 index 00000000..461304aa --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ExternalInteractorCounter.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "DADF4373-6F4A-4943-ABC3-CA7B31CC1998")] + [ExportMetadata("Label", "External Interactor Counter Status Info Provider")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ExternalInteractorCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"External Interactors: {_model?.Entities?.OfType().Count() ?? 0}"; + + public string Description => "Counter of the External Interactors defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IExternalInteractor) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "External Interactors Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsCounter.cs new file mode 100644 index 00000000..0f8f1c4f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsCounter.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "FC6BC3D2-36C6-43E3-9558-A59B4C163981")] + [ExportMetadata("Label", "Fully Mitigated Threat Events Counter Status Info Provider")] + [ExportMetadata("Priority", 61)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FullyMitigatedThreatEventsCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Fully-mitigated Threat Events: {_model.FullyMitigatedThreatEvents}"; + + public string Description => "Threat Events that have been fully mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Fully-mitigated Threat Events"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsPerc.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsPerc.cs new file mode 100644 index 00000000..da967046 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatEventsPerc.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "0B7C32A9-5E69-42EE-A379-288FDF9BB9F2")] + [ExportMetadata("Label", "Fully Mitigated Threat Events Percentage Status Info Provider")] + [ExportMetadata("Priority", 60)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FullyMitigatedThreatEventsPerc : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Fully-mitigated Threat Events: {(((float) _model.FullyMitigatedThreatEvents * 100f) / ((float)_model.TotalThreatEvents)).ToString("F1")}%"; + + public string Description => "Percentage of the Threat Events that have been fully mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Fully-mitigated Threat Events Percentage"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatTypesCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatTypesCounter.cs new file mode 100644 index 00000000..b12462cf --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/FullyMitigatedThreatTypesCounter.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "5481B935-029B-4943-991D-BAE432757DF0")] + [ExportMetadata("Label", "Fully mitigated Threat Types Counter Status Info Provider")] + [ExportMetadata("Priority", 29)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FullyMitigatedThreatTypesCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += ChildCreated; + _model.ChildRemoved += ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + } + } + } + + public string CurrentStatus => + $"Fully-mitigated Threat Types: {_model.FullyMitigatedThreatTypes}"; + + public string Description => "Counter of the Threat Types having full Mitigations."; + + private void ChildCreated(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void ChildRemoved(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void Update(IThreatTypeMitigationsContainer arg1, IThreatTypeMitigation arg2) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Fully mitigated Threat Type Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= ChildCreated; + _model.ChildRemoved -= ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + } + } + + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventByTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventByTypeCounter.cs new file mode 100644 index 00000000..b4622715 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventByTypeCounter.cs @@ -0,0 +1,88 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "3A188FDC-1DED-489D-B3E3-B046B9E0501C")] + [ExportMetadata("Label", "High Severity Threat Event by Type Counter Status Info Provider")] + [ExportMetadata("Priority", 46)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class HighByTypeThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"High by Type: {_model.CountThreatEventsByType((int)DefaultSeverity.High)}"; + + public string Description => "Counter of the Threat Events by Type which have been categorized as High Severity.\nThis counter counts as a single instance all Threat Events belonging to the same Threat Type having High as top Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "High Severity Threat Event by Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventCounter.cs new file mode 100644 index 00000000..46c8402f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/HighThreatEventCounter.cs @@ -0,0 +1,88 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "ACD8E13F-8F32-42D2-80BC-9C0C3ECBCBC9")] + [ExportMetadata("Label", "High Severity Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 41)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class HighThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"High: {_model.CountThreatEvents((int)DefaultSeverity.High)}"; + + public string Description => "Counter of the Threat Events which have been categorized as High Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "High Severity Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventByTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventByTypeCounter.cs new file mode 100644 index 00000000..87bbfa2a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventByTypeCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "C0C62CD7-2146-45D7-AB3D-EA2C9E1FA3E5")] + [ExportMetadata("Label", "Info Severity Threat Event by Type Counter Status Info Provider")] + [ExportMetadata("Priority", 49)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class InfoByTypeThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Info by Type: {_model.CountThreatEventsByType((int)DefaultSeverity.Info)}"; + + public string Description => "Counter of the Threat Events by Type which have been categorized as Info Severity.\nThis counter counts as a single instance all Threat Events belonging to the same Threat Type having Info as top Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Info Severity Threat Event by Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventCounter.cs new file mode 100644 index 00000000..7119b1ad --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/InfoThreatEventCounter.cs @@ -0,0 +1,88 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "5D7BB0EC-CEA0-4A37-86E9-06B690FFC333")] + [ExportMetadata("Label", "Info Severity Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 44)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class InfoThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Info: {_model.CountThreatEvents((int)DefaultSeverity.Info)}"; + + public string Description => "Counter of the Threat Events which have been categorized as Info Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Info Severity Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/KnownMitigationCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/KnownMitigationCounter.cs new file mode 100644 index 00000000..cddea134 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/KnownMitigationCounter.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "F6103ED2-6ECF-43D0-B47E-A08FB56E7A84")] + [ExportMetadata("Label", "Mitigation Counter Status Info Provider")] + [ExportMetadata("Priority", 21)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class KnownMitigationCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Known Mitigations: {_model?.Mitigations?.Count() ?? 0}"; + + public string Description => "Counter of the Known Mitigations defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IMitigation) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Known Mitigation Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventByTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventByTypeCounter.cs new file mode 100644 index 00000000..731d7008 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventByTypeCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "74FC9227-1574-474D-95DA-3017D9369BB7")] + [ExportMetadata("Label", "Low Severity Threat Event by Type Counter Status Info Provider")] + [ExportMetadata("Priority", 48)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class LowByTypeThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Low by Type: {_model.CountThreatEventsByType((int)DefaultSeverity.Low)}"; + + public string Description => "Counter of the Threat Events by Type which have been categorized as Low Severity.\nThis counter counts as a single instance all Threat Events belonging to the same Threat Type having Low as top Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Low Severity Threat Event by Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventCounter.cs new file mode 100644 index 00000000..eee3bde7 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/LowThreatEventCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "D9E2D0BA-8320-4E08-8A6B-368FFE407E7F")] + [ExportMetadata("Label", "Low Severity Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 43)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class LowThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Low: {_model.CountThreatEvents((int)DefaultSeverity.Low)}"; + + public string Description => "Counter of the Threat Events which have been categorized as Low Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Low Severity Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventByTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventByTypeCounter.cs new file mode 100644 index 00000000..11c7ef84 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventByTypeCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "D36928F8-6175-4CD9-8222-1B19F9F49AD0")] + [ExportMetadata("Label", "Medium Severity Threat Event by Type Counter Status Info Provider")] + [ExportMetadata("Priority", 47)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class MediumByTypeThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Medium by Type: {_model.CountThreatEventsByType((int)DefaultSeverity.Medium)}"; + + public string Description => "Counter of the Threat Events by Type which have been categorized as Medium.\nThis counter counts as a single instance all Threat Events belonging to the same Threat Type having Medium as top Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Medium Severity Threat Event by Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventCounter.cs new file mode 100644 index 00000000..d366da68 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MediumThreatEventCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "3F64310D-A38E-4689-9564-FAB9DFEA61FD")] + [ExportMetadata("Label", "Medium Severity Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 42)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class MediumThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + + var modelTe = _model.ThreatEvents?.ToArray(); + if (modelTe?.Any() ?? false) + { + foreach (var te1 in modelTe) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)te1).PropertyChanged += OnPropertyChanged; + } + } + } + + private void OnPropertyChanged(object sender, PropertyChangedEventArgs e) + { + if (sender is IThreatEvent) + { + if (e.PropertyName == "Severity") UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + public string CurrentStatus => + $"Medium: {_model.CountThreatEvents((int)DefaultSeverity.Medium)}"; + + public string Description => "Counter of the Threat Events which have been categorized as Medium Severity."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + // ReSharper disable once SuspiciousTypeConversion.Global + ((INotifyPropertyChanged)threatEvent).PropertyChanged += OnPropertyChanged; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Medium Severity Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MitigationCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MitigationCounter.cs new file mode 100644 index 00000000..303ddb30 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/MitigationCounter.cs @@ -0,0 +1,89 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "3C0D4BF7-0651-4409-AE98-82F8617BD6DA")] + [ExportMetadata("Label", "Mitigation Counter Status Info Provider")] + [ExportMetadata("Priority", 35)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class MitigationCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Mitigations: {CountMitigations()}"; + + public string Description => "Counter of the Mitigations which have been applied.\nThis counter will count multiple times any Known Mitigation which has been applied to multiple Threat Events."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Mitigation Counter"; + } + + private int CountMitigations() + { + return (_model.ThreatEvents?.Sum(x => x.Mitigations?.Count() ?? 0) ?? 0) + + (_model.Entities?.Sum(x => x.ThreatEvents?.Sum(y => y.Mitigations?.Count() ?? 0) ?? 0) ?? 0) + + (_model.DataFlows?.Sum(x => x.ThreatEvents?.Sum(y => y.Mitigations?.Count() ?? 0) ?? 0) ?? 0); + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsCounter.cs new file mode 100644 index 00000000..4704e082 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsCounter.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "3E723A65-69EB-489B-9538-D6F664CAC892")] + [ExportMetadata("Label", "Not Mitigated Threat Events Counter Status Info Provider")] + [ExportMetadata("Priority", 65)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NotMitigatedThreatEventsCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Not mitigated Threat Events: {_model.NotMitigatedThreatEvents}"; + + public string Description => "Threat Events that have not been mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Not mitigated Threat Events"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsPerc.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsPerc.cs new file mode 100644 index 00000000..76e42edb --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatEventsPerc.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "E2D450B9-A70F-433F-878D-51CF99B4D11E")] + [ExportMetadata("Label", "Not Mitigated Threat Events Percentage Status Info Provider")] + [ExportMetadata("Priority", 64)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NotMitigatedThreatEventsPerc : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Not mitigated Threat Events: {(((float) _model.NotMitigatedThreatEvents * 100f) / ((float)_model.TotalThreatEvents)).ToString("F1")}%"; + + public string Description => "Percentage of the Threat Events that have not been mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Not mitigated Threat Events Percentage"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatTypesCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatTypesCounter.cs new file mode 100644 index 00000000..9157c407 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/NotMitigatedThreatTypesCounter.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "2EF6DB5F-5DEB-4166-8C5B-44B6DE126E2A")] + [ExportMetadata("Label", "Not mitigated Threat Types Counter Status Info Provider")] + [ExportMetadata("Priority", 31)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NotMitigatedThreatTypesCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += ChildCreated; + _model.ChildRemoved += ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + } + } + } + + public string CurrentStatus => + $"Not mitigated Threat Types: {_model.NotMitigatedThreatTypes}"; + + public string Description => "Counter of the Threat Types having no Mitigation."; + + private void ChildCreated(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void ChildRemoved(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void Update(IThreatTypeMitigationsContainer arg1, IThreatTypeMitigation arg2) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Not mitigated Threat Type Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= ChildCreated; + _model.ChildRemoved -= ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + } + } + + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsCounter.cs new file mode 100644 index 00000000..8c9b3ca3 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsCounter.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "DACE4940-F5E0-459C-9751-073400DF5358")] + [ExportMetadata("Label", "Partially Mitigated Threat Events Counter Status Info Provider")] + [ExportMetadata("Priority", 63)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PartiallyMitigatedThreatEventsCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Partially-mitigated Threat Events: {_model.PartiallyMitigatedThreatEvents}"; + + public string Description => "Threat Events that have been partially mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Partially-mitigated Threat Events"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsPerc.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsPerc.cs new file mode 100644 index 00000000..71de1235 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatEventsPerc.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "87CB6E6F-D0EC-4D60-AC97-0CA3459B13BA")] + [ExportMetadata("Label", "Partially Mitigated Threat Events Percentage Status Info Provider")] + [ExportMetadata("Priority", 62)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PartiallyMitigatedThreatEventsPerc : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Partially-mitigated Threat Events: {(((float) _model.PartiallyMitigatedThreatEvents * 100f) / ((float)_model.TotalThreatEvents)).ToString("F1")}%"; + + public string Description => "Percentage of the Threat Events that have been partially mitigated."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Partially-mitigated Threat Events Percentage"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatTypesCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatTypesCounter.cs new file mode 100644 index 00000000..115c4634 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/PartiallyMitigatedThreatTypesCounter.cs @@ -0,0 +1,100 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "A4ADAC0C-46BB-4306-925C-C09CA4976E83")] + [ExportMetadata("Label", "Partially mitigated Threat Types Counter Status Info Provider")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PartiallyMitigatedThreatTypesCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += ChildCreated; + _model.ChildRemoved += ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + } + } + } + + public string CurrentStatus => + $"Partially-mitigated Threat Types: {_model.PartiallyMitigatedThreatTypes}"; + + public string Description => "Counter of the Threat Types having partial mitigations."; + + private void ChildCreated(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded += Update; + threat.ThreatTypeMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void ChildRemoved(IIdentity identity) + { + if (identity is IThreatType threat) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + } + + private void Update(IThreatTypeMitigationsContainer arg1, IThreatTypeMitigation arg2) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Partially-mitigated Threat Type Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= ChildCreated; + _model.ChildRemoved -= ChildRemoved; + + var threats = _model.ThreatTypes?.ToArray(); + if (threats?.Any() ?? false) + { + foreach (var threat in threats) + { + threat.ThreatTypeMitigationAdded -= Update; + threat.ThreatTypeMitigationRemoved -= Update; + } + } + + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ProcessCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ProcessCounter.cs new file mode 100644 index 00000000..609a4f23 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ProcessCounter.cs @@ -0,0 +1,61 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "82DF6644-1955-464A-A244-C395856B527B")] + [ExportMetadata("Label", "Process Counter Status Info Provider")] + [ExportMetadata("Priority", 11)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ProcessCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Processes: {_model?.Entities?.OfType().Count() ?? 0}"; + + public string Description => "Counter of the Processes defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IProcess) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Processes Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatEventCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatEventCounter.cs new file mode 100644 index 00000000..6f81dd6d --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatEventCounter.cs @@ -0,0 +1,67 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "2A01104E-E774-4AB9-8700-27F015CCADDE")] + [ExportMetadata("Label", "Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 25)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ThreatEventCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + } + + public string CurrentStatus => + $"Threat Events: {_model.TotalThreatEvents}"; + + public string Description => "Counter of the Threat Events defined in the Threat Model."; + + private void Update([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Threat Event Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatTypeCounter.cs new file mode 100644 index 00000000..72a24cf0 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/ThreatTypeCounter.cs @@ -0,0 +1,61 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "89B5883D-91F9-4C6B-8DBC-514C2A718079")] + [ExportMetadata("Label", "Threat Type Counter Status Info Provider")] + [ExportMetadata("Priority", 20)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ThreatTypeCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Threat Types: {_model?.ThreatTypes?.Count() ?? 0}"; + + public string Description => "Counter of the Threat Types defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is IThreatType) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Threat Type Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/TrustBoundaryCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/TrustBoundaryCounter.cs new file mode 100644 index 00000000..6c07d0c2 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/TrustBoundaryCounter.cs @@ -0,0 +1,60 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "731C499F-5FE8-412F-A1A9-A81921A8D15C")] + [ExportMetadata("Label", "Trust Boundary Counter Status Info Provider")] + [ExportMetadata("Priority", 14)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class TrustBoundaryCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ChildCreated += Update; + _model.ChildRemoved += Update; + } + + public string CurrentStatus => + $"Trust Boundaries: {_model?.Groups?.OfType().Count() ?? 0}"; + + public string Description => "Counter of the Trust Boundaries defined in the Threat Model."; + + private void Update(IIdentity obj) + { + if (obj is ITrustBoundary) + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Trust Boundary Counter"; + } + + public void Dispose() + { + _model.ChildCreated -= Update; + _model.ChildRemoved -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UnassignedThreatTypeCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UnassignedThreatTypeCounter.cs new file mode 100644 index 00000000..dd58e7bc --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UnassignedThreatTypeCounter.cs @@ -0,0 +1,67 @@ +using System; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "7C960B99-F1DD-4D94-A030-48BFEB11B927")] + [ExportMetadata("Label", "Threat Types with no associated Threat Event Counter Status Info Provider")] + [ExportMetadata("Priority", 28)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class UnassignedThreatTypeCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += Update; + _model.ThreatEventAddedToEntity += Update; + _model.ThreatEventAddedToDataFlow += Update; + _model.ThreatEventRemoved += Update; + _model.ThreatEventRemovedFromEntity += Update; + _model.ThreatEventRemovedFromDataFlow += Update; + } + + public string CurrentStatus => + $"Unassigned Threat Types: {(_model.ThreatTypes?.Count() ?? 0) - _model.AssignedThreatTypes}"; + + public string Description => "Counter of the Threat Types having no associated Threat Event."; + + private void Update(IThreatEventsContainer container, IThreatEvent mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Unassigned Threat Type Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= Update; + _model.ThreatEventAddedToEntity -= Update; + _model.ThreatEventAddedToDataFlow -= Update; + _model.ThreatEventRemoved -= Update; + _model.ThreatEventRemovedFromEntity -= Update; + _model.ThreatEventRemovedFromDataFlow -= Update; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UniqueMitigationCounter.cs b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UniqueMitigationCounter.cs new file mode 100644 index 00000000..591184a4 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/StatusInfoProviders/UniqueMitigationCounter.cs @@ -0,0 +1,80 @@ +using System; +using System.ComponentModel.Composition; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Extensions.StatusInfoProviders +{ + [Export(typeof(IStatusInfoProviderExtension))] + [ExportMetadata("Id", "9F9FC6E2-466D-4156-8BE7-E28ECC364E03")] + [ExportMetadata("Label", "Unique Mitigation Counter Status Info Provider")] + [ExportMetadata("Priority", 36)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class UniqueMitigationCounter : IStatusInfoProviderExtension + { + private IThreatModel _model; + + public event Action UpdateInfo; + + public void Initialize([NotNull] IThreatModel model) + { + if (_model != null) + { + Dispose(); + } + + _model = model; + _model.ThreatEventAdded += ThreatEventAdded; + _model.ThreatEventAddedToEntity += ThreatEventAdded; + _model.ThreatEventAddedToDataFlow += ThreatEventAdded; + _model.ThreatEventRemoved += ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity += ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow += ThreatEventRemoved; + } + + public string CurrentStatus => + $"Unique Mitigations: {_model.UniqueMitigations}"; + + public string Description => "Counter of the unique Mitigations which have been applied.\nThis counter will count a single instance even if the same Mitigation has been applied to multiple Threat Events."; + + private void ThreatEventAdded([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded += Update; + threatEvent.ThreatEventMitigationRemoved += Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void ThreatEventRemoved([NotNull] IThreatEventsContainer container, [NotNull] IThreatEvent threatEvent) + { + threatEvent.ThreatEventMitigationAdded -= Update; + threatEvent.ThreatEventMitigationRemoved -= Update; + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + private void Update(IThreatEventMitigationsContainer container, IThreatEventMitigation mitigation) + { + UpdateInfo?.Invoke(this.GetExtensionId(), CurrentStatus); + } + + public override string ToString() + { + return "Unique Mitigation Counter"; + } + + public void Dispose() + { + _model.ThreatEventAdded -= ThreatEventAdded; + _model.ThreatEventAddedToEntity -= ThreatEventAdded; + _model.ThreatEventAddedToDataFlow -= ThreatEventAdded; + _model.ThreatEventRemoved -= ThreatEventRemoved; + _model.ThreatEventRemovedFromEntity -= ThreatEventRemoved; + _model.ThreatEventRemovedFromDataFlow -= ThreatEventRemoved; + _model = null; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Extensions/ThreatsManager.Extensions.csproj b/Sources/Extensions/ThreatsManager.Extensions/ThreatsManager.Extensions.csproj new file mode 100644 index 00000000..8c591f77 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Extensions/ThreatsManager.Extensions.csproj @@ -0,0 +1,55 @@ + + + + netcoreapp3.1;net472 + Threats Manager Platform Extensions library. + 1.3.3.0 + Simone Curzi + Simone Curzi + Threats Manager Platform + Copyright © Simone Curzi, 2018-2020. All Rights Reserved. + https://www.nuget.org/packages/ThreatsManager.Engine/ + https://github.com/simonec73/threatsmanager + 1.3.3.0 + 1.3.3 + true + ..\..\ThreatsManager.Engine\ThreatsManager.snk + + + + + + + + + + + + + + + ..\..\Resources\net472\ThreatsManager.Icons.dll + true + + + ..\..\Resources\netcoreapp3.1\ThreatsManager.Icons.dll + true + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/Sources/Extensions/ThreatsManager.MsTmt/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.MsTmt/ExtensionsContainer.cs index 111b7431..b8227c8a 100644 --- a/Sources/Extensions/ThreatsManager.MsTmt/ExtensionsContainer.cs +++ b/Sources/Extensions/ThreatsManager.MsTmt/ExtensionsContainer.cs @@ -1,3 +1,3 @@ using ThreatsManager.Interfaces; -[assembly: ExtensionsContainer("1.3.1")] \ No newline at end of file +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.csproj b/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.csproj index 6710bdb8..38eaf809 100644 --- a/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.csproj +++ b/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.csproj @@ -2,16 +2,16 @@ netcoreapp3.1;net472 - Threats Manager Platform Microsoft Threat Modeling Tool Importmport library. - 1.3.1.0 + Threats Manager Platform Microsoft Threat Modeling Tool Import library. + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Engine/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 true ..\..\ThreatsManager.Engine\ThreatsManager.snk diff --git a/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.sln b/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.sln deleted file mode 100644 index d2a13b5e..00000000 --- a/Sources/Extensions/ThreatsManager.MsTmt/ThreatsManager.MsTmt.sln +++ /dev/null @@ -1,43 +0,0 @@ - -Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio Version 16 -VisualStudioVersion = 16.0.30413.136 -MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ThreatsManager.MsTmt", "ThreatsManager.MsTmt.csproj", "{8284D400-317B-42B9-B379-A6BF44D848FC}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.AutoThreatGeneration", "..\ThreatsManager.AutoThreatGeneration\ThreatsManager.AutoThreatGeneration.csproj", "{4B85F87F-71FC-42C2-99B8-5303B45231A8}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Interfaces", "..\..\ThreatsManager.Interfaces\ThreatsManager.Interfaces.csproj", "{4A9362DE-7DC1-4D53-BA26-0ED37A6084E5}" -EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ThreatsManager.Utilities", "..\..\ThreatsManager.Utilities\ThreatsManager.Utilities.csproj", "{D0D1CA1F-3151-45E5-AE57-F176545C8E91}" -EndProject -Global - GlobalSection(SolutionConfigurationPlatforms) = preSolution - Debug|Any CPU = Debug|Any CPU - Release|Any CPU = Release|Any CPU - EndGlobalSection - GlobalSection(ProjectConfigurationPlatforms) = postSolution - {8284D400-317B-42B9-B379-A6BF44D848FC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {8284D400-317B-42B9-B379-A6BF44D848FC}.Debug|Any CPU.Build.0 = Debug|Any CPU - {8284D400-317B-42B9-B379-A6BF44D848FC}.Release|Any CPU.ActiveCfg = Release|Any CPU - {8284D400-317B-42B9-B379-A6BF44D848FC}.Release|Any CPU.Build.0 = Release|Any CPU - {4B85F87F-71FC-42C2-99B8-5303B45231A8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4B85F87F-71FC-42C2-99B8-5303B45231A8}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4B85F87F-71FC-42C2-99B8-5303B45231A8}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4B85F87F-71FC-42C2-99B8-5303B45231A8}.Release|Any CPU.Build.0 = Release|Any CPU - {4A9362DE-7DC1-4D53-BA26-0ED37A6084E5}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {4A9362DE-7DC1-4D53-BA26-0ED37A6084E5}.Debug|Any CPU.Build.0 = Debug|Any CPU - {4A9362DE-7DC1-4D53-BA26-0ED37A6084E5}.Release|Any CPU.ActiveCfg = Release|Any CPU - {4A9362DE-7DC1-4D53-BA26-0ED37A6084E5}.Release|Any CPU.Build.0 = Release|Any CPU - {D0D1CA1F-3151-45E5-AE57-F176545C8E91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {D0D1CA1F-3151-45E5-AE57-F176545C8E91}.Debug|Any CPU.Build.0 = Debug|Any CPU - {D0D1CA1F-3151-45E5-AE57-F176545C8E91}.Release|Any CPU.ActiveCfg = Release|Any CPU - {D0D1CA1F-3151-45E5-AE57-F176545C8E91}.Release|Any CPU.Build.0 = Release|Any CPU - EndGlobalSection - GlobalSection(SolutionProperties) = preSolution - HideSolutionNode = FALSE - EndGlobalSection - GlobalSection(ExtensibilityGlobals) = postSolution - SolutionGuid = {CFB2BDD3-6CB1-4912-98A0-9ED0438ED205} - EndGlobalSection -EndGlobal diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/EncryptedFilePackageManager.cs b/Sources/Extensions/ThreatsManager.PackageManagers/EncryptedFilePackageManager.cs new file mode 100644 index 00000000..eb6d071d --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/EncryptedFilePackageManager.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Security; +using System.Security.Cryptography.X509Certificates; +using ThreatsManager.Interfaces; +using ThreatsManager.Packaging; +using ThreatsManager.Interfaces.Exceptions; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Utilities; +using ThreatsManager.Utilities.Exceptions; + +namespace ThreatsManager.PackageManagers +{ + [Export(typeof(IPackageManager))] + [ExportMetadata("Id", "C3E6420A-296D-4859-99BD-6045D45A20E3")] + [ExportMetadata("Label", "Encrypted File Package Manager")] + [ExportMetadata("Priority", 11)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class EncryptedFilePackageManager : ISecurePackageManager + { + private const string ThreatModelFile = "threatmodel.json"; + + private IProtectionData _protectionData; + + public LocationType SupportedLocations => LocationType.FileSystem; + + public ProtectionType RequiredProtection => ProtectionType.Password; + + public string GetFilter(LocationType locationType) + { + return "Secured Threat Model (*.tmx)|*.tmx"; + } + + public bool CanHandle(LocationType locationType, string location) + { + return SupportedLocations.HasFlag(locationType) && + string.Compare(Path.GetExtension(location), ".tmx", StringComparison.OrdinalIgnoreCase) == 0; + } + + public IThreatModel Load(LocationType locationType, string location) + { + throw new EncryptionRequiredException(RequiredProtection); + } + + public IThreatModel Load(LocationType locationType, string location, SecureString password) + { + IThreatModel result = null; + + if (File.Exists(location)) + { + var package = new Package(location); + + var threatModelContent = package.Read(ThreatModelFile, password); + if (threatModelContent != null) + { + result = ThreatModelManager.Deserialize(threatModelContent); + } + } + else + { + throw new FileNotFoundException(); + } + + return result; + } + + public IThreatModel Load(LocationType locationType, string location, X509Certificate2 certificate) + { + throw new UnsupportedEncryptionException(); + } + + public bool Save(IThreatModel model, LocationType locationType, string location) + { + throw new EncryptionRequiredException(RequiredProtection); + } + + public bool Save(IThreatModel model, LocationType locationType, string location, SecureString password) + { + bool result = false; + + if (model is IThreatModel tm) + { + var tmSerialized = ThreatModelManager.Serialize(tm); + + var package = Package.Create(location); + package.Add(ThreatModelFile, tmSerialized, password); + package.Save(); + + result = true; + } + + return result; + } + + public bool Save(IThreatModel model, LocationType locationType, string location, IEnumerable certificates) + { + throw new UnsupportedEncryptionException(); + } + } +} diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfo.cs b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfo.cs new file mode 100644 index 00000000..a0338add --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfo.cs @@ -0,0 +1,26 @@ +using Newtonsoft.Json; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.PackageManagers +{ + [JsonObject(MemberSerialization.OptIn)] + public class ExtensionInfo + { + public ExtensionInfo() + { + + } + + public ExtensionInfo([Required] string id, [Required] string label) + { + Id = id; + Label = label; + } + + [JsonProperty("id")] + public string Id { get; set; } + + [JsonProperty("label")] + public string Label { get; set; } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfoComparer.cs b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfoComparer.cs new file mode 100644 index 00000000..a416c492 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionInfoComparer.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; + +namespace ThreatsManager.PackageManagers +{ + public class ExtensionInfoComparer : IEqualityComparer + { + public bool Equals(ExtensionInfo x, ExtensionInfo y) + { + return (x == null && y == null) || + (x != null && y != null && string.CompareOrdinal(x.Id, y.Id) == 0); + } + + public int GetHashCode(ExtensionInfo obj) + { + return obj.Id.GetHashCode(); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsContainer.cs new file mode 100644 index 00000000..b8227c8a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsContainer.cs @@ -0,0 +1,3 @@ +using ThreatsManager.Interfaces; + +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsList.cs b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsList.cs new file mode 100644 index 00000000..029d2be8 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/ExtensionsList.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace ThreatsManager.PackageManagers +{ + [JsonObject(MemberSerialization.OptIn)] + public class ExtensionsList + { + [JsonProperty("extensions")] + public List Extensions { get; set; } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/JsonFilePackageManager.cs b/Sources/Extensions/ThreatsManager.PackageManagers/JsonFilePackageManager.cs new file mode 100644 index 00000000..3605f2d1 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/JsonFilePackageManager.cs @@ -0,0 +1,173 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Linq; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Utilities; +using ThreatsManager.Utilities.Exceptions; + +namespace ThreatsManager.PackageManagers +{ + [Export(typeof(IPackageManager))] + [ExportMetadata("Id", "FA6F6023-8369-4D2F-97C1-1EB5ED83DA21")] + [ExportMetadata("Label", "Json File Package Manager")] + [ExportMetadata("Priority", 15)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class JsonFilePackageManager : IPackageManager + { + public LocationType SupportedLocations => LocationType.FileSystem; + + public bool CanHandle(LocationType locationType, [Required] string location) + { + return SupportedLocations.HasFlag(locationType) && + string.Compare(Path.GetExtension(location), ".tmj", StringComparison.OrdinalIgnoreCase) == 0; + } + + public string GetFilter(LocationType locationType) + { + return "Json Threat Model (*.tmj)|*.tmj"; + } + + public string GetLatest(LocationType locationType, [Required] string location, out DateTime dateTime) + { + string result = null; + dateTime = DateTime.MinValue; + + if (CanHandle(locationType, location)) + { + var directory = Path.GetDirectoryName(location); + var filter = string.Concat(Path.GetFileNameWithoutExtension(location), "_??????????????", ".tmj"); + + if (!string.IsNullOrWhiteSpace(directory)) + { + result = Directory + .GetFiles(directory, filter, SearchOption.TopDirectoryOnly) + .OrderByDescending(x => x) + .FirstOrDefault(); + + if (result != null) + dateTime = GetDateTime(result); + } + } + + return result; + } + + + public IThreatModel Load(LocationType locationType, [Required] string location, + IEnumerable extensions, bool strict = true) + { + IThreatModel result = null; + + if (File.Exists(location)) + { + var threatModelContent = File.ReadAllBytes(location); + if (threatModelContent != null) + { + try + { + result = ThreatModelManager.Deserialize(threatModelContent, !strict); + } + catch (JsonSerializationException e) + { + throw new ThreatModelOpeningFailureException("A serialization issue has occurred.", e); + } + } + } + else + { + throw new FileNotFoundException("Unable to find the specified file.", location); + } + + return result; + } + + public bool Save([NotNull] IThreatModel model, LocationType locationType, [Required] string location, + bool autoAddDateTime, IEnumerable extensions, out string newLocation) + { + bool result = false; + newLocation = null; + + if (model is IThreatModel tm) + { + var tmSerialized = ThreatModelManager.Serialize(tm); + + newLocation = autoAddDateTime + ? Path.Combine(Path.GetDirectoryName(location), + $"{StripDateTimeSuffix(Path.GetFileNameWithoutExtension(location))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}{Path.GetExtension(location)}") + : location; + + File.WriteAllBytes(newLocation, tmSerialized); + + + result = true; + } + + return result; + } + + public void AutoCleanup(LocationType locationType, [Required] string location, [StrictlyPositive] int maxInstances) + { + if (CanHandle(locationType, location)) + { + var directory = Path.GetDirectoryName(location); + var filter = string.Concat(StripDateTimeSuffix(Path.GetFileNameWithoutExtension(location)), "_??????????????", ".tm"); + + if (!string.IsNullOrWhiteSpace(directory)) + { + var files = Directory.GetFiles(directory, filter, SearchOption.TopDirectoryOnly); + var orderedFiles = files.OrderByDescending(x => x).Skip(maxInstances); + + foreach (var file in orderedFiles) + { + File.Delete(file); + } + } + } + } + + private string StripDateTimeSuffix([Required] string text) + { + string result = text; + + Regex regex = new Regex("(_[0-9]{14})"); + var match = regex.Match(text); + if (match.Success) + { + var capture = match.Captures.OfType().FirstOrDefault(); + if (capture != null) + { + result = text.Replace(capture.Value, ""); + } + } + + return result; + } + + private DateTime GetDateTime([Required] string text) + { + DateTime result = DateTime.MinValue; + + Regex regex = new Regex("(_[0-9]{14})"); + var match = regex.Match(text); + if (match.Success) + { + var capture = match.Captures.OfType().FirstOrDefault(); + if (capture != null) + { + result = DateTime.ParseExact(capture.Value.Substring(1), "yyyyMMddHHmmss", + System.Globalization.CultureInfo.InvariantCulture); + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/PlainFilePackageManager.cs b/Sources/Extensions/ThreatsManager.PackageManagers/PlainFilePackageManager.cs new file mode 100644 index 00000000..3d052fb6 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/PlainFilePackageManager.cs @@ -0,0 +1,241 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.IO; +using System.Linq; +using System.Text; +using System.Text.RegularExpressions; +using Newtonsoft.Json; +using ThreatsManager.Packaging; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Utilities; +using ThreatsManager.Utilities.Exceptions; + +namespace ThreatsManager.PackageManagers +{ + [Export(typeof(IPackageManager))] + [ExportMetadata("Id", "84252804-27F2-46C0-91A7-8EB7BF57EE58")] + [ExportMetadata("Label", "File Package Manager")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PlainFilePackageManager : IPackageManager + { + private const string ThreatModelFile = "threatmodel.json"; + private const string ExtensionsFile = "extensions.json"; + + public LocationType SupportedLocations => LocationType.FileSystem; + + public bool CanHandle(LocationType locationType, [Required] string location) + { + return SupportedLocations.HasFlag(locationType) && + string.Compare(Path.GetExtension(location), ".tm", StringComparison.OrdinalIgnoreCase) == 0; + } + + public string GetFilter(LocationType locationType) + { + return "Threat Model (*.tm)|*.tm"; + } + + public string GetLatest(LocationType locationType, [Required] string location, out DateTime dateTime) + { + string result = null; + dateTime = DateTime.MinValue; + + if (CanHandle(locationType, location)) + { + var directory = Path.GetDirectoryName(location); + var filter = string.Concat(Path.GetFileNameWithoutExtension(location), "_??????????????", ".tm"); + + if (!string.IsNullOrWhiteSpace(directory)) + { + result = Directory + .GetFiles(directory, filter, SearchOption.TopDirectoryOnly) + .OrderByDescending(x => x) + .FirstOrDefault(); + + if (result != null) + dateTime = GetDateTime(result); + } + } + + return result; + } + + + public IThreatModel Load(LocationType locationType, [Required] string location, + IEnumerable extensions, bool strict = true) + { + IThreatModel result = null; + + if (File.Exists(location)) + { + var package = new Package(location); + + var threatModelContent = package.Read(ThreatModelFile); + if (threatModelContent != null) + { + try + { + result = ThreatModelManager.Deserialize(threatModelContent, !strict); + } + catch (JsonSerializationException e) + { + HandleJsonSerializationException(package, extensions, e); + throw; + } + } + } + else + { + throw new FileNotFoundException("Unable to find the specified file.", location); + } + + return result; + } + + public bool Save([NotNull] IThreatModel model, LocationType locationType, [Required] string location, + bool autoAddDateTime, IEnumerable extensions, out string newLocation) + { + bool result = false; + newLocation = null; + + if (model is IThreatModel tm) + { + var tmSerialized = ThreatModelManager.Serialize(tm); + var extList = new ExtensionsList + { + Extensions = + new List(extensions.Where(x => x != null).Select(x => new ExtensionInfo(x.Id, x.Label))) + }; + var extSerialized = Encoding.Unicode.GetBytes(JsonConvert.SerializeObject(extList, new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.None, + })); + + newLocation = autoAddDateTime + ? Path.Combine(Path.GetDirectoryName(location), + $"{StripDateTimeSuffix(Path.GetFileNameWithoutExtension(location))}_{DateTime.Now.ToString("yyyyMMddHHmmss")}{Path.GetExtension(location)}") + : location; + + var package = Package.Create(newLocation); + package.Add(ThreatModelFile, tmSerialized); + package.Add(ExtensionsFile, extSerialized); + package.Save(); + + result = true; + } + + return result; + } + + public void AutoCleanup(LocationType locationType, [Required] string location, [StrictlyPositive] int maxInstances) + { + if (CanHandle(locationType, location)) + { + var directory = Path.GetDirectoryName(location); + var filter = string.Concat(StripDateTimeSuffix(Path.GetFileNameWithoutExtension(location)), "_??????????????", ".tm"); + + if (!string.IsNullOrWhiteSpace(directory)) + { + var files = Directory.GetFiles(directory, filter, SearchOption.TopDirectoryOnly); + var orderedFiles = files.OrderByDescending(x => x).Skip(maxInstances); + + foreach (var file in orderedFiles) + { + File.Delete(file); + } + } + } + } + + private void HandleJsonSerializationException([NotNull] Package package, + IEnumerable extensions, + [NotNull] JsonSerializationException e) + { + byte[] extensionsContent = null; + + try + { + extensionsContent = package.Read(ExtensionsFile); + + } + catch + { + } + + if (extensionsContent?.Any() ?? false) + { + var storedExtensions = JsonConvert.DeserializeObject( + Encoding.Unicode.GetString(extensionsContent), new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.None, + }); + + var currentExtensions = extensions?.Select(x => new ExtensionInfo(x.Id, x.Label)).ToArray(); + + if (currentExtensions?.Any() ?? false) + { + var missingExtensions = + storedExtensions.Extensions.Except(currentExtensions, new ExtensionInfoComparer()) + .ToArray(); + + if (missingExtensions.Any()) + { + var builder = new StringBuilder(); + builder.AppendLine( + "A serialization issue has occurred, probably due to one or more of those missing Extensions:"); + foreach (var ext in missingExtensions) + { + builder.AppendLine($"- {ext.Label}"); + } + + throw new ThreatModelOpeningFailureException(builder.ToString(), e); + } + + throw new ThreatModelOpeningFailureException("A serialization issue has occurred.", e); + } + } + } + + private string StripDateTimeSuffix([Required] string text) + { + string result = text; + + Regex regex = new Regex("(_[0-9]{14})"); + var match = regex.Match(text); + if (match.Success) + { + var capture = match.Captures.OfType().FirstOrDefault(); + if (capture != null) + { + result = text.Replace(capture.Value, ""); + } + } + + return result; + } + + private DateTime GetDateTime([Required] string text) + { + DateTime result = DateTime.MinValue; + + Regex regex = new Regex("(_[0-9]{14})"); + var match = regex.Match(text); + if (match.Success) + { + var capture = match.Captures.OfType().FirstOrDefault(); + if (capture != null) + { + result = DateTime.ParseExact(capture.Value.Substring(1), "yyyyMMddHHmmss", + System.Globalization.CultureInfo.InvariantCulture); + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.PackageManagers/ThreatsManager.PackageManagers.csproj b/Sources/Extensions/ThreatsManager.PackageManagers/ThreatsManager.PackageManagers.csproj new file mode 100644 index 00000000..8b0ee369 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.PackageManagers/ThreatsManager.PackageManagers.csproj @@ -0,0 +1,34 @@ + + + + netcoreapp3.1;net472 + Threats Manager Platform Package Managers library. + 1.3.3.0 + Simone Curzi + Simone Curzi + Threats Manager Platform + Copyright © Simone Curzi, 2018-2020. All Rights Reserved. + https://www.nuget.org/packages/ThreatsManager.Engine/ + https://github.com/simonec73/threatsmanager + 1.3.3.0 + 1.3.3 + true + ..\..\ThreatsManager.Engine\ThreatsManager.snk + + + + + + + + + + + + + + + + + + diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/ComplexDiagrams.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/ComplexDiagrams.cs new file mode 100644 index 00000000..31c3f819 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/ComplexDiagrams.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "BF79DB1A-15D1-443D-AE1E-6BEA8137E64A")] + [ExportMetadata("Label", "Complex Diagrams Quality Analyzer")] + [ExportMetadata("Priority", 21)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class ComplexDiagrams : IQualityAnalyzer + { + public string Label => "Too Complex Diagrams"; + public string Description => "Diagrams with too many objects are not easily understood and shall be avoided."; + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.95; + minYellow = 0.97; + maxYellow = 1.58; + minRed = 1.60; + maxRed = 2; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var diagrams = model.Diagrams?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (diagrams?.Any() ?? false) + { + List list = new List(); + + foreach (var diagram in diagrams) + { + var count = (diagram?.Entities?.Count() ?? 0) + + (diagram?.Groups?.Count() ?? 0) + + (diagram?.Links?.Count() ?? 0); + if (count > 80) + { + list.Add(diagram); + result += 2.0; + } + else if (count > 60) + { + list.Add(diagram); + result += 1.5; + } + else if (count > 40) + { + list.Add(diagram); + result += 1.0; + } + } + + if (list.Any()) + instances = list; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/DefaultName.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/DefaultName.cs new file mode 100644 index 00000000..d070dddb --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/DefaultName.cs @@ -0,0 +1,138 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using System.Text.RegularExpressions; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "208AB31D-2B01-4BE2-B726-90896EE67C69")] + [ExportMetadata("Label", "Objects with Default Name Quality Analyzer")] + [ExportMetadata("Priority", 4)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class DefaultName : IQualityAnalyzer + { + public string Label => "Default Name Objects"; + public string Description => + "Objects with a default name should be considered a mistake because they do not allow to understand their meaning."; + + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.Groups?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var found = new List(); + + var entities = model.Entities?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + Regex eiRegex = null; + Regex pRegex = null; + Regex dsRegex = null; + Regex regex = null; + + foreach (var entity in entities) + { + if (entity is IExternalInteractor) + { + if (eiRegex == null) + eiRegex = new Regex($"{model.GetIdentityTypeName(entity)} [0-9]*"); + regex = eiRegex; + } else if (entity is IProcess) + { + if (pRegex == null) + pRegex = new Regex($"{model.GetIdentityTypeName(entity)} [0-9]*"); + regex = pRegex; + } if (entity is IDataStore) + { + if (dsRegex == null) + dsRegex = new Regex($"{model.GetIdentityTypeName(entity)} [0-9]*"); + regex = dsRegex; + } + + if (!string.IsNullOrWhiteSpace(entity.Name) && (regex?.Match(entity.Name).Success ?? false)) + found.Add(entity); + } + } + + var flows = model.DataFlows?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + if (string.CompareOrdinal(flow.Name, "Flow") == 0) + found.Add(flow); + } + } + + var groups = model.Groups?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (groups?.Any() ?? false) + { + Regex tbRegex = null; + + foreach (var group in groups) + { + if (tbRegex == null) + tbRegex = new Regex($"{model.GetIdentityTypeName(group)} [0-9]*"); + + if (!string.IsNullOrWhiteSpace(group.Name) && (tbRegex?.Match(group.Name).Success ?? false)) + found.Add(group); + } + } + + result = found.Count; + instances = found; + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/EquivalentEntities.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/EquivalentEntities.cs new file mode 100644 index 00000000..e1ec9634 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/EquivalentEntities.cs @@ -0,0 +1,288 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "A5516681-A026-44DA-84C5-EED00DE6BDA6")] + [ExportMetadata("Label", "Equivalent Entities Quality Analyzer")] + [ExportMetadata("Priority", 19)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class EquivalentEntities : IQualityAnalyzer + { + public string Label => "Equivalent Entities"; + + public string Description => + "Entities are Equivalent if they have the same Threats and Mitigations,\nand they are associated to equivalent Flows.\nEquivalent Entities should be avoided because they complicate the Threat Model unnecessarily.\nNote: Scenarios are not considered."; + + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Where(y => !isFalsePositive(this, y)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.25; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var entities = model.Entities?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + var flows = model.DataFlows?.ToArray(); + + if (flows?.Any() ?? false) + { + var found = new List(); + + foreach (var entityA in entities) + { + foreach (var entityB in entities) + { + if (entityA != entityB && AreEquivalent(entityA, entityB, flows)) + { + if (!found.Contains(entityA)) + found.Add(entityA); + if (!found.Contains(entityB)) + found.Add(entityB); + break; + } + } + } + + result = found.Count; + instances = found; + } + else + { + if (entities.Any()) + instances = entities; + result = entities.Length; + } + } + + return result; + } + + private bool AreEquivalent([NotNull] IEntity left, [NotNull] IEntity right, + [NotNull] IEnumerable flows) + { + bool result = false; + + if (left.GetEntityType() == right.GetEntityType()) + { + result = AreEquivalent(left, right) && + AreEquivalent(left, flows.Where(x => x.Source == left), + right, flows.Where(x => x.Source == right), false) && + AreEquivalent(left, flows.Where(x => x.Target == left), + right, flows.Where(x => x.Target == right), true); + } + + return result; + } + + private bool AreEquivalent([NotNull] IThreatEventsContainer left, [NotNull] IThreatEventsContainer right) + { + bool result = false; + + var leftThreats = left.ThreatEvents?.ToArray(); + var rightThreats = right.ThreatEvents?.ToArray(); + + if (leftThreats?.Any() ?? false) + { + if (rightThreats?.Any() ?? false) + { + if (leftThreats.Length == rightThreats.Length) + { + result = true; + + foreach (var threat in leftThreats) + { + var rightThreat = rightThreats.FirstOrDefault(x => x.ThreatTypeId == threat.ThreatTypeId); + if (rightThreat == null || !AreEquivalent(threat, rightThreat)) + { + result = false; + break; + } + } + } + } + } + else + { + if (!(rightThreats?.Any() ?? false)) + { + result = true; + } + } + + return result; + } + + private bool AreEquivalent([NotNull] IThreatEvent left, [NotNull] IThreatEvent right) + { + return (left.SeverityId == right.SeverityId) && + AreEquivalent(left.Mitigations, right.Mitigations); + } + + private bool AreEquivalent(IEnumerable left, + IEnumerable right) + { + bool result = false; + + if (left?.Any() ?? false) + { + if (right?.Any() ?? false) + { + if (left.Count() == right.Count()) + { + result = true; + + foreach (var mitigation in left) + { + var rightMitigation = right.FirstOrDefault(x => x.MitigationId == mitigation.MitigationId); + if (rightMitigation == null || + (mitigation.Status != rightMitigation.Status) || + (mitigation.StrengthId != rightMitigation.StrengthId) || + string.CompareOrdinal(mitigation.Directives, rightMitigation.Directives) != 0) + { + result = false; + break; + } + } + } + } + } + else + { + if (!(right?.Any() ?? false)) + { + result = true; + } + } + + return result; + } + + private bool AreEquivalent([NotNull] IEntity left, IEnumerable leftFlows, + [NotNull] IEntity right, IEnumerable rightFlows, bool incoming) + { + bool result = false; + + if (leftFlows?.Any() ?? false) + { + if (rightFlows?.Any() ?? false) + { + if (leftFlows.Count() == rightFlows.Count()) + { + result = true; + + foreach (var flow in leftFlows) + { + IDataFlow rightFlow = null; + if (incoming) + { + if (flow.Source is IEntity source) + { + rightFlow = rightFlows.FirstOrDefault(x => x.Source == source); + } + } + else + { + if (flow.Target is IEntity target) + { + rightFlow = rightFlows.FirstOrDefault(x => x.Target == target); + } + } + + if (rightFlow == null || + (flow.FlowType != rightFlow.FlowType) || + !AreEquivalent(flow, rightFlow)) + { + result = false; + break; + } + } + } + } + } + else + { + if (!(rightFlows?.Any() ?? false)) + { + result = true; + } + } + + return result; + } + + private bool AreEquivalentFlows([NotNull] IDataFlow left, [NotNull] IDataFlow right) + { + bool result = false; + + if (left.FlowType == right.FlowType) + { + result = AreEquivalent(left, right); + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenDataStores.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenDataStores.cs new file mode 100644 index 00000000..06edcfed --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenDataStores.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "DF2DB940-E3C4-44B2-A7B8-C14CAB1FCE80")] + [ExportMetadata("Label", "Flow Between Data Stores Quality Analyzer")] + [ExportMetadata("Priority", 15)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FlowBetweenDataStores : IQualityAnalyzer + { + public string Label => "Flow Between Data Stores"; + public string Description => "Flows between Data Stores must be avoided: a Process between them is in order."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var flows = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && + x.Source is IDataStore && x.Target is IDataStore) + .ToArray(); + + if (flows?.Any() ?? false) + { + result = flows.Length; + instances = flows; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenInteractors.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenInteractors.cs new file mode 100644 index 00000000..ad42568b --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowBetweenInteractors.cs @@ -0,0 +1,85 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "76E92DDA-D315-43E9-AB82-331F0460EBF3")] + [ExportMetadata("Label", "Flow Between Interactors Quality Analyzer")] + [ExportMetadata("Priority", 15)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FlowBetweenInteractors : IQualityAnalyzer + { + public string Label => "Flow Between External Interactors"; + public string Description => "Flows between External Interactors must be avoided, because they are out of scope."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var flows = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && + x.Source is IExternalInteractor && x.Target is IExternalInteractor) + .ToArray(); + + if (flows?.Any() ?? false) + { + result = flows.Length; + instances = flows; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowNoBoundary.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowNoBoundary.cs new file mode 100644 index 00000000..b82b3d6b --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/FlowNoBoundary.cs @@ -0,0 +1,104 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "B6D77089-F2E3-4175-B870-FA3333593A08")] + [ExportMetadata("Label", "Flow Missing Trust Boundary Quality Analyzer")] + [ExportMetadata("Priority", 17)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class FlowNoBoundary : IQualityAnalyzer + { + public string Label => "Flow Missing Trust Boundary"; + public string Description => "Flows between an External Interactor and a Process or Data Store must cross a Trust Boundary."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var list = new List(); + + var flowsSources = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && + x.Source is IExternalInteractor && + (x.Target is IProcess || x.Target is IDataStore) && + x.Source.ParentId == x.Target.ParentId) + .ToArray(); + if (flowsSources?.Any() ?? false) + { + list.AddRange(flowsSources); + } + + var flowsTargets = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && + x.Target is IExternalInteractor && + (x.Source is IProcess || x.Source is IDataStore) && + x.Source.ParentId == x.Target.ParentId) + .ToArray(); + if (flowsTargets?.Any() ?? false) + { + list.AddRange(flowsTargets); + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/IsolatedEntity.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/IsolatedEntity.cs new file mode 100644 index 00000000..aa59d809 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/IsolatedEntity.cs @@ -0,0 +1,100 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "A45D83AA-5DEF-4647-AC25-1D4EC8E76118")] + [ExportMetadata("Label", "Isolated Entities Quality Analyzer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class IsolatedEntity : IQualityAnalyzer + { + public string Label => "Isolated Entities"; + public string Description => "An Entity cannot be isolated.\nAdd Flows to connect it to other Entities."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var entities = model.Entities?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + var flows = model.DataFlows?.ToArray(); + + if (flows?.Any() ?? false) + { + List found = new List(); + + foreach (var entity in entities) + { + if (!flows.Any(x => x.SourceId == entity.Id || x.TargetId == entity.Id)) + found.Add(entity); + } + + result = found.Count; + instances = found; + } + else + { + if (entities.Any()) + instances = entities; + result = entities.Length; + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/Loops.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/Loops.cs new file mode 100644 index 00000000..af847a2f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/Loops.cs @@ -0,0 +1,101 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "8ED1AAA3-2A7A-45D8-A282-374317C5DE5F")] + [ExportMetadata("Label", "Loops Quality Analyzer")] + [ExportMetadata("Priority", 20)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class Loops : IQualityAnalyzer + { + public string Label => "Loops"; + public string Description => "Loops between two Entities should be avoided, but in some situation may be necessary.\nConsider the possibility to use Flow Type to assign the required semantics."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + var flows = model.DataFlows?.Where(x => !isFalsePositive(this, x)).ToArray(); + + if (flows?.Any() ?? false) + { + List found = new List(); + + foreach (var entity in entities) + { + var loopFlow = flows.FirstOrDefault(x => x.SourceId == entity.Id && + flows.Any(y => + y.SourceId == x.TargetId && y.TargetId == x.SourceId)); + if (loopFlow != null) + { + found.Add(loopFlow); + } + } + + result = found.Count; + if (found.Any()) + instances = found; + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/MissingDocumentation.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/MissingDocumentation.cs new file mode 100644 index 00000000..6068e9d7 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/MissingDocumentation.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "5477244B-BF14-4C2C-99AE-24C19F674058")] + [ExportMetadata("Label", "Missing Documentation Quality Analyzer")] + [ExportMetadata("Priority", 60)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class MissingDocumentation : IQualityAnalyzer + { + public string Label => "Missing Documentation"; + public string Description => "On average, most objects in the Threat Model should be documented.\nThe analyzer does not take in account Threat Type, Threat Events or Mitigations."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (isFalsePositive(this, model) ? 0 : 1) + + (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.Groups?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + if (string.IsNullOrWhiteSpace(model.Description) && !isFalsePositive(this, model)) + items.Add(model); + + AnalyzeContainer(model.Entities?.Where(x => !isFalsePositive(this, x)), items); + AnalyzeContainer(model.DataFlows?.Where(x => !isFalsePositive(this, x)), items); + AnalyzeContainer(model.Groups?.Where(x => !isFalsePositive(this, x)), items); + AnalyzeContainer(model.Diagrams?.Where(x => !isFalsePositive(this, x)), items); + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer(IEnumerable identities, [NotNull] IList list) + { + var items = identities?.ToArray(); + if (items?.Any() ?? false) + { + foreach (var item in items) + { + if (string.IsNullOrWhiteSpace(item.Description)) + list.Add(item); + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoDataStores.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoDataStores.cs new file mode 100644 index 00000000..0f58efb6 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoDataStores.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "D765E1A3-F335-47E0-AE0A-1EA87FE6980A")] + [ExportMetadata("Label", "No Data Stores Quality Analyzer")] + [ExportMetadata("Priority", 28)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoDataStores : IQualityAnalyzer + { + public string Label => "Diagrams Missing Data Stores"; + + public string Description => + "Diagrams should have Data Stores, but occasionally they may be not necessary."; + + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.2; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.5; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var diagrams = model.Diagrams?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (diagrams?.Any() ?? false) + { + List list = new List(); + + foreach (var diagram in diagrams) + { + if (!(diagram.Entities?.Any(x => x.Identity is IDataStore) ?? false)) + { + list.Add(diagram); + } + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoExternalInteractors.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoExternalInteractors.cs new file mode 100644 index 00000000..baf17944 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoExternalInteractors.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "37F972FB-B069-4BB3-B95D-A7E6C9F4D6E0")] + [ExportMetadata("Label", "No External Interactors Quality Analyzer")] + [ExportMetadata("Priority", 26)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoExternalInteractors : IQualityAnalyzer + { + public string Label => "Diagrams Missing External Interactors"; + + public string Description => + "Diagrams should have External Interactors, but occasionally they may be not necessary."; + + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.2; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.5; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var diagrams = model.Diagrams?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (diagrams?.Any() ?? false) + { + List list = new List(); + + foreach (var diagram in diagrams) + { + if (!(diagram.Entities?.Any(x => x.Identity is IExternalInteractor) ?? false)) + { + list.Add(diagram); + } + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoMitigations.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoMitigations.cs new file mode 100644 index 00000000..e40bad74 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoMitigations.cs @@ -0,0 +1,119 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "9696B01B-F8EA-4034-8069-AC44DCAC8CB1")] + [ExportMetadata("Label", "Missing Mitigations Quality Analyzer")] + [ExportMetadata("Priority", 40)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoMitigations : IQualityAnalyzer + { + public string Label => "Missing Mitigations"; + public string Description => "All Threat Events should have at least an associated Mitigation."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Select(x => x.ThreatEvents?.Where(y => !isFalsePositive(this, y)).Count() ?? 0).Sum() ?? 0) + + (model.DataFlows?.Select(x => x.ThreatEvents?.Where(y => !isFalsePositive(this, y)).Count() ?? 0).Sum() ?? 0) + + (model.ThreatEvents?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + AnalyzeContainer(model, isFalsePositive, items); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, isFalsePositive, items); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, isFalsePositive, items); + } + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, + Func isFalsePositive, + [NotNull] IList list) + { + var threatEvents = container.ThreatEvents? + .Where(x => !isFalsePositive(this, x) && !(x.Mitigations?.Any() ?? false)).ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var te in threatEvents) + list.Add(te); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoName.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoName.cs new file mode 100644 index 00000000..6c9763dc --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoName.cs @@ -0,0 +1,98 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "7B677E73-6A14-4BCC-BE20-FA1B0F578FD9")] + [ExportMetadata("Label", "Objects with No Name Quality Analyzer")] + [ExportMetadata("Priority", 6)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoName : IQualityAnalyzer + { + public string Label => "No Name Objects"; + public string Description => + "Objects with no name should be considered a mistake because they do not allow to understand their meaning."; + + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var found = new List(); + + var entities = model.Entities?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + if (string.IsNullOrWhiteSpace(entity.Name)) + found.Add(entity); + } + } + + var flows = model.DataFlows?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + if (string.IsNullOrWhiteSpace(flow.Name)) + found.Add(flow); + } + } + + result = found.Count; + instances = found; + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoProcesses.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoProcesses.cs new file mode 100644 index 00000000..2e068748 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoProcesses.cs @@ -0,0 +1,95 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "617694EB-9DAF-48D5-90D6-7CBD33F670BC")] + [ExportMetadata("Label", "No Processes Quality Analyzer")] + [ExportMetadata("Priority", 24)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoProcesses : IQualityAnalyzer + { + public string Label => "Diagrams Missing Processes"; + + public string Description => + "Diagrams must have Processes, otherwise they would miss components to process information."; + + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var diagrams = model.Diagrams?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (diagrams?.Any() ?? false) + { + List list = new List(); + + foreach (var diagram in diagrams) + { + if (!(diagram.Entities?.Any(x => x.Identity is IProcess) ?? false)) + { + list.Add(diagram); + } + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoThreatEvents.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoThreatEvents.cs new file mode 100644 index 00000000..1cadeb0a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoThreatEvents.cs @@ -0,0 +1,113 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "B6EFBB56-C526-4ABE-99EC-50E312FBDCDD")] + [ExportMetadata("Label", "Missing Threat Events Quality Analyzer")] + [ExportMetadata("Priority", 30)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoThreatEvent : IQualityAnalyzer + { + public string Label => "Missing Threat Events"; + public string Description => "Most Entities and Flows should have at least an associated Threat Event."; + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (isFalsePositive(this, model) ? 0 : 1) + + (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + if (!(model.ThreatEvents?.Any() ?? false) && !isFalsePositive(this, model)) + items.Add(model); + + var entities = model.Entities? + .Where(x => !isFalsePositive(this, x) && !(x.ThreatEvents?.Any() ?? false)).ToArray(); + if (entities?.Any() ?? false) + { + items.AddRange(entities); + } + + var flows = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && !(x.ThreatEvents?.Any() ?? false)).ToArray(); + if (flows?.Any() ?? false) + { + items.AddRange(flows); + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoTrustBoundary.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoTrustBoundary.cs new file mode 100644 index 00000000..2c704935 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NoTrustBoundary.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Diagrams; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "83276980-842D-427F-944C-B3CABC9AC54E")] + [ExportMetadata("Label", "No Trust Boundary Quality Analyzer")] + [ExportMetadata("Priority", 16)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NoTrustBoundary : IQualityAnalyzer + { + public string Label => "Diagrams Missing Trust Boundaries"; + + public string Description => + "Diagrams should have Trust Boundaries, but occasionally they may be not necessary."; + + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Diagrams?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.2; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.5; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var diagrams = model.Diagrams?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (diagrams?.Any() ?? false) + { + List list = new List(); + + foreach (var diagram in diagrams) + { + if (!(diagram.Groups?.Any(x => x.Identity is ITrustBoundary) ?? false)) + { + list.Add(diagram); + } + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotEnoughControlTypes.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotEnoughControlTypes.cs new file mode 100644 index 00000000..a1ed06b9 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotEnoughControlTypes.cs @@ -0,0 +1,156 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "81BF8B32-C6C7-4E4E-A605-772907067A8A")] + [ExportMetadata("Label", "Not Enough Control Types Quality Analyzer")] + [ExportMetadata("Priority", 44)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NotEnoughControlTypes : IQualityAnalyzer + { + public string Label => "Not Enough Control Types"; + public string Description => "On average, Threat Events should have associated Mitigations belonging to multiple Control Types.\nThe analyzer takes in account only the Threat Events with more than a Mitigation."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Count() ?? 0) > 1).Count() ?? 0).Sum() ?? 0) + + (model.DataFlows?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Count() ?? 0) > 1).Count() ?? 0).Sum() ?? 0) + + (model.ThreatEvents?.Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Count() ?? 0) > 1).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + AnalyzeContainer(model, isFalsePositive, items); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, isFalsePositive, items); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, isFalsePositive, items); + } + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, + Func isFalsePositive, [NotNull] IList list) + { + var threatEvents = container.ThreatEvents? + .Where(x => !isFalsePositive(this, x)).ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var te in threatEvents) + { + var mitigations = te.Mitigations?.ToArray(); + if ((mitigations?.Length ?? 0) >= 2) + { + SecurityControlType? controlType = null; + bool found = false; + foreach (var m in mitigations) + { + if (!controlType.HasValue) + { + controlType = m.Mitigation?.ControlType; + } + else + { + if (controlType != m.Mitigation?.ControlType) + { + found = true; + break; + } + } + } + + if (!found) + list.Add(te); + } + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotInAnyDiagram.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotInAnyDiagram.cs new file mode 100644 index 00000000..27eb6b6d --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/NotInAnyDiagram.cs @@ -0,0 +1,137 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "CE92020F-11E4-4837-811B-F0FCB4C40467")] + [ExportMetadata("Label", "Objects Not In Any Diagram Quality Analyzer")] + [ExportMetadata("Priority", 22)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class NotInAnyDiagram : IQualityAnalyzer + { + public string Label => "Not In Any Diagram"; + public string Description => "Objects should be present in at least a Diagram."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.Groups?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.25; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + var entities = model.Entities? + .Where(x => !isFalsePositive(this, x) && !IsInDiagram(x, model)).ToArray(); + if (entities?.Any() ?? false) + { + items.AddRange(entities); + } + + var flows = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && !IsInDiagram(x, model)).ToArray(); + if (flows?.Any() ?? false) + { + items.AddRange(flows); + } + + var groups = model.Groups? + .Where(x => !isFalsePositive(this, x) && !IsInDiagram(x, model)).ToArray(); + if (groups?.Any() ?? false) + { + items.AddRange(groups); + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private bool IsInDiagram([NotNull] IEntity entity, [NotNull] IThreatModel model) + { + return model.Diagrams? + .Any(x => x.Entities?.Any(y => y.AssociatedId == entity.Id) ?? false) ?? false; + } + + private bool IsInDiagram([NotNull] IDataFlow flow, [NotNull] IThreatModel model) + { + return model.Diagrams? + .Any(x => x.Links?.Any(y => y.AssociatedId == flow.Id) ?? false) ?? false; + } + + private bool IsInDiagram([NotNull] IGroup group, [NotNull] IThreatModel model) + { + return model.Diagrams? + .Any(x => x.Groups?.Any(y => y.AssociatedId == group.Id) ?? false) ?? false; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/PartiallyConnectedStorage.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/PartiallyConnectedStorage.cs new file mode 100644 index 00000000..68aa9a9c --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/PartiallyConnectedStorage.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "DAEB7324-13B8-4827-8655-F295E96D99E4")] + [ExportMetadata("Label", "Partially Connected Data Store Quality Analyzer")] + [ExportMetadata("Priority", 12)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class PartiallyConnectedStorage : IQualityAnalyzer + { + public string Label => "Partially Connected Data Stores"; + public string Description => "Data Stores should both be used to save and read data.\nPlease check the Flow Type for the incoming Flows."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.Entities?.OfType() + .Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var entities = model.Entities?.OfType() + .Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + var flows = model.DataFlows?.ToArray(); + + if (flows?.Any() ?? false) + { + List found = new List(); + + foreach (var entity in entities) + { + var read = flows.Any(x => x.TargetId == entity.Id && + (x.FlowType == FlowType.Read || + x.FlowType == FlowType.ReadWriteCommand)); + var write = flows.Any(x => x.TargetId == entity.Id && + (x.FlowType == FlowType.WriteCommand || + x.FlowType == FlowType.ReadWriteCommand)); + + if (read ^ write) + found.Add(entity); + } + + result = found.Count; + if (found.Any()) + instances = found; + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/RedundantTrustBoundary.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/RedundantTrustBoundary.cs new file mode 100644 index 00000000..04fdeb62 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/RedundantTrustBoundary.cs @@ -0,0 +1,106 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "AA8E43D1-695D-49DB-930E-DB913A798126")] + [ExportMetadata("Label", "Redundant Trust Boundary Quality Analyzer")] + [ExportMetadata("Priority", 18)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class RedundantTrustBoundary : IQualityAnalyzer + { + public string Label => "Redundant Trust Boundaries"; + public string Description => "Nested Trust Boundaries may be redundant and should be avoided."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Groups?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.2; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.5; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var trustBoundaries = model.Groups?.OfType() + .Where(x => !isFalsePositive(this, x)).ToArray(); + if (trustBoundaries?.Any() ?? false) + { + var list = new List(); + + foreach (var trustBoundary in trustBoundaries) + { + var parent = trustBoundary.Parent; + if (parent != null && + !(parent.Entities?.Any() ?? false) && + (parent.Groups?.Count() ?? 0) == 1) + { + list.Add(trustBoundary); + } + } + + if (list.Any()) + { + instances = list; + result = list.Count; + } + } + + return result; + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/SameName.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SameName.cs new file mode 100644 index 00000000..c6dc3a0d --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SameName.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "EB78DFE2-B125-49EF-AFF6-D15BC553618F")] + [ExportMetadata("Label", "Objects with the Same Name Quality Analyzer")] + [ExportMetadata("Priority", 8)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class SameName : IQualityAnalyzer + { + public string Label => "Same Name Objects"; + + public string Description => + "Objects with the same name make more difficult to understand the model and thus shall be avoided."; + + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds(IThreatModel model, Func isFalsePositive, out double minRed, out double maxRed, out double minYellow, + out double maxYellow, out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.DataFlows?.Where(x => !isFalsePositive(this, x)).Count() ?? 0) + + (model.Groups?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + [SuppressMessage("ReSharper", "SimplifyLinqExpression")] + public double Analyze(IThreatModel model, Func isFalsePositive, out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var found = new List(); + + var entities = model.Entities?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + if (entities.Any(x => (entity.Id != x.Id) && + entity.GetEntityType() == x.GetEntityType() && + string.CompareOrdinal(entity.Name, x.Name) == 0) && + !found.OfType().Any(x => string.CompareOrdinal(x.Name, entity.Name) == 0)) + found.Add(entity); + } + } + + var flows = model.DataFlows?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + if (flows.Any(x => (flow.Id != x.Id) && + string.CompareOrdinal(flow.Name, x.Name) == 0) && + !found.OfType().Any(x => string.CompareOrdinal(x.Name, flow.Name) == 0)) + found.Add(flow); + } + } + + var groups = model.Groups?.Where(x => !isFalsePositive(this, x)).ToArray(); + if (groups?.Any() ?? false) + { + foreach (var group in groups) + { + if (groups.Any(x => (group.Id != x.Id) && + string.CompareOrdinal(group.Name, x.Name) == 0) && + !found.OfType().Any(x => string.CompareOrdinal(x.Name, group.Name) == 0)) + found.Add(group); + } + } + + result = found.Count; + instances = found; + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleMitigation.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleMitigation.cs new file mode 100644 index 00000000..bac4434f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleMitigation.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "8C5691D1-EA92-4311-8497-39EAEA94D4C4")] + [ExportMetadata("Label", "Single Mitigation Quality Analyzer")] + [ExportMetadata("Priority", 42)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class SingleMitigation : IQualityAnalyzer + { + public string Label => "Single Mitigation"; + public string Description => "On average, Threat Events should have more than only one associated Mitigation.\nThe analyzer takes in account only the Threat Events with at least a Mitigation."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Any() ?? false)).Count() ?? 0).Sum() ?? 0) + + (model.DataFlows?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Any() ?? false)).Count() ?? 0).Sum() ?? 0) + + (model.ThreatEvents?.Where(y => !isFalsePositive(this, y) && (y.Mitigations?.Any() ?? false)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + AnalyzeContainer(model, isFalsePositive, items); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, isFalsePositive, items); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, isFalsePositive, items); + } + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, + Func isFalsePositive, + [NotNull] IList list) + { + var threatEvents = container.ThreatEvents? + .Where(x => !isFalsePositive(this, x) && (x.Mitigations?.Count() ?? 0) == 1).ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var te in threatEvents) + list.Add(te); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleThreatEvent.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleThreatEvent.cs new file mode 100644 index 00000000..5b4fa72f --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/SingleThreatEvent.cs @@ -0,0 +1,115 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "A099EB5E-9768-45D5-89D3-B370A5D48109")] + [ExportMetadata("Label", "Single Threat Events Quality Analyzer")] + [ExportMetadata("Priority", 32)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class SingleThreatEvent : IQualityAnalyzer + { + public string Label => "Single Threat Event"; + public string Description => "On average, Entities and Flows should have more than only one associated Threat Event.\nThe analyzer takes in account only the objects with at least a Threat Event."; + public double MultiplicationFactor => 0.5; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (isFalsePositive(this, model) ? 0 : ((model.ThreatEvents?.Any() ?? false) ? 1 : 0)) + + (model.Entities? + .Where(y => !isFalsePositive(this, y) && (y.ThreatEvents?.Any() ?? false)).Count() ?? 0) + + (model.DataFlows? + .Where(y => !isFalsePositive(this, y) && (y.ThreatEvents?.Any() ?? false)).Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + if (!isFalsePositive(this, model) && ((model.ThreatEvents?.Count() ?? 0) == 1)) + items.Add(model); + + var entities = model.Entities? + .Where(x => !isFalsePositive(this, x) && ((x.ThreatEvents?.Count() ?? 0) == 1)).ToArray(); + if (entities?.Any() ?? false) + { + items.AddRange(entities); + } + + var flows = model.DataFlows? + .Where(x => !isFalsePositive(this, x) && ((x.ThreatEvents?.Count() ?? 0) == 1)).ToArray(); + if (flows?.Any() ?? false) + { + items.AddRange(flows); + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/StorageFlowsSource.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/StorageFlowsSource.cs new file mode 100644 index 00000000..4c5e3ba2 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/StorageFlowsSource.cs @@ -0,0 +1,99 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Entities; +using ThreatsManager.Interfaces.ObjectModel.Properties; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "C38FABD0-16CA-46E5-A6FC-50B40A02E8B5")] + [ExportMetadata("Label", "Data Store as a source for Flows Quality Analyzer")] + [ExportMetadata("Priority", 14)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class StorageFlowsSource : IQualityAnalyzer + { + public string Label => "Data Store as a Source for Flows"; + public string Description => "Data Stores cannot be used as a Source for Flows.\nThis typically points to a missing Process."; + public double MultiplicationFactor => 1.0; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = Double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = model.Entities?.OfType() + .Where(x => !isFalsePositive(this, x)).Count() ?? 0; + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var entities = model.Entities?.OfType() + .Where(x => !isFalsePositive(this, x)).ToArray(); + if (entities?.Any() ?? false) + { + var flows = model.DataFlows?.ToArray(); + + if (flows?.Any() ?? false) + { + List found = new List(); + + foreach (var entity in entities) + { + if (flows.Any(x => x.SourceId == entity.Id)) + found.Add(entity); + } + + result = found.Count; + if (result > 0) + instances = found; + } + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnbalancedSeverities.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnbalancedSeverities.cs new file mode 100644 index 00000000..af1abbd8 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnbalancedSeverities.cs @@ -0,0 +1,210 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "863E8714-D186-4D13-87F5-F8E52B1DD3CB")] + [ExportMetadata("Label", "Unbalanced Severities Quality Analyzer")] + [ExportMetadata("Priority", 48)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class UnbalancedSeverities : IQualityAnalyzer + { + private const int CriticalMin = 0; + private const int CriticalMax = 15; + private const int HighMin = 10; + private const int HighMax = 30; + private const int MediumMin = 20; + private const int MediumMax = 70; + private const int LowMin = 10; + private const int LowMax = 50; + private const int InfoMin = 0; + private const int InfoMax = 30; + + public override string ToString() + { + return Label; + } + + public string Label => "Unbalanced Severities"; + public string Description => "Severities assigned to Threat Events should be Balanced.\n" + + "The typical percentage for balanced Threat Models, are:\n" + + $"- Critical: {CriticalMin}-{CriticalMax}%\n" + + $"- High: {HighMin}-{HighMax}%\n" + + $"- Medium: {MediumMin}-{MediumMax}%\n" + + $"- Low: {LowMin}-{LowMax}%\n" + + $"- Info: {InfoMin}-{InfoMax}%"; + + public double MultiplicationFactor => 0.5; + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = ((model.ThreatEvents?.Any() ?? false) ? 1 : 0) + + (model.Entities? + .Where(y => y.ThreatEvents?.Any() ?? false).Count() ?? 0) + + (model.DataFlows? + .Where(y => y.ThreatEvents?.Any() ?? false).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 5.4; + minYellow = 5.6; + maxYellow = 15.4; + minRed = 15.6; + maxRed = 20; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + var critical = 0; + var high = 0; + var medium = 0; + var low = 0; + var info = 0; + AnalyzeContainer(model, ref critical, ref high, ref medium, ref low, ref info); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, ref critical, ref high, ref medium, ref low, ref info); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, ref critical, ref high, ref medium, ref low, ref info); + } + } + + var total = critical + high + medium + low + info; + if (total > 0) + { + var cP = (critical * 100) / total; + var hP = (high * 100) / total; + var mP = (medium * 100) / total; + var lP = (low * 100) / total; + var iP = (info * 100) / total; + + List list = new List(); + if (cP < CriticalMin || cP > CriticalMax) + { + list.Add( + $"Threat Events with Critical Severity are out of Boundary: {cP}% ({CriticalMin}-{CriticalMax})"); + if (cP < CriticalMin) + result += CriticalMin - cP; + else + result += cP - CriticalMax; + } + + if (hP < HighMin || hP > HighMax) + { + list.Add($"Threat Events with High Severity are out of Boundary: {hP}% ({HighMin}-{HighMax})"); + if (hP < HighMin) + result += HighMin - hP; + else + result += hP - HighMax; + } + + if (mP < MediumMin || mP > MediumMax) + { + list.Add( + $"Threat Events with Medium Severity are out of Boundary: {mP}% ({MediumMin}-{MediumMax})"); + if (mP < MediumMin) + result += MediumMin - mP; + else + result += mP - MediumMax; + } + + if (lP < LowMin || lP > LowMax) + { + list.Add($"Threat Events with Low Severity are out of Boundary: {lP}% ({LowMin}-{LowMax})"); + if (lP < LowMin) + result += LowMin - lP; + else + result += lP - LowMax; + } + + if (iP < InfoMin || iP > InfoMax) + { + list.Add($"Informational Threat Events are out of Boundary: {iP}% ({InfoMin}-{InfoMax})"); + if (iP < InfoMin) + result += InfoMin - iP; + else + result += iP - InfoMax; + } + + if (list.Any()) + { + instances = list; + } + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, ref int critical, + ref int high, ref int medium, ref int low, ref int info) + { + var threatEvents = container.ThreatEvents?.ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var te in threatEvents) + { + if (te.SeverityId >= (int) DefaultSeverity.Critical) + critical++; + else if (te.SeverityId >= (int) DefaultSeverity.High) + high++; + else if (te.SeverityId >= (int) DefaultSeverity.Medium) + medium++; + else if (te.SeverityId >= (int) DefaultSeverity.Low) + low++; + else + info++; + } + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnchangedSeverity.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnchangedSeverity.cs new file mode 100644 index 00000000..1c1887bf --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UnchangedSeverity.cs @@ -0,0 +1,151 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "1C18A756-C5D0-4217-AFE4-4647DA6D0F21")] + [ExportMetadata("Label", "Unchanged Severity Quality Analyzer")] + [ExportMetadata("Priority", 46)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class UnchangedSeverity : IQualityAnalyzer + { + public string Label => "Unchanged Severities"; + public string Description => "Threat Events with one or more Mitigations marked as Existing or Implemented should have an adjusted Severity."; + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && ((y.Mitigations?.Any(z => z.Status == MitigationStatus.Existing) ?? false) || + (y.Mitigations?.Any(z => z.Status == MitigationStatus.Implemented) ?? false))) + .Count() ?? 0).Sum() ?? 0) + + (model.DataFlows?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && ((y.Mitigations?.Any(z => z.Status == MitigationStatus.Existing) ?? false) || + (y.Mitigations?.Any(z => z.Status == MitigationStatus.Implemented) ?? false))) + .Count() ?? 0).Sum() ?? 0) + + (model.ThreatEvents? + .Where(y => !isFalsePositive(this, y) && ((y.Mitigations?.Any(z => z.Status == MitigationStatus.Existing) ?? false) || + (y.Mitigations?.Any(z => z.Status == MitigationStatus.Implemented) ?? false))) + .Count() ?? 0); + + if (count >= 10) + { + minGreen = 0.0; + maxGreen = count * 0.5; + minYellow = Math.Floor(maxGreen * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxYellow = count * 0.75; + minRed = Math.Floor(maxYellow * 10.0) / 10.0 + Math.Floor(count / 10.0) / 10; + maxRed = count; + + result = true; + } + else if (count > 0) + { + minGreen = 0.0; + maxGreen = count * 0.75; + minRed = maxGreen + count * 0.02; + maxRed = count; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + AnalyzeContainer(model, isFalsePositive, items); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, isFalsePositive, items); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, isFalsePositive, items); + } + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, + Func isFalsePositive, + List list) + { + var threatEvents = container.ThreatEvents?.Where(x => IsSeverityUnchanged(x) && !isFalsePositive(this, x)).ToArray(); + if (threatEvents?.Any() ?? false) + { + list.AddRange(threatEvents); + } + } + + private bool IsSeverityUnchanged([NotNull] IThreatEvent threatEvent) + { + bool result = false; + + if (threatEvent.Mitigations? + .Any(x => x.Status == MitigationStatus.Existing || x.Status == MitigationStatus.Implemented) ?? + false) + { + result = threatEvent.SeverityId == (threatEvent.ThreatType?.SeverityId ?? 0); + } + + return result; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Analyzers/UndefinedMitigations.cs b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UndefinedMitigations.cs new file mode 100644 index 00000000..25c3b485 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Analyzers/UndefinedMitigations.cs @@ -0,0 +1,121 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel.Composition; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; + +namespace ThreatsManager.Quality.Analyzers +{ + [Export(typeof(IQualityAnalyzer))] + [ExportMetadata("Id", "13F15DE4-D3C7-4FB3-B458-6458947AAF6D")] + [ExportMetadata("Label", "Undefined Mitigations Quality Analyzer")] + [ExportMetadata("Priority", 50)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class UndefinedMitigations : IQualityAnalyzer + { + public string Label => "Undefined Mitigations"; + public string Description => "No Mitigation should be in Undefined Status."; + public double MultiplicationFactor => 0.75; + + public override string ToString() + { + return Label; + } + + public bool GetThresholds([NotNull] IThreatModel model, + Func isFalsePositive, + out double minRed, out double maxRed, out double minYellow, out double maxYellow, + out double minGreen, out double maxGreen) + { + bool result = false; + minRed = 0; + maxRed = 0; + minYellow = double.NaN; + maxYellow = double.NaN; + minGreen = 0; + maxGreen = 0; + + var count = (model.Entities?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y)).Count() ?? 0).Sum() ?? 0) + + (model.DataFlows?.Select(x => x.ThreatEvents? + .Where(y => !isFalsePositive(this, y)).Count() ?? 0).Sum() ?? 0) + + (model.ThreatEvents?.Where(x => !isFalsePositive(this, x)).Count() ?? 0); + + if (count > 0) + { + minGreen = 0; + maxGreen = 0.49; + minRed = 0.51; + maxRed = 1; + + result = true; + } + else + { + minGreen = 0; + maxGreen = 1; + minRed = double.NaN; + maxRed = double.NaN; + } + + return result; + } + + public double Analyze([NotNull] IThreatModel model, + Func isFalsePositive, + out IEnumerable instances) + { + double result = 0.0; + instances = null; + + List items = new List(); + + AnalyzeContainer(model, isFalsePositive, items); + + var entities = model.Entities?.ToArray(); + if (entities?.Any() ?? false) + { + foreach (var entity in entities) + { + AnalyzeContainer(entity, isFalsePositive, items); + } + } + + var flows = model.DataFlows?.ToArray(); + if (flows?.Any() ?? false) + { + foreach (var flow in flows) + { + AnalyzeContainer(flow, isFalsePositive, items); + } + } + + if (items.Any()) + { + result = items.Count; + instances = items; + } + + return result; + } + + private void AnalyzeContainer([NotNull] IThreatEventsContainer container, + Func isFalsePositive, + [NotNull] IList list) + { + var threatEvents = container.ThreatEvents? + .Where(x => (x.Mitigations?.Any(y => y.Status == MitigationStatus.Undefined) ?? false) && !isFalsePositive(this, x)).ToArray(); + if (threatEvents?.Any() ?? false) + { + foreach (var te in threatEvents) + list.Add(te); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/ExtensionsContainer.cs b/Sources/Extensions/ThreatsManager.Quality/ExtensionsContainer.cs new file mode 100644 index 00000000..b8227c8a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/ExtensionsContainer.cs @@ -0,0 +1,3 @@ +using ThreatsManager.Interfaces; + +[assembly: ExtensionsContainer("1.3.3")] \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Initializers/QualityInitializer.cs b/Sources/Extensions/ThreatsManager.Quality/Initializers/QualityInitializer.cs new file mode 100644 index 00000000..93e24710 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Initializers/QualityInitializer.cs @@ -0,0 +1,23 @@ +using System.ComponentModel.Composition; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Quality.Schemas; +using ThreatsManager.Utilities; + +namespace ThreatsManager.Quality.Initializers +{ + [Export(typeof(IExtensionInitializer))] + [ExportMetadata("Id", "1069F3AA-BD5E-41C6-B681-0D37FCA12937")] + [ExportMetadata("Label", "Quality Initializer")] + [ExportMetadata("Priority", 10)] + [ExportMetadata("Parameters", null)] + [ExportMetadata("Mode", ExecutionMode.Simplified)] + public class QualityInitializer : IExtensionInitializer + { + public void Initialize() + { + KnownTypesBinder.AddKnownType(typeof(FalsePositiveList)); + KnownTypesBinder.AddKnownType(typeof(FalsePositiveInfo)); + } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.Designer.cs b/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.Designer.cs new file mode 100644 index 00000000..d80db165 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.Designer.cs @@ -0,0 +1,311 @@ +//------------------------------------------------------------------------------ +// +// This code was generated by a tool. +// Runtime Version:4.0.30319.42000 +// +// Changes to this file may cause incorrect behavior and will be lost if +// the code is regenerated. +// +//------------------------------------------------------------------------------ + +namespace ThreatsManager.Quality.Properties { + using System; + + + /// + /// A strongly-typed resource class, for looking up localized strings, etc. + /// + // This class was auto-generated by the StronglyTypedResourceBuilder + // class via a tool like ResGen or Visual Studio. + // To add or remove a member, edit your .ResX file then rerun ResGen + // with the /str option, or rebuild your VS project. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "16.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Returns the cached ResourceManager instance used by this class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ThreatsManager.Quality.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Overrides the current thread's CurrentUICulture property for all + /// resource lookups using this strongly typed resource class. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + + /// + /// Looks up a localized string similar to https://www.simoneonsecurity.com/tm/2018. + /// + internal static string DefaultNamespace { + get { + return ResourceManager.GetString("DefaultNamespace", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_frown { + get { + object obj = ResourceManager.GetObject("emoticon_frown", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_frown_small { + get { + object obj = ResourceManager.GetObject("emoticon_frown_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_smile { + get { + object obj = ResourceManager.GetObject("emoticon_smile", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_smile_small { + get { + object obj = ResourceManager.GetObject("emoticon_smile_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_straight_face { + get { + object obj = ResourceManager.GetObject("emoticon_straight_face", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap emoticon_straight_face_small { + get { + object obj = ResourceManager.GetObject("emoticon_straight_face_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hand_thumb_up { + get { + object obj = ResourceManager.GetObject("hand_thumb_up", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hand_thumb_up_big { + get { + object obj = ResourceManager.GetObject("hand_thumb_up_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hand_thumb_up_huge { + get { + object obj = ResourceManager.GetObject("hand_thumb_up_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap hand_thumb_up_small { + get { + object obj = ResourceManager.GetObject("hand_thumb_up_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap logo { + get { + object obj = ResourceManager.GetObject("logo", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf { + get { + object obj = ResourceManager.GetObject("pdf", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_big { + get { + object obj = ResourceManager.GetObject("pdf_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_huge { + get { + object obj = ResourceManager.GetObject("pdf_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap pdf_small { + get { + object obj = ResourceManager.GetObject("pdf_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized string similar to Quality. + /// + internal static string SchemaName { + get { + return ResourceManager.GetString("SchemaName", resourceCulture); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap wax_seal { + get { + object obj = ResourceManager.GetObject("wax_seal", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap wax_seal_big { + get { + object obj = ResourceManager.GetObject("wax_seal_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap wax_seal_huge { + get { + object obj = ResourceManager.GetObject("wax_seal_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap wax_seal_small { + get { + object obj = ResourceManager.GetObject("wax_seal_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx { + get { + object obj = ResourceManager.GetObject("xlsx", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_big { + get { + object obj = ResourceManager.GetObject("xlsx_big", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_huge { + get { + object obj = ResourceManager.GetObject("xlsx_huge", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + + /// + /// Looks up a localized resource of type System.Drawing.Bitmap. + /// + internal static System.Drawing.Bitmap xlsx_small { + get { + object obj = ResourceManager.GetObject("xlsx_small", resourceCulture); + return ((System.Drawing.Bitmap)(obj)); + } + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.resx b/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.resx new file mode 100644 index 00000000..15e1656a --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Properties/Resources.resx @@ -0,0 +1,126 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + https://www.simoneonsecurity.com/tm/2018 + + + Quality + + \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveInfo.cs b/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveInfo.cs new file mode 100644 index 00000000..0e9ab7e5 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveInfo.cs @@ -0,0 +1,21 @@ +using System; +using Newtonsoft.Json; + +namespace ThreatsManager.Quality.Schemas +{ + [JsonObject(MemberSerialization.OptIn)] + public class FalsePositiveInfo + { + [JsonProperty("id")] + public string QualityInitializerId { get; set; } + + [JsonProperty("reason")] + public string Reason { get; set; } + + [JsonProperty("author")] + public string Author { get; set; } + + [JsonProperty("timestamp")] + public DateTime Timestamp { get; set; } + } +} \ No newline at end of file diff --git a/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveList.cs b/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveList.cs new file mode 100644 index 00000000..950dee97 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Schemas/FalsePositiveList.cs @@ -0,0 +1,12 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace ThreatsManager.Quality.Schemas +{ + [JsonObject(MemberSerialization.OptIn)] + public class FalsePositiveList + { + [JsonProperty("falsePositives")] + public List FalsePositives { get; set; } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/Schemas/QualityPropertySchemaManager.cs b/Sources/Extensions/ThreatsManager.Quality/Schemas/QualityPropertySchemaManager.cs new file mode 100644 index 00000000..35c9bab1 --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/Schemas/QualityPropertySchemaManager.cs @@ -0,0 +1,185 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using PostSharp.Patterns.Contracts; +using ThreatsManager.Interfaces; +using ThreatsManager.Interfaces.Extensions; +using ThreatsManager.Interfaces.ObjectModel; +using ThreatsManager.Interfaces.ObjectModel.Properties; +using ThreatsManager.Utilities; +using ThreatsManager.Utilities.Aspects; + +namespace ThreatsManager.Quality.Schemas +{ + public class QualityPropertySchemaManager : IInitializableObject + { + private readonly IThreatModel _model; + private static string FalsePositive = "FalsePositive"; + + public QualityPropertySchemaManager([NotNull] IThreatModel model) + { + _model = model; + } + + public bool IsInitialized => _model != null; + + [InitializationRequired] + public IPropertySchema GetSchema() + { + var schema = _model.GetSchema(Properties.Resources.SchemaName, Properties.Resources.DefaultNamespace); + if (schema == null) + { + schema = _model.AddSchema(Properties.Resources.SchemaName, Properties.Resources.DefaultNamespace); + schema.Visible = false; + schema.AppliesTo = Scope.All; + schema.System = true; + schema.AutoApply = false; + } + + return schema; + } + + [InitializationRequired] + public IPropertyType GetFalsePositivePropertyType() + { + IPropertyType result = null; + + var schema = GetSchema(); + if (schema != null) + { + result = schema.GetPropertyType(FalsePositive) ?? schema.AddPropertyType(FalsePositive, PropertyValueType.JsonSerializableObject); + } + + return result; + } + + public bool IsFalsePositive([NotNull] IPropertiesContainer container, + [NotNull] IQualityAnalyzer qualityAnalyzer) + { + bool result = false; + + var propertyType = GetFalsePositivePropertyType(); + if (propertyType != null) + { + var property = container.GetProperty(propertyType) as IPropertyJsonSerializableObject; + if (property?.Value is FalsePositiveList list) + { + result = list.FalsePositives? + .Any(x => + string.CompareOrdinal(x.QualityInitializerId, qualityAnalyzer.GetExtensionId()) == 0) ?? false; + } + } + + return result; + } + + public static bool IsFalsePositive([NotNull] IQualityAnalyzer qualityAnalyzer, [NotNull] IPropertiesContainer container) + { + bool result = false; + + if (container is IThreatModelChild threatModelChild && + threatModelChild.Model is IThreatModel model) + { + result = new QualityPropertySchemaManager(model).IsFalsePositive(container, qualityAnalyzer); + } + + return result; + } + + public void SetFalsePositive([NotNull] IPropertiesContainer container, + [NotNull] IQualityAnalyzer analyzer, + [Required] string reason) + { + SetFalsePositive(container, analyzer.GetExtensionId(), reason); + } + + public void SetFalsePositive([NotNull] IPropertiesContainer container, + [Required] string analyzerId, + [Required] string reason) + { + var propertyType = GetFalsePositivePropertyType(); + if (propertyType != null) + { + var property = container.GetProperty(propertyType) as IPropertyJsonSerializableObject; + if (property == null) + { + var list = new FalsePositiveList + { + FalsePositives = new List {CreateInfo(analyzerId, reason)} + }; + property = container.AddProperty(propertyType, null) as IPropertyJsonSerializableObject; + if (property != null) + property.Value = list; + + } + else + { + if (property.Value is FalsePositiveList list && + !(list.FalsePositives?.Any(x => string.CompareOrdinal(x.QualityInitializerId, analyzerId) == 0) ?? false)) + { + if (list.FalsePositives == null) + list.FalsePositives = new List(); + list.FalsePositives.Add(CreateInfo(analyzerId, reason)); + } + } + } + } + + public void ResetFalsePositive([NotNull] IPropertiesContainer container, + [NotNull] IQualityAnalyzer analyzer) + { + var propertyType = GetFalsePositivePropertyType(); + if (propertyType != null) + { + var property = container.GetProperty(propertyType) as IPropertyJsonSerializableObject; + if (property?.Value is FalsePositiveList list) + { + var item = list.FalsePositives?.FirstOrDefault(x => + string.CompareOrdinal(x.QualityInitializerId, analyzer.GetExtensionId()) == 0); + if (item != null) + list.FalsePositives.Remove(item); + } + } + } + + public string GetReason([NotNull] IPropertiesContainer container, + [NotNull] IQualityAnalyzer analyzer) + { + string result = null; + + var propertyType = GetFalsePositivePropertyType(); + if (propertyType != null) + { + var property = container.GetProperty(propertyType) as IPropertyJsonSerializableObject; + if (property?.Value is FalsePositiveList list) + { + result = list.FalsePositives?.FirstOrDefault(x => + string.CompareOrdinal(x.QualityInitializerId, analyzer.GetExtensionId()) == 0)?.Reason; + } + } + + return result; + } + + private FalsePositiveInfo CreateInfo([Required] string analyzerId, [Required] string reason) + { + string userName; + try + { + userName = UserName.GetDisplayName(); + } + catch + { + userName = Environment.UserName; + } + + return new FalsePositiveInfo() + { + QualityInitializerId = analyzerId, + Reason = reason, + Author = userName, + Timestamp = DateTime.Now + }; + } + } +} diff --git a/Sources/Extensions/ThreatsManager.Quality/ThreatsManager.Quality.csproj b/Sources/Extensions/ThreatsManager.Quality/ThreatsManager.Quality.csproj new file mode 100644 index 00000000..bc732d2e --- /dev/null +++ b/Sources/Extensions/ThreatsManager.Quality/ThreatsManager.Quality.csproj @@ -0,0 +1,44 @@ + + + + netcoreapp3.1;net472 + Threats Manager Platform Quality library. + 1.3.3.0 + Simone Curzi + Simone Curzi + Threats Manager Platform + Copyright © Simone Curzi, 2018-2020. All Rights Reserved. + https://www.nuget.org/packages/ThreatsManager.Engine/ + https://github.com/simonec73/threatsmanager + 1.3.3.0 + 1.3.3 + true + ..\..\ThreatsManager.Engine\ThreatsManager.snk + + + + + + + + + + + + + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + + diff --git a/Sources/ThreatsManager.Engine/ExtensionsManager.cs b/Sources/ThreatsManager.Engine/ExtensionsManager.cs index 21f294e1..516470f6 100644 --- a/Sources/ThreatsManager.Engine/ExtensionsManager.cs +++ b/Sources/ThreatsManager.Engine/ExtensionsManager.cs @@ -13,7 +13,8 @@ using ThreatsManager.Interfaces.Extensions.Actions; using ThreatsManager.Interfaces.Extensions.Panels; using ThreatsManager.Utilities; -using ThreatsManager.Utilities.Training; +using ThreatsManager.Utilities.Help; +using PostSharp.Patterns.Threading; namespace ThreatsManager.Engine { @@ -65,9 +66,9 @@ class ExtensionsManager [ExtensionDescription("Property Schemas Extractor")] private IEnumerable> _propertySchemasExtractors; - [ImportMany(typeof(IDevOpsConnector))] - [ExtensionDescription("DevOps Connector")] - private IEnumerable> _devOpsConnectors; + [ImportMany(typeof(IDevOpsConnectorFactory))] + [ExtensionDescription("DevOps Connector Factory")] + private IEnumerable> _devOpsConnectorsFactories; [ImportMany(typeof(ISettingsPanelProvider))] [ExtensionDescription("Settings Panel Provider")] @@ -105,15 +106,7 @@ public void Load() try { _container.ComposeParts(this); - - var assemblies = _catalog.Catalogs.OfType().Select(x => x.Assembly).ToArray(); - if (assemblies.Any()) - { - foreach (var assembly in assemblies) - { - TrainingPillsManager.Instance.Add(assembly); - } - } + LoadHelpConfiguration(); } catch (ReflectionTypeLoadException ex) { @@ -326,5 +319,21 @@ private bool IsExecutionModeCompliant(ExecutionMode requiredMode) return result; } + + [Background] + private void LoadHelpConfiguration() + { + var assemblies = _catalog.Catalogs.OfType().Select(x => x.Assembly).ToArray(); + if (assemblies.Any()) + { + foreach (var assembly in assemblies) + { + LearningManager.Instance.Add(assembly); + TroubleshootingManager.Instance.Add(assembly); + } + LearningManager.Instance.AnalyzeSources(); + TroubleshootingManager.Instance.AnalyzeSources(); + } + } } } diff --git a/Sources/ThreatsManager.Engine/Manager.cs b/Sources/ThreatsManager.Engine/Manager.cs index 2bd61332..1bb4b0cc 100644 --- a/Sources/ThreatsManager.Engine/Manager.cs +++ b/Sources/ThreatsManager.Engine/Manager.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Reflection; +using System.Security.Cryptography; using System.Security.Cryptography.X509Certificates; using Newtonsoft.Json; using PostSharp.Patterns.Contracts; @@ -133,7 +134,7 @@ private void AddAssemblies(IEnumerable folders, IEnumerable pref { skip = true; reason = - $"Assembly {assembly.FullName} has not been loaded because it is not designed for this client."; + $"Extension library {assembly.FullName} has not been loaded because it is not designed for this client."; } if (!skip && CheckVersion(platformVersion, assembly)) @@ -141,13 +142,30 @@ private void AddAssemblies(IEnumerable folders, IEnumerable pref if (certificates?.Any() ?? false) { #pragma warning disable SecurityIntelliSenseCS // MS Security rules violation - var certificate = X509Certificate.CreateFromSignedFile(dll); - if (certificate != null && - certificates.Any(x => + X509Certificate certificate = null; + try + { + certificate = X509Certificate.CreateFromSignedFile(dll); + } + catch (CryptographicException) + { + _showWarning?.Invoke($"Extension library {assembly.FullName} has not been loaded because it has not been signed."); + } + + if (certificate != null) + { + if (certificates.Any(x => string.Compare(x.Thumbprint, new X509Certificate2(certificate).Thumbprint, StringComparison.InvariantCultureIgnoreCase) == 0)) - _extensionsManager.AddExtensionsAssembly(dll); + { + _extensionsManager.AddExtensionsAssembly(dll); + } + else + { + _showWarning?.Invoke($"Extension library {assembly.FullName} has not been loaded because its signature is not trusted."); + } + } #pragma warning restore SecurityIntelliSenseCS // MS Security rules violation } else @@ -159,16 +177,16 @@ private void AddAssemblies(IEnumerable folders, IEnumerable pref { _showWarning?.Invoke( reason ?? - $"Assembly {assembly.FullName} not loaded because it does not target this version of the Platform."); + $"Extension library {assembly.FullName} has not been loaded because it does not target this version of the Platform."); } } catch (FileLoadException) { // Ignore: this could be caused by the fact that the library has been loaded from somewhere else. } - catch + catch (Exception) { - _showWarning?.Invoke($"Assembly {fileName} not loaded because it is not compatible with the current Platform."); + _showWarning?.Invoke($"Extension library {fileName} has not been loaded because it is not compatible with the current Platform."); } } } @@ -195,11 +213,27 @@ private bool CheckVersion([NotNull] Version platformVersion, [NotNull] Assembly switch (attribute.ConstructorArguments.Count) { case 1: - attrib = new ExtensionsContainerAttribute(attribute.ConstructorArguments[0].Value.ToString()); + attrib = new ExtensionsContainerAttribute((string) attribute.ConstructorArguments[0].Value); break; case 2: - attrib = new ExtensionsContainerAttribute(attribute.ConstructorArguments[0].Value.ToString(), - attribute.ConstructorArguments[1].ToString()); + if (attribute.ConstructorArguments[1].ArgumentType == typeof(string)) + { + attrib = new ExtensionsContainerAttribute( + (string) attribute.ConstructorArguments[0].Value, + (string) attribute.ConstructorArguments[1].Value); + } + else + { + attrib = new ExtensionsContainerAttribute( + (string) attribute.ConstructorArguments[0].Value, + (uint) attribute.ConstructorArguments[1].Value); + } + break; + case 3: + attrib = new ExtensionsContainerAttribute( + (string) attribute.ConstructorArguments[0].Value, + (string) attribute.ConstructorArguments[1].Value, + (uint) attribute.ConstructorArguments[2].Value); break; } diff --git a/Sources/ThreatsManager.Engine/ObjectModel/Entities/FlowTemplate.cs b/Sources/ThreatsManager.Engine/ObjectModel/Entities/FlowTemplate.cs index 278211fd..faf6084e 100644 --- a/Sources/ThreatsManager.Engine/ObjectModel/Entities/FlowTemplate.cs +++ b/Sources/ThreatsManager.Engine/ObjectModel/Entities/FlowTemplate.cs @@ -132,6 +132,7 @@ public IDataFlow CreateFlow([Required] string name, Guid sourceId, Guid targetId public void ApplyTo([NotNull] IDataFlow flow) { + flow.FlowType = FlowType; flow.ClearProperties(); this.CloneProperties(flow); if (flow is DataFlow internalFlow) diff --git a/Sources/ThreatsManager.Engine/ObjectModel/Entities/TrustBoundary.cs b/Sources/ThreatsManager.Engine/ObjectModel/Entities/TrustBoundary.cs index fff01be3..cdefd123 100644 --- a/Sources/ThreatsManager.Engine/ObjectModel/Entities/TrustBoundary.cs +++ b/Sources/ThreatsManager.Engine/ObjectModel/Entities/TrustBoundary.cs @@ -26,7 +26,7 @@ namespace ThreatsManager.Engine.ObjectModel.Entities [GroupsReadOnlyContainerAspect] [GroupElementAspect] [TypeLabel("Trust Boundary")] - [TypeInitial("D")] + [TypeInitial("T")] public class TrustBoundary : ITrustBoundary, IInitializableObject { public TrustBoundary() diff --git a/Sources/ThreatsManager.Engine/Properties/launchSettings.json b/Sources/ThreatsManager.Engine/Properties/launchSettings.json new file mode 100644 index 00000000..ca63ee71 --- /dev/null +++ b/Sources/ThreatsManager.Engine/Properties/launchSettings.json @@ -0,0 +1,8 @@ +{ + "profiles": { + "ThreatsManager.Engine": { + "commandName": "Executable", + "executablePath": "C:\\src\\Threats Manager Platform\\Dev\\ThreatsManager\\bin\\Debug\\ThreatsManager.exe" + } + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Engine/ThreatsManager.Engine.csproj b/Sources/ThreatsManager.Engine/ThreatsManager.Engine.csproj index fcfb8a65..ed708ed2 100644 --- a/Sources/ThreatsManager.Engine/ThreatsManager.Engine.csproj +++ b/Sources/ThreatsManager.Engine/ThreatsManager.Engine.csproj @@ -3,15 +3,15 @@ netcoreapp3.1;net472 Threats Manager Platform Engine. - 1.3.1.0 + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Engine/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 true ThreatsManager.snk false diff --git a/Sources/ThreatsManager.Interfaces/Extensions/Actions/AnswerType.cs b/Sources/ThreatsManager.Interfaces/Extensions/Actions/AnswerType.cs new file mode 100644 index 00000000..62026ae9 --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/Actions/AnswerType.cs @@ -0,0 +1,29 @@ +namespace ThreatsManager.Interfaces.Extensions.Actions +{ + /// + /// Type of answers received from the user. + /// + public enum AnswerType + { + /// + /// No valid answer received. + /// + None, + /// + /// User pressed the OK button. + /// + Ok, + /// + /// User pressed the Yes button. + /// + Yes, + /// + /// User pressed the No button. + /// + No, + /// + /// User pressed the Cancel button. + /// + Cancel + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/Actions/IAsker.cs b/Sources/ThreatsManager.Interfaces/Extensions/Actions/IAsker.cs new file mode 100644 index 00000000..12fc9112 --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/Actions/IAsker.cs @@ -0,0 +1,30 @@ +using System; + +namespace ThreatsManager.Interfaces.Extensions.Actions +{ + /// + /// Auxiliary interface for Actions to ask for feedback from the user. + /// + public interface IAsker + { + /// + /// Ask a question to the user. + /// + /// The parameters are: + /// The IAsker which should receive the answer. + /// An object which provides the context and that must be returned as is to method . + /// The caption of the request to be shown to the user. + /// The text of the request to be shown to the user. + /// A boolean, which is positive if the request is a warning and false if it is informational only. + /// The available options for the answer. + /// + event Action Ask; + + /// + /// Return the answer from the user. + /// + /// Context of the request. + /// Received answer. + void Answer(object context, AnswerType answer); + } +} diff --git a/Sources/ThreatsManager.Interfaces/Extensions/Actions/RequestOptions.cs b/Sources/ThreatsManager.Interfaces/Extensions/Actions/RequestOptions.cs new file mode 100644 index 00000000..e9b4ad66 --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/Actions/RequestOptions.cs @@ -0,0 +1,21 @@ +namespace ThreatsManager.Interfaces.Extensions.Actions +{ + /// + /// Type of requests to be sent. + /// + public enum RequestOptions + { + /// + /// Possible answers are Yes and No. + /// + YesNo, + /// + /// Possible answers are Yes, No and Cancel. + /// + YesNoCancel, + /// + /// Possible answers are Ok and Cancel. + /// + OkCancel + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/BugInfo.cs b/Sources/ThreatsManager.Interfaces/Extensions/BugInfo.cs deleted file mode 100644 index e73f3072..00000000 --- a/Sources/ThreatsManager.Interfaces/Extensions/BugInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace ThreatsManager.Interfaces.Extensions -{ - /// - /// Information about a Bug. - /// - public class BugInfo - { - /// - /// Public constructor. - /// - /// Identified of the Bug. - /// Status of the Bug. - public BugInfo(int id, BugStatus status) - { - Id = id; - Status = status; - } - - /// - /// Identifier of the Bug. - /// - public int Id { get; private set; } - - /// - /// Status of the Bug. - /// - public BugStatus Status { get; private set; } - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/BugStatus.cs b/Sources/ThreatsManager.Interfaces/Extensions/BugStatus.cs deleted file mode 100644 index 144c6a22..00000000 --- a/Sources/ThreatsManager.Interfaces/Extensions/BugStatus.cs +++ /dev/null @@ -1,30 +0,0 @@ -namespace ThreatsManager.Interfaces.Extensions -{ - /// - /// Status of the Bug. - /// - public enum BugStatus - { - /// - /// The status of the Bug is unknown. - /// - Unknown, - /// - /// The Bug has been created. - /// - Created, - /// - /// Bug fixing has started. - /// - [EnumLabel("In Progress")] - InProgress, - /// - /// Bug has been fixed. - /// - Fixed, - /// - /// Bug has been removed. - /// - Removed - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/DevOpsItemInfo.cs b/Sources/ThreatsManager.Interfaces/Extensions/DevOpsItemInfo.cs deleted file mode 100644 index 06b25b7a..00000000 --- a/Sources/ThreatsManager.Interfaces/Extensions/DevOpsItemInfo.cs +++ /dev/null @@ -1,65 +0,0 @@ -using System.Text.RegularExpressions; -using PostSharp.Patterns.Contracts; - -namespace ThreatsManager.Interfaces.Extensions -{ - /// - /// Information related to an item stored in the DevOps system. - /// - public class DevOpsItemInfo - { - /// - /// Constructor. - /// - /// Name of the Item. - public DevOpsItemInfo([RegularExpression(@"(?[\d]+)#(?.*)")] string name) - { - var regex = new Regex(@"(?[\d]+)#(?.*)"); - var match = regex.Match(name); - if (match.Success && int.TryParse(match.Groups["Id"].Value, out var id)) - { - Id = id; - Name = match.Groups["Name"].Value; - } - } - - /// - /// Constructor. - /// - /// Identifier of the Item. - /// Name of the Item. - public DevOpsItemInfo([Positive] int id, [Required] string name) - { - Id = id; - Name = name; - } - - /// - /// Identifier of the Item. - /// - public int Id { get; } - - /// - /// Name of the Item. - /// - public string Name { get; } - - /// - /// Serialize the content of the object. - /// - /// Serialized object. - public string Serialize() - { - return $"{Id}#{Name}"; - } - - /// - /// Returns a string that represents the current object. - /// - /// A string that represents the current object. - public override string ToString() - { - return Name; - } - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnector.cs b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnector.cs index 827e8ca0..3a379b02 100644 --- a/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnector.cs +++ b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnector.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Threading.Tasks; using ThreatsManager.Interfaces.ObjectModel.ThreatsMitigations; namespace ThreatsManager.Interfaces.Extensions @@ -8,6 +9,14 @@ namespace ThreatsManager.Interfaces.Extensions /// public interface IDevOpsConnector { + #region Relationship with Factory. + /// + /// Identifier of the associated Factory. + /// + string FactoryId { get; } + #endregion + + #region Connection management. /// /// Initiates connection to a DevOps server. /// @@ -27,6 +36,12 @@ public interface IDevOpsConnector /// void Disconnect(); + /// + /// Check if the Connector is connected to the DevOps server. + /// + /// True if the connector is connected, otherwise false. + bool IsConnected(); + /// /// Url of the Server to which the Connector is connected. /// @@ -36,184 +51,126 @@ public interface IDevOpsConnector /// Project to which the Connector is connected. /// string Project { get; } + #endregion - #if NEXT_VERSION + #region Parent management. /// - /// Identifier of the Parent to be used for all the objects managed by the Connector. + /// Information about the Parent to be used for all the objects managed by the Connector. /// - int MasterParent { get; set; } + IDevOpsItemInfo MasterParent { get; set; } /// /// Search for items to be shown and selected to be used as Master Parent. /// /// Filter to be used for the search. It must contain at least 3 characters. /// Enumeration of the items whose name includes the three characters. - IEnumerable GetItems(string filter); - #endif - - /// - /// Check if the Connector is connected to the DevOps server. - /// - /// True if the connector is connected, otherwise false. - bool IsConnected(); + Task> GetItemsAsync(string filter); + #endregion + #region Tag management. /// /// Tag used to recognize the items managed by the Platform. /// string Tag { get; set; } + #endregion - #region Bugs management. - #if NEXT_VERSION - /// - /// Get the current mapping between states supported by the DevOps system and the Bug Status. - /// - IEnumerable> BugStateMappings { get; } - - /// - /// Set a mapping between state supported by the DevOps system and Bug States. - /// - /// State supported by the DevOps system. - /// Associated Bug Status. - /// To remove an association, map BugStatus.Unknown. - void SetBugStateMapping(string devOpsState, BugStatus status); - - /// - /// Get the current mapping between the Fields supported by the DevOps system for the Bugs and the fields defined in the Threat Model for the Threat Events. - /// - IEnumerable> BugFieldMappings { get; } - - /// - /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Bugs. - /// - /// Definition of the DevOps field. - /// Definition of the field in the Threat Model. - void SetBugFieldMapping(DevOpsField devOpsField, IdentityField modelField); - - /// - /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Bugs. - /// - /// Identifier of the DevOps field. - /// Definition of the field in the Threat Model. - void SetBugFieldMapping(string devOpsFieldId, IdentityField modelField); - - /// - /// Get the list of fields supported by the DevOps system for the Bugs. - /// - /// List of known DevOps fields. - IEnumerable GetBugDevOpsFields(); - #endif - + #region Work Item Types management. /// - /// Create a Bug out of a Threat Event. + /// Get the list of supported Work Item Types. /// - /// Threat Event to be used to generate the Bug. - /// Identifier of the Bug. It may be -1 if the Bug creation has failed. - int CreateBug(IThreatEvent threatEvent); + /// List of supported Work Item Types. + Task> GetWorkItemTypesAsync(); /// - /// Get updated information about a Bug. + /// Property to get and set the Work Item Type for new Work Items. /// - /// Threat Event associated with the Bug. - /// Information about the Bug. - BugInfo GetBugInfo(IThreatEvent threatEvent); + string WorkItemType { get; set; } + #endregion + #region Work Item States management. /// - /// Get updated information about a Bug. + /// Get the current mapping between the Work Item states and the states supported by the DevOps system. /// - /// Identifier of the Bug. - /// Information about the Bug. - BugInfo GetBugInfo(int id); + IEnumerable> WorkItemStateMappings { get; } /// - /// Get updated information about multiple Bugs. + /// Set a mapping between state supported by the DevOps system and Work Item States. /// - /// Enumeration of the Bug identifiers. - /// Dictionary containing the info for each Bug. - IDictionary GetBugInfo(IEnumerable ids); + /// State supported by the DevOps system. + /// Associated Work Item Status. + /// To remove an association, map it to WorkItemStatus.Unknown. + void SetWorkItemStateMapping(string devOpsState, WorkItemStatus status); /// - /// Get information about the Bugs that are in a specific status. + /// Get Work Item States from the DevOps system. /// - /// Desired status. - /// Information about the Bugs in the desired status. - IEnumerable GetBugInfo(BugStatus status); + /// List of States supported by the DevOps system. + Task> GetWorkItemStatesAsync(); #endregion - #region Task management. - #if NEXT_VERSION + #region Work Item Fields management. /// - /// Get the current mapping between the Task States and the states supported by the DevOps system. + /// Get the current mapping between the Fields supported by the DevOps system for the Work Item + /// and the fields defined in the Threat Model for the Mitigations. /// - IEnumerable> TaskStateMappings { get; } + IEnumerable> WorkItemFieldMappings { get; } /// - /// Set a mapping between state supported by the DevOps system and Task States. - /// - /// State supported by the DevOps system. - /// Associated Task Status. - /// To remove an association, map TaskStatus.Unknown. - void SetTaskStateMapping(string devOpsState, TaskStatus status); - - /// - /// Get the current mapping between the Fields supported by the DevOps system for the Tasks and the fields defined in the Threat Model for the Mitigations. - /// - IEnumerable> TaskFieldMappings { get; } - - /// - /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Tasks. + /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Work Items. /// /// Definition of the DevOps field. /// Definition of the field in the Threat Model. - void SetTaskFieldMapping(DevOpsField devOpsField, IdentityField modelField); + void SetWorkItemFieldMapping(IDevOpsField devOpsField, IdentityField modelField); /// - /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Tasks. + /// Set the mapping between a field defined in the DevOps and a internal field as defined in the Model, for Work Items. /// /// Identifier of the DevOps field. /// Definition of the field in the Threat Model. - void SetTaskFieldMapping(string devOpsFieldId, IdentityField modelField); + void SetWorkItemFieldMapping(string devOpsFieldId, IdentityField modelField); /// - /// Get the list of fields supported by the DevOps system for the Tasks. + /// Get the list of fields supported by the DevOps system for the Work Item. /// /// List of known DevOps fields. - IEnumerable GetTaskDevOpsFields(); - #endif + Task> GetWorkItemDevOpsFieldsAsync(); + #endregion + #region Work Items management. /// - /// Create a mitigation associated to a Task. + /// Create a mitigation associated to a Work Item. /// - /// Mitigation to a Task. - /// Identifier of the Task. It may be -1 if the Task creation has failed. - int CreateTask(IThreatEventMitigation mitigation); + /// Mitigation to be associated to a Work Item. + /// Identifier of the Work Item. It may be -1 if the Task creation has failed. + Task CreateWorkItemAsync(IMitigation mitigation); /// - /// Get updated information about a Task. + /// Get updated information about a Work Item. /// - /// Mitigation associated to the Task. - /// Information about the Task. - TaskInfo GetTaskInfo(IThreatEventMitigation mitigation); + /// Mitigation associated to the Work Item. + /// Information about the Work Item. + Task GetWorkItemInfoAsync(IMitigation mitigation); /// - /// Get updated information about a Task. + /// Get updated information about a Work Item. /// - /// Identifier of the Task. - /// Information about the Task. - TaskInfo GetTaskInfo(int id); + /// Identifier of the Work Item. + /// Information about the Work Item. + Task GetWorkItemInfoAsync(int id); /// - /// Get information about multiple Tasks. + /// Get information about multiple Work Items. /// - /// Enumeration of the Task identifiers. - /// Dictionary containing the information for each Task. - IDictionary GetTaskInfo(IEnumerable ids); + /// Enumeration of the Work Items identifiers. + /// Enumeration with the information for each Work Items. + Task> GetWorkItemsInfoAsync(IEnumerable ids); /// - /// Get information about the Tasks that are in a specific status. + /// Get information about the Work Items that are in a specific status. /// /// Desired status. - /// Information about the Tasks in the desired status. - IEnumerable GetTaskInfo(TaskStatus status); + /// Information about the Work Items in the desired status. + Task> GetWorkItemsInfoAsync(WorkItemStatus status); #endregion } } \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnectorFactory.cs b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnectorFactory.cs new file mode 100644 index 00000000..1e92aaa0 --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsConnectorFactory.cs @@ -0,0 +1,14 @@ +namespace ThreatsManager.Interfaces.Extensions +{ + /// + /// Interface implemented by factories used to create IDevOpsConnector objects. + /// + public interface IDevOpsConnectorFactory + { + /// + /// Create an instance of IDevOpsConnector. + /// + /// New instance of IDevOpsConnector. + IDevOpsConnector Create(); + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/DevOpsField.cs b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsField.cs similarity index 74% rename from Sources/ThreatsManager.Interfaces/Extensions/DevOpsField.cs rename to Sources/ThreatsManager.Interfaces/Extensions/IDevOpsField.cs index 95bc5821..93cb2fc3 100644 --- a/Sources/ThreatsManager.Interfaces/Extensions/DevOpsField.cs +++ b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsField.cs @@ -3,16 +3,16 @@ /// /// Definition of a Field for the DevOps system. /// - public class DevOpsField + public interface IDevOpsField { /// /// Identifier of the field. /// - public string Id { get; set; } + string Id { get; set; } /// /// Label of the field. /// - public string Label { get; set; } + string Label { get; set; } } } \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsItemInfo.cs b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsItemInfo.cs new file mode 100644 index 00000000..2a812b6c --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/IDevOpsItemInfo.cs @@ -0,0 +1,32 @@ +using System.Text.RegularExpressions; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Interfaces.Extensions +{ + /// + /// Information related to an item stored in the DevOps system. + /// + public interface IDevOpsItemInfo + { + /// + /// Identifier of the Item. + /// + int Id { get; } + + /// + /// Name of the Item. + /// + string Name { get; } + + /// + /// Url of the Item. + /// + string Url { get; } + + /// + /// Serialize the content of the object. + /// + /// Serialized object. + string Serialize(); + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/IdentityField.cs b/Sources/ThreatsManager.Interfaces/Extensions/IdentityField.cs index 9ff3dcdd..d76af81c 100644 --- a/Sources/ThreatsManager.Interfaces/Extensions/IdentityField.cs +++ b/Sources/ThreatsManager.Interfaces/Extensions/IdentityField.cs @@ -42,5 +42,13 @@ public IdentityField([NotNull] IPropertyType propertyType) /// /// It is defined only if the FieldType is Property. public IPropertyType PropertyType { get; private set; } + + /// + /// Representation of the field. + /// + public override string ToString() + { + return FieldType == IdentityFieldType.Property ? PropertyType.ToString() : FieldType.ToString(); + } } } \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/IdentityFieldType.cs b/Sources/ThreatsManager.Interfaces/Extensions/IdentityFieldType.cs index 5e43309f..40e389e5 100644 --- a/Sources/ThreatsManager.Interfaces/Extensions/IdentityFieldType.cs +++ b/Sources/ThreatsManager.Interfaces/Extensions/IdentityFieldType.cs @@ -18,24 +18,14 @@ public enum IdentityFieldType /// /// Description of the Identity. /// - /// For Threat Event Mitigations, it includes the Directives. + /// For Mitigations, it includes the Directives for the associated Directives. Description, /// - /// Priority, automatically calculated Threats or Mitigations. + /// Priority, retrieved from the Roadmap. /// Priority, - /// - /// Severity, as defined for Threats. - /// - Severity, - - /// - /// Indicates where the Threat or Mitigation applies. - /// - AppliesTo, - /// /// A Property Type. /// diff --git a/Sources/ThreatsManager.Interfaces/Extensions/TaskInfo.cs b/Sources/ThreatsManager.Interfaces/Extensions/TaskInfo.cs deleted file mode 100644 index 991a8ba0..00000000 --- a/Sources/ThreatsManager.Interfaces/Extensions/TaskInfo.cs +++ /dev/null @@ -1,29 +0,0 @@ -namespace ThreatsManager.Interfaces.Extensions -{ - /// - /// Information about a Task. - /// - public class TaskInfo - { - /// - /// Public constructor. - /// - /// Identified of the Task. - /// Status of the Task. - public TaskInfo(int id, TaskStatus status) - { - Id = id; - Status = status; - } - - /// - /// Identifier of the Task. - /// - public int Id { get; private set; } - - /// - /// Status of the Task. - /// - public TaskStatus Status { get; private set; } - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/WorkItemInfo.cs b/Sources/ThreatsManager.Interfaces/Extensions/WorkItemInfo.cs new file mode 100644 index 00000000..7f99ea21 --- /dev/null +++ b/Sources/ThreatsManager.Interfaces/Extensions/WorkItemInfo.cs @@ -0,0 +1,29 @@ +namespace ThreatsManager.Interfaces.Extensions +{ + /// + /// Information about a Work Item. + /// + public class WorkItemInfo + { + /// + /// Public constructor. + /// + /// Identified of the Work Item. + /// Status of the Work Item. + public WorkItemInfo(int id, WorkItemStatus status) + { + Id = id; + Status = status; + } + + /// + /// Identifier of the Work Item. + /// + public int Id { get; private set; } + + /// + /// Status of the Work Item. + /// + public WorkItemStatus Status { get; private set; } + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/Extensions/TaskStatus.cs b/Sources/ThreatsManager.Interfaces/Extensions/WorkItemStatus.cs similarity index 87% rename from Sources/ThreatsManager.Interfaces/Extensions/TaskStatus.cs rename to Sources/ThreatsManager.Interfaces/Extensions/WorkItemStatus.cs index 55c5df86..7e059602 100644 --- a/Sources/ThreatsManager.Interfaces/Extensions/TaskStatus.cs +++ b/Sources/ThreatsManager.Interfaces/Extensions/WorkItemStatus.cs @@ -1,13 +1,14 @@ namespace ThreatsManager.Interfaces.Extensions { /// - /// Status of the Task. + /// Status of the Work Item. /// - public enum TaskStatus + public enum WorkItemStatus { /// /// The Task status is unknown. /// + [EnumLabel("Unknown or Standard")] Unknown, /// /// The Task has been created. diff --git a/Sources/ThreatsManager.Interfaces/ExtensionsContainerAttribute.cs b/Sources/ThreatsManager.Interfaces/ExtensionsContainerAttribute.cs index 4a8cabd4..db8a6b41 100644 --- a/Sources/ThreatsManager.Interfaces/ExtensionsContainerAttribute.cs +++ b/Sources/ThreatsManager.Interfaces/ExtensionsContainerAttribute.cs @@ -13,9 +13,17 @@ public class ExtensionsContainerAttribute : Attribute /// Constructor to describe dependency with a specific version of the Engine. /// /// Version of the Engine. - public ExtensionsContainerAttribute([Required] string version) : this(version, version) + public ExtensionsContainerAttribute([Required] string version) : this(version, version, 0) { + } + /// + /// Constructor to describe dependency with a specific version of the Engine. + /// + /// Version of the Engine. + /// Client Identifier. + public ExtensionsContainerAttribute([Required] string version, uint clientId) : this(version, version, clientId) + { } /// @@ -23,10 +31,21 @@ public ExtensionsContainerAttribute([Required] string version) : this(version, v /// /// Minimum supported versions of the Engine. /// Maximum supported versions of the Engine. - public ExtensionsContainerAttribute([Required] string minVersion, [Required] string maxVersion) + public ExtensionsContainerAttribute([Required] string minVersion, [Required] string maxVersion) : this(minVersion, maxVersion, 0) + { + } + + /// + /// Constructor to describe dependency with a range of versions of the Engine. + /// + /// Minimum supported versions of the Engine. + /// Maximum supported versions of the Engine. + /// Client Identifier. + public ExtensionsContainerAttribute([Required] string minVersion, [Required] string maxVersion, uint clientId) { MinVersion = minVersion; MaxVersion = maxVersion; + ClientId = clientId; } /// @@ -39,6 +58,13 @@ public ExtensionsContainerAttribute([Required] string minVersion, [Required] str /// public string MaxVersion { get; set; } + /// + /// Client Identifier. + /// + /// If the Client Id is not 0, then the Extension Container requires a special client to be executed. + /// This is not a security feature! + public uint ClientId { get; set; } + /// /// Checks if the Extension supports the version of the Engine passed as argument. /// diff --git a/Sources/ThreatsManager.Interfaces/MicrosoftContainerAttribute.cs b/Sources/ThreatsManager.Interfaces/MicrosoftContainerAttribute.cs deleted file mode 100644 index 464fa769..00000000 --- a/Sources/ThreatsManager.Interfaces/MicrosoftContainerAttribute.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace ThreatsManager.Interfaces -{ - /// - /// Attribute to be applied to the Assembly to characterize it as a container reserved for Microsoft internal consumption. - /// - [AttributeUsage(AttributeTargets.Assembly)] - public class MicrosoftContainerAttribute : Attribute - { - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Interfaces/ObjectModel/Entities/FlowType.cs b/Sources/ThreatsManager.Interfaces/ObjectModel/Entities/FlowType.cs index c603b63b..174114f6 100644 --- a/Sources/ThreatsManager.Interfaces/ObjectModel/Entities/FlowType.cs +++ b/Sources/ThreatsManager.Interfaces/ObjectModel/Entities/FlowType.cs @@ -24,7 +24,8 @@ public enum FlowType /// The Source sends a command to the Target and/or writes data to it. /// /// This is the typical scenario that occurs when the Source - /// sends a "fire and forget" request to the Target. + /// sends a "fire and forget" request to the Target. + /// It is also used when Pushing data. [EnumLabel("Write/Command only")] WriteCommand } diff --git a/Sources/ThreatsManager.Interfaces/ThreatsManager.Interfaces.csproj b/Sources/ThreatsManager.Interfaces/ThreatsManager.Interfaces.csproj index 243cdc2c..b0b19d2f 100644 --- a/Sources/ThreatsManager.Interfaces/ThreatsManager.Interfaces.csproj +++ b/Sources/ThreatsManager.Interfaces/ThreatsManager.Interfaces.csproj @@ -3,15 +3,15 @@ netcoreapp3.1;net472 Common Interfaces used to define the object, entities and extensions that compose the Threats Manager Platform and allow to extend it. - 1.3.1.0 + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Interfaces/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 false false diff --git a/Sources/ThreatsManager.Packaging/ThreatsManager.Packaging.csproj b/Sources/ThreatsManager.Packaging/ThreatsManager.Packaging.csproj index 745a8c75..77c1df02 100644 --- a/Sources/ThreatsManager.Packaging/ThreatsManager.Packaging.csproj +++ b/Sources/ThreatsManager.Packaging/ThreatsManager.Packaging.csproj @@ -3,15 +3,15 @@ netcoreapp3.1;net472 Library to manage the solution files at a low level. - 1.3.1.0 + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Utilities/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 true ..\ThreatsManager.Engine\ThreatsManager.snk diff --git a/Sources/ThreatsManager.Utilities/Training/TrainingExtensions.cs b/Sources/ThreatsManager.Utilities/Help/HelpExtensions.cs similarity index 88% rename from Sources/ThreatsManager.Utilities/Training/TrainingExtensions.cs rename to Sources/ThreatsManager.Utilities/Help/HelpExtensions.cs index 21e38737..8d77c9d9 100644 --- a/Sources/ThreatsManager.Utilities/Training/TrainingExtensions.cs +++ b/Sources/ThreatsManager.Utilities/Help/HelpExtensions.cs @@ -2,12 +2,12 @@ using ThreatsManager.Icons; using ThreatsManager.Interfaces; -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// /// Training specific extensions. /// - public static class TrainingExtensions + public static class HelpExtensions { /// /// Calculate the image for the Level. @@ -15,13 +15,13 @@ public static class TrainingExtensions /// Level for which the image must be returned. /// Size of the image. /// Bitmap with the image corresponding to the training level. - public static Bitmap GetLevelImage(this TrainingLevel level, ImageSize size) + public static Bitmap GetLevelImage(this LearningLevel level, ImageSize size) { Bitmap result = null; switch (level) { - case TrainingLevel.Introductive: + case LearningLevel.Introductive: switch (size) { case ImageSize.Small: @@ -35,7 +35,7 @@ public static Bitmap GetLevelImage(this TrainingLevel level, ImageSize size) break; } break; - case TrainingLevel.Advanced: + case LearningLevel.Advanced: switch (size) { case ImageSize.Small: @@ -49,7 +49,7 @@ public static Bitmap GetLevelImage(this TrainingLevel level, ImageSize size) break; } break; - case TrainingLevel.Expert: + case LearningLevel.Expert: switch (size) { case ImageSize.Small: diff --git a/Sources/ThreatsManager.Utilities/Training/TrainingsDefinition.cs b/Sources/ThreatsManager.Utilities/Help/LearningDefinition.cs similarity index 62% rename from Sources/ThreatsManager.Utilities/Training/TrainingsDefinition.cs rename to Sources/ThreatsManager.Utilities/Help/LearningDefinition.cs index 2d6627da..ff57598f 100644 --- a/Sources/ThreatsManager.Utilities/Training/TrainingsDefinition.cs +++ b/Sources/ThreatsManager.Utilities/Help/LearningDefinition.cs @@ -1,13 +1,13 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +using System.Collections.Generic; +using Newtonsoft.Json; -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// - /// Definition of trainings. + /// Definition of Learnings. /// [JsonObject(MemberSerialization.OptIn)] - public class TrainingsDefinition + public class LearningDefinition { /// /// Sections defined. Each section describes a training level. diff --git a/Sources/ThreatsManager.Utilities/Training/TrainingLevel.cs b/Sources/ThreatsManager.Utilities/Help/LearningLevel.cs similarity index 54% rename from Sources/ThreatsManager.Utilities/Training/TrainingLevel.cs rename to Sources/ThreatsManager.Utilities/Help/LearningLevel.cs index 9e45d0bf..37de7bbd 100644 --- a/Sources/ThreatsManager.Utilities/Training/TrainingLevel.cs +++ b/Sources/ThreatsManager.Utilities/Help/LearningLevel.cs @@ -1,20 +1,20 @@ -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// - /// Type of Training Sections + /// Levels of Learning /// - public enum TrainingLevel + public enum LearningLevel { /// - /// Introductive Training. + /// Introductive lessons. /// Introductive, /// - /// Advanced Training. + /// Advanced lessons. /// Advanced, /// - /// Expert Training. + /// Pages for experts. /// Expert } diff --git a/Sources/ThreatsManager.Utilities/Help/LearningManager.cs b/Sources/ThreatsManager.Utilities/Help/LearningManager.cs new file mode 100644 index 00000000..1900c8ee --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/LearningManager.cs @@ -0,0 +1,177 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net; +using System.Net.Cache; +using System.Reflection; +using Newtonsoft.Json; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Learning Manager. + /// + /// Implements the Singleton pattern. + public sealed class LearningManager + { + private static readonly Lazy _instance = + new Lazy(() => new LearningManager()); + + private readonly Dictionary> _knownSources = new Dictionary>(); + + private readonly Dictionary> _learning = + new Dictionary>(); + + /// + /// Returns the unique instance of the Learning Manager. + /// + public static LearningManager Instance => _instance.Value; + + private LearningManager() + { + } + + /// + /// Add the Learning source related to the Assembly. + /// + /// Assembly to be analyzed. + /// It should be used only by class ExtensionsManager from ThreatsManager.Engine. + [SuppressMessage("ReSharper", "IdentifierTypo")] + public void Add([PostSharp.Patterns.Contracts.NotNull] Assembly assembly) + { + var attrib = assembly.GetCustomAttributes().FirstOrDefault(); + if (attrib != null) + { + var priority = attrib.Priority; + List sources; + if (_knownSources.ContainsKey(priority)) + { + sources = _knownSources[priority]; + } + else + { + sources = new List(); + _knownSources.Add(priority, sources); + } + + sources.Add(attrib.Url); + } + } + + /// + /// Analyze all the sources. + /// + /// It should be used only by class ExtensionsManager from ThreatsManager.Engine. + public void AnalyzeSources() + { + if (_knownSources.Any()) + { + var sourcesList = _knownSources + .OrderByDescending(x => x.Key) + .Select(x => x.Value) + .ToArray(); + + foreach (var sources in sourcesList) + { + if (sources.Any()) + { + foreach (var source in sources) + { + ProcessSource(source); + } + } + } + } + } + + /// + /// Supported levels. + /// + public IEnumerable SupportedLevels => _learning.Keys; + + /// + /// Get the Topics for a specific level. + /// + /// Learning Level. + /// List of Topics for the given level. + public IEnumerable GetTopics(LearningLevel level) + { + IEnumerable result; + if (_learning.TryGetValue(level, out var topics)) + { + result = topics; + } + else + { + result = null; + } + + return result; + } + + private void ProcessSource([Required] string url) + { + using (var webClient = new System.Net.WebClient()) + { + string json; + try + { + webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); + json = webClient.DownloadString(new Uri(url)); + } + catch + { + return; + } + + if (!string.IsNullOrWhiteSpace(json)) + { + var definition = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.None + }); + + var sections = definition?.Sections?.ToArray(); + if (sections?.Any() ?? false) + { + foreach (var section in sections) + { + var topics = section.Topics?.ToArray(); + if (topics?.Any() ?? false) + { + if (!_learning.TryGetValue(section.SectionType, out var topicInfos)) + { + topicInfos = new List(); + _learning.Add(section.SectionType, topicInfos); + } + + foreach (var topic in topics) + { + var topicInfo = topicInfos.FirstOrDefault(x => + string.CompareOrdinal(topic.Name, x.Name) == 0); + if (topicInfo == null) + { + topicInfo = new TopicInfo(topic.Name); + topicInfos.Add(topicInfo); + } + + var lessons = topic.Lessons?.ToArray(); + if (lessons?.Any() ?? false) + { + foreach (var lesson in lessons) + { + topicInfo.AddLesson(lesson); + } + } + } + } + } + } + } + } + } + } +} diff --git a/Sources/ThreatsManager.Utilities/Help/LearningSourceAttribute.cs b/Sources/ThreatsManager.Utilities/Help/LearningSourceAttribute.cs new file mode 100644 index 00000000..44b8c1b3 --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/LearningSourceAttribute.cs @@ -0,0 +1,45 @@ +using System; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Attribute to be applied to the Assembly to specify where the Learning configuration file for the Extension library can be found. + /// + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] + public class LearningSourceAttribute : Attribute + { + /// + /// Constructor to specify the full URL of the Learning configuration file for the Extension library. + /// + /// Url containing the Learning configuration file. + /// The default Priority is Medium. + public LearningSourceAttribute([RegularExpression(@"(https?|ftp)://[^\s/$.?#].[^\s]*\.json")] string url) + { + Url = url; + Priority = Priority.Medium; + } + + /// + /// Constructor to specify the full URL of the Learning configuration file for the Extension library. + /// + /// Url containing the Learning configuration file. + /// Priority of the source. + public LearningSourceAttribute([RegularExpression(@"(https?|ftp)://[^\s/$.?#].[^\s]*\.json")] string url, + Priority priority) + { + Url = url; + Priority = priority; + } + + /// + /// Url containing the full path of the Learning configuration file. + /// + public string Url { get; set; } + + /// + /// Priority of the source. + /// + public Priority Priority { get; set; } + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Utilities/Training/Lesson.cs b/Sources/ThreatsManager.Utilities/Help/Page.cs similarity index 51% rename from Sources/ThreatsManager.Utilities/Training/Lesson.cs rename to Sources/ThreatsManager.Utilities/Help/Page.cs index 85123a8e..82df6863 100644 --- a/Sources/ThreatsManager.Utilities/Training/Lesson.cs +++ b/Sources/ThreatsManager.Utilities/Help/Page.cs @@ -1,21 +1,13 @@ using Newtonsoft.Json; -using System.Collections.Generic; -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// - /// Training Lesson. + /// Help page. /// [JsonObject(MemberSerialization.OptIn)] - public class Lesson + public class Page { - /// - /// Identifier of the lesson. - /// - /// It must be unique for the Section. - [JsonProperty("id")] - public int Id; - /// /// Name of the topic. /// @@ -29,9 +21,9 @@ public class Lesson public string Description; /// - /// Tags associated to the topic. + /// Url of the lesson. /// - [JsonProperty("tags")] - public List Tags; + [JsonProperty("url")] + public string Url; } } diff --git a/Sources/ThreatsManager.Utilities/Help/Priority.cs b/Sources/ThreatsManager.Utilities/Help/Priority.cs new file mode 100644 index 00000000..b6d9ffd5 --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/Priority.cs @@ -0,0 +1,25 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Priority of the definition. + /// + public enum Priority + { + /// + /// Low priority. This is the default. + /// + Low, + /// + /// Medium priority. + /// + Medium, + /// + /// High priority. + /// + High + } +} diff --git a/Sources/ThreatsManager.Utilities/Training/Section.cs b/Sources/ThreatsManager.Utilities/Help/Section.cs similarity index 64% rename from Sources/ThreatsManager.Utilities/Training/Section.cs rename to Sources/ThreatsManager.Utilities/Help/Section.cs index 78fac772..7daf83c3 100644 --- a/Sources/ThreatsManager.Utilities/Training/Section.cs +++ b/Sources/ThreatsManager.Utilities/Help/Section.cs @@ -1,8 +1,8 @@ -using Newtonsoft.Json; +using System.Collections.Generic; +using Newtonsoft.Json; using Newtonsoft.Json.Converters; -using System.Collections.Generic; -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// @@ -17,14 +17,7 @@ public class Section /// [JsonProperty("type")] [JsonConverter(typeof(StringEnumConverter))] - public TrainingLevel SectionType; - - /// - /// Prefix for the items. - /// - /// This is optional. - [JsonProperty("prefix")] - public string Prefix; + public LearningLevel SectionType; /// /// List of topics. diff --git a/Sources/ThreatsManager.Utilities/Training/Topic.cs b/Sources/ThreatsManager.Utilities/Help/Topic.cs similarity index 58% rename from Sources/ThreatsManager.Utilities/Training/Topic.cs rename to Sources/ThreatsManager.Utilities/Help/Topic.cs index 78d93bce..c459945b 100644 --- a/Sources/ThreatsManager.Utilities/Training/Topic.cs +++ b/Sources/ThreatsManager.Utilities/Help/Topic.cs @@ -1,10 +1,10 @@ -using Newtonsoft.Json; -using System.Collections.Generic; +using System.Collections.Generic; +using Newtonsoft.Json; -namespace ThreatsManager.Utilities.Training +namespace ThreatsManager.Utilities.Help { /// - /// Training Topic, which is a container of Lessons. + /// Training Topic, which is a container of Pages. /// [JsonObject(MemberSerialization.OptIn)] public class Topic @@ -16,9 +16,9 @@ public class Topic public string Name; /// - /// Lessons associated to the topic. + /// Pages associated to the topic. /// [JsonProperty("lessons")] - public List Lessons; + public List Lessons; } } diff --git a/Sources/ThreatsManager.Utilities/Help/TopicInfo.cs b/Sources/ThreatsManager.Utilities/Help/TopicInfo.cs new file mode 100644 index 00000000..c328a8c4 --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/TopicInfo.cs @@ -0,0 +1,42 @@ +using System.Collections.Generic; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Information about a Topic. + /// + public class TopicInfo + { + private readonly List _lessons = new List(); + + /// + /// Public constructor. + /// + /// Name of the Topic. + public TopicInfo([Required] string name) + { + Name = name; + } + + /// + /// Name of the Topic. + /// + public string Name { get; private set; } + + /// + /// Lessons associated to the Topic. + /// + public IEnumerable Lessons => _lessons; + + /// + /// Add a lesson to the Topic. + /// + /// Lesson to be added. + public void AddLesson(Page lesson) + { + if (!_lessons.Contains(lesson)) + _lessons.Add(lesson); + } + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Utilities/Help/TroubleshootingDefinition.cs b/Sources/ThreatsManager.Utilities/Help/TroubleshootingDefinition.cs new file mode 100644 index 00000000..f1f0481b --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/TroubleshootingDefinition.cs @@ -0,0 +1,18 @@ +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Definition of Learnings. + /// + [JsonObject(MemberSerialization.OptIn)] + public class TroubleshootingDefinition + { + /// + /// Pages defined. + /// + [JsonProperty("pages")] + public List Pages; + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Utilities/Help/TroubleshootingManager.cs b/Sources/ThreatsManager.Utilities/Help/TroubleshootingManager.cs new file mode 100644 index 00000000..93c2d47f --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/TroubleshootingManager.cs @@ -0,0 +1,124 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using System.Net.Cache; +using System.Reflection; +using Newtonsoft.Json; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Troubleshooting Manager. + /// + /// Implements the Singleton pattern. + public sealed class TroubleshootingManager + { + private static readonly Lazy _instance = + new Lazy(() => new TroubleshootingManager()); + + private readonly Dictionary> _knownSources = new Dictionary>(); + + private readonly List _pages = new List(); + + /// + /// Returns the unique instance of the Troubleshooting Manager. + /// + public static TroubleshootingManager Instance => _instance.Value; + + private TroubleshootingManager() + { + } + + /// + /// Enumeration of the Troubleshooting pages. + /// + public IEnumerable Pages => _pages; + + /// + /// Add the Troubleshooting source related to the Assembly. + /// + /// Assembly to be analyzed. + /// It should be used only by class ExtensionsManager from ThreatsManager.Engine. + [SuppressMessage("ReSharper", "IdentifierTypo")] + public void Add([PostSharp.Patterns.Contracts.NotNull] Assembly assembly) + { + var attrib = assembly.GetCustomAttributes().FirstOrDefault(); + if (attrib != null) + { + var priority = attrib.Priority; + List sources; + if (_knownSources.ContainsKey(priority)) + { + sources = _knownSources[priority]; + } + else + { + sources = new List(); + _knownSources.Add(priority, sources); + } + + sources.Add(attrib.Url); + } + } + + /// + /// Analyze all the sources. + /// + /// It should be used only by class ExtensionsManager from ThreatsManager.Engine. + public void AnalyzeSources() + { + if (_knownSources.Any()) + { + var sourcesList = _knownSources + .OrderByDescending(x => x.Key) + .Select(x => x.Value) + .ToArray(); + + foreach (var sources in sourcesList) + { + if (sources.Any()) + { + foreach (var source in sources) + { + ProcessSource(source); + } + } + } + } + } + + private void ProcessSource([Required] string url) + { + using (var webClient = new System.Net.WebClient()) + { + string json; + try + { + webClient.CachePolicy = new RequestCachePolicy(RequestCacheLevel.BypassCache); + json = webClient.DownloadString(new Uri(url)); + } + catch + { + return; + } + + if (!string.IsNullOrWhiteSpace(json)) + { + var definition = JsonConvert.DeserializeObject(json, + new JsonSerializerSettings() + { + TypeNameHandling = TypeNameHandling.None + }); + + var pages = definition?.Pages?.ToArray(); + if (pages?.Any() ?? false) + { + _pages.AddRange(pages); + } + } + } + } + } +} diff --git a/Sources/ThreatsManager.Utilities/Help/TroubleshootingSourceAttribute.cs b/Sources/ThreatsManager.Utilities/Help/TroubleshootingSourceAttribute.cs new file mode 100644 index 00000000..b1888a7d --- /dev/null +++ b/Sources/ThreatsManager.Utilities/Help/TroubleshootingSourceAttribute.cs @@ -0,0 +1,45 @@ +using System; +using PostSharp.Patterns.Contracts; + +namespace ThreatsManager.Utilities.Help +{ + /// + /// Attribute to be applied to the Assembly to specify where the Troubleshooting configuration file for the Extension library can be found. + /// + [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] + public class TroubleshootingSourceAttribute : Attribute + { + /// + /// Constructor to specify the full URL of the Troubleshooting configuration file for the Extension library. + /// + /// Url containing the Troubleshooting configuration file. + /// The default Priority is Medium. + public TroubleshootingSourceAttribute([RegularExpression(@"(https?|ftp)://[^\s/$.?#].[^\s]*\.json")] string url) + { + Url = url; + Priority = Priority.Medium; + } + + /// + /// Constructor to specify the full URL of the Troubleshooting configuration file for the Extension library. + /// + /// Url containing the Troubleshooting configuration file. + /// Priority of the source. + public TroubleshootingSourceAttribute([RegularExpression(@"(https?|ftp)://[^\s/$.?#].[^\s]*\.json")] string url, + Priority priority) + { + Url = url; + Priority = priority; + } + + /// + /// Url containing the full path of the Troubleshooting configuration file. + /// + public string Url { get; set; } + + /// + /// Priority of the source. + /// + public Priority Priority { get; set; } + } +} \ No newline at end of file diff --git a/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.csproj b/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.csproj index 105176f4..d21fdb10 100644 --- a/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.csproj +++ b/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.csproj @@ -3,15 +3,15 @@ netcoreapp3.1;net472 Library to manage the solution files at a low level. - 1.3.1.0 + 1.3.3.0 Simone Curzi Simone Curzi Threats Manager Platform Copyright © Simone Curzi, 2018-2020. All Rights Reserved. https://www.nuget.org/packages/ThreatsManager.Utilities/ https://github.com/simonec73/threatsmanager - 1.3.1.0 - 1.3.1 + 1.3.3.0 + 1.3.3 diff --git a/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.xml b/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.xml index 25731c37..093c2066 100644 --- a/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.xml +++ b/Sources/ThreatsManager.Utilities/ThreatsManager.Utilities.xml @@ -642,7 +642,7 @@ - Training Topic, which is a container of Lessons. + Training Topic, which is a container of Pages. @@ -650,9 +650,9 @@ Name of the topic. - + - Lessons associated to the topic. + Pages associated to the topic. @@ -743,14 +743,14 @@ Level of the training. Required tags. - List of Lessons for the given level and with at least one of the searched tags, if specified. + List of Pages for the given level and with at least one of the searched tags, if specified. Get the lessons. Required tags. - List of Lessons with at least one of the searched tags, if specified. + List of Pages with at least one of the searched tags, if specified. diff --git a/Sources/ThreatsManager.Utilities/Training/LessonInfo.cs b/Sources/ThreatsManager.Utilities/Training/LessonInfo.cs deleted file mode 100644 index dfdea224..00000000 --- a/Sources/ThreatsManager.Utilities/Training/LessonInfo.cs +++ /dev/null @@ -1,66 +0,0 @@ -using PostSharp.Patterns.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; - -namespace ThreatsManager.Utilities.Training -{ - /// - /// Information about a Lesson. - /// - public class LessonInfo - { - /// - /// Constructor. - /// - /// Base Url of the training. - /// Prefix to be adopted to perform the search. - /// Topic containing the lesson. - /// Lesson definition. - public LessonInfo([Required] string jsonUrl, string prefix, - [Required] string topic, [NotNull] Lesson lesson) - { - Uri uri = new Uri(jsonUrl); - Url = new Uri(uri, $"{prefix}{lesson.Id}/{prefix}{lesson.Id}.html"); - Topic = topic; - Name = lesson.Name; - Description = lesson.Description; - Tags = lesson.Tags?.ToArray(); - } - - /// - /// Url of the entry point. - /// - public Uri Url {get; private set;} - - /// - /// Topic for the lesson. - /// - public string Topic {get; private set;} - - /// - /// Name of the training. - /// - public string Name {get; private set;} - - /// - /// Description of the training. - /// - public string Description {get; private set;} - - /// - /// Tags associated to the Training. - /// - public IEnumerable Tags {get; private set;} - - /// - /// Checks if the Training Info has at least a Tag among the specified list. - /// - /// List of desired tags. - /// True if at least a tag is present, false otherwise. - public bool HasTag([NotNull] IEnumerable tags) - { - return tags.Any(x => Tags?.Contains(x) ?? false); - } - } -} diff --git a/Sources/ThreatsManager.Utilities/Training/TrainingPillsAttribute.cs b/Sources/ThreatsManager.Utilities/Training/TrainingPillsAttribute.cs deleted file mode 100644 index 200cd00b..00000000 --- a/Sources/ThreatsManager.Utilities/Training/TrainingPillsAttribute.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using PostSharp.Patterns.Contracts; - -namespace ThreatsManager.Utilities.Training -{ - /// - /// Attribute to be applied to the Assembly to specify where Training Pills for the implemented Extensions can be found. - /// - [AttributeUsage(AttributeTargets.Assembly, AllowMultiple = false)] - public class TrainingPillsAttribute : Attribute - { - /// - /// Constructor to specify where the Training Pills for the implemented Extensions are uploaded. - /// - /// Url containing the Training Pills. - public TrainingPillsAttribute([Required] string baseUrl) - { - BaseUrl = baseUrl; - } - - /// - /// Url containing the Training Pills. - /// - public string BaseUrl { get; set; } - } -} \ No newline at end of file diff --git a/Sources/ThreatsManager.Utilities/Training/TrainingPillsManager.cs b/Sources/ThreatsManager.Utilities/Training/TrainingPillsManager.cs deleted file mode 100644 index d9f021a7..00000000 --- a/Sources/ThreatsManager.Utilities/Training/TrainingPillsManager.cs +++ /dev/null @@ -1,209 +0,0 @@ -using PostSharp.Patterns.Contracts; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using PostSharp.Patterns.Threading; -using Newtonsoft.Json; - -namespace ThreatsManager.Utilities.Training -{ - /// - /// Training Pills Manager. - /// - /// In implements the Singleton pattern. - public sealed class TrainingPillsManager - { - private static readonly Lazy _instance = - new Lazy(() => new TrainingPillsManager()); - - private List _knownSources = new List(); - - private Dictionary> _trainings = - new Dictionary>(); - - private List _tags = new List(); - - /// - /// Returns the unique instance of the Training Pills Manager. - /// - public static TrainingPillsManager Instance => _instance.Value; - - private TrainingPillsManager() - { - } - - /// - /// Add the Training Pills source related to the Assembly. - /// - /// Assembly to be analyzed. - public void Add([NotNull] Assembly assembly) - { - var attribs = assembly.GetCustomAttributes().ToArray(); - if (attribs.Any()) - { - foreach (var attrib in attribs) - Add(attrib.BaseUrl); - } - } - - /// - /// Add the Training Pills source from the specified base url. - /// - /// - public void Add([Required] string baseUrl) - { - if (!_knownSources.Contains(baseUrl)) - { - lock (_instance) - { - if (!_knownSources.Contains(baseUrl)) - { - _knownSources.Add(baseUrl); - ProcessTrainingPills(baseUrl); - } - } - } - } - - /// - /// Get the list of known tags, ordered alphabetically. - /// - public IEnumerable Tags => _tags.OrderBy(x => x).ToArray(); - - /// - /// Supported levels. - /// - public IEnumerable SupportedLevels => _trainings.Keys; - - /// - /// Get the lessons for a specific level. - /// - /// Level of the training. - /// Required tags. - /// List of Lessons for the given level and with at least one of the searched tags, if specified. - public IEnumerable GetLessons(TrainingLevel level, IEnumerable requiredTags = null) - { - IEnumerable result; - - if (!_trainings.TryGetValue(level, out var trainings)) - trainings = null; - - if ((trainings?.Any() ?? false) && requiredTags != null) - { - result = GetLessons(trainings, requiredTags); - } - else - result = trainings; - - return result; - } - - /// - /// Get the lessons. - /// - /// Required tags. - /// List of Lessons with at least one of the searched tags, if specified. - public IEnumerable GetLessons(IEnumerable requiredTags = null) - { - List trainings = new List(); - var intro = GetLessons(TrainingLevel.Introductive, requiredTags); - if (intro?.Any() ?? false) - { - trainings.AddRange(intro); - } - var adv = GetLessons(TrainingLevel.Advanced, requiredTags); - if (adv?.Any() ?? false) - { - trainings.AddRange(adv); - } - var exp = GetLessons(TrainingLevel.Expert, requiredTags); - if (exp?.Any() ?? false) - { - trainings.AddRange(exp); - } - - return trainings; - } - - private IEnumerable GetLessons([NotNull] IEnumerable trainings, [NotNull] IEnumerable tags) - { - List result = new List(); - - foreach (var item in trainings) - { - if (item.HasTag(tags)) - result.Add(item); - } - - return result; - } - - [Background] - private void ProcessTrainingPills([Required] string baseUrl) - { - using (var webClient = new System.Net.WebClient()) - { - Uri uri = new Uri(baseUrl); - - string json = null; - try - { - json = webClient.DownloadString(new Uri(uri, "trainingpills.json")); - } - catch - { - return; - } - - if (!string.IsNullOrWhiteSpace(json)) - { - var definition = JsonConvert.DeserializeObject(json, - new JsonSerializerSettings() - { - TypeNameHandling = TypeNameHandling.None - }); - - var sections = definition?.Sections?.ToArray(); - if (sections?.Any() ?? false) - { - foreach (var section in sections) - { - var topics = section.Topics?.ToArray(); - if (topics?.Any() ?? false) - { - List trainings; - if (!_trainings.TryGetValue(section.SectionType, out trainings)) - { - trainings = new List(); - _trainings.Add(section.SectionType, trainings); - } - - foreach (var topic in topics) - { - var lessons = topic.Lessons?.ToArray(); - if (lessons?.Any() ?? false) - { - foreach (var lesson in lessons) - { - trainings.Add(new LessonInfo(baseUrl, section.Prefix, topic.Name, lesson)); - var tags = lesson.Tags?.ToArray(); - if (tags?.Any() ?? false) - { - foreach (var tag in tags) - { - if (!_tags.Contains(tag)) - _tags.Add(tag); - } - } - } - } - } - } - } - } - } - } - } - } -}