diff --git a/.vscode/launch.json b/.vscode/launch.json index 43d3bb4..9e413a2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -11,7 +11,7 @@ "preLaunchTask": "build debug", // If you have changed target frameworks, make sure to update the program path. //#### THIS MEANS YOU JOHNNY! If the debugger fails this is the issue - "program": "${workspaceFolder}/server/bin/Debug/net6.0/sockeye.dll", + "program": "${workspaceFolder}/server/bin/Debug/net10.0/sockeye.dll", "args": [], "cwd": "${workspaceFolder}/server", "stopAtEntry": false, diff --git a/server/ConfigureSwaggerOptions.cs b/server/ConfigureSwaggerOptions.cs index 28e7200..f338101 100644 --- a/server/ConfigureSwaggerOptions.cs +++ b/server/ConfigureSwaggerOptions.cs @@ -1,9 +1,10 @@ namespace Sockeye { + using Asp.Versioning.ApiExplorer; using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Options; - using Microsoft.OpenApi.Models; + using Microsoft.OpenApi; using Swashbuckle.AspNetCore.SwaggerGen; using System; diff --git a/server/Controllers/ApiRootController.cs b/server/Controllers/ApiRootController.cs index b46e3e8..0954b74 100644 --- a/server/Controllers/ApiRootController.cs +++ b/server/Controllers/ApiRootController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.Extensions.Logging; using System; using Sockeye.Util; diff --git a/server/Controllers/AttachmentController.cs b/server/Controllers/AttachmentController.cs index 22364cd..4cd4af1 100644 --- a/server/Controllers/AttachmentController.cs +++ b/server/Controllers/AttachmentController.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/AuthController.cs b/server/Controllers/AuthController.cs index 848a510..58b1de2 100644 --- a/server/Controllers/AuthController.cs +++ b/server/Controllers/AuthController.cs @@ -1,5 +1,6 @@ using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Authorization; using TwoFactorAuthNet; using QRCoder; diff --git a/server/Controllers/AuthorizationRolesController.cs b/server/Controllers/AuthorizationRolesController.cs index 2673cb1..9c8b00e 100644 --- a/server/Controllers/AuthorizationRolesController.cs +++ b/server/Controllers/AuthorizationRolesController.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/BackupController.cs b/server/Controllers/BackupController.cs index eafc520..d0d4c3a 100644 --- a/server/Controllers/BackupController.cs +++ b/server/Controllers/BackupController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/CustomerController.cs b/server/Controllers/CustomerController.cs index d5e930f..f96864c 100644 --- a/server/Controllers/CustomerController.cs +++ b/server/Controllers/CustomerController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/CustomerNoteController.cs b/server/Controllers/CustomerNoteController.cs index 70d1769..9ffd3b5 100644 --- a/server/Controllers/CustomerNoteController.cs +++ b/server/Controllers/CustomerNoteController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/CustomerNotifySubscriptionController.cs b/server/Controllers/CustomerNotifySubscriptionController.cs index 12d3aba..669cd93 100644 --- a/server/Controllers/CustomerNotifySubscriptionController.cs +++ b/server/Controllers/CustomerNotifySubscriptionController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/DashboardViewController.cs b/server/Controllers/DashboardViewController.cs index 215441a..53fbc20 100644 --- a/server/Controllers/DashboardViewController.cs +++ b/server/Controllers/DashboardViewController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/DataListColumnViewController.cs b/server/Controllers/DataListColumnViewController.cs index 8ba925d..6e6b37e 100644 --- a/server/Controllers/DataListColumnViewController.cs +++ b/server/Controllers/DataListColumnViewController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/DataListController.cs b/server/Controllers/DataListController.cs index 605655a..5fdcd6e 100644 --- a/server/Controllers/DataListController.cs +++ b/server/Controllers/DataListController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/DataListSavedFilterController.cs b/server/Controllers/DataListSavedFilterController.cs index bbb4a6e..0658e2e 100644 --- a/server/Controllers/DataListSavedFilterController.cs +++ b/server/Controllers/DataListSavedFilterController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/EnumListController.cs b/server/Controllers/EnumListController.cs index 5786ade..c47ac24 100644 --- a/server/Controllers/EnumListController.cs +++ b/server/Controllers/EnumListController.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Collections.Generic; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/EventLogController.cs b/server/Controllers/EventLogController.cs index 2597d09..d1a2ca8 100644 --- a/server/Controllers/EventLogController.cs +++ b/server/Controllers/EventLogController.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/ExportController.cs b/server/Controllers/ExportController.cs index 179163a..680f49f 100644 --- a/server/Controllers/ExportController.cs +++ b/server/Controllers/ExportController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/FetchController.cs b/server/Controllers/FetchController.cs index 53bd9f3..bb381a6 100644 --- a/server/Controllers/FetchController.cs +++ b/server/Controllers/FetchController.cs @@ -12,7 +12,9 @@ namespace Sockeye.Api.Controllers [Route("fetch")]//Legacy v7 license fetch route [Produces("text/plain")] +#pragma warning disable AV0014 // Missing API behavior public class FetchController : ControllerBase +#pragma warning restore AV0014 // Missing API behavior { private readonly AyContext ct; diff --git a/server/Controllers/FormCustomController.cs b/server/Controllers/FormCustomController.cs index b771ae3..fbd04cc 100644 --- a/server/Controllers/FormCustomController.cs +++ b/server/Controllers/FormCustomController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/FormFieldsDefinitionsController.cs b/server/Controllers/FormFieldsDefinitionsController.cs index 45ea545..3c79b47 100644 --- a/server/Controllers/FormFieldsDefinitionsController.cs +++ b/server/Controllers/FormFieldsDefinitionsController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/FormUserOptionsController.cs b/server/Controllers/FormUserOptionsController.cs index cc2d6cf..0d65137 100644 --- a/server/Controllers/FormUserOptionsController.cs +++ b/server/Controllers/FormUserOptionsController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/GZCaseController.cs b/server/Controllers/GZCaseController.cs index f66e5aa..369d226 100644 --- a/server/Controllers/GZCaseController.cs +++ b/server/Controllers/GZCaseController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/GlobalBizSettingsController.cs b/server/Controllers/GlobalBizSettingsController.cs index 1991d86..d1220ed 100644 --- a/server/Controllers/GlobalBizSettingsController.cs +++ b/server/Controllers/GlobalBizSettingsController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/GlobalOpsBackupSettingsController.cs b/server/Controllers/GlobalOpsBackupSettingsController.cs index 5576f83..04cc8a9 100644 --- a/server/Controllers/GlobalOpsBackupSettingsController.cs +++ b/server/Controllers/GlobalOpsBackupSettingsController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/GlobalOpsNotificationSettingsController.cs b/server/Controllers/GlobalOpsNotificationSettingsController.cs index 6adbc1b..57e4c42 100644 --- a/server/Controllers/GlobalOpsNotificationSettingsController.cs +++ b/server/Controllers/GlobalOpsNotificationSettingsController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/HeadOfficeController.cs b/server/Controllers/HeadOfficeController.cs index fa58035..31a8f92 100644 --- a/server/Controllers/HeadOfficeController.cs +++ b/server/Controllers/HeadOfficeController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/HealthController.cs b/server/Controllers/HealthController.cs index e2218f1..57e0a4c 100644 --- a/server/Controllers/HealthController.cs +++ b/server/Controllers/HealthController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Diagnostics.HealthChecks; @@ -36,7 +37,8 @@ namespace Sockeye.Api.Controllers public async Task Get() { var report = await _healthCheckService.CheckHealthAsync(); - Response.Headers.Add("Cache-Control", "no-store, no-cache"); + //Response.Headers.Append("Cache-Control", "no-store, no-cache"); + Response.Headers["Cache-Control"] = "no-store, no-cache"; return report.Status == HealthStatus.Healthy ? Ok(report.Status.ToString()) : StatusCode(503, report.Status.ToString()); } }//eoc diff --git a/server/Controllers/ImportController.cs b/server/Controllers/ImportController.cs index 9718dfd..8cf9c3d 100644 --- a/server/Controllers/ImportController.cs +++ b/server/Controllers/ImportController.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/IntegrationController.cs b/server/Controllers/IntegrationController.cs index 244b45f..58bb361 100644 --- a/server/Controllers/IntegrationController.cs +++ b/server/Controllers/IntegrationController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/JobOperationsController.cs b/server/Controllers/JobOperationsController.cs index 4987276..a72e7e8 100644 --- a/server/Controllers/JobOperationsController.cs +++ b/server/Controllers/JobOperationsController.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/KPIController.cs b/server/Controllers/KPIController.cs index 5615575..9054e91 100644 --- a/server/Controllers/KPIController.cs +++ b/server/Controllers/KPIController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/LicenseController.cs b/server/Controllers/LicenseController.cs index 71b1f78..b8c8e56 100644 --- a/server/Controllers/LicenseController.cs +++ b/server/Controllers/LicenseController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/LogFilesController.cs b/server/Controllers/LogFilesController.cs index ce3e57a..e6c835d 100644 --- a/server/Controllers/LogFilesController.cs +++ b/server/Controllers/LogFilesController.cs @@ -1,6 +1,7 @@ using System.Linq; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/LogoController.cs b/server/Controllers/LogoController.cs index 301adcd..3f7c6a0 100644 --- a/server/Controllers/LogoController.cs +++ b/server/Controllers/LogoController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/MemoController.cs b/server/Controllers/MemoController.cs index 2c90dd9..4fad8f2 100644 --- a/server/Controllers/MemoController.cs +++ b/server/Controllers/MemoController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/NameController.cs b/server/Controllers/NameController.cs index 7cbdf68..c242be0 100644 --- a/server/Controllers/NameController.cs +++ b/server/Controllers/NameController.cs @@ -1,5 +1,6 @@ using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/NotifyController.cs b/server/Controllers/NotifyController.cs index 60f06ae..e7e97f7 100644 --- a/server/Controllers/NotifyController.cs +++ b/server/Controllers/NotifyController.cs @@ -1,6 +1,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/NotifySubscriptionController.cs b/server/Controllers/NotifySubscriptionController.cs index 0fc72e1..80f785a 100644 --- a/server/Controllers/NotifySubscriptionController.cs +++ b/server/Controllers/NotifySubscriptionController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/OrderController.cs b/server/Controllers/OrderController.cs deleted file mode 100644 index d3c92c8..0000000 --- a/server/Controllers/OrderController.cs +++ /dev/null @@ -1,78 +0,0 @@ -using System.Threading.Tasks; -using Microsoft.AspNetCore.Mvc; -using Microsoft.AspNetCore.Routing; -using Microsoft.Extensions.Logging; -using Sockeye.Models; -using Sockeye.Api.ControllerHelpers; -using Newtonsoft.Json.Linq; -using System; -using Sockeye.Biz; - -namespace Sockeye.Api.Controllers -{ - - [Produces("application/json")] - [Route("api/order")] - public class OrderController : ControllerBase //RECEIVE ORDERS FROM VENDOR (MyCommerce) - { - - private readonly AyContext ct; - private readonly ILogger log; - private readonly ApiServerState serverState; - - /// - /// ctor - /// - /// - /// - /// - public OrderController(AyContext dbcontext, ILogger logger, ApiServerState apiServerState) - { - ct = dbcontext; - log = logger; - serverState = apiServerState; - } - //Receive an order notification from ShareIt - //https://account.mycommerce.com/home/wiki/7479805 - [HttpPost("shareit")] - public async Task Post([FromHeader] string Authorization, [FromBody] JObject j) - { - if (!serverState.IsOpen) - { - var msg = ("Server state was not open when Vendor Order notification received; returning 503 (temp. unavailable) to them, they should retry when server open again."); - log.LogError(msg); - await NotifyEventHelper.AddOpsProblemEvent(msg); - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - } - - if (!ModelState.IsValid) - { - return BadRequest(ModelState); - } - try - { - (string username, string password) = Sockeye.Util.AutoOrderProcessingUtil.GetUsernameAndPasswordFromAuthorizeHeader(Authorization); - if (username == "Y24PYYDQSA1L12905N5MKU" && password == "MA8GMQK2PC3FDNT1RTR68R") - { - //save it to the database - var vn = new VendorNotification(); - vn.Created = DateTime.UtcNow; - vn.VendorId = 1;//MyCommerce/shareit is vendor 1, for now that's all that's needed - vn.VendorData = j.ToString(); - await ct.VendorNotification.AddAsync(vn); - await ct.SaveChangesAsync(); - } - } - catch (Exception ex) - { - log.LogError(ex, "OrderController/shareit - Exception processing vendor notification, returned 503 to vendor"); - await NotifyEventHelper.AddOpsProblemEvent("OrderController/shareit - Exception processing vendor notification, see log"); - return StatusCode(503);//ask it to retry again later - } - return Ok("ok");//shareit notifier looks for an OK response to know if it should resend or not https://account.mycommerce.com/home/wiki/7479805 - } - //------------ - - - }//eoc -}//eons \ No newline at end of file diff --git a/server/Controllers/PickListController.cs b/server/Controllers/PickListController.cs index b99700d..168c329 100644 --- a/server/Controllers/PickListController.cs +++ b/server/Controllers/PickListController.cs @@ -1,4 +1,5 @@ using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/ProductController.cs b/server/Controllers/ProductController.cs index 2737891..b9e01d4 100644 --- a/server/Controllers/ProductController.cs +++ b/server/Controllers/ProductController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/PurchaseController.cs b/server/Controllers/PurchaseController.cs index 1cd9dde..b76f679 100644 --- a/server/Controllers/PurchaseController.cs +++ b/server/Controllers/PurchaseController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/ReminderController.cs b/server/Controllers/ReminderController.cs index c62d8d2..0474d86 100644 --- a/server/Controllers/ReminderController.cs +++ b/server/Controllers/ReminderController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/ReportController.cs b/server/Controllers/ReportController.cs index c07c7e8..58d2eaf 100644 --- a/server/Controllers/ReportController.cs +++ b/server/Controllers/ReportController.cs @@ -3,6 +3,7 @@ using System.Threading.Tasks; using System; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http.Features; diff --git a/server/Controllers/ReviewController.cs b/server/Controllers/ReviewController.cs index 944ddc1..fe64daa 100644 --- a/server/Controllers/ReviewController.cs +++ b/server/Controllers/ReviewController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/RvfController.cs b/server/Controllers/RvfController.cs index cca612e..e59923c 100644 --- a/server/Controllers/RvfController.cs +++ b/server/Controllers/RvfController.cs @@ -14,7 +14,9 @@ namespace Sockeye.Api.Controllers // [AllowAnonymous] [Route("rvf")]//v8 fetch license route [Produces("application/json")] +#pragma warning disable AV0014 // Missing API behavior public class RvfController : ControllerBase +#pragma warning restore AV0014 // Missing API behavior { private readonly AyContext ct; diff --git a/server/Controllers/RvrController.cs b/server/Controllers/RvrController.cs index 6d80517..92cb747 100644 --- a/server/Controllers/RvrController.cs +++ b/server/Controllers/RvrController.cs @@ -13,7 +13,9 @@ namespace Sockeye.Api.Controllers { [Route("rvr")]//v8 TRIAL REQUEST HANDLER ROUTE [Produces("application/json")] +#pragma warning disable AV0014 // Missing API behavior public class RvrController : ControllerBase +#pragma warning restore AV0014 // Missing API behavior { private readonly AyContext ct; diff --git a/server/Controllers/ScheduleController.cs b/server/Controllers/ScheduleController.cs index ea1cb7e..1685684 100644 --- a/server/Controllers/ScheduleController.cs +++ b/server/Controllers/ScheduleController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using System; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/SearchController.cs b/server/Controllers/SearchController.cs index 5e53977..5834774 100644 --- a/server/Controllers/SearchController.cs +++ b/server/Controllers/SearchController.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/ServerMetricsController.cs b/server/Controllers/ServerMetricsController.cs index 7d5e84f..abed455 100644 --- a/server/Controllers/ServerMetricsController.cs +++ b/server/Controllers/ServerMetricsController.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.EntityFrameworkCore; @@ -14,7 +15,7 @@ using Newtonsoft.Json.Linq; using Sockeye.Models; using Sockeye.Api.ControllerHelpers; using Sockeye.Biz; -//using StackExchange.Profiling; + namespace Sockeye.Api.Controllers { diff --git a/server/Controllers/ServerStateController.cs b/server/Controllers/ServerStateController.cs index 3e10091..9ac5d97 100644 --- a/server/Controllers/ServerStateController.cs +++ b/server/Controllers/ServerStateController.cs @@ -2,6 +2,7 @@ using System; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; using Sockeye.Api.ControllerHelpers; diff --git a/server/Controllers/SubscriptionController.cs b/server/Controllers/SubscriptionController.cs index 3b9a318..57e426a 100644 --- a/server/Controllers/SubscriptionController.cs +++ b/server/Controllers/SubscriptionController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/SubscriptionServerController.cs b/server/Controllers/SubscriptionServerController.cs index 545b4ce..bc58044 100644 --- a/server/Controllers/SubscriptionServerController.cs +++ b/server/Controllers/SubscriptionServerController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/SubscriptionServerTrialRequestController.cs b/server/Controllers/SubscriptionServerTrialRequestController.cs index 750c0d2..e26538f 100644 --- a/server/Controllers/SubscriptionServerTrialRequestController.cs +++ b/server/Controllers/SubscriptionServerTrialRequestController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; diff --git a/server/Controllers/TagController.cs b/server/Controllers/TagController.cs index 9e8e05d..54ae2d4 100644 --- a/server/Controllers/TagController.cs +++ b/server/Controllers/TagController.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.Logging; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/TranslationController.cs b/server/Controllers/TranslationController.cs index 0d70e19..7248236 100644 --- a/server/Controllers/TranslationController.cs +++ b/server/Controllers/TranslationController.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/TrialLicenseRequestController.cs b/server/Controllers/TrialLicenseRequestController.cs index 11eea8e..d2e267a 100644 --- a/server/Controllers/TrialLicenseRequestController.cs +++ b/server/Controllers/TrialLicenseRequestController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/UserController.cs b/server/Controllers/UserController.cs index 00d24ec..19ff231 100644 --- a/server/Controllers/UserController.cs +++ b/server/Controllers/UserController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/UserOptionsController.cs b/server/Controllers/UserOptionsController.cs index 66c5be3..d82df38 100644 --- a/server/Controllers/UserOptionsController.cs +++ b/server/Controllers/UserOptionsController.cs @@ -2,6 +2,7 @@ using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; diff --git a/server/Controllers/VendorController.cs b/server/Controllers/VendorController.cs index 92a789f..3029e45 100644 --- a/server/Controllers/VendorController.cs +++ b/server/Controllers/VendorController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/Controllers/VendorNotificationController.cs b/server/Controllers/VendorNotificationController.cs index 7321b78..d794ac9 100644 --- a/server/Controllers/VendorNotificationController.cs +++ b/server/Controllers/VendorNotificationController.cs @@ -1,6 +1,7 @@ using System.Threading.Tasks; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; +using Asp.Versioning; using Microsoft.AspNetCore.Routing; using Microsoft.AspNetCore.Authorization; using Microsoft.Extensions.Logging; diff --git a/server/DataList/DataListSqlFilterCriteriaBuilder.cs b/server/DataList/DataListSqlFilterCriteriaBuilder.cs index 01c7f04..6d3ac55 100644 --- a/server/DataList/DataListSqlFilterCriteriaBuilder.cs +++ b/server/DataList/DataListSqlFilterCriteriaBuilder.cs @@ -843,6 +843,11 @@ namespace Sockeye.DataList sValue = sValue.Replace(nfi.CurrencyGroupSeparator, ""); sValue = sValue.Replace(nfi.CurrencyDecimalSeparator, "."); } + //case 4676 + // Decimal, Currency (after the existing separator normalisation) + if (!decimal.TryParse(sValue, NumberStyles.Number, CultureInfo.InvariantCulture, out var d)) + throw new ArgumentException($"Invalid numeric filter value [{sValue}]"); + sValue = d.ToString(CultureInfo.InvariantCulture); } break; case UiFieldDataType.Integer: @@ -852,6 +857,12 @@ namespace Sockeye.DataList sValue = sValue.Replace(nfi.NumberGroupSeparator, ""); sValue = sValue.Replace(nfi.NumberDecimalSeparator, "."); } + + //case 4676 + // Integer, InternalId, Enum, MemorySize, Roles + if (!long.TryParse(sValue, NumberStyles.Integer, CultureInfo.InvariantCulture, out var l)) + throw new ArgumentException($"Invalid numeric filter value [{sValue}]"); + sValue = l.ToString(CultureInfo.InvariantCulture); } break; case UiFieldDataType.InternalId: @@ -1152,7 +1163,7 @@ namespace Sockeye.DataList /// public static string TagFilterToSqlCriteriaHelper(string SqlColumnNameToFilter, List sValue, bool bAny) { - if(sValue.Count==0) return string.Empty; + if (sValue.Count == 0) return string.Empty; //if it's an OR (any) query then need to build individual terms, if it's not then it's just an all or AND query and can pass through as is if (sValue.Count > 0 && bAny == true) { diff --git a/server/Program.cs b/server/Program.cs index 1be6757..aa570a5 100644 --- a/server/Program.cs +++ b/server/Program.cs @@ -124,11 +124,9 @@ namespace Sockeye logConfig.AddTarget("blackhole", nullTarget); // Step 3. Set target properties - fileTarget.FileName = Path.Combine(ServerBootConfig.SOCKEYE_LOG_PATH, "log-sockeye.txt"); fileTarget.Layout = "${longdate}|${uppercase:${level}}|${logger}|${message:exceptionSeparator==>:withException=true}"; - fileTarget.ArchiveFileName = Path.Combine(ServerBootConfig.SOCKEYE_LOG_PATH, "log-sockeye-{#}.txt"); - fileTarget.ArchiveNumbering = ArchiveNumberingMode.Rolling;//so expect to see 1 to 10 or 0 to ten as may be + fileTarget.ArchiveFileName = Path.Combine(ServerBootConfig.SOCKEYE_LOG_PATH, "log-sockeye-{#}.txt"); fileTarget.ArchiveAboveSize = 1000000;//1mb maximum file size fileTarget.MaxArchiveFiles = 9;//max 10 files totalling 10mb, the current log-sockeye.txt and log-sockeye-[0-9].txt @@ -197,7 +195,9 @@ namespace Sockeye } // NLog: setup the logger first to catch all errors - var logger = NLogBuilder.ConfigureNLog(logConfig).GetLogger("BOOT"); + // var logger = NLogBuilder.ConfigureNLog(logConfig).GetLogger("BOOT"); + NLog.LogManager.Configuration = logConfig; + var logger = NLog.LogManager.GetLogger("BOOT"); #endregion diff --git a/server/Startup.cs b/server/Startup.cs index 25996af..4f46628 100644 --- a/server/Startup.cs +++ b/server/Startup.cs @@ -4,7 +4,6 @@ using System.Linq; using System; using System.Collections.Generic; using Microsoft.AspNetCore.Builder; -using Microsoft.AspNetCore.Mvc.ApiExplorer; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using Microsoft.EntityFrameworkCore; @@ -12,7 +11,7 @@ using Microsoft.AspNetCore.Authentication.JwtBearer; using Microsoft.IdentityModel.Tokens; using Microsoft.Extensions.Hosting; using Microsoft.AspNetCore.Http; -using Microsoft.OpenApi.Models; +using Microsoft.OpenApi; using Microsoft.Extensions.Options; using Swashbuckle.AspNetCore.SwaggerGen; @@ -21,7 +20,8 @@ using Sockeye.Util; using Sockeye.Generator; using Sockeye.Biz; using NLog.Extensions.Logging; -using StackExchange.Profiling; +using Asp.Versioning.ApiExplorer; +using Asp.Versioning; namespace Sockeye @@ -56,24 +56,6 @@ namespace Sockeye _newLog.LogDebug("Health"); services.AddHealthChecks().AddDbContextCheck(); ; - _newLog.LogDebug("Profiler"); - //https://dotnetthoughts.net/using-miniprofiler-in-aspnetcore-webapi/ - services.AddMemoryCache(); - services.AddMiniProfiler(options => - { - options.RouteBasePath = "/profiler"; - //in testing only ignorepaths was reliable and worked and docs say it prevents any profiling at all - options.IgnorePath("/auth").IgnorePath("/user").IgnorePath("/docs").IgnorePath("/cust").IgnorePath("/notify/hello").IgnorePath("/notify/new-count"); - options.ResultsAuthorize = request => - { - if (request.HttpContext.Items["AY_PROFILER_ALLOWED"] != null) - return true; - return false; - }; - - }).AddEntityFramework(); - - //Server state service for shutting people out of api _newLog.LogDebug("ServerState service"); services.AddSingleton(new Sockeye.Api.ControllerHelpers.ApiServerState()); @@ -195,28 +177,46 @@ namespace Sockeye + // #region Swagger + + // services + // .AddApiVersioning(options => + // { + // options.AssumeDefaultVersionWhenUnspecified = true; + // options.DefaultApiVersion = new ApiVersion(8,0);// Microsoft.AspNetCore.Mvc.ApiVersion.Parse("8.0"); + // options.ReportApiVersions = true; + // }); + // services.AddVersionedApiExplorer(options => + // { + + // // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service + // // note: the specified format code will format the version as "'v'major[.minor][-status]" + // options.GroupNameFormat = "'v'VVV"; + + // // note: this option is only necessary when versioning by url segment. the SubstitutionFormat + // // can also be used to control the format of the API version in route templates + + // //THIS IS WHAT ADDS THE API version PARAMETER AUTOMATICALLY so you don't need to type an 8 in every swagger-ui route test + // options.SubstituteApiVersionInUrl = true; + // }); #region Swagger services - .AddApiVersioning(options => - { - options.AssumeDefaultVersionWhenUnspecified = true; - options.DefaultApiVersion = Microsoft.AspNetCore.Mvc.ApiVersion.Parse("8.0"); - options.ReportApiVersions = true; - }); - services.AddVersionedApiExplorer(options => - { + .AddApiVersioning(options => + { + options.AssumeDefaultVersionWhenUnspecified = true; + options.DefaultApiVersion = new ApiVersion(8, 0); + options.ReportApiVersions = true; + }) + .AddMvc() + .AddApiExplorer(options => + { + // format the version as "'v'major[.minor][-status]" + options.GroupNameFormat = "'v'VVV"; - // add the versioned api explorer, which also adds IApiVersionDescriptionProvider service - // note: the specified format code will format the version as "'v'major[.minor][-status]" - options.GroupNameFormat = "'v'VVV"; - - // note: this option is only necessary when versioning by url segment. the SubstitutionFormat - // can also be used to control the format of the API version in route templates - - //THIS IS WHAT ADDS THE API version PARAMETER AUTOMATICALLY so you don't need to type an 8 in every swagger-ui route test - options.SubstituteApiVersionInUrl = true; - }); + // THIS IS WHAT ADDS THE API version PARAMETER AUTOMATICALLY so you don't need to type an 8 in every swagger-ui route test + options.SubstituteApiVersionInUrl = true; + }); services.AddTransient, ConfigureSwaggerOptions>(); services.AddSwaggerGen( c => @@ -234,16 +234,23 @@ namespace Sockeye Scheme = "bearer" //The name of the HTTP Authorization scheme to be used in the Authorization header. In this case "bearer". }); - c.AddSecurityRequirement(new OpenApiSecurityRequirement{ - { - new OpenApiSecurityScheme{ - Reference = new OpenApiReference{ - Id = "Bearer", //The name of the previously defined security scheme. - Type = ReferenceType.SecurityScheme - } - },new List() - } - }); + // c.AddSecurityRequirement(new OpenApiSecurityRequirement{ + // { + // new OpenApiSecurityScheme{ + // Reference = new OpenApiReference{ + // Id = "Bearer", //The name of the previously defined security scheme. + // Type = ReferenceType.SecurityScheme + // } + // },new List() + // } + // }); + + c.AddSecurityRequirement(document => new OpenApiSecurityRequirement + { + // "Bearer" must match the name given to AddSecurityDefinition above + [new OpenApiSecuritySchemeReference("Bearer", document)] = [] + }); + } ); services.AddSwaggerGenNewtonsoftSupport(); @@ -390,56 +397,7 @@ namespace Sockeye { if (!context.User.Identity.IsAuthenticated) { - #region Profiler workaround - //Is this a profiler route? If so we're going to use the dl token to authorize - if (context.Request.Path.Value.StartsWith("/profiler/results")) - { - //someone is requesting the profiler - //check for a dl token "t" and rehydrate user if found - //Note that the profiler UI triggers it's own requests to to get the token - //we need to check the referer which was the first page of profile - - string token = string.Empty; - //is the token in the request? - if (context.Request.Query.ContainsKey("t")) - { - token = context.Request.Query["t"].ToString(); - } - else if (context.Request.Headers["Referer"].Count > 0) - {//Maybe it's in the referer - //try to split it on the ? - string[] stuff = context.Request.Headers["Referer"].ToString().Split('?'); - if (stuff.Count() > 1) - { - var q = Microsoft.AspNetCore.WebUtilities.QueryHelpers.ParseQuery(stuff[1]); - if (q.ContainsKey("t")) - { - token = q["t"].ToString(); - } - } - } - - if (!string.IsNullOrWhiteSpace(token)) - { - using (AyContext ct = ServiceProviderProvider.DBContext) - { - var u = ct.User.AsNoTracking().SingleOrDefault(z => z.DlKey == token.ToString() && z.Active == true); - if (u != null) - { - //this is necessary because they might have an expired JWT but this would just keep on working without a date check - //the default is the same timespan as the jwt so it's all good - var utcNow = new DateTimeOffset(DateTime.Now.ToUniversalTime(), TimeSpan.Zero); - if (u.DlKeyExpire > utcNow.DateTime) - { - if (Sockeye.Api.ControllerHelpers.Authorized.HasReadFullRole(u.Roles, SockType.ServerMetrics)) - context.Request.HttpContext.Items["AY_PROFILER_ALLOWED"] = true; - } - } - } - } - } - #endregion profiler workaround - + context.Request.HttpContext.Items["AY_ROLES"] = 0; await next.Invoke(); } @@ -510,7 +468,7 @@ namespace Sockeye if (!bLocalReportRenderRequest) { context.Response.StatusCode = 401; - context.Response.Headers.Add("X-Sockeye-Authorization-Error", "E2004 - Authorization token replaced by more recent login"); + context.Response.Headers.Append("X-Sockeye-Authorization-Error", "E2004 - Authorization token replaced by more recent login"); await context.Response.WriteAsync("E2004 - Authorization token replaced by more recent login"); } } @@ -525,11 +483,7 @@ namespace Sockeye #endregion - _newLog.LogDebug("Profiler"); - app.UseMiniProfiler(); - - - + _newLog.LogDebug("Endpoints pipeline"); app.UseEndpoints(endpoints => { diff --git a/server/biz/KeyFactory.cs b/server/biz/KeyFactory.cs index 3c77dcc..b598cb7 100644 --- a/server/biz/KeyFactory.cs +++ b/server/biz/KeyFactory.cs @@ -7,6 +7,7 @@ using Org.BouncyCastle.Crypto; using Org.BouncyCastle.OpenSsl; using Sockeye.Models; using Sockeye.Util; +using System.Globalization; @@ -311,12 +312,10 @@ namespace Sockeye.Biz //stamp a unique value in the key so it can be revoked later //used to use the digest value of the key for this with xml key //whole unix timestamp seconds but kept as a double to work beyond 2038 + //case 4670 w.WritePropertyName("Id"); - var vv = Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds); - string sId = vv.ToString(); - if (sId.Contains(",")) - sId = sId.Split('.')[0]; - w.WriteValue(sId); + w.WriteValue(Math.Truncate((DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds).ToString(CultureInfo.InvariantCulture)); + w.WritePropertyName("Created"); w.WriteValue(System.DateTime.Now); @@ -348,7 +347,8 @@ namespace Sockeye.Biz w.WriteValue(l.MaintenanceExpire.AddYears(2)); w.WritePropertyName("TotalScheduleableUsers"); - w.WriteValue(l.Users.ToString());//Needs to be a string to match rockfish format + //cae 4670 + w.WriteValue(l.Users.ToString(CultureInfo.InvariantCulture));//Needs to be a string to match rockfish format w.WritePropertyName("Expires"); w.WriteValue(l.MaintenanceExpire); @@ -649,7 +649,71 @@ HOW TO INSTALL YOUR LICENSE KEY #endregion templates + #region key signing test harness function + internal static string Sign(string keyText) + { + + // StringBuilder sbKey = new StringBuilder(); + // StringWriter sw = new StringWriter(sbKey); + //GET JSON as a string with whitespace stripped outside of delimited strings + //http://stackoverflow.com/questions/8913138/minify-indented-json-string-in-net + string keyNoWS = System.Text.RegularExpressions.Regex.Replace(keyText, "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); + + + //**** Note this is our real 2016 private key + var privatePEM = @"-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAz7wrvLDcKVMZ31HFGBnLWL08IodYIV5VJkKy1Z0n2snprhSi +u3izxTyz+SLpftvKHJpky027ii7l/pL9Bo3JcjU5rKrxXavnE7TuYPjXn16dNLd0 +K/ERSU+pXLmUaVN0nUWuGuUMoGJMEXoulS6pJiG11yu3BM9fL2Nbj0C6a+UwzEHF +mns3J/daZOb4gAzMUdJfh9OJ0+wRGzR8ZxyC99Na2gDmqYglUkSMjwLTL/HbgwF4 +OwmoQYJBcET0Wa6Gfb17SaF8XRBV5ZtpCsbStkthGeoXZkFriB9c1eFQLKpBYQo2 +DW3H1MPG2nAlQZLbkJj5cSh7/t1bRF08m6P+EQIDAQABAoIBAQCGvTpxLRXgB/Kk +EtmQBEsMx9EVZEwZeKIqKuDsBP8wvf4/10ql5mhT6kehtK9WhSDW5J2z8DtQKZMs +SBKuCZE77qH2CPp9E17SPWzQoRbaW/gDlWpYhgf8URs89XH5zxO4XtXKw/4omRlV +zLYiNR2pifv0EHqpOAg5KGzewdEo4VgXgtRWpHZLMpH2Q0/5ZIKMhstI6vFHP1p7 +jmU4YI6uxiu7rVrZDmIUsAGoTdMabNqK/N8hKaoBiIto0Jn1ck26g+emLg8m160y +Xciu5yFUU+PP1SJMUs+k1UnAWf4p46X9jRLQCBRue9o0Ntiq/75aljRoDvgdwDsR +mg4ZANqxAoGBAPBoM5KoMZ4sv8ZFv8V+V8hgL5xiLgGoiwQl91mRsHRM/NQU5A/w +tH8nmwUrJOrksV7kX9228smKmoliTptyGGyi1NPmSkA7cN9YYnENoOEBHCVNK9vh +P+bkbMYUDNMW4fgOj09oXtQtMl5E2B3OTGoNwZ2w13YQJ8RIniLPsX7nAoGBAN01 +eQNcUzQk9YrFGTznOs8udDLBfigDxaNnawvPueulJdBy6ZXDDrKmkQQA7xxl8YPr +dNtBq2lOgnb6+smC15TaAfV/fb8BLmkSwdn4Fy0FApIXIEOnLq+wjkte98nuezl8 +9KXDzaqNI9hPuk2i36tJuLLMH8hzldveWbWjSlRHAoGBAKRPE7CQtBjfjNL+qOta +RrT0yJWhpMANabYUHNJi+K8ET2jEPnuGkFa3wwPtUPYaCABLJhprB9Unnid3wTIM +8RSO1ddd9jGgbqy3w9Bw+BvQnmQAMpG9iedNB+r5mSpM4XSgvuIO+4EYwuwbMXpt +nVx+um4Eh75xnDxTRYGVYkLRAoGAaZVpUlpR+HSfooHbPv+bSWKB4ewLPCw4vHrT +VErtEfW8q9b9eRcmP81TMFcFykc6VN4g47pfh58KlKHM7DwAjDLWdohIy89TiKGE +V3acEUfv5y0UoFX+6ara8Ey+9upWdKUY3Lotw3ckoc3EPeQ84DQK7YSSswnAgLaL +mS/8fWcCgYBjRefVbEep161d2DGruk4X7eNI9TFJ278h6ydW5kK9aTJuxkrtKIp4 +CYf6emoB4mLXFPvAmnsalkhN2iB29hUZCXXSUjpKZrpijL54Wdu2S6ynm7aT97NF +oArP0E2Vbow3JMxq/oeXmHbrLMLQfYyXwFmciLFigOtkd45bfHdrbA== +-----END RSA PRIVATE KEY-----"; + + PemReader pr = new PemReader(new StringReader(privatePEM)); + AsymmetricCipherKeyPair keys = (AsymmetricCipherKeyPair)pr.ReadObject(); + var encoder = new UTF8Encoding(false, true); + var inputData = encoder.GetBytes(keyNoWS); + var signer = SignerUtilities.GetSigner("SHA256WITHRSA"); + signer.Init(true, keys.Private); + signer.BlockUpdate(inputData, 0, inputData.Length); + var sign = signer.GenerateSignature(); + var signature = Convert.ToBase64String(sign); + + + System.Text.StringBuilder sbOut = new StringBuilder(); + sbOut.AppendLine("[KEY"); + sbOut.AppendLine(keyText); + sbOut.AppendLine("KEY]"); + sbOut.AppendLine("[SIGNATURE"); + sbOut.AppendLine(signature); + sbOut.AppendLine("SIGNATURE]"); + + return sbOut.ToString(); + + + } + #endregion //eoc diff --git a/server/biz/RavenKeyFactory.cs b/server/biz/RavenKeyFactory.cs index 5d9e568..cde31ad 100644 --- a/server/biz/RavenKeyFactory.cs +++ b/server/biz/RavenKeyFactory.cs @@ -206,6 +206,73 @@ oArP0E2Vbow3JMxq/oeXmHbrLMLQfYyXwFmciLFigOtkd45bfHdrbA== } + #region key signing test harness function + + internal static string Sign(string keyText) + { + + // StringBuilder sbKey = new StringBuilder(); + // StringWriter sw = new StringWriter(sbKey); + //GET JSON as a string with whitespace stripped outside of delimited strings + //http://stackoverflow.com/questions/8913138/minify-indented-json-string-in-net + string keyNoWS = System.Text.RegularExpressions.Regex.Replace(keyText, "(\"(?:[^\"\\\\]|\\\\.)*\")|\\s+", "$1"); + + + //**** Note this is our real 2016 private key + var privatePEM = @"-----BEGIN RSA PRIVATE KEY----- +MIIEpAIBAAKCAQEAz7wrvLDcKVMZ31HFGBnLWL08IodYIV5VJkKy1Z0n2snprhSi +u3izxTyz+SLpftvKHJpky027ii7l/pL9Bo3JcjU5rKrxXavnE7TuYPjXn16dNLd0 +K/ERSU+pXLmUaVN0nUWuGuUMoGJMEXoulS6pJiG11yu3BM9fL2Nbj0C6a+UwzEHF +mns3J/daZOb4gAzMUdJfh9OJ0+wRGzR8ZxyC99Na2gDmqYglUkSMjwLTL/HbgwF4 +OwmoQYJBcET0Wa6Gfb17SaF8XRBV5ZtpCsbStkthGeoXZkFriB9c1eFQLKpBYQo2 +DW3H1MPG2nAlQZLbkJj5cSh7/t1bRF08m6P+EQIDAQABAoIBAQCGvTpxLRXgB/Kk +EtmQBEsMx9EVZEwZeKIqKuDsBP8wvf4/10ql5mhT6kehtK9WhSDW5J2z8DtQKZMs +SBKuCZE77qH2CPp9E17SPWzQoRbaW/gDlWpYhgf8URs89XH5zxO4XtXKw/4omRlV +zLYiNR2pifv0EHqpOAg5KGzewdEo4VgXgtRWpHZLMpH2Q0/5ZIKMhstI6vFHP1p7 +jmU4YI6uxiu7rVrZDmIUsAGoTdMabNqK/N8hKaoBiIto0Jn1ck26g+emLg8m160y +Xciu5yFUU+PP1SJMUs+k1UnAWf4p46X9jRLQCBRue9o0Ntiq/75aljRoDvgdwDsR +mg4ZANqxAoGBAPBoM5KoMZ4sv8ZFv8V+V8hgL5xiLgGoiwQl91mRsHRM/NQU5A/w +tH8nmwUrJOrksV7kX9228smKmoliTptyGGyi1NPmSkA7cN9YYnENoOEBHCVNK9vh +P+bkbMYUDNMW4fgOj09oXtQtMl5E2B3OTGoNwZ2w13YQJ8RIniLPsX7nAoGBAN01 +eQNcUzQk9YrFGTznOs8udDLBfigDxaNnawvPueulJdBy6ZXDDrKmkQQA7xxl8YPr +dNtBq2lOgnb6+smC15TaAfV/fb8BLmkSwdn4Fy0FApIXIEOnLq+wjkte98nuezl8 +9KXDzaqNI9hPuk2i36tJuLLMH8hzldveWbWjSlRHAoGBAKRPE7CQtBjfjNL+qOta +RrT0yJWhpMANabYUHNJi+K8ET2jEPnuGkFa3wwPtUPYaCABLJhprB9Unnid3wTIM +8RSO1ddd9jGgbqy3w9Bw+BvQnmQAMpG9iedNB+r5mSpM4XSgvuIO+4EYwuwbMXpt +nVx+um4Eh75xnDxTRYGVYkLRAoGAaZVpUlpR+HSfooHbPv+bSWKB4ewLPCw4vHrT +VErtEfW8q9b9eRcmP81TMFcFykc6VN4g47pfh58KlKHM7DwAjDLWdohIy89TiKGE +V3acEUfv5y0UoFX+6ara8Ey+9upWdKUY3Lotw3ckoc3EPeQ84DQK7YSSswnAgLaL +mS/8fWcCgYBjRefVbEep161d2DGruk4X7eNI9TFJ278h6ydW5kK9aTJuxkrtKIp4 +CYf6emoB4mLXFPvAmnsalkhN2iB29hUZCXXSUjpKZrpijL54Wdu2S6ynm7aT97NF +oArP0E2Vbow3JMxq/oeXmHbrLMLQfYyXwFmciLFigOtkd45bfHdrbA== +-----END RSA PRIVATE KEY-----"; + + PemReader pr = new PemReader(new StringReader(privatePEM)); + AsymmetricCipherKeyPair keys = (AsymmetricCipherKeyPair)pr.ReadObject(); + var encoder = new UTF8Encoding(false, true); + var inputData = encoder.GetBytes(keyNoWS); + var signer = SignerUtilities.GetSigner("SHA256WITHRSA"); + signer.Init(true, keys.Private); + signer.BlockUpdate(inputData, 0, inputData.Length); + var sign = signer.GenerateSignature(); + var signature = Convert.ToBase64String(sign); + + + System.Text.StringBuilder sbOut = new StringBuilder(); + sbOut.AppendLine("[KEY"); + sbOut.AppendLine(keyText); + sbOut.AppendLine("KEY]"); + sbOut.AppendLine("[SIGNATURE"); + sbOut.AppendLine(signature); + sbOut.AppendLine("SIGNATURE]"); + + return sbOut.ToString(); + + + } + #endregion + + #region old stuff #region license classes diff --git a/server/biz/ReportBiz.cs b/server/biz/ReportBiz.cs index 1c72364..89c09d7 100644 --- a/server/biz/ReportBiz.cs +++ b/server/biz/ReportBiz.cs @@ -519,7 +519,8 @@ namespace Sockeye.Biz else { log.LogDebug($"Windows: Calling browserFetcher download async now:"); - await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision); + //await new BrowserFetcher().DownloadAsync(BrowserFetcher.DefaultChromiumRevision); + await new BrowserFetcher().DownloadAsync(); } @@ -532,17 +533,20 @@ namespace Sockeye.Biz //Keep for debugging headfully // var DefaultArgs = "--no-sandbox"; - var DefaultArgs = "--headless --no-sandbox"; + //var DefaultArgs = "--headless --no-sandbox"; + var DefaultArgs = new[] { "--no-sandbox" }; if (!string.IsNullOrWhiteSpace(ServerBootConfig.SOCKEYE_REPORT_RENDER_BROWSER_PARAMS)) { log.LogDebug($"SOCKEYE_REPORT_RENDER_BROWSER_PARAMS will be used: {ServerBootConfig.SOCKEYE_REPORT_RENDER_BROWSER_PARAMS}"); - lo.Args = new string[] { $"{ServerBootConfig.SOCKEYE_REPORT_RENDER_BROWSER_PARAMS}" };// SOCKEYE_REPORT_RENDER_BROWSER_PARAMS + //lo.Args = new string[] { $"{ServerBootConfig.SOCKEYE_REPORT_RENDER_BROWSER_PARAMS}" };// SOCKEYE_REPORT_RENDER_BROWSER_PARAMS + lo.Args = ServerBootConfig.SOCKEYE_REPORT_RENDER_BROWSER_PARAMS.Split(' ', StringSplitOptions.RemoveEmptyEntries); } else { log.LogDebug($"SOCKEYE_REPORT_RENDER_BROWSER_PARAMS not set, using defaults '{DefaultArgs}'"); - lo.Args = new string[] { DefaultArgs }; + //lo.Args = new string[] { DefaultArgs }; + lo.Args = DefaultArgs; } System.Text.StringBuilder PageLog = new System.Text.StringBuilder(); @@ -568,8 +572,9 @@ namespace Sockeye.Biz case ConsoleType.Error: try { - var errorArgs = await Task.WhenAll(args.Message.Args.Select(arg => arg.ExecutionContext.EvaluateFunctionAsync("(arg) => arg instanceof Error ? arg.message : arg", arg))); - PageLog.AppendLine($"ERROR: {args.Message.Text} args: [{string.Join(", ", errorArgs)}]"); + var errorArgs = await Task.WhenAll(args.Message.Args.Select(arg => arg.EvaluateFunctionAsync("(arg) => arg instanceof Error ? arg.message : arg"))); + // PageLog.AppendLine($"ERROR: {args.Message.Text} args: [{string.Join(", ", errorArgs)}]"); + PageLog.AppendLine($"ERROR: {args.Message.Text} args: [{string.Join(", ", errorArgs)}]"); } catch { } break; diff --git a/server/sockeye.csproj b/server/sockeye.csproj index d047440..23095f8 100644 --- a/server/sockeye.csproj +++ b/server/sockeye.csproj @@ -1,11 +1,11 @@ - net6.0 + net10.0 true - 8.0.16 - 8.0.16.0 + 8.1.0 + 8.1.0.0 sockeye.ico bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml 1591 @@ -18,35 +18,30 @@ - - - - - - - - - - - + + + + + + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive all - - - - - - - - - - - - - - - + + + + + + + + + @@ -69,6 +64,8 @@ - + + + \ No newline at end of file diff --git a/server/util/FileUtil.cs b/server/util/FileUtil.cs index b65474a..d1294c4 100644 --- a/server/util/FileUtil.cs +++ b/server/util/FileUtil.cs @@ -863,7 +863,7 @@ namespace Sockeye.Util using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) { - file.Read(bytes, 0, bytes.Length); + file.ReadExactly(bytes, 0, bytes.Length); } var headerPos = BitConverter.ToInt32(bytes, peHeaderOffset); diff --git a/sockeye.tests/ResignTests.cs b/sockeye.tests/ResignTests.cs new file mode 100644 index 0000000..983b0eb --- /dev/null +++ b/sockeye.tests/ResignTests.cs @@ -0,0 +1,102 @@ +namespace sockeye.tests; + +/* +Extract key fixture data, note that pgroup / format is 1 for v7 product family keys and not 1 for any v8 family keys +mkdir C:\data\sockeye-fixtures +$env:PGCLIENTENCODING = "UTF8" +.\psql -U postgres -d sockeye -At -o C:\data\sockeye-fixtures\resign.json -c " + SELECT json_agg(t ORDER BY t.id) FROM ( + SELECT id, + pgroup AS format, + key + FROM alicense + WHERE key IS NOT NULL + ) t;" + + + +*/ +// public class UnitTest1 +// { +// [Fact] +// public void Test1() +// { + +// } +// } + + +using System.Text.Json; + +public record ResignRow(long Id, int Format, string Key); + +public static class ResignFixture +{ + static readonly Lazy> _rows = new(Load); + public static IReadOnlyDictionary Rows => _rows.Value; + + static Dictionary Load() + { + var path = "C:\\data\\sockeye-fixtures\\resign.json";//Environment.GetEnvironmentVariable("SOCKEYE_RESIGN_FIXTURE"); + if (string.IsNullOrWhiteSpace(path) || !File.Exists(path)) + throw new InvalidOperationException( + "Set SOCKEYE_RESIGN_FIXTURE to the exported alicense JSON file."); + + var rows = JsonSerializer.Deserialize>( + File.ReadAllText(path), + new JsonSerializerOptions { PropertyNameCaseInsensitive = true }); + + return rows.ToDictionary(r => r.Id); + } +} + +public class ResignTests +{ + public static IEnumerable RowIds() => + ResignFixture.Rows.Keys.Select(id => new object[] { id }); + + [Theory] + [MemberData(nameof(RowIds))] + public void Stored_licence_resigns_identically(long id) + { + var row = ResignFixture.Rows[id]; + var keyText = Between(row.Key, "[KEY", "KEY]"); + var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]")); + + var actual = row.Format == 1 + ? Sockeye.Biz.KeyFactory.Sign(keyText) // your extracted internal methods + : Sockeye.Biz.RavenKeyFactory.Sign(keyText); + //test sign returns whole key with signature need to re-extract signature only + actual = StripWs(Between(actual, "[SIGNATURE", "SIGNATURE]")); + + Assert.Equal(expected, actual); + } + + [Fact] + public void Fixture_covers_both_formats() + { + Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 1); + Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 2); + Assert.Contains(ResignFixture.Rows.Values, r => r.Format == 3); + } + + [Fact] + public void Tampered_payload_does_not_match() + { + var row = ResignFixture.Rows.Values.First(r => r.Format == 1); + var keyText = Between(row.Key, "[KEY", "KEY]") + "x"; + var expected = StripWs(Between(row.Key, "[SIGNATURE", "SIGNATURE]")); + Assert.NotEqual(expected, StripWs(Between(Sockeye.Biz.KeyFactory.Sign(keyText), "[SIGNATURE", "SIGNATURE]"))); + } + + static string Between(string s, string start, string end) + { + int a = s.IndexOf(start, StringComparison.Ordinal); + int b = s.IndexOf(end, StringComparison.Ordinal); + if (a < 0 || b < 0 || b < a) + throw new FormatException($"Markers {start}/{end} not found"); + return s.Substring(a + start.Length, b - a - start.Length); + } + + static string StripWs(string s) => string.Concat(s.Where(c => !char.IsWhiteSpace(c))); +} \ No newline at end of file diff --git a/sockeye.tests/sockeye.tests.csproj b/sockeye.tests/sockeye.tests.csproj new file mode 100644 index 0000000..20a6358 --- /dev/null +++ b/sockeye.tests/sockeye.tests.csproj @@ -0,0 +1,24 @@ + + + net10.0 + enable + disable + false + + + + + + + runtime; build; native; contentfiles; analyzers; buildtransitive + all + + + + + + + + + + \ No newline at end of file