From 002a8bb6e45f12db8d61a744b3f47f793164f899 Mon Sep 17 00:00:00 2001 From: Tim Purschke Date: Mon, 6 May 2024 17:50:20 +0200 Subject: [PATCH 1/8] catch import response error --- roles/importer/files/importer/common.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/roles/importer/files/importer/common.py b/roles/importer/files/importer/common.py index 96c8f2916..a41654f10 100644 --- a/roles/importer/files/importer/common.py +++ b/roles/importer/files/importer/common.py @@ -349,7 +349,11 @@ def replace_device_id(config, mgm_details): with open(filename, 'r') as json_file: config = json.load(json_file) except requests.exceptions.RequestException: - error_string = 'got HTTP status code{code} while trying to read config file from URL {filename}'.format(code=str(r.status_code), filename=filename) + try: + r + error_string = 'got HTTP status code{code} while trying to read config file from URL {filename}'.format(code=str(r.status_code), filename=filename) + except NameError: + error_string = 'got error while trying to read config file from URL {filename}'.format(filename=filename) error_count += 1 error_count = complete_import(current_import_id, error_string, start_time, mgm_details, change_count, error_count, jwt) raise ConfigFileNotFound(error_string) from None From ed7fd29bd74202da9c8599b04b623684a2dd58c0 Mon Sep 17 00:00:00 2001 From: Tim Purschke Date: Tue, 14 May 2024 16:13:52 +0200 Subject: [PATCH 2/8] hotfix mail cred decryption --- roles/lib/files/FWO.Mail/FWO.Mail.csproj | 4 ++++ roles/lib/files/FWO.Mail/MailerMailKit.cs | 13 ++++++++++++- .../files/FWO.UI/Pages/Settings/SettingsEmail.razor | 12 ------------ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/roles/lib/files/FWO.Mail/FWO.Mail.csproj b/roles/lib/files/FWO.Mail/FWO.Mail.csproj index ceba8ce07..beaff5d3b 100644 --- a/roles/lib/files/FWO.Mail/FWO.Mail.csproj +++ b/roles/lib/files/FWO.Mail/FWO.Mail.csproj @@ -12,4 +12,8 @@ + + + + diff --git a/roles/lib/files/FWO.Mail/MailerMailKit.cs b/roles/lib/files/FWO.Mail/MailerMailKit.cs index d1bbff594..084d6bb35 100644 --- a/roles/lib/files/FWO.Mail/MailerMailKit.cs +++ b/roles/lib/files/FWO.Mail/MailerMailKit.cs @@ -4,6 +4,7 @@ using MailKit.Security; using MimeKit; using Microsoft.AspNetCore.Http; +using FWO.Encryption; namespace FWO.Mail { @@ -199,7 +200,17 @@ await smtp.ConnectAsync( } if (emailConn.User != null && emailConn.User != "") { - await smtp.AuthenticateAsync(emailConn.User, emailConn.Password, ct); + string mainKey = AesEnc.GetMainKey(); + string decryptedSecret = emailConn.Password; + try + { + decryptedSecret = AesEnc.Decrypt(emailConn.Password, mainKey); + } + catch (Exception) + { + } + + await smtp.AuthenticateAsync(emailConn.User, decryptedSecret, ct); } await smtp.SendAsync(mail, ct); await smtp.DisconnectAsync(true, ct); diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsEmail.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsEmail.razor index 2f6bbd59e..a5f6a06c3 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsEmail.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsEmail.razor @@ -210,13 +210,6 @@ { try { - // decrypt password if set - string encryptedPassword = ""; - if (actEmailConnection.Password != null) - { - encryptedPassword = actEmailConnection.Password; - actEmailConnection.Password = AesEnc.Decrypt(actEmailConnection.Password, AesEnc.GetMainKey()); - } MailKitMailer mailer = new(actEmailConnection); if (userConfig.User.Email == null || userConfig.User.Email == "") { @@ -235,11 +228,6 @@ DisplayMessageInUi(null, userConfig.GetText("test_email_connection"), "could not send message", true); } } - // if password was set, re-assign the enrypted password - if (actEmailConnection.Password != null) - { - actEmailConnection.Password = encryptedPassword; - } } catch (System.Exception exception) { From 0797d30a52b4204cfc69978602467fb79ae58e9e Mon Sep 17 00:00:00 2001 From: Tim Purschke Date: Tue, 14 May 2024 16:17:08 +0200 Subject: [PATCH 3/8] localization spinner --- .../files/sql/idempotent/fworch-texts.sql | 23 +- .../Pages/Monitoring/MonitorAlerts.razor | 2 +- .../FWO.UI/Pages/Monitoring/MonitorAll.razor | 2 +- .../Monitoring/MonitorAutodiscoveryLog.razor | 2 +- .../Pages/Monitoring/MonitorDailyChecks.razor | 2 +- .../Pages/Monitoring/MonitorImportLog.razor | 2 +- .../Monitoring/MonitorImportStatus.razor | 2 +- .../Pages/Monitoring/MonitorUiLog.razor | 2 +- .../Pages/Monitoring/MonitoringMain.razor | 2 +- .../NetworkModelling/NetworkModelling.razor | 208 ++++++++++++++---- .../Pages/Request/DisplayAccessElements.razor | 2 +- .../Pages/Request/RequestApprovals.razor | 2 +- .../Request/RequestImplementations.razor | 2 +- .../Pages/Request/RequestPlannings.razor | 2 +- .../FWO.UI/Pages/Request/RequestReviews.razor | 2 +- .../FWO.UI/Pages/Request/RequestTickets.razor | 2 +- .../Request/RequestTicketsOverview.razor | 2 +- .../Pages/Settings/SettingsActions.razor | 2 +- .../Pages/Settings/SettingsCustomizing.razor | 2 +- .../Pages/Settings/SettingsDefaults.razor | 2 +- .../Settings/SettingsExternalWorkflow.razor | 145 ++++++++++++ .../Pages/Settings/SettingsImport.razor | 2 +- .../Pages/Settings/SettingsModelling.razor | 2 +- .../Settings/SettingsModellingPers.razor | 2 +- .../FWO.UI/Pages/Settings/SettingsOwner.razor | 4 +- .../Settings/SettingsPasswordPolicy.razor | 2 +- .../Settings/SettingsRecertificationGen.razor | 4 +- .../SettingsRecertificationPers.razor | 2 +- .../Pages/Settings/SettingsReport.razor | 2 +- .../Pages/Settings/SettingsStateMatrix.razor | 2 +- .../Pages/Settings/SettingsStates.razor | 2 +- .../files/FWO.UI/Shared/RequestLayout.razor | 2 +- 32 files changed, 363 insertions(+), 75 deletions(-) create mode 100644 roles/ui/files/FWO.UI/Pages/Settings/SettingsExternalWorkflow.razor diff --git a/roles/database/files/sql/idempotent/fworch-texts.sql b/roles/database/files/sql/idempotent/fworch-texts.sql index 488db5e9f..bb6392856 100644 --- a/roles/database/files/sql/idempotent/fworch-texts.sql +++ b/roles/database/files/sql/idempotent/fworch-texts.sql @@ -245,6 +245,8 @@ INSERT INTO txt VALUES ('in_progress', 'German', 'in Arbeit'); INSERT INTO txt VALUES ('in_progress', 'English', 'in progress'); INSERT INTO txt VALUES ('select', 'German', 'Auswählen'); INSERT INTO txt VALUES ('select', 'English', 'Select'); +INSERT INTO txt VALUES ('loading', 'German', 'Laden...'); +INSERT INTO txt VALUES ('loading', 'English', 'Loading...'); -- (re)login INSERT INTO txt VALUES ('login', 'German', 'Anmelden'); @@ -1128,8 +1130,13 @@ INSERT INTO txt VALUES ('save_service', 'German', 'Dienst speichern'); INSERT INTO txt VALUES ('save_service', 'English', 'Save Service'); INSERT INTO txt VALUES ('delete_service', 'German', 'Dienst löschen'); INSERT INTO txt VALUES ('delete_service', 'English', 'Delete Service'); -INSERT INTO txt VALUES ('ext_request', 'German', 'Externer Antrag'); -INSERT INTO txt VALUES ('ext_request', 'English', 'External Request'); +INSERT INTO txt VALUES ('ext_ticket_url', 'German', 'URL des externen Ticketing Systems'); +INSERT INTO txt VALUES ('ext_ticket_url', 'English', 'URL of external ticketing system'); +INSERT INTO txt VALUES ('ext_ticket_template', 'German', 'Template Ticket-Text'); +INSERT INTO txt VALUES ('ext_ticket_template', 'English', 'Template ticket text'); +INSERT INTO txt VALUES ('ext_task_template', 'German', 'Template Aufgabentext'); +INSERT INTO txt VALUES ('ext_task_template', 'English', 'Template task text'); + INSERT INTO txt VALUES ('area', 'German', 'Area'); INSERT INTO txt VALUES ('area', 'English', 'Area'); INSERT INTO txt VALUES ('interface', 'German', 'Schnittstelle'); @@ -1182,6 +1189,8 @@ INSERT INTO txt VALUES ('log_change', 'German', 'Änderung loggen'); INSERT INTO txt VALUES ('log_change', 'English', 'Log Change'); INSERT INTO txt VALUES ('show_history', 'German', 'Änderungshistorie'); INSERT INTO txt VALUES ('show_history', 'English', 'Show History'); +INSERT INTO txt VALUES ('request_fw_change', 'German', 'Firewall-Änderungen beantragen'); +INSERT INTO txt VALUES ('request_fw_change', 'English', 'Request firewall changes'); INSERT INTO txt VALUES ('changed_by', 'German', 'Geändert von'); INSERT INTO txt VALUES ('changed_by', 'English', 'Changed by'); INSERT INTO txt VALUES ('object_id', 'German', 'Objekt-Id'); @@ -1910,6 +1919,10 @@ INSERT INTO txt VALUES ('import_source', 'German', 'Importquelle'); INSERT INTO txt VALUES ('import_source', 'English', 'Import Source'); INSERT INTO txt VALUES ('modelling_settings', 'German', 'Modellierungseinstellungen'); INSERT INTO txt VALUES ('modelling_settings', 'English', 'Modelling Settings'); +INSERT INTO txt VALUES ('ext_ticketing', 'German', 'Externes Ticket-System'); +INSERT INTO txt VALUES ('ext_ticketing', 'English', 'External ticket tool'); +INSERT INTO txt VALUES ('ext_ticket_settings', 'German', 'Einstellungen externes Ticket-System'); +INSERT INTO txt VALUES ('ext_ticket_settings', 'English', 'Settings external ticket tool'); INSERT INTO txt VALUES ('modIconify', 'German', 'Nutzung von Piktogrammen'); INSERT INTO txt VALUES ('modIconify', 'English', 'Prefer use of Icons'); INSERT INTO txt VALUES ('use_in_src', 'German', 'in Quelle'); @@ -4646,6 +4659,12 @@ INSERT INTO txt VALUES ('H5627', 'German', 'App-Server-Typen: Hier können INSERT INTO txt VALUES ('H5627', 'English', 'App Server Types: Here any App Server Types can be defined with name and Id. Please use different Ids. Be careful when deleting types already in use! The default type should always exist and is used during data import. Here only the displayed name can be chosen. It is not available for manual assignment to an App Server. '); +INSERT INTO txt VALUES ('H5628', 'German', 'Vordefinierte Dienste: Hier wird dem Administrator ein Menü angeboten, um Dienste und Gruppierungen von Diensten vorzudefinieren, + zu bearbeiten oder zu löschen. Diese stehen dann allen Applikationen zur Verfügung. +'); +INSERT INTO txt VALUES ('H5628', 'English', 'Predefined Services: Offers a menu to the administrator to define, change or delete predefined services or service groups. + These services are available for all applications. +'); INSERT INTO txt VALUES ('H5701', 'German', 'Die in der Datenbank hinterlegten sprachabhängigen Texte können individuell überschrieben werden. Dabei werden die vom System vorgegebenen Texte nicht geändert, sondern nur durch die hier definierten Texte - falls vorhanden - überblendet. diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAlerts.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAlerts.razor index e91030d7d..be2e504db 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAlerts.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAlerts.razor @@ -43,7 +43,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAll.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAll.razor index a3feae8e6..5eca9a687 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAll.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAll.razor @@ -35,7 +35,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAutodiscoveryLog.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAutodiscoveryLog.razor index 363f2bddc..37468f39e 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAutodiscoveryLog.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorAutodiscoveryLog.razor @@ -36,7 +36,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorDailyChecks.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorDailyChecks.razor index 36c501ab1..e1f2a9736 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorDailyChecks.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorDailyChecks.razor @@ -26,7 +26,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportLog.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportLog.razor index b3ff515c5..ee3961d2d 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportLog.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportLog.razor @@ -34,7 +34,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportStatus.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportStatus.razor index 4a7aefc01..53eb2f0f9 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportStatus.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorImportStatus.razor @@ -86,7 +86,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorUiLog.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorUiLog.razor index 296988d42..0e4f17e56 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorUiLog.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitorUiLog.razor @@ -47,7 +47,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitoringMain.razor b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitoringMain.razor index 93e4dfcea..78fe0ee0b 100644 --- a/roles/ui/files/FWO.UI/Pages/Monitoring/MonitoringMain.razor +++ b/roles/ui/files/FWO.UI/Pages/Monitoring/MonitoringMain.razor @@ -86,7 +86,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/NetworkModelling/NetworkModelling.razor b/roles/ui/files/FWO.UI/Pages/NetworkModelling/NetworkModelling.razor index 9ce940b8f..abfbdf670 100644 --- a/roles/ui/files/FWO.UI/Pages/NetworkModelling/NetworkModelling.razor +++ b/roles/ui/files/FWO.UI/Pages/NetworkModelling/NetworkModelling.razor @@ -1,5 +1,12 @@ @using FWO.Config.Api +@using FWO.Config.Api.Data @using FWO.Ui.Display +@using FWO.Tufin.SecureChange +@using FWO.Rest.Client +@using System.Text.Json +@using System.Text.Json.Serialization +@using System.Net +@using RestSharp @page "/networkmodelling/{appId?}/{connId?}" @attribute [Authorize(Roles = $"{Roles.Admin}, {Roles.Modeller}, {Roles.Auditor}")] @@ -7,13 +14,14 @@ @inject ApiConnection apiConnection @inject UserConfig userConfig @inject NavigationManager NavigationManager +@inject GlobalConfig globalConfig -@if(!appHandler?.EditConnMode ?? true) +@if (!appHandler?.EditConnMode ?? true) {
-

@(userConfig.GetText("network_modelling"))

- -
+

@(userConfig.GetText("network_modelling"))

+ +
@@ -22,58 +30,72 @@
- - - @* *@ + + +

- @if(appSelected) + @if (appSelected) {
-
@(userConfig.GetText("comm_profile"))  - @if(appActive) - { -
- - - - - -
- } +
@(userConfig.GetText("comm_profile"))  + @if (appActive) + { +
+ + + + + +
+ }
- - + + - - + + - @if(selectedApp.CommSvcPossible) + @if (selectedApp.CommSvcPossible) { - - + + }
- + } } else { - + } - - + + @code { @@ -104,7 +126,8 @@ else protected override async Task OnInitializedAsync() { // if use has modeller role, choose it before all others for this menu - apiConnection.SetProperRole(authenticationStateTask!.Result.User, new List { Roles.Modeller, Roles.Admin, Roles.Auditor }); + apiConnection.SetProperRole(authenticationStateTask!.Result.User, new List { Roles.Modeller, Roles.Admin, +Roles.Auditor }); await InitAppList(); } @@ -112,12 +135,12 @@ else { if (appSelected && appHandler != null) { - if(!tabSelected) + if (!tabSelected) { tabSelected = true; appHandler.InitActiveTab(); } - else if(restoreTab) + else if (restoreTab) { restoreTab = false; appHandler.RestoreTab(lastConn); @@ -136,14 +159,15 @@ else { try { - apps = await ModellingHandlerBase.GetOwnApps(authenticationStateTask, userConfig, apiConnection, DisplayMessageInUi, true); + apps = await ModellingHandlerBase.GetOwnApps(authenticationStateTask, userConfig, apiConnection, DisplayMessageInUi, + true); if (apps.Count == 0) { DisplayMessageInUi(null, userConfig.GetText("fetch_data"), userConfig.GetText("E9001"), true); } else { - if(AppId != null) + if (AppId != null) { await HandleLink(); } @@ -163,7 +187,7 @@ else private async Task HandleLink() { FwoOwner? existingApp = apps.FirstOrDefault(a => a.ExtAppId == AppId); - if(existingApp != null) + if (existingApp != null) { selectedApp = existingApp; } @@ -179,17 +203,18 @@ else { appSelected = false; selectedApp = newApp; - bool isOwner = authenticationStateTask!.Result.User.IsInRole(Roles.Modeller) && userConfig.User.Ownerships.Contains(selectedApp.Id); + bool isOwner = authenticationStateTask!.Result.User.IsInRole(Roles.Modeller) && + userConfig.User.Ownerships.Contains(selectedApp.Id); appHandler = new ModellingAppHandler(apiConnection, userConfig, selectedApp, DisplayMessageInUi, isOwner); await appHandler.Init(); appActive = selectedApp.Active; - if(isOwner) + if (isOwner) { apiConnection.SetRole(Roles.Modeller); } else { - apiConnection.SetProperRole(authenticationStateTask!.Result.User, new List { Roles.Admin, Roles.Auditor}); + apiConnection.SetProperRole(authenticationStateTask!.Result.User, new List { Roles.Admin, Roles.Auditor }); } appSelected = true; tabSelected = false; @@ -203,7 +228,7 @@ else private async Task InitConn() { - if(ConnId != null && int.TryParse(ConnId, out int connectionId)) + if (ConnId != null && int.TryParse(ConnId, out int connectionId)) { ModellingConnection? selectedConn = appHandler?.Connections.FirstOrDefault(c => c.Id == connectionId); if (selectedConn != null) @@ -230,8 +255,107 @@ else NavigationManager.NavigateTo($"/report/generation/{selectedApp.Id}"); } - private async Task ExtRequest() + private async Task RequestFwChange() { + SCTicket ticket = new("test ticket 1", TicketPriority.High); + ConfigData? configData; + string extTicketingSystemUrl = ""; + string ticketTemplate = ""; + string taskTemplate = ""; + + // mockup + + List sources = new() + { + new() + { + Id = 42, + Name = "srv1", + Type = new NetworkObjectType(){ Name = ObjectType.Host }, + IP = "1.2.3.4" + } + }; + + List destinations = new() + { + new() + { + Id = 4711, + Name = "srv1", + Type = new NetworkObjectType(){ Name = ObjectType.Host }, + IP = "5.5.5.5" + } + }; + + List svcs = new() + { + new() + { + Id = 1234, + Name = "svcX", + Type = new NetworkServiceType(){ Name = ServiceType.SimpleService }, + DestinationPort = 112, + Protocol = new NetworkProtocol(){Id = 50, Name = "ESP"} + } + }; + + // adding access request + ticket.AddTask(sources, svcs, destinations); + + try + { + configData = await globalConfig.GetEditableConfig(); + List extTicketSystems = System.Text.Json.JsonSerializer.Deserialize>(configData.ExtTicketSystems) ?? new(); + if (extTicketSystems.Count()>0) + { + RestResponse ticketIdResponse = await ticket.CreateTicketInTufin(extTicketSystems.First(), appHandler.Connections); + if (ticketIdResponse.StatusCode != HttpStatusCode.OK) + { + DisplayMessageInUi(null, userConfig.GetText("xxx"), userConfig.GetText("xxx"), true); + } + else + { + DisplayMessageInUi(null, userConfig.GetText("xxx"), "created ticket: " + ticketIdResponse.Data, true); + } + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("read_config"), userConfig.GetText("E5301"), false); + } + + +/* + if (appHandler?.Connections != null && appHandler?.Connections.Count()>0) + { + if (appHandler.Connections.First() != null) + { + ModellingConnection firstConn = appHandler.Connections.First(); + //ticket.AddTask(FirstConn.SourceAppServers[0], FirstConn.Services[0], FirstConn.DestinationAppServers[0]); + //ticketNumber = ticket.CreateTicketInTufin(); + } + + foreach (Connection conn in appHandler.Connections) + { + SCTicket ticket = new (conn); + ticketNumber = ticket.Create(); + } + + + + foreach conn in appHandler.conns + create ticket to create objects?? + store these tickets with conn? + + SCTicket ticket = new (conn); + ticketNumber = ticket.Create(); + store ticketNumber with conn with state = open + + in MW: create scheduler to check each conn that has open tickets + + + } +*/ } } diff --git a/roles/ui/files/FWO.UI/Pages/Request/DisplayAccessElements.razor b/roles/ui/files/FWO.UI/Pages/Request/DisplayAccessElements.razor index e55102411..f87241452 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/DisplayAccessElements.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/DisplayAccessElements.razor @@ -210,7 +210,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestApprovals.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestApprovals.razor index 7bc20306e..c9377769f 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestApprovals.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestApprovals.razor @@ -24,7 +24,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestImplementations.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestImplementations.razor index 5fc7de691..f30f051dd 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestImplementations.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestImplementations.razor @@ -34,7 +34,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestPlannings.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestPlannings.razor index 8c664f4df..a0a9d0905 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestPlannings.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestPlannings.razor @@ -24,7 +24,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestReviews.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestReviews.razor index 00586e54b..e825ce73e 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestReviews.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestReviews.razor @@ -33,7 +33,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestTickets.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestTickets.razor index e04b5b8a9..1e5890bba 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestTickets.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestTickets.razor @@ -23,7 +23,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Request/RequestTicketsOverview.razor b/roles/ui/files/FWO.UI/Pages/Request/RequestTicketsOverview.razor index 07cc62502..716e9fcdd 100644 --- a/roles/ui/files/FWO.UI/Pages/Request/RequestTicketsOverview.razor +++ b/roles/ui/files/FWO.UI/Pages/Request/RequestTicketsOverview.razor @@ -22,7 +22,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsActions.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsActions.razor index a13db841d..823e897ed 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsActions.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsActions.razor @@ -317,7 +317,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsCustomizing.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsCustomizing.razor index 3f3bb8c8a..72f766ae7 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsCustomizing.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsCustomizing.razor @@ -117,7 +117,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsDefaults.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsDefaults.razor index 40c13bd80..4807c0687 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsDefaults.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsDefaults.razor @@ -179,7 +179,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsExternalWorkflow.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsExternalWorkflow.razor new file mode 100644 index 000000000..8f389f38b --- /dev/null +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsExternalWorkflow.razor @@ -0,0 +1,145 @@ + +@using System.Net +@using FWO.Api.Client +@using FWO.Config.Api +@using FWO.Config.Api.Data +@using FWO.Middleware.Client +@using FWO.Middleware.RequestParameters +@using RestSharp +@using FWO.GlobalConstants +@using FWO.Api.Data +@using FWO.Logging +@using FWO.Recert +@using FWO.Ui.Pages.NetworkModelling + + +@using FWO.Config.Api +@using FWO.GlobalConstants +@using FWO.Api.Data +@using System.Text.Json +@using System.Net +@using FWO.Middleware.Client +@using FWO.Middleware.RequestParameters +@using RestSharp + + +@page "/settings/extticketing" +@attribute [Authorize(Roles = $"{Roles.Admin}, {Roles.Auditor}")] + +@inject ApiConnection apiConnection +@inject GlobalConfig globalConfig +@inject UserConfig userConfig + +
+

@(userConfig.GetText("ext_ticket_settings"))

+ +
+@(userConfig.GetText("U5322")) +
+ +@if (configData != null) +{ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+ +
+ +
+
+
+
+
+ + + + + + + + +

+

@(userConfig.GetText("U5303"))

+} +else +{ +
+ @(userConfig.GetText("loading")) +
+} + +@code +{ + [CascadingParameter] + Action DisplayMessageInUi { get; set; } = DefaultInit.DoNothing; + + private ConfigData? configData; + private string extTicketingSystemUrl = ""; + private string extTicketingSystemAuth = ""; + private string ticketTemplate = ""; + private string tasksTemplate = ""; + + ExternalTicketSystem currentSystem = new(); + + protected override async Task OnInitializedAsync() + { + try + { + configData = await globalConfig.GetEditableConfig(); + List extTicketSystems = System.Text.Json.JsonSerializer.Deserialize>(configData.ExtTicketSystems) ?? new(); + if (extTicketSystems.Count()>0) + { + extTicketingSystemUrl = extTicketSystems.First().Url; + extTicketingSystemAuth = extTicketSystems.First().Authorization; + ticketTemplate = extTicketSystems.First().TicketTemplate; + tasksTemplate = extTicketSystems.First().TasksTemplate; + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("read_config"), userConfig.GetText("E5301"), false); + } + } + + private async Task Save() + { + try + { + if (configData != null) + { + List currentSystems = new(); + currentSystems.Add(new ExternalTicketSystem(extTicketingSystemUrl, ticketTemplate, tasksTemplate, extTicketingSystemAuth)); + configData.ExtTicketSystems = System.Text.Json.JsonSerializer.Serialize(currentSystems); + await globalConfig.WriteToDatabase(configData, apiConnection); + DisplayMessageInUi(null, userConfig.GetText("ext_ticket_settings"), userConfig.GetText("U5301"), false); + } + else + { + throw new Exception("Data saved before loaded. This should be impossible."); + } + } + catch (Exception exception) + { + DisplayMessageInUi(exception, userConfig.GetText("ext_ticket_settings"), "", true); + } + } + +} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsImport.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsImport.razor index b8c11c8fd..c3e37b857 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsImport.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsImport.razor @@ -108,7 +108,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsModelling.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsModelling.razor index 1e76a1d7f..84032e8f7 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsModelling.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsModelling.razor @@ -221,7 +221,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsModellingPers.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsModellingPers.razor index d65c61b96..530b3a639 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsModellingPers.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsModellingPers.razor @@ -39,7 +39,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsOwner.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsOwner.razor index 51b86d8cb..f6555c5db 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsOwner.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsOwner.razor @@ -46,7 +46,7 @@ } else { -
Loading...
+
@(userConfig.GetText("loading"))
} @@ -324,7 +324,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsPasswordPolicy.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsPasswordPolicy.razor index 62299382c..27718d6f6 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsPasswordPolicy.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsPasswordPolicy.razor @@ -63,7 +63,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationGen.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationGen.razor index df2f69c48..bb095457b 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationGen.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationGen.razor @@ -188,7 +188,7 @@ } else { -
Loading...
+
@(userConfig.GetText("loading"))
}
@@ -214,7 +214,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationPers.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationPers.razor index 36f4a0d73..65affc1aa 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationPers.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsRecertificationPers.razor @@ -32,7 +32,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsReport.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsReport.razor index 9bbf65589..11e455bd8 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsReport.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsReport.razor @@ -63,7 +63,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsStateMatrix.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsStateMatrix.razor index 1c07b6e29..b73813290 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsStateMatrix.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsStateMatrix.razor @@ -230,7 +230,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Pages/Settings/SettingsStates.razor b/roles/ui/files/FWO.UI/Pages/Settings/SettingsStates.razor index ede059e0d..ff43d15c2 100644 --- a/roles/ui/files/FWO.UI/Pages/Settings/SettingsStates.razor +++ b/roles/ui/files/FWO.UI/Pages/Settings/SettingsStates.razor @@ -133,7 +133,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} diff --git a/roles/ui/files/FWO.UI/Shared/RequestLayout.razor b/roles/ui/files/FWO.UI/Shared/RequestLayout.razor index 8ae0e8fa4..c239798b2 100644 --- a/roles/ui/files/FWO.UI/Shared/RequestLayout.razor +++ b/roles/ui/files/FWO.UI/Shared/RequestLayout.razor @@ -93,7 +93,7 @@ else {
- Loading... + @(userConfig.GetText("loading"))
} From d92915d3adf981cff863d1f3185b33c7226c483a Mon Sep 17 00:00:00 2001 From: Tim Purschke Date: Tue, 14 May 2024 16:20:52 +0200 Subject: [PATCH 4/8] docs --- roles/importer/files/importer/common.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/roles/importer/files/importer/common.py b/roles/importer/files/importer/common.py index a41654f10..ca620ba5a 100644 --- a/roles/importer/files/importer/common.py +++ b/roles/importer/files/importer/common.py @@ -350,7 +350,9 @@ def replace_device_id(config, mgm_details): config = json.load(json_file) except requests.exceptions.RequestException: try: + # check if response "r" is defined: r + error_string = 'got HTTP status code{code} while trying to read config file from URL {filename}'.format(code=str(r.status_code), filename=filename) except NameError: error_string = 'got error while trying to read config file from URL {filename}'.format(filename=filename) From 48d6f8d844cafb52748d63b282428a00ba95cc2a Mon Sep 17 00:00:00 2001 From: Tim Purschke Date: Tue, 14 May 2024 17:19:43 +0200 Subject: [PATCH 5/8] start of securechange integration mock up first --- documentation/revision-history-develop.md | 6 +- inventory/group_vars/all.yml | 2 +- roles/FWO.sln | 7 + .../files/sql/creation/fworch-fill-stm.sql | 1 + roles/database/files/upgrade/8.2.2.sql | 37 ++ .../Data/ExternalTicketSystem.cs | 68 +++ roles/lib/files/FWO.Config.Api/Config.cs | 5 - .../files/FWO.Config.Api/Data/ConfigData.cs | 407 +++++++++--------- .../FWO.GlobalConstants/GlobalConstants.cs | 73 ++-- .../FWO.Tufin.SecureChange/ExternalTicket.cs | 324 ++++++++++++++ .../ExternalTicketTask.cs | 65 +++ .../FWO.Tufin.SecureChange.csproj | 21 + roles/ui/files/FWO.UI/FWO.Ui.csproj | 1 + .../files/FWO.UI/Shared/SettingsLayout.razor | 5 + 14 files changed, 780 insertions(+), 242 deletions(-) create mode 100644 roles/database/files/upgrade/8.2.2.sql create mode 100644 roles/lib/files/FWO.Api.Client/Data/ExternalTicketSystem.cs create mode 100644 roles/lib/files/FWO.Tufin.SecureChange/ExternalTicket.cs create mode 100644 roles/lib/files/FWO.Tufin.SecureChange/ExternalTicketTask.cs create mode 100644 roles/lib/files/FWO.Tufin.SecureChange/FWO.Tufin.SecureChange.csproj diff --git a/documentation/revision-history-develop.md b/documentation/revision-history-develop.md index df39a94e6..21c33a55e 100644 --- a/documentation/revision-history-develop.md +++ b/documentation/revision-history-develop.md @@ -203,5 +203,9 @@ bugfix release: - upgrade to dotnet 8.0 - adding all imported modelling users to uiuser -# 8.2.1 - xx.05.2024 DEVELOP +# 8.2.1 - 03.05.2024 DEVELOP - fix misleading login error message when authorisation is missing + +# 8.2.2 - 14.05.2024 DEVELOP +- fix email credential decryption +- start of Tufin SecureChange integration diff --git a/inventory/group_vars/all.yml b/inventory/group_vars/all.yml index 19c999f6b..bbc82d385 100644 --- a/inventory/group_vars/all.yml +++ b/inventory/group_vars/all.yml @@ -1,5 +1,5 @@ ### general settings -product_version: "8.2.1" +product_version: "8.2.2" ansible_user: "{{ lookup('env', 'USER') }}" ansible_become_method: sudo ansible_python_interpreter: /usr/bin/python3 diff --git a/roles/FWO.sln b/roles/FWO.sln index 75e798229..64c522a80 100644 --- a/roles/FWO.sln +++ b/roles/FWO.sln @@ -39,6 +39,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.Encryption", "lib\files EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.GlobalConstants", "lib\files\FWO.GlobalConstants\FWO.GlobalConstants.csproj", "{0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FWO.Tufin.SecureChange", "lib\files\FWO.Tufin.SecureChange\FWO.Tufin.SecureChange.csproj", "{17AA0E0C-BB46-42FE-A08C-68539EA7FD53}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -113,6 +115,10 @@ Global {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Debug|Any CPU.Build.0 = Debug|Any CPU {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Release|Any CPU.ActiveCfg = Release|Any CPU {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3}.Release|Any CPU.Build.0 = Release|Any CPU + {17AA0E0C-BB46-42FE-A08C-68539EA7FD53}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {17AA0E0C-BB46-42FE-A08C-68539EA7FD53}.Debug|Any CPU.Build.0 = Debug|Any CPU + {17AA0E0C-BB46-42FE-A08C-68539EA7FD53}.Release|Any CPU.ActiveCfg = Release|Any CPU + {17AA0E0C-BB46-42FE-A08C-68539EA7FD53}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -132,6 +138,7 @@ Global {B48F8BD5-1056-4670-BEFA-F4A260293B6F} = {CE55F125-0CD2-4789-A3C1-045DEF33ABA5} {6EBEBF57-3399-4008-BA10-0D21F6827244} = {B48F8BD5-1056-4670-BEFA-F4A260293B6F} {0CBD4CC5-3E39-4134-A0E1-4DB8999619F3} = {B48F8BD5-1056-4670-BEFA-F4A260293B6F} + {17AA0E0C-BB46-42FE-A08C-68539EA7FD53} = {B48F8BD5-1056-4670-BEFA-F4A260293B6F} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {68364621-1011-4D44-9CF5-518F0DC3F459} diff --git a/roles/database/files/sql/creation/fworch-fill-stm.sql b/roles/database/files/sql/creation/fworch-fill-stm.sql index 8d1e8d45c..1b8721119 100644 --- a/roles/database/files/sql/creation/fworch-fill-stm.sql +++ b/roles/database/files/sql/creation/fworch-fill-stm.sql @@ -109,6 +109,7 @@ insert into config (config_key, config_value, config_user) VALUES ('impChangeNot insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyType', '0', 0); insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifySleepTime', '0', 0); insert into config (config_key, config_value, config_user) VALUES ('impChangeNotifyStartAt', '00:00:00', 0); +insert into config (config_key, config_value, config_user) VALUES ('extTicketSystems', '[{"Url":"","TicketTemplate":"{}", "TasksTemplates": "{}" }]', 0); INSERT INTO "report_format" ("report_format_name") VALUES ('json'); diff --git a/roles/database/files/upgrade/8.2.2.sql b/roles/database/files/upgrade/8.2.2.sql new file mode 100644 index 000000000..861ae84fc --- /dev/null +++ b/roles/database/files/upgrade/8.2.2.sql @@ -0,0 +1,37 @@ +/* + + plan "Tufin SecureChange Request Module" - TUREM + + User Interface + - modeller user can choose to request the current state of modelling for one app/owner + - a button can be used within the modeller top level menu to do so + - modelling which has already been requested and that which has not need to be displayed in NeMo so that each can be easily identified + + Automatic steps: + - TUREM needs to store the last modelling state that was requested in order to be able to request the differences + - database structure needs to be defined - if possible find a simple model which does not look like the current FWO change tracking + (work with a flag - modelled/requested) + - TUREM needs to request the creation of objects (network, service) as well as access requests based on these objects + - TUREM will not take the rulebase of the actual firewalls into account - this will be done by SC + - specifically will changes between two TUREM requests (not requested via TUREM) not be taken into account + + Open decisions/tests + - do we also need to get feedback on the implementation state of the SC ticket? If so, what to do with it? + - at least we should store the tufin ticket numbers in NeMo for reference + - can we always just create a single SC ticket or do we need multiple tickets? + - probably SC cannot deal with order of tasks so that in the first task objects are requested which are then Nused in the same ticket within an AR + - if we need multiple SC tickets, we need to be prepared to store multiple ticket numbers in NeMo for a single TUREM request + - for non-initial requests: do we have to create change requests or do we simply request the whole modelled rulebase? + - same question for changes to (modelled) objects + - what about changes to basic objects like NAs - do we requests these of just assume that they already have been implemented? + - where to draw the line? + + Preparations + - get a technical user with SC create ticket rights on Tufin STEST system + + Not customer related: + - develop in parallel: internal request module which requests the changes within the FWO request module + +*/ + +insert into config (config_key, config_value, config_user) VALUES ('extTicketSystems', '[{"Url":"","TicketTemplate":"{}", "TasksTemplates": "{}" }]', 0) ON CONFLICT DO NOTHING; diff --git a/roles/lib/files/FWO.Api.Client/Data/ExternalTicketSystem.cs b/roles/lib/files/FWO.Api.Client/Data/ExternalTicketSystem.cs new file mode 100644 index 000000000..6e0365feb --- /dev/null +++ b/roles/lib/files/FWO.Api.Client/Data/ExternalTicketSystem.cs @@ -0,0 +1,68 @@ +using Newtonsoft.Json; +using System.Text.Json; +using System.Text.Json.Serialization; + +namespace FWO.Api.Data +{ + + public enum TicketSystemType + { + Generic, + TufinSecureChange, + AlgoSec, + ServiceNow + } + + public enum TicketPriority + { + Low, + Normal, + High, + Critical + } + + public enum TicketTaskType + { + AccessRequest, + NetworkObjectCreate, + NetworkServiceCreate + } + + public class ExternalTicketSystem + { + [JsonProperty("Id"), JsonPropertyName("Id")] + public int Id { get; set; } = 0; + + [JsonProperty("TicketSystemType"), JsonPropertyName("TicketSystemType")] + public TicketSystemType Type { get; set; } = TicketSystemType.Generic; + + [JsonProperty("Authorization"), JsonPropertyName("Authorization")] + public string Authorization { get; set; } = "Basic xyz"; // replace xyz with b64encode(username:password) + + [JsonProperty("Name"), JsonPropertyName("Name")] + public string Name { get; set; } = ""; + + [JsonProperty("Url"), JsonPropertyName("Url")] + public string Url { get; set; } = ""; + + [JsonProperty("TicketTemplate"), JsonPropertyName("TicketTemplate")] + public string TicketTemplate { get; set; } = ""; + + [JsonProperty("TasksTemplate"), JsonPropertyName("TasksTemplate")] + public string TasksTemplate { get; set; } = ""; + + public ExternalTicketSystem() + + { + } + + public ExternalTicketSystem(string url, string ticketTemplate, string tasksTemplate, string auth) + + { + Url = url; + TicketTemplate = ticketTemplate; + TasksTemplate = tasksTemplate; + Authorization = auth; + } + } +} diff --git a/roles/lib/files/FWO.Config.Api/Config.cs b/roles/lib/files/FWO.Config.Api/Config.cs index 38c5a963b..2154ca607 100644 --- a/roles/lib/files/FWO.Config.Api/Config.cs +++ b/roles/lib/files/FWO.Config.Api/Config.cs @@ -2,14 +2,9 @@ using FWO.Api.Client.Queries; using FWO.Config.Api.Data; using FWO.Logging; -using System; -using System.Collections.Generic; using System.ComponentModel; -using System.Linq; using System.Reflection; -using System.Text; using System.Text.Json.Serialization; -using System.Threading.Tasks; namespace FWO.Config.Api { diff --git a/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs b/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs index 9568c912a..7008dc1fd 100644 --- a/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs +++ b/roles/lib/files/FWO.Config.Api/Data/ConfigData.cs @@ -7,303 +7,306 @@ namespace FWO.Config.Api.Data { - [AttributeUsage(AttributeTargets.Property)] - public class UserConfigDataAttribute : Attribute { } + [AttributeUsage(AttributeTargets.Property)] + public class UserConfigDataAttribute : Attribute { } - public class ConfigData : ICloneable - { - public readonly bool Editable; + public class ConfigData : ICloneable + { + public readonly bool Editable; - [JsonProperty("DefaultLanguage"), JsonPropertyName("DefaultLanguage")] - public virtual string DefaultLanguage { get; set; } = GlobalConst.kEnglish; + [JsonProperty("DefaultLanguage"), JsonPropertyName("DefaultLanguage")] + public virtual string DefaultLanguage { get; set; } = GlobalConst.kEnglish; - [JsonProperty("sessionTimeout"), JsonPropertyName("sessionTimeout")] - public int SessionTimeout { get; set; } = 720; + [JsonProperty("sessionTimeout"), JsonPropertyName("sessionTimeout")] + public int SessionTimeout { get; set; } = 720; - [JsonProperty("sessionTimeoutNoticePeriod"), JsonPropertyName("sessionTimeoutNoticePeriod")] - public int SessionTimeoutNoticePeriod { get; set; } = 60; + [JsonProperty("sessionTimeoutNoticePeriod"), JsonPropertyName("sessionTimeoutNoticePeriod")] + public int SessionTimeoutNoticePeriod { get; set; } = 60; - [JsonProperty("uiHostName"), JsonPropertyName("uiHostName")] - public string UiHostName { get; set; } = "http://localhost:5000"; + [JsonProperty("uiHostName"), JsonPropertyName("uiHostName")] + public string UiHostName { get; set; } = "http://localhost:5000"; - // [JsonProperty("maxMessages"), JsonPropertyName("maxMessages"), UserConfigData] - // public int MaxMessages { get; set; } = 3; + // [JsonProperty("maxMessages"), JsonPropertyName("maxMessages"), UserConfigData] + // public int MaxMessages { get; set; } = 3; - [JsonProperty("elementsPerFetch"), JsonPropertyName("elementsPerFetch"), UserConfigData] - public int ElementsPerFetch { get; set; } = 100; + [JsonProperty("elementsPerFetch"), JsonPropertyName("elementsPerFetch"), UserConfigData] + public int ElementsPerFetch { get; set; } = 100; - [JsonProperty("maxInitialFetchesRightSidebar"), JsonPropertyName("maxInitialFetchesRightSidebar")] - public int MaxInitialFetchesRightSidebar { get; set; } = 10; + [JsonProperty("maxInitialFetchesRightSidebar"), JsonPropertyName("maxInitialFetchesRightSidebar")] + public int MaxInitialFetchesRightSidebar { get; set; } = 10; - [JsonProperty("autoFillRightSidebar"), JsonPropertyName("autoFillRightSidebar")] - public bool AutoFillRightSidebar { get; set; } = false; + [JsonProperty("autoFillRightSidebar"), JsonPropertyName("autoFillRightSidebar")] + public bool AutoFillRightSidebar { get; set; } = false; - [JsonProperty("unusedTolerance"), JsonPropertyName("unusedTolerance")] - public int UnusedTolerance { get; set; } = 400; + [JsonProperty("unusedTolerance"), JsonPropertyName("unusedTolerance")] + public int UnusedTolerance { get; set; } = 400; - [JsonProperty("creationTolerance"), JsonPropertyName("creationTolerance")] - public int CreationTolerance { get; set; } = 90; + [JsonProperty("creationTolerance"), JsonPropertyName("creationTolerance")] + public int CreationTolerance { get; set; } = 90; - [JsonProperty("dataRetentionTime"), JsonPropertyName("dataRetentionTime")] - public int DataRetentionTime { get; set; } = 731; + [JsonProperty("dataRetentionTime"), JsonPropertyName("dataRetentionTime")] + public int DataRetentionTime { get; set; } = 731; - [JsonProperty("importSleepTime"), JsonPropertyName("importSleepTime")] - public int ImportSleepTime { get; set; } = 40; + [JsonProperty("importSleepTime"), JsonPropertyName("importSleepTime")] + public int ImportSleepTime { get; set; } = 40; - [JsonProperty("importCheckCertificates"), JsonPropertyName("importCheckCertificates")] - public bool ImportCheckCertificates { get; set; } = false; + [JsonProperty("importCheckCertificates"), JsonPropertyName("importCheckCertificates")] + public bool ImportCheckCertificates { get; set; } = false; - [JsonProperty("importSuppressCertificateWarnings"), JsonPropertyName("importSuppressCertificateWarnings")] - public bool ImportSuppressCertificateWarnings { get; set; } = true; + [JsonProperty("importSuppressCertificateWarnings"), JsonPropertyName("importSuppressCertificateWarnings")] + public bool ImportSuppressCertificateWarnings { get; set; } = true; - [JsonProperty("autoDiscoverSleepTime"), JsonPropertyName("autoDiscoverSleepTime")] - public int AutoDiscoverSleepTime { get; set; } = 24; + [JsonProperty("autoDiscoverSleepTime"), JsonPropertyName("autoDiscoverSleepTime")] + public int AutoDiscoverSleepTime { get; set; } = 24; - [JsonProperty("autoDiscoverStartAt"), JsonPropertyName("autoDiscoverStartAt")] - public DateTime AutoDiscoverStartAt { get; set; } = new DateTime(); + [JsonProperty("autoDiscoverStartAt"), JsonPropertyName("autoDiscoverStartAt")] + public DateTime AutoDiscoverStartAt { get; set; } = new DateTime(); - [JsonProperty("fwApiElementsPerFetch"), JsonPropertyName("fwApiElementsPerFetch")] - public int FwApiElementsPerFetch { get; set; } = 150; + [JsonProperty("fwApiElementsPerFetch"), JsonPropertyName("fwApiElementsPerFetch")] + public int FwApiElementsPerFetch { get; set; } = 150; - [JsonProperty("impChangeNotifyRecipients"), JsonPropertyName("impChangeNotifyRecipients")] - public string ImpChangeNotifyRecipients { get; set; } = ""; + [JsonProperty("impChangeNotifyRecipients"), JsonPropertyName("impChangeNotifyRecipients")] + public string ImpChangeNotifyRecipients { get; set; } = ""; - [JsonProperty("impChangeNotifySubject"), JsonPropertyName("impChangeNotifySubject")] - public string ImpChangeNotifySubject { get; set; } = ""; + [JsonProperty("impChangeNotifySubject"), JsonPropertyName("impChangeNotifySubject")] + public string ImpChangeNotifySubject { get; set; } = ""; - [JsonProperty("impChangeNotifyBody"), JsonPropertyName("impChangeNotifyBody")] - public string ImpChangeNotifyBody { get; set; } = ""; + [JsonProperty("impChangeNotifyBody"), JsonPropertyName("impChangeNotifyBody")] + public string ImpChangeNotifyBody { get; set; } = ""; - [JsonProperty("impChangeNotifyActive"), JsonPropertyName("impChangeNotifyActive")] - public bool ImpChangeNotifyActive { get; set; } = false; + [JsonProperty("impChangeNotifyActive"), JsonPropertyName("impChangeNotifyActive")] + public bool ImpChangeNotifyActive { get; set; } = false; - [JsonProperty("impChangeNotifyType"), JsonPropertyName("impChangeNotifyType")] - public int ImpChangeNotifyType { get; set; } + [JsonProperty("impChangeNotifyType"), JsonPropertyName("impChangeNotifyType")] + public int ImpChangeNotifyType { get; set; } - [JsonProperty("impChangeNotifySleepTime"), JsonPropertyName("impChangeNotifySleepTime")] - public int ImpChangeNotifySleepTime { get; set; } = 60; + [JsonProperty("impChangeNotifySleepTime"), JsonPropertyName("impChangeNotifySleepTime")] + public int ImpChangeNotifySleepTime { get; set; } = 60; - [JsonProperty("impChangeNotifyStartAt"), JsonPropertyName("impChangeNotifyStartAt")] - public DateTime ImpChangeNotifyStartAt { get; set; } = new DateTime(); + [JsonProperty("impChangeNotifyStartAt"), JsonPropertyName("impChangeNotifyStartAt")] + public DateTime ImpChangeNotifyStartAt { get; set; } = new DateTime(); - [JsonProperty("recertificationPeriod"), JsonPropertyName("recertificationPeriod")] - public int RecertificationPeriod { get; set; } = 365; + [JsonProperty("recertificationPeriod"), JsonPropertyName("recertificationPeriod")] + public int RecertificationPeriod { get; set; } = 365; - [JsonProperty("recertificationNoticePeriod"), JsonPropertyName("recertificationNoticePeriod")] - public int RecertificationNoticePeriod { get; set; } = 30; + [JsonProperty("recertificationNoticePeriod"), JsonPropertyName("recertificationNoticePeriod")] + public int RecertificationNoticePeriod { get; set; } = 30; - [JsonProperty("recertificationDisplayPeriod"), JsonPropertyName("recertificationDisplayPeriod")] - public int RecertificationDisplayPeriod { get; set; } = 30; + [JsonProperty("recertificationDisplayPeriod"), JsonPropertyName("recertificationDisplayPeriod")] + public int RecertificationDisplayPeriod { get; set; } = 30; - [JsonProperty("ruleRemovalGracePeriod"), JsonPropertyName("ruleRemovalGracePeriod")] - public int RuleRemovalGracePeriod { get; set; } = 60; + [JsonProperty("ruleRemovalGracePeriod"), JsonPropertyName("ruleRemovalGracePeriod")] + public int RuleRemovalGracePeriod { get; set; } = 60; - [JsonProperty("commentRequired"), JsonPropertyName("commentRequired")] - public bool CommentRequired { get; set; } = false; + [JsonProperty("commentRequired"), JsonPropertyName("commentRequired")] + public bool CommentRequired { get; set; } = false; - [JsonProperty("recAutocreateDeleteTicket"), JsonPropertyName("recAutocreateDeleteTicket")] - public bool RecAutoCreateDeleteTicket { get; set; } = false; + [JsonProperty("recAutocreateDeleteTicket"), JsonPropertyName("recAutocreateDeleteTicket")] + public bool RecAutoCreateDeleteTicket { get; set; } = false; - [JsonProperty("recDeleteRuleTicketTitle"), JsonPropertyName("recDeleteRuleTicketTitle")] - public string RecDeleteRuleTicketTitle { get; set; } = ""; + [JsonProperty("recDeleteRuleTicketTitle"), JsonPropertyName("recDeleteRuleTicketTitle")] + public string RecDeleteRuleTicketTitle { get; set; } = ""; - [JsonProperty("recDeleteRuleTicketReason"), JsonPropertyName("recDeleteRuleTicketReason")] - public string RecDeleteRuleTicketReason { get; set; } = ""; + [JsonProperty("recDeleteRuleTicketReason"), JsonPropertyName("recDeleteRuleTicketReason")] + public string RecDeleteRuleTicketReason { get; set; } = ""; - [JsonProperty("recDeleteRuleReqTaskTitle"), JsonPropertyName("recDeleteRuleReqTaskTitle")] - public string RecDeleteRuleReqTaskTitle { get; set; } = ""; + [JsonProperty("recDeleteRuleReqTaskTitle"), JsonPropertyName("recDeleteRuleReqTaskTitle")] + public string RecDeleteRuleReqTaskTitle { get; set; } = ""; - [JsonProperty("recDeleteRuleReqTaskReason"), JsonPropertyName("recDeleteRuleReqTaskReason")] - public string RecDeleteRuleReqTaskReason { get; set; } = ""; + [JsonProperty("recDeleteRuleReqTaskReason"), JsonPropertyName("recDeleteRuleReqTaskReason")] + public string RecDeleteRuleReqTaskReason { get; set; } = ""; - [JsonProperty("recDeleteRuleTicketPriority"), JsonPropertyName("recDeleteRuleTicketPriority")] - public int RecDeleteRuleTicketPriority { get; set; } = 3; + [JsonProperty("recDeleteRuleTicketPriority"), JsonPropertyName("recDeleteRuleTicketPriority")] + public int RecDeleteRuleTicketPriority { get; set; } = 3; - [JsonProperty("recDeleteRuleInitState"), JsonPropertyName("recDeleteRuleInitState")] - public int RecDeleteRuleInitState { get; set; } = 0; + [JsonProperty("recDeleteRuleInitState"), JsonPropertyName("recDeleteRuleInitState")] + public int RecDeleteRuleInitState { get; set; } = 0; - [JsonProperty("recCheckActive"), JsonPropertyName("recCheckActive")] - public bool RecCheckActive { get; set; } = false; + [JsonProperty("recCheckActive"), JsonPropertyName("recCheckActive")] + public bool RecCheckActive { get; set; } = false; - [JsonProperty("recCheckParams"), JsonPropertyName("recCheckParams")] - public string RecCheckParams { get; set; } = System.Text.Json.JsonSerializer.Serialize(new RecertCheckParams()); + [JsonProperty("recCheckParams"), JsonPropertyName("recCheckParams")] + public string RecCheckParams { get; set; } = System.Text.Json.JsonSerializer.Serialize(new RecertCheckParams()); - [JsonProperty("recCheckEmailSubject"), JsonPropertyName("recCheckEmailSubject")] - public string RecCheckEmailSubject { get; set; } = ""; + [JsonProperty("recCheckEmailSubject"), JsonPropertyName("recCheckEmailSubject")] + public string RecCheckEmailSubject { get; set; } = ""; - [JsonProperty("recCheckEmailUpcomingText"), JsonPropertyName("recCheckEmailUpcomingText")] - public string RecCheckEmailUpcomingText { get; set; } = ""; + [JsonProperty("recCheckEmailUpcomingText"), JsonPropertyName("recCheckEmailUpcomingText")] + public string RecCheckEmailUpcomingText { get; set; } = ""; - [JsonProperty("recCheckEmailOverdueText"), JsonPropertyName("recCheckEmailOverdueText")] - public string RecCheckEmailOverdueText { get; set; } = ""; + [JsonProperty("recCheckEmailOverdueText"), JsonPropertyName("recCheckEmailOverdueText")] + public string RecCheckEmailOverdueText { get; set; } = ""; - [JsonProperty("recRefreshStartup"), JsonPropertyName("recRefreshStartup")] - public bool RecRefreshStartup { get; set; } = false; + [JsonProperty("recRefreshStartup"), JsonPropertyName("recRefreshStartup")] + public bool RecRefreshStartup { get; set; } = false; - [JsonProperty("recRefreshDaily"), JsonPropertyName("recRefreshDaily")] - public bool RecRefreshDaily { get; set; } = false; + [JsonProperty("recRefreshDaily"), JsonPropertyName("recRefreshDaily")] + public bool RecRefreshDaily { get; set; } = false; - [JsonProperty("pwMinLength"), JsonPropertyName("pwMinLength")] - public int PwMinLength { get; set; } = 10; + [JsonProperty("pwMinLength"), JsonPropertyName("pwMinLength")] + public int PwMinLength { get; set; } = 10; - [JsonProperty("pwUpperCaseRequired"), JsonPropertyName("pwUpperCaseRequired")] - public bool PwUpperCaseRequired { get; set; } = false; + [JsonProperty("pwUpperCaseRequired"), JsonPropertyName("pwUpperCaseRequired")] + public bool PwUpperCaseRequired { get; set; } = false; - [JsonProperty("pwLowerCaseRequired"), JsonPropertyName("pwLowerCaseRequired")] - public bool PwLowerCaseRequired { get; set; } = false; + [JsonProperty("pwLowerCaseRequired"), JsonPropertyName("pwLowerCaseRequired")] + public bool PwLowerCaseRequired { get; set; } = false; - [JsonProperty("pwNumberRequired"), JsonPropertyName("pwNumberRequired")] - public bool PwNumberRequired { get; set; } = false; + [JsonProperty("pwNumberRequired"), JsonPropertyName("pwNumberRequired")] + public bool PwNumberRequired { get; set; } = false; - [JsonProperty("pwSpecialCharactersRequired"), JsonPropertyName("pwSpecialCharactersRequired")] - public bool PwSpecialCharactersRequired { get; set; } = false; + [JsonProperty("pwSpecialCharactersRequired"), JsonPropertyName("pwSpecialCharactersRequired")] + public bool PwSpecialCharactersRequired { get; set; } = false; - [JsonProperty("emailServerAddress"), JsonPropertyName("emailServerAddress")] - public string EmailServerAddress { get; set; } = ""; + [JsonProperty("emailServerAddress"), JsonPropertyName("emailServerAddress")] + public string EmailServerAddress { get; set; } = ""; - [JsonProperty("emailPort"), JsonPropertyName("emailPort")] - public int EmailPort { get; set; } + [JsonProperty("emailPort"), JsonPropertyName("emailPort")] + public int EmailPort { get; set; } - [JsonProperty("emailTls"), JsonPropertyName("emailTls")] - public EmailEncryptionMethod EmailTls { get; set; } = EmailEncryptionMethod.None; + [JsonProperty("emailTls"), JsonPropertyName("emailTls")] + public EmailEncryptionMethod EmailTls { get; set; } = EmailEncryptionMethod.None; - [JsonProperty("emailUser"), JsonPropertyName("emailUser")] - public string EmailUser { get; set; } = ""; + [JsonProperty("emailUser"), JsonPropertyName("emailUser")] + public string EmailUser { get; set; } = ""; - [JsonProperty("emailPassword"), JsonPropertyName("emailPassword")] - public string EmailPassword { get; set; } = ""; + [JsonProperty("emailPassword"), JsonPropertyName("emailPassword")] + public string EmailPassword { get; set; } = ""; - [JsonProperty("emailSenderAddress"), JsonPropertyName("emailSenderAddress")] - public string EmailSenderAddress { get; set; } = ""; + [JsonProperty("emailSenderAddress"), JsonPropertyName("emailSenderAddress")] + public string EmailSenderAddress { get; set; } = ""; - [JsonProperty("useDummyEmailAddress"), JsonPropertyName("useDummyEmailAddress")] - public bool UseDummyEmailAddress { get; set; } = false; + [JsonProperty("useDummyEmailAddress"), JsonPropertyName("useDummyEmailAddress")] + public bool UseDummyEmailAddress { get; set; } = false; - [JsonProperty("dummyEmailAddress"), JsonPropertyName("dummyEmailAddress")] - public string DummyEmailAddress { get; set; } = ""; + [JsonProperty("dummyEmailAddress"), JsonPropertyName("dummyEmailAddress")] + public string DummyEmailAddress { get; set; } = ""; - [JsonProperty("minCollapseAllDevices"), JsonPropertyName("minCollapseAllDevices"), UserConfigData] - public int MinCollapseAllDevices { get; set; } = 15; + [JsonProperty("minCollapseAllDevices"), JsonPropertyName("minCollapseAllDevices"), UserConfigData] + public int MinCollapseAllDevices { get; set; } = 15; - [JsonProperty("messageViewTime"), JsonPropertyName("messageViewTime"), UserConfigData] - public int MessageViewTime { get; set; } = 7; + [JsonProperty("messageViewTime"), JsonPropertyName("messageViewTime"), UserConfigData] + public int MessageViewTime { get; set; } = 7; - [JsonProperty("dailyCheckStartAt"), JsonPropertyName("dailyCheckStartAt")] - public DateTime DailyCheckStartAt { get; set; } = new DateTime(); + [JsonProperty("dailyCheckStartAt"), JsonPropertyName("dailyCheckStartAt")] + public DateTime DailyCheckStartAt { get; set; } = new DateTime(); - [JsonProperty("maxImportDuration"), JsonPropertyName("maxImportDuration")] - public int MaxImportDuration { get; set; } = 4; + [JsonProperty("maxImportDuration"), JsonPropertyName("maxImportDuration")] + public int MaxImportDuration { get; set; } = 4; - [JsonProperty("maxImportInterval"), JsonPropertyName("maxImportInterval")] - public int MaxImportInterval { get; set; } = 12; + [JsonProperty("maxImportInterval"), JsonPropertyName("maxImportInterval")] + public int MaxImportInterval { get; set; } = 12; - [JsonProperty("reqAvailableTaskTypes"), JsonPropertyName("reqAvailableTaskTypes")] - public string ReqAvailableTaskTypes { get; set; } = ""; + [JsonProperty("reqAvailableTaskTypes"), JsonPropertyName("reqAvailableTaskTypes")] + public string ReqAvailableTaskTypes { get; set; } = ""; - [JsonProperty("reqOwnerBased"), JsonPropertyName("reqOwnerBased")] - public bool ReqOwnerBased { get; set; } = false; + [JsonProperty("reqOwnerBased"), JsonPropertyName("reqOwnerBased")] + public bool ReqOwnerBased { get; set; } = false; - [JsonProperty("reqReducedView"), JsonPropertyName("reqReducedView")] - public bool ReqReducedView { get; set; } = false; + [JsonProperty("reqReducedView"), JsonPropertyName("reqReducedView")] + public bool ReqReducedView { get; set; } = false; - [JsonProperty("reqAllowObjectSearch"), JsonPropertyName("reqAllowObjectSearch")] - public bool ReqAllowObjectSearch { get; set; } = false; + [JsonProperty("reqAllowObjectSearch"), JsonPropertyName("reqAllowObjectSearch")] + public bool ReqAllowObjectSearch { get; set; } = false; - [JsonProperty("reqAllowManualOwnerAdmin"), JsonPropertyName("reqAllowManualOwnerAdmin")] - public bool AllowManualOwnerAdmin { get; set; } = false; + [JsonProperty("reqAllowManualOwnerAdmin"), JsonPropertyName("reqAllowManualOwnerAdmin")] + public bool AllowManualOwnerAdmin { get; set; } = false; - [JsonProperty("reqPriorities"), JsonPropertyName("reqPriorities")] - public string ReqPriorities { get; set; } = ""; + [JsonProperty("reqPriorities"), JsonPropertyName("reqPriorities")] + public string ReqPriorities { get; set; } = ""; - [JsonProperty("reqAutoCreateImplTasks"), JsonPropertyName("reqAutoCreateImplTasks")] - public AutoCreateImplTaskOptions ReqAutoCreateImplTasks { get; set; } = AutoCreateImplTaskOptions.never; + [JsonProperty("reqAutoCreateImplTasks"), JsonPropertyName("reqAutoCreateImplTasks")] + public AutoCreateImplTaskOptions ReqAutoCreateImplTasks { get; set; } = AutoCreateImplTaskOptions.never; - [JsonProperty("reqActivatePathAnalysis"), JsonPropertyName("reqActivatePathAnalysis")] - public bool ReqActivatePathAnalysis { get; set; } = true; + [JsonProperty("reqActivatePathAnalysis"), JsonPropertyName("reqActivatePathAnalysis")] + public bool ReqActivatePathAnalysis { get; set; } = true; - [JsonProperty("reqShowCompliance"), JsonPropertyName("reqShowCompliance")] - public bool ReqShowCompliance { get; set; } = false; + [JsonProperty("reqShowCompliance"), JsonPropertyName("reqShowCompliance")] + public bool ReqShowCompliance { get; set; } = false; - [JsonProperty("ruleOwnershipMode"), JsonPropertyName("ruleOwnershipMode")] - public RuleOwnershipMode RuleOwnershipMode { get; set; } = RuleOwnershipMode.mixed; + [JsonProperty("ruleOwnershipMode"), JsonPropertyName("ruleOwnershipMode")] + public RuleOwnershipMode RuleOwnershipMode { get; set; } = RuleOwnershipMode.mixed; - [JsonProperty("allowServerInConn"), JsonPropertyName("allowServerInConn")] - public bool AllowServerInConn { get; set; } = true; + [JsonProperty("allowServerInConn"), JsonPropertyName("allowServerInConn")] + public bool AllowServerInConn { get; set; } = true; - [JsonProperty("allowServiceInConn"), JsonPropertyName("allowServiceInConn")] - public bool AllowServiceInConn { get; set; } = true; + [JsonProperty("allowServiceInConn"), JsonPropertyName("allowServiceInConn")] + public bool AllowServiceInConn { get; set; } = true; - [JsonProperty("overviewDisplayLines"), JsonPropertyName("overviewDisplayLines")] - public int OverviewDisplayLines { get; set; } = 3; + [JsonProperty("overviewDisplayLines"), JsonPropertyName("overviewDisplayLines")] + public int OverviewDisplayLines { get; set; } = 3; - [JsonProperty("reducedProtocolSet"), JsonPropertyName("reducedProtocolSet")] - public bool ReducedProtocolSet { get; set; } = true; + [JsonProperty("reducedProtocolSet"), JsonPropertyName("reducedProtocolSet")] + public bool ReducedProtocolSet { get; set; } = true; - [JsonProperty("importAppDataPath"), JsonPropertyName("importAppDataPath")] - public string ImportAppDataPath { get; set; } = ""; + [JsonProperty("importAppDataPath"), JsonPropertyName("importAppDataPath")] + public string ImportAppDataPath { get; set; } = ""; - [JsonProperty("importAppDataSleepTime"), JsonPropertyName("importAppDataSleepTime")] - public int ImportAppDataSleepTime { get; set; } = 24; + [JsonProperty("importAppDataSleepTime"), JsonPropertyName("importAppDataSleepTime")] + public int ImportAppDataSleepTime { get; set; } = 24; - [JsonProperty("importAppDataStartAt"), JsonPropertyName("importAppDataStartAt")] - public DateTime ImportAppDataStartAt { get; set; } = new DateTime(); + [JsonProperty("importAppDataStartAt"), JsonPropertyName("importAppDataStartAt")] + public DateTime ImportAppDataStartAt { get; set; } = new DateTime(); - [JsonProperty("importSubnetDataPath"), JsonPropertyName("importSubnetDataPath")] - public string ImportSubnetDataPath { get; set; } = ""; + [JsonProperty("importSubnetDataPath"), JsonPropertyName("importSubnetDataPath")] + public string ImportSubnetDataPath { get; set; } = ""; - [JsonProperty("importSubnetDataSleepTime"), JsonPropertyName("importSubnetDataSleepTime")] - public int ImportSubnetDataSleepTime { get; set; } = 24; + [JsonProperty("importSubnetDataSleepTime"), JsonPropertyName("importSubnetDataSleepTime")] + public int ImportSubnetDataSleepTime { get; set; } = 24; - [JsonProperty("importSubnetDataStartAt"), JsonPropertyName("importSubnetDataStartAt")] - public DateTime ImportSubnetDataStartAt { get; set; } = new DateTime(); + [JsonProperty("importSubnetDataStartAt"), JsonPropertyName("importSubnetDataStartAt")] + public DateTime ImportSubnetDataStartAt { get; set; } = new DateTime(); - [JsonProperty("modNamingConvention"), JsonPropertyName("modNamingConvention")] - public string ModNamingConvention { get; set; } = ""; + [JsonProperty("modNamingConvention"), JsonPropertyName("modNamingConvention")] + public string ModNamingConvention { get; set; } = ""; - [JsonProperty("modIconify"), JsonPropertyName("modIconify")] - public bool ModIconify { get; set; } = true; + [JsonProperty("modIconify"), JsonPropertyName("modIconify")] + public bool ModIconify { get; set; } = true; - [JsonProperty("modCommonAreas"), JsonPropertyName("modCommonAreas")] - public string ModCommonAreas { get; set; } = ""; + [JsonProperty("modCommonAreas"), JsonPropertyName("modCommonAreas")] + public string ModCommonAreas { get; set; } = ""; - [JsonProperty("modAppServerTypes"), JsonPropertyName("modAppServerTypes")] - public string ModAppServerTypes { get; set; } = ""; + [JsonProperty("modAppServerTypes"), JsonPropertyName("modAppServerTypes")] + public string ModAppServerTypes { get; set; } = ""; - [JsonProperty("modReqInterfaceName"), JsonPropertyName("modReqInterfaceName")] - public string ModReqInterfaceName { get; set; } = ""; + [JsonProperty("modReqInterfaceName"), JsonPropertyName("modReqInterfaceName")] + public string ModReqInterfaceName { get; set; } = ""; - [JsonProperty("modReqEmailSubject"), JsonPropertyName("modReqEmailSubject")] - public string ModReqEmailSubject { get; set; } = ""; + [JsonProperty("modReqEmailSubject"), JsonPropertyName("modReqEmailSubject")] + public string ModReqEmailSubject { get; set; } = ""; - [JsonProperty("modReqEmailBody"), JsonPropertyName("modReqEmailBody")] - public string ModReqEmailBody { get; set; } = ""; + [JsonProperty("modReqEmailBody"), JsonPropertyName("modReqEmailBody")] + public string ModReqEmailBody { get; set; } = ""; - [JsonProperty("modReqTicketTitle"), JsonPropertyName("modReqTicketTitle")] - public string ModReqTicketTitle { get; set; } = ""; + [JsonProperty("modReqTicketTitle"), JsonPropertyName("modReqTicketTitle")] + public string ModReqTicketTitle { get; set; } = ""; - [JsonProperty("modReqTaskTitle"), JsonPropertyName("modReqTaskTitle")] - public string ModReqTaskTitle { get; set; } = ""; + [JsonProperty("modReqTaskTitle"), JsonPropertyName("modReqTaskTitle")] + public string ModReqTaskTitle { get; set; } = ""; - public ConfigData(bool editable = false) - { - Editable = editable; - } + [JsonProperty("extTicketSystems"), JsonPropertyName("extTicketSystems")] + public string ExtTicketSystems { get; set; } = ""; - public object Clone() - { - // Watch out for references they need to be deep cloned (currently none) - ConfigData configData = (ConfigData)MemberwiseClone(); - return configData; - } + public ConfigData(bool editable = false) + { + Editable = editable; + } - public object CloneEditable() - { - object clone = Clone(); - typeof(ConfigData).GetProperty("Editable")?.SetValue(clone, true); - return clone; - } - } + public object Clone() + { + // Watch out for references they need to be deep cloned (currently none) + ConfigData configData = (ConfigData)MemberwiseClone(); + return configData; + } + + public object CloneEditable() + { + object clone = Clone(); + typeof(ConfigData).GetProperty("Editable")?.SetValue(clone, true); + return clone; + } + } } diff --git a/roles/lib/files/FWO.GlobalConstants/GlobalConstants.cs b/roles/lib/files/FWO.GlobalConstants/GlobalConstants.cs index 66d88e02f..abf0a1598 100644 --- a/roles/lib/files/FWO.GlobalConstants/GlobalConstants.cs +++ b/roles/lib/files/FWO.GlobalConstants/GlobalConstants.cs @@ -1,46 +1,53 @@ namespace FWO.GlobalConstants { - /// - /// Global string constants used e.g. as database keys etc. - /// - public struct GlobalConst - { - public const string kFwoProdName = "fworch"; - public const string kFwoBaseDir = "/usr/local/" + kFwoProdName; - public const string kMainKeyFile = kFwoBaseDir + "/etc/secrets/main_key"; + /// + /// Global string constants used e.g. as database keys etc. + /// + public struct GlobalConst + { + public const string kFwoProdName = "fworch"; + public const string kFwoBaseDir = "/usr/local/" + kFwoProdName; + public const string kMainKeyFile = kFwoBaseDir + "/etc/secrets/main_key"; - public const string kEnglish = "English"; - public const int kTenant0Id = 1; + public const string kEnglish = "English"; + public const int kTenant0Id = 1; - public const int kSidebarLeftWidth = 300; - public const int kSidebarRightWidth = 300; - public const int kHoursToMilliseconds = 3600000; + public const int kSidebarLeftWidth = 300; + public const int kSidebarRightWidth = 300; + public const int kHoursToMilliseconds = 3600000; - public const string kHtml = "html"; - public const string kPdf = "pdf"; - public const string kJson = "json"; - public const string kCsv = "csv"; + public const string kHtml = "html"; + public const string kPdf = "pdf"; + public const string kJson = "json"; + public const string kCsv = "csv"; - public const string kAutodiscovery = "autodiscovery"; - public const string kDailyCheck = "dailycheck"; - public const string kUi = "ui"; - public const string kCertification = "Certification"; - public const string kImportAppData = "importAppData"; - public const string kImportAreaSubnetData = "importAreaSubnetData"; - public const string kManual = "manual"; - public const string kModellerGroup = "ModellerGroup_"; - public const string kImportChangeNotify = "importChangeNotify"; + public const string kAutodiscovery = "autodiscovery"; + public const string kDailyCheck = "dailycheck"; + public const string kUi = "ui"; + public const string kCertification = "Certification"; + public const string kImportAppData = "importAppData"; + public const string kImportAreaSubnetData = "importAreaSubnetData"; + public const string kManual = "manual"; + public const string kModellerGroup = "ModellerGroup_"; + public const string kImportChangeNotify = "importChangeNotify"; - public const string kLdapInternalPostfix = "dc=" + kFwoProdName + ",dc=internal"; + public const string kLdapInternalPostfix = "dc=" + kFwoProdName + ",dc=internal"; - public const string kDummyAppRole = "DummyAppRole"; - } + public const string kDummyAppRole = "DummyAppRole"; + } - public struct ObjectType + public struct ObjectType + { + public const string Group = "group"; + public const string Host = "host"; + public const string Network = "network"; + public const string IPRange = "ip_range"; + } + + public struct ServiceType { public const string Group = "group"; - public const string Host = "host"; - public const string Network = "network"; - public const string IPRange = "ip_range"; + public const string SimpleService = "simple"; + public const string Rpc = "rpc"; } } diff --git a/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicket.cs b/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicket.cs new file mode 100644 index 000000000..c410a6f35 --- /dev/null +++ b/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicket.cs @@ -0,0 +1,324 @@ +using FWO.Api.Data; +using FWO.Tufin.SecureChange; +using RestSharp; +// using FWO.Middleware.RequestParameters; +// using RestSharp.Authenticators; +// using RestSharp.Serializers.SystemTextJson; +// using System.Text.Json; +// using Newtonsoft.Json; +using RestSharp.Serializers.NewtonsoftJson; +using RestSharp.Serializers; +// using System.Runtime.CompilerServices; +// using System.Data; +// using FWO.Api.Client; +// using FWO.Config.Api; +// using FWO.Config.Api.Data; +// using Org.BouncyCastle.Security; + +namespace FWO.Tufin.SecureChange +{ + + + abstract public class ExternalTicket : RequestTicket + + { + + protected TicketPriority Priority = TicketPriority.Normal; + protected string OnBehalfOfUser = ""; + // protected string OnBehalfOfUser = """"requester_id": 55,""""; + + public string TicketTemplate = """ +{ + "ticket": { + "subject": "@@TICKET_SUBJECT@@", + "priority": "@@PRIORITY@@", + "requester": "@@ONBEHALF@@", + "domain_name": "", + "workflow": { + "name": "@@WORKFLOW_NAME@@" + }, + @@TASKS@@ + } +} +"""; + + public string DefaultTufinAccessRequestTasksTemplate = """ + "steps": { + "step": [ + { + "name": "Erfassung des Antrags", + "tasks": { + "task": { + "fields": { + "field": [ + { + "@xsi.type": "multi_access_request", + "name": "Gewünschter Zugang", + "read_only": false, + "access_request": { + "order": "AR1", + "verifier_result": { + "status": "not run" + }, + "use_topology": true, + "targets": { + "target": { + "@type": "ANY" + } + }, + "users": { + "user": @@USERS@@ + }, + "sources": { + "source": @@SOURCES@@ + }, + "destinations": { + "destination": @@DESTINATIONS@@ + }, + "services": { + "service": @@SERVICES@@ + }, + "action": "@@ACTION@@", + "labels": "" + } + }, + { + "@xsi.type": "text_area", + "name": "Grund für den Antrag", + "read_only": false, + "text": "@@REASON@@" + }, + { + "@xsi.type": "drop_down_list", + "name": "Regel Log aktivieren?", + "selection": "@@LOGGING@@" + }, + { + "@xsi.type": "date", + "name": "Regel befristen bis:", + "date": "@@ENDDATE@@" + }, + { + "@xsi.type": "text_field", + "name": "Anwendungs-ID", + "text": "@@APPID@@" + }, + { + "@xsi.type": "checkbox", + "name": "Die benötigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt", + "value": "@@COM_DOCUMENTED@@" + }, + { + "@xsi.type": "drop_down_list", + "name": "Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)", + "selection": "Nein" + } + ] + } + } + } + } + ] + } + """; + + } + +} + + +public class SCTicket : ExternalTicket +{ + private string Subject { get; set; } = ""; + private TicketPriority Priority { get; set; } = TicketPriority.Normal; + private string OnBehalfUser { get; set; } = ""; + protected string TicketText = ""; + + List TicketTasks = new(); + + public SCTicket(string subject, TicketPriority priority = TicketPriority.Normal) + + { + Subject = subject; + Priority = priority; + } + + public void AddTask(List sources, List services, List destinations) + + { + TicketTasks.Add(new ExternalAccessRequestTicketTask(sources, services, destinations)); + } + private void ConfigureRestClientSerialization(SerializerConfig config) + { + JsonNetSerializer serializer = new JsonNetSerializer(); // Case insensivitive is enabled by default + config.UseSerializer(() => serializer); + } + public async Task> CreateTicketInTufin(ExternalTicketSystem tufinSystem, List appConnections, string authHeader = "") + + { + TicketText = TicketTemplate + .Replace("@@TICKET_SUBJECT@@", "test ticket create connection1") + .Replace("@@PRIORITY@@", Priority.ToString()) + .Replace("@@ONBEHALF@@", OnBehalfOfUser) + .Replace("@@WORKFLOW_NAME@@", "workflow_name"); + + // .Replace("@@TASKS@@", tufinSystem.TasksTemplate) + // .Replace("@@USERS@@", "[ \"Any\" ]") + // .Replace("@@SOURCES@@", "\"src1\"") + // .Replace("@@DESTINATIONS@@", "\"dst1\"") + // .Replace("@@SERVICES@@", "\"svc1\"") + // ; + + foreach (ModellingConnection conn in appConnections) + { + ExternalAccessRequestTicketTask task = new (conn); + TicketText = task.FillTaskTemplate(DefaultTufinAccessRequestTasksTemplate); + + + } + + RestRequest request = new RestRequest("Tickets.json", Method.Post); + request.AddJsonBody(TicketText); + request.AddHeader("Content-Type", "application/json"); + request.AddHeader("Authorization", authHeader); + RestClientOptions restClientOptions = new RestClientOptions(); + restClientOptions.RemoteCertificateValidationCallback += (_, _, _, _) => true; + restClientOptions.BaseUrl = new Uri(tufinSystem.Url); + RestClient restClient = new RestClient(restClientOptions, null, ConfigureRestClientSerialization); + + return await restClient.ExecuteAsync(request); + } + /* + + Create Ticket Sample Call + + curl --request POST \ + --insecure \ + --url https://tufin-stest.xxx.de/securechangeworkflow/api/securechange/tickets.json \ + --header 'Authorization: Basic xxx' \ + --header 'Content-Type: application/json' \ + --data '{ + "ticket": { + "subject": "NeMo-Testing", + "priority": "Normal", + "domain_name": "", + "workflow": { + "name": "1. xxx Standard Firewall Request" + }, + "steps": { + "step": [ + { + "name": "Erfassung des Antrags", + "tasks": { + "task": { + "fields": { + "field": [ + { + "@xsi.type": "multi_access_request", + "name": "Gewünschter Zugang", + "read_only": false, + "access_request": { + "order": "AR1", + "verifier_result": { + "status": "not run" + }, + "use_topology": true, + "targets": { + "target": { + "@type": "ANY" + } + }, + "users": { + "user": [ + "Any" + ] + }, + "sources": { + "source": [ + { + "@type": "IP", + "ip_address": "10.10.100.10", + "netmask": "255.255.255.255", + "cidr": 32 + } + ] + }, + "destinations": { + "destination": [ + { + "@type": "IP", + "ip_address": "10.20.200.0", + "netmask": "255.255.255.128", + "cidr": 25 + } + ] + }, + "services": { + "service": [ + { + "@type": "PREDEFINED", + "protocol": "TCP", + "port": 23, + "predefined_name": "telnet" + }, + { + "@type": "PREDEFINED", + "protocol": "TCP", + "port": 79, + "predefined_name": "finger" + }, + { + "@type": "PROTOCOL", + "protocol": "TCP", + "port": 90 + } + ] + }, + "action": "Accept", + "labels": "" + } + }, + { + "@xsi.type": "text_area", + "name": "Grund für den Antrag", + "read_only": false, + "text": "dsadsa" + }, + { + "@xsi.type": "drop_down_list", + "name": "Regel Log aktivieren?", + "selection": "Ja" + }, + { + "@xsi.type": "date", + "name": "Regel befristen bis:" + }, + { + "@xsi.type": "text_field", + "name": "Anwendungs-ID", + "text": "APP-3838" + }, + { + "@xsi.type": "checkbox", + "name": "Die benötigte Kommunikationsverbindung ist im Kommunikationsprofil nach IT-Sicherheitsstandard hinterlegt", + "value": false + }, + { + "@xsi.type": "drop_down_list", + "name": "Expertenmodus: Exakt wie beantragt implementieren (Designervorschlag ignorieren)", + "selection": "Nein" + } + ] + } + } + } + } + ] + } + } + }' + + */ + +} + diff --git a/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicketTask.cs b/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicketTask.cs new file mode 100644 index 000000000..c0690bb50 --- /dev/null +++ b/roles/lib/files/FWO.Tufin.SecureChange/ExternalTicketTask.cs @@ -0,0 +1,65 @@ +using FWO.Api.Data; +using FWO.Tufin.SecureChange; + +namespace FWO.Tufin.SecureChange +{ + + + public class ExternalAccessRequestTicketTask : RequestReqTask + { + + private List? SourceUsers = []; + private List? DestinationUsers = []; + private List Sources = []; + private List Services = []; + private List Destinations = []; + + // mockup: + private string Action = "accept"; + //private string Reason = "reasoning ..."; + private string Logging = "Ja"; + + private string EndDate = ""; + private string AppId = "APP-4711"; + private string ComDocumented = "false"; + private string TicketText = ""; + + private TicketTaskType TaskType = TicketTaskType.AccessRequest; + + public string FillTaskTemplate(string taskTemplate) + { + return TicketText.Replace("@@TASKS@@", taskTemplate) + .Replace("@@USERS@@", SourceUsers.ToString()) + .Replace("@@SOURCES@@", Sources.ToString()) + .Replace("@@DESTINATIONS@@", Destinations.ToString()) + .Replace("@@SERVICES@@", Services.ToString()) + .Replace("@@ACTION@@", Action) + .Replace("@@REASON@@", Reason) + .Replace("@@LOGGING@@", Logging) + .Replace("@@ENDDATE@@", EndDate) + .Replace("@@APPID@@", AppId) + .Replace("@@COM_DOCUMENTED@@", ComDocumented); + + } + + // TODO: implement Users, Action, Reason, Logging, EndDate, AppId, ComDocumented + + public ExternalAccessRequestTicketTask(ModellingConnection conn) + + { + // Sources = conn.SourceNwGroups.All(); + // Destinations = conn.DestinationNwGroups.All(); + // Services = conn.Services.All( _ => _); + } + + public ExternalAccessRequestTicketTask(List sources, List services, List destinations) + + { + Sources = sources; + Destinations = destinations; + Services = services; + } + + } +} + diff --git a/roles/lib/files/FWO.Tufin.SecureChange/FWO.Tufin.SecureChange.csproj b/roles/lib/files/FWO.Tufin.SecureChange/FWO.Tufin.SecureChange.csproj new file mode 100644 index 000000000..5c7462ca7 --- /dev/null +++ b/roles/lib/files/FWO.Tufin.SecureChange/FWO.Tufin.SecureChange.csproj @@ -0,0 +1,21 @@ + + + + net8.0 + enable + enable + + + + + + + + + + + + + + + diff --git a/roles/ui/files/FWO.UI/FWO.Ui.csproj b/roles/ui/files/FWO.UI/FWO.Ui.csproj index 5730b734d..9a3de6167 100644 --- a/roles/ui/files/FWO.UI/FWO.Ui.csproj +++ b/roles/ui/files/FWO.UI/FWO.Ui.csproj @@ -19,6 +19,7 @@ + diff --git a/roles/ui/files/FWO.UI/Shared/SettingsLayout.razor b/roles/ui/files/FWO.UI/Shared/SettingsLayout.razor index 6f8c824e8..48601b8e3 100644 --- a/roles/ui/files/FWO.UI/Shared/SettingsLayout.razor +++ b/roles/ui/files/FWO.UI/Shared/SettingsLayout.razor @@ -103,6 +103,11 @@ @(userConfig.GetText("modelling")) +