diff --git a/client/src/views/adm-global-settings.vue b/client/src/views/adm-global-settings.vue index 0b7b81a..bbd4430 100644 --- a/client/src/views/adm-global-settings.vue +++ b/client/src/views/adm-global-settings.vue @@ -555,6 +555,61 @@ export default { loading: false }); } + }, + async erase() { + const vm = this; + + try { + if (this.dbIsEmpty != true) { + let dialogResult = await window.$gz.dialog.confirmGeneric( + "AdminEraseDatabaseWarning", + "dire" + ); + if (dialogResult == false) { + return; + } + + dialogResult = await window.$gz.dialog.confirmGeneric( + "AdminEraseDatabaseLastWarning", + "dire" + ); + if (dialogResult == false) { + return; + } + } + //call erase + window.$gz.erasingDatabase = true; //suspend notify polling + await window.$gz.api.upsert( + API_BASE_URL + "/permanently-erase-all-data", + "I bloody understand" + ); + + vm.$router.push("/login"); + } catch (error) { + window.$gz.errorHandler.handleFormError(error, vm); + } + }, + async import() { + const vm = this; + + try { + if (this.dbIsEmpty != true) { + let dialogResult = await window.$gz.dialog.confirmGeneric( + "Import", + "warning" + ); + if (dialogResult == false) { + return; + } + } + //call erase + window.$gz.erasingDatabase = true; //suspend notify polling + await window.$gz.api.upsert(API_BASE_URL + "/import-rockfish"); + + vm.$router.push("/login"); + } catch (error) { + window.$gz.errorHandler.handleFormError(error, vm); + } } } }; @@ -572,6 +627,12 @@ async function clickHandler(menuItem) { case "save": m.vm.submit(); break; + case "erase": + m.vm.erase(); + break; + case "import-rockfish": + m.vm.import(); + break; default: window.$gz.eventBus.$emit( "notify-warning", @@ -608,6 +669,20 @@ function generateMenu(vm) { }); } menuOptions.menuItems.push({ divider: true, inset: false }); + menuOptions.menuItems.push({ + title: "AdminEraseDatabase", + icon: "$sockiSkullCrossbones", + key: FORM_KEY + ":erase", + vm: vm + }); + menuOptions.menuItems.push({ + title: "Import", + icon: "$sockiFileImport", + key: FORM_KEY + ":import-rockfish", + vm: vm + }); + menuOptions.menuItems.push({ divider: true, inset: false }); + menuOptions.menuItems.push({ divider: true, inset: false }); window.$gz.eventBus.$emit("menu-change", menuOptions); } @@ -680,7 +755,10 @@ async function fetchTranslatedText() { "AddressCountry", "AddressPostal", "AddressLatitude", - "AddressLongitude" + "AddressLongitude", + "AdminEraseDatabaseWarning", + "AdminEraseDatabase", + "AdminEraseDatabaseLastWarning" ]); } diff --git a/server/Controllers/GlobalBizSettingsController.cs b/server/Controllers/GlobalBizSettingsController.cs index 78ebe6e..4001bde 100644 --- a/server/Controllers/GlobalBizSettingsController.cs +++ b/server/Controllers/GlobalBizSettingsController.cs @@ -86,7 +86,7 @@ namespace Sockeye.Api.Controllers if (!Authorized.HasModifyRole(HttpContext.Items, biz.BizType)) return StatusCode(403, new ApiNotAuthorizedResponse()); - var o = await biz.PutAsync(updatedObject); + var o = await biz.PutAsync(updatedObject); if (o == null) return StatusCode(409, new ApiErrorResponse(biz.Errors)); return Ok(ApiOkResponse.Response(new { Concurrency = o.Concurrency })); @@ -121,7 +121,50 @@ namespace Sockeye.Api.Controllers return Ok(ApiOkResponse.Response(ret)); } - + [HttpPost("permanently-erase-all-data")] + public async Task RemoveAllData([FromBody] string acceptCode) + { + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + + if (!ModelState.IsValid) + return BadRequest(new ApiErrorResponse(ModelState)); + + long UserId = UserIdFromContext.Id(HttpContext.Items); + + //SuperUser only and must have accept code + if (string.IsNullOrWhiteSpace(acceptCode) || acceptCode.ToLowerInvariant() != "i bloody understand") + return StatusCode(403, new ApiNotAuthorizedResponse()); + + + + //empty the db + await Sockeye.Util.DbUtil.EmptyBizDataFromDatabaseForSeedingOrImportingAsync(log); + + //Log + await EventLogProcessor.LogEventToDatabaseAsync(new Event(1, 0, SockType.Global, SockEvent.EraseAllData), ct); + + return NoContent(); + } + + + + /// + /// import data from rockfish that isn't already present + /// + /// No content + [HttpPost("import-rockfish")] + public async Task ImportRockfish([FromBody] Customer newObject, ApiVersion apiVersion) + { + if (!serverState.IsOpen) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + + GlobalBizSettingsBiz biz = GlobalBizSettingsBiz.GetBiz(ct, HttpContext); + await biz.ImportRockfish(); + return NoContent(); + } + + }//eoc diff --git a/server/biz/GlobalBizSettingsBiz.cs b/server/biz/GlobalBizSettingsBiz.cs index 5240233..605cfb9 100644 --- a/server/biz/GlobalBizSettingsBiz.cs +++ b/server/biz/GlobalBizSettingsBiz.cs @@ -112,6 +112,17 @@ namespace Sockeye.Biz + + //IMPORT FROM ROCKFISH + + public async Task ImportRockfish() + { + //connect to rockfish + //in the correct order retrieve every object and if it's not already present in sockeye, import it + //this should be callable any time and it will just update so it can be test live in sync / parallel until ready to switch over +await Task.CompletedTask; + + } ///////////////////////////////////////////////////////////////////// }//eoc