@using Microsoft.Extensions.Options @using MongoDB.Driver @using Rms.Risk.Mango.Pivot.Core.MongoDb @using Rms.Risk.Mango.Services.Context @using Rms.Service.Bootstrap.Security @inject IDatabaseConfigurationService DatabaseConfig @inject IUserSession UserSession @inject IJSRuntime JsRuntime @inject IPasswordManager PasswordManager @inject IOptions Settings @inject IUserService UserService @* * dbMango * * Copyright 2025 Deutsche Bank AG * SPDX-License-Identifier: Apache-2.0 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. *@
@code { [CascadingParameter] public IModalService Modal { get; set; } = null!; [Parameter] public string Name { get; set; } = "New connection"; [Parameter] public DatabasesConfig.DatabaseConfig Value { get; set; } = new(); [Parameter] public EventCallback OnRefresh { get; set; } private EditContext EditContext => _editContext!; private EditContext? _editContext; private string UserUser { get => Value.Config.Auth?.User ?? ""; set { Value.Config.Auth ??= new(); Value.Config.Auth.User = value; } } private string UserPassword { get => Value.Config.Auth?.Password ?? ""; set { Value.Config.Auth ??= new(); Value.Config.Auth.Password = value; } } private string AuthDatabase { get => Value.Config.Auth?.AuthDatabase ?? ""; set { Value.Config.Auth ??= new(); Value.Config.Auth.AuthDatabase = value; } } private string AuthMethod { get => Value.Config.Auth?.Method ?? ""; set { Value.Config.Auth ??= new(); Value.Config.Auth.Method = value; } } private string AdminUser { get => Value.Config.AdminAuth?.User ?? ""; set { Value.Config.AdminAuth ??= new(); Value.Config.AdminAuth.User = value; } } private string AdminPassword { get => Value.Config.AdminAuth?.Password ?? ""; set { Value.Config.AdminAuth ??= new(); Value.Config.AdminAuth.Password = value; } } protected override void OnInitialized() { _editContext = new(this); } private Task CanExecuteCommand() => Shell.CanExecuteCommand(UserSession, InvokeAsync, Modal); private async Task Update() { var ticket = await CanExecuteCommand(); if (string.IsNullOrWhiteSpace(ticket)) return; var res = await ModalDialogUtils.ShowConfirmationDialog( Modal, "Update configuration", $"Are you sure want to update configuration for {Name}?" ); if (res.Cancelled) return; try { PrepareForSaving(); await DatabaseConfig.Update(Name, Value, UserSession.User.GetEmail()); await ModalDialogUtils.ShowInfoDialog(Modal, "Success", $"Configuration {Name} was updated successfully."); // exception in Audit() call can lead to 2 dialogs shown in total: Success in config change + error recording audit try { await Audit(ticket, "update", Name); } catch (Exception ex2) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex2); } } catch (Exception ex) { try { await Audit(ticket, "update", Name, ex); } catch (Exception ex2) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex2); } await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex); } await OnRefresh.InvokeAsync(); } private async Task Audit(string ticket, string action, string configName, Exception? exception = null) { var doc = new BsonDocument { ["dbMangoOnboarding"] = exception?.Message ?? "Success", ["action"] = action, ["configName"] = configName, ["ticket"] = ticket }; var auditRecord = new AuditRecord(UserSession.Database, DateTime.UtcNow, UserService.GetEmail(), ticket, exception == null, doc, exception?.Message); await UserSession.Audit.Record(auditRecord); } private async Task Delete() { var ticket = await CanExecuteCommand(); if (string.IsNullOrWhiteSpace(ticket)) return; var res = await ModalDialogUtils.ShowConfirmationDialog( Modal, "Delete configuration", $"Are you sure want to delete configuration for {Name}? (Note that pre-configured databases can't be deleted.)" ); if (res.Cancelled) return; try { await DatabaseConfig.Delete(Name, UserSession.User.GetEmail()); await ModalDialogUtils.ShowInfoDialog(Modal, "Success", $"Configuration {Name} was deleted successfully."); try { await Audit(ticket, "delete", Name); } catch (Exception ex2) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex2); } } catch (Exception ex) { try { await Audit(ticket, "delete", Name, ex); } catch (Exception ex2) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex2); } await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex); } await OnRefresh.InvokeAsync(); } private void PrepareForSaving() { if (string.IsNullOrWhiteSpace(Value.Config.Auth?.Password) || string.IsNullOrWhiteSpace(Value.Config.Auth?.User)) Value.Config.Auth = null; if (string.IsNullOrWhiteSpace(Value.Config.AdminAuth?.Password) || string.IsNullOrWhiteSpace(Value.Config.AdminAuth?.User)) Value.Config.AdminAuth = null; } private class ClipboardFormat { public string Name { get; set; } = ""; public DatabasesConfig.DatabaseConfig Value { get; set; } = new(); } private async Task Copy() { try { PrepareForSaving(); var obj = new ClipboardFormat { Name = Name, Value = Value }; var json = JsonUtils.ToJson(obj, new() {WriteIndented = true}); var clone = JsonUtils.FromJson(json); if (clone == null) return; if (!string.IsNullOrWhiteSpace(clone.Value.Config.Auth?.Password)) clone.Value.Config.Auth.Password = PasswordManager.EncryptPassword(clone.Value.Config.Auth.Password); if (!string.IsNullOrWhiteSpace(clone.Value.Config.AdminAuth?.Password)) clone.Value.Config.AdminAuth.Password = PasswordManager.EncryptPassword(clone.Value.Config.AdminAuth.Password); json = JsonUtils.ToJson(clone, new() { WriteIndented = true }); await JsRuntime.InvokeVoidAsync("DashboardUtils.CopyToClipboard", json); await ModalDialogUtils.ShowInfoDialog(Modal, "Copied", $"Configuration {Name} was copied to clipboard."); } catch (Exception ex) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex); } } private async Task Paste() { try { var json = await JsRuntime.InvokeAsync("DashboardUtils.PasteFromClipboard"); var clone = JsonUtils.FromJson(json); if (clone == null) return; if (clone.Value.Config.Auth?.Password.StartsWith('*') ?? false) clone.Value.Config.Auth.Password = PasswordManager.DecryptPassword(clone.Value.Config.Auth.Password); if (clone.Value.Config.AdminAuth?.Password.StartsWith('*') ?? false) clone.Value.Config.AdminAuth.Password = PasswordManager.DecryptPassword(clone.Value.Config.AdminAuth.Password); Name = clone.Name; Value = clone.Value; await InvokeAsync(StateHasChanged); await ModalDialogUtils.ShowInfoDialog(Modal, "Copied", $"Configuration {Name} was successfully parsed. You still need to save it!"); } catch (Exception ex) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex); } } private async Task Test() { try { var databaseInstance = !string.IsNullOrWhiteSpace(Value.Config.MongoDbDatabase) ? Value.Config.MongoDbDatabase : "admin"; var cts = new CancellationTokenSource(TimeSpan.FromSeconds(10)); var db = MongoDbHelper.GetDatabase(Value.Config, Settings.Value.Settings, databaseInstance); _ = await db.RunCommandAsync( new BsonDocumentCommand(BsonDocument.Parse( @"{ ""ping"" : 1 }")), cancellationToken: cts.Token); await ModalDialogUtils.ShowInfoDialog(Modal, "Success", $"Successfully connected to {Name}."); } catch (Exception ex) { await ModalDialogUtils.ShowExceptionDialog(Modal, "Error", ex); } } }