Skip to content

Commit cff34b5

Browse files
[~] Fileupload Service now returns generic error lists
[+] ErrorBaseModel to extend fileupload error [-] Old/Unused FileUpload Component CactuseSecurity#3024
1 parent f378f8c commit cff34b5

File tree

7 files changed

+229
-300
lines changed

7 files changed

+229
-300
lines changed

roles/database/files/sql/idempotent/fworch-texts.sql

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,8 +1607,12 @@ INSERT INTO txt VALUES ('generate_name', 'German', 'Name generieren');
16071607
INSERT INTO txt VALUES ('generate_name', 'English', 'Generate Name');
16081608
INSERT INTO txt VALUES ('change_source', 'German', 'Änderungsquelle');
16091609
INSERT INTO txt VALUES ('change_source', 'English', 'Change Source');
1610-
INSERT INTO txt VALUES ('tableofcontent', 'German', 'Inhaltsverzeichnis');
1611-
INSERT INTO txt VALUES ('tableofcontent', 'English', 'Table of content');
1610+
INSERT INTO txt VALUES ('tableofcontent', 'German', 'Inhaltsverzeichnis');
1611+
INSERT INTO txt VALUES ('tableofcontent', 'English', 'Table of content');
1612+
INSERT INTO txt VALUES ('entrydata', 'German', 'Dateneintrag');
1613+
INSERT INTO txt VALUES ('entrydata', 'English', 'Data entry');
1614+
INSERT INTO txt VALUES ('error_message', 'German', 'Fehlermeldung');
1615+
INSERT INTO txt VALUES ('error_message', 'English', 'Error message');
16121616

16131617
-- compliance
16141618
INSERT INTO txt VALUES ('compliance', 'German', 'Compliance');
@@ -2365,6 +2369,8 @@ INSERT INTO txt VALUES ('app_zone_pattern', 'German', 'Muster App Zone');
23652369
INSERT INTO txt VALUES ('app_zone_pattern', 'English', 'App Zone Pattern');
23662370
INSERT INTO txt VALUES ('app_zone_creation', 'German', 'App Zonen Objekte erstellen');
23672371
INSERT INTO txt VALUES ('app_zone_creation', 'English', 'Create App Zone Objects');
2372+
INSERT INTO txt VALUES ('appserver_import', 'German', 'App server import');
2373+
INSERT INTO txt VALUES ('appserver_import', 'English', 'App server import');
23682374

23692375
-- monitoring
23702376
INSERT INTO txt VALUES ('open_alerts', 'German', 'Offene Alarme');
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
namespace FWO.Ui.Data
2+
{
3+
/// <summary>
4+
/// Defines a model for errors that occured on csv file upload
5+
/// </summary>
6+
public class CSVFileUploadErrorModel : ErrorBaseModel
7+
{
8+
public CSVFileUploadErrorModel() : base()
9+
{
10+
}
11+
12+
/// <summary>
13+
/// Additional Data/Info
14+
/// </summary>
15+
public string? EntryData { get; set; }
16+
}
17+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
namespace FWO.Ui.Data
2+
{
3+
public class ErrorBaseModel()
4+
{
5+
/// <summary>
6+
/// The error message containing infos abour what went wrong
7+
/// </summary>
8+
public string? Message { get; set; }
9+
10+
/// <summary>
11+
/// Additional info on errors at system level
12+
/// </summary>
13+
public Exception? InternalException { get; set; }
14+
15+
/// <summary>
16+
/// Identifier for severity typing
17+
/// </summary>
18+
public MessageType MessageType { get; set; }
19+
}
20+
}

roles/ui/files/FWO.UI/Pages/Settings/SettingsModelling.razor

Lines changed: 41 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
@using System.Text.Json
2+
@using FWO.Ui.Data
23
@using FWO.Ui.Pages.NetworkModelling
34

45
@page "/settings/modelling"
@@ -19,7 +20,7 @@
1920
{
2021
<form onsubmit="return false">
2122
<button type="button" class="btn btn-sm btn-dark ms-5" data-toggle="tooltip" title="@(userConfig.PureLine("H5602"))"
22-
@onclick="PredefServices">
23+
@onclick="PredefServices">
2324
@(userConfig.GetText("predef_services"))
2425
</button>
2526
<hr />
@@ -82,7 +83,7 @@
8283
<div class="form-group row mt-4" data-toggle="tooltip" title="@(userConfig.PureLine("H9055"))">
8384
<label class="col-form-label col-sm-4">@userConfig.GetText("import_app_server"):</label>
8485
<div class="row col-sm-6">
85-
<CSVFileUpload SupportedFileFormats=".csv" AuthorizedRoles="@Roles.Admin" OnAddAppServerError="OnAddAppServerError" OnAddAppServerWarning="OnAddAppServerWarning" OnImportSuccess="OnAppServerImportSuccess"></CSVFileUpload>
86+
<FileUpload SupportedFileFormats=".csv" AuthorizedRoles="@Roles.Admin" OnImportSuccess="OnAppServerImportSuccess" OnAddAppServerError="OnAddAppServerError" TImportResult="CSVFileUploadErrorModel" OnAfterImportResults="OnAfterImportResults"></FileUpload>
8687
</div>
8788
</div>
8889
<hr />
@@ -371,6 +372,37 @@ else
371372
}
372373
<PredefServices @bind-Display="predefServices" />
373374
<SearchNwObject @bind-Display="searchArea" ObjectList="pureAreaList" Add="AddArea" CommonAreaMode="true" />
375+
<PopUp Title="@(userConfig.GetText("appserver_import"))" Show="@ShowCSVImportPopUp" Size=PopupSize.Large OnClose="() => ShowCSVImportPopUp = false">
376+
<Body>
377+
@if(CSVImportSuccess is not null)
378+
{
379+
<div class="mt-3">
380+
<Collapse StartToggled="true" Style="success" Title="@(userConfig.GetText("success"))">
381+
<Table PageSize="0" TableClass="table table-bordered table-sm th-bg-secondary table-responsive overflow-auto sticky-header" TableItem="string" Items="CSVImportSuccess">
382+
<Column TableItem="string" Title="@(userConfig.GetText("entrydata"))" Type="typeof(string)" Field="@(_ => new string(_))" Sortable="true" Filterable="true" />
383+
</Table>
384+
</Collapse>
385+
</div>
386+
}
387+
@if(CSVImportErrors is not null)
388+
{
389+
<div class="mt-1">
390+
<Collapse StartToggled="false" Style="danger" Title="@(userConfig.GetText("errors"))">
391+
<Table PageSize="0" TableClass="table table-bordered table-sm th-bg-secondary table-responsive overflow-auto sticky-header" TableItem="CSVFileUploadErrorModel" Items="CSVImportErrors">
392+
<Column TableItem="CSVFileUploadErrorModel" Title="@(userConfig.GetText("entrydata"))" Field="@(_ => _.EntryData)" Sortable="true" Filterable="true" />
393+
<Column TableItem="CSVFileUploadErrorModel" Title="@(userConfig.GetText("error_message"))" Field="@(_ => _.Message)" Sortable="true" Filterable="true" />
394+
<Column TableItem="CSVFileUploadErrorModel" Title="@(userConfig.GetText("type"))" Field="@(_ => _.MessageType)" Sortable="true" />
395+
</Table>
396+
</Collapse>
397+
</div>
398+
}
399+
</Body>
400+
<Footer>
401+
<div class="btn-group">
402+
<button type="button" class="btn btn-sm btn-primary" @onclick="() => ShowCSVImportPopUp = false">@(userConfig.GetText("ok"))</button>
403+
</div>
404+
</Footer>
405+
</PopUp>
374406

375407
@code
376408
{
@@ -416,23 +448,22 @@ else
416448
private List<UiLdapConnection> connectedLdaps = new List<UiLdapConnection>();
417449
private UiLdapConnection selectedLdap = new();
418450
private bool initComplete = false;
419-
451+
private bool ShowCSVImportPopUp { get; set; }
452+
private List<CSVFileUploadErrorModel>? CSVImportErrors;
453+
private List<string>? CSVImportSuccess;
420454

421455
private void OnAddAppServerError((Exception Exception, string Message) error)
422456
{
423457
DisplayMessageInUi(error.Exception, userConfig.GetText("add_app_server"), error.Message, false);
424458
}
425459

426-
private void OnAddAppServerWarning(string errorMessage)
460+
private void OnAfterImportResults((List<string>? Success, List<CSVFileUploadErrorModel>? Errors) importResult)
427461
{
428-
DisplayMessageInUi(null, userConfig.GetText("add_app_server"), errorMessage, true);
429-
}
462+
CSVImportSuccess = importResult.Success;
463+
CSVImportErrors = importResult.Errors;
430464

431-
private void OnAddAppServerWarning(Exception ex)
432-
{
433-
DisplayMessageInUi(ex, userConfig.GetText("add_app_server"), ex.Message, false);
465+
ShowCSVImportPopUp = true;
434466
}
435-
436467
private void OnAppServerImportSuccess()
437468
{
438469
DisplayMessageInUi(null, userConfig.GetText("import_app_server"), userConfig.GetText("importAppServerDataSuccess"), false);

roles/ui/files/FWO.UI/Services/FileUploadService.cs

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using FWO.Api.Client.Queries;
1+
using FWO.Api.Client.Queries;
22
using FWO.Api.Client;
33
using FWO.Data;
44
using FWO.Data.Modelling;
@@ -8,6 +8,7 @@
88
using FWO.Ui.Data;
99
using Microsoft.AspNetCore.Components.Forms;
1010
using System.Text.Json;
11+
using System.Collections.Generic;
1112

1213
namespace FWO.Ui.Services
1314
{
@@ -18,11 +19,6 @@ public class FileUploadService
1819
/// </summary>
1920
private byte[] UploadedData { get; set; } = [];
2021

21-
/// <summary>
22-
/// Errors that occured while trying to write file data in database.
23-
/// </summary>
24-
private List<Exception> ImportErrors { get; set; } = [];
25-
2622
private UserConfig UserConfig { get; set; }
2723
private ApiConnection ApiConnection { get; set; }
2824
private readonly ModellingNamingConvention NamingConvention = new();
@@ -44,29 +40,45 @@ public async Task ReadFileToBytes(InputFileChangeEventArgs args)
4440
UploadedData = ms.ToArray();
4541
}
4642

47-
public async Task<List<Exception>> ImportUploadedData(FileUploadCase fileUploadCase, string filename = "")
43+
public async Task<(List<string>? success, List<TError>? errors)> ImportUploadedData<TError>(FileUploadCase fileUploadCase, string filename = "")
44+
where TError : ErrorBaseModel
4845
{
49-
ImportErrors.Clear();
50-
5146
if (fileUploadCase == FileUploadCase.ImportAppServerFromCSV)
5247
{
5348
ImportSource = GlobalConst.kCSV_ + filename;
54-
await ImportAppServersFromCSV();
49+
(List<string>? success, List<CSVFileUploadErrorModel>? errors) = await ImportAppServersFromCSV();
50+
51+
List<TError>? importErrors = errors is not null ? [.. errors.Cast<TError>()] : default;
52+
53+
return (success, importErrors);
5554
}
5655

57-
return ImportErrors;
56+
throw new NotImplementedException();
5857
}
5958

60-
private async Task ImportAppServersFromCSV()
59+
private async Task<(List<string>? success, List<CSVFileUploadErrorModel>? errors)> ImportAppServersFromCSV()
6160
{
61+
List<string> success = [];
62+
List<CSVFileUploadErrorModel> errors = [];
63+
6264
string text = System.Text.Encoding.UTF8.GetString(UploadedData);
6365
string[] lines = text.Split('\r');
6466

6567
foreach (string line in lines)
6668
{
67-
// create import model
68-
if (!TryGetEntries(line, ';', out string[] entries) && !TryGetEntries(line, ',', out entries))
69+
CSVFileUploadErrorModel? error = new()
70+
{
71+
EntryData = line,
72+
MessageType = MessageType.Error,
73+
};
74+
75+
if(!TryGetEntries(line, ';', out string[] entries) && !TryGetEntries(line, ',', out entries))
76+
{
77+
error.Message = "Entry doesn't contain all required columns";
78+
errors.Add(error);
79+
6980
continue;
81+
}
7082

7183
if (IsHeader(entries))
7284
continue;
@@ -76,16 +88,26 @@ private async Task ImportAppServersFromCSV()
7688
AppID = entries[1],
7789
AppServerTyp = entries[2]
7890
};
91+
7992
importAppServer.AppServerName = UserConfig.DnsLookup ?
8093
await AppServerHelper.ConstructAppServerNameFromDns(importAppServer.ToModellingAppServer(), NamingConvention, UserConfig.OverwriteExistingNames) :
8194
entries[0];
8295

8396
// write to db
84-
(bool importSuccess, Exception? error) = await AddAppServerToDb(importAppServer);
97+
(bool importSuccess, Exception? e) = await AddAppServerToDb(importAppServer);
8598

86-
if (!importSuccess && error is not null)
87-
ImportErrors.Add(error);
99+
if (!importSuccess && e is not null)
100+
{
101+
error.Message = e.Message;
102+
errors.Add(error);
103+
}
104+
else
105+
{
106+
success.Add(line);
107+
}
88108
}
109+
110+
return (success, errors);
89111
}
90112

91113
private static bool TryGetEntries(string line, char separator, out string[] entries)

0 commit comments

Comments
 (0)