From ff20c44710db7cd37f7c7c65117bdd5bdb65d96b Mon Sep 17 00:00:00 2001 From: John Cardinal Date: Wed, 10 Jun 2020 14:40:12 +0000 Subject: [PATCH] --- devdocs/todo.txt | 2 +- server/AyaNova/Controllers/AuthController.cs | 2 +- .../GlobalBizSettingsController.cs | 26 ++++++++--- .../AyaNova/Controllers/NotifyController.cs | 14 +++--- server/AyaNova/util/License.cs | 44 +++++++++++++++++-- 5 files changed, 71 insertions(+), 17 deletions(-) diff --git a/devdocs/todo.txt b/devdocs/todo.txt index 5aa3802e..6d07e6e7 100644 --- a/devdocs/todo.txt +++ b/devdocs/todo.txt @@ -25,7 +25,7 @@ todo: FRESH PURCHASE ONBOARD TODO: auth route if not licensed at all (not merely expired, but non-existent) then only manager account can login, no one else (because there could be other users somehow but no license) -todo: notify/hello route should no longer return false for trial true for not but instead: +todo: client global biz settings route should no longer return false for trial true for not but instead: Return a license state enumeration value 0 = No license at all of any kind 1 = trial license key diff --git a/server/AyaNova/Controllers/AuthController.cs b/server/AyaNova/Controllers/AuthController.cs index b1c7460d..ea0aff97 100644 --- a/server/AyaNova/Controllers/AuthController.cs +++ b/server/AyaNova/Controllers/AuthController.cs @@ -66,7 +66,7 @@ namespace AyaNova.Api.Controllers //so the only real barrier here would be a completely closed api - if (serverState.IsClosed && AyaNova.Core.License.ActiveKey.IsLicensed) + if (serverState.IsClosed && AyaNova.Core.License.ActiveKey.KeyDoesNotNeedAttention) { return StatusCode(503, new ApiErrorResponse(ApiErrorCode.API_CLOSED, null, serverState.Reason)); } diff --git a/server/AyaNova/Controllers/GlobalBizSettingsController.cs b/server/AyaNova/Controllers/GlobalBizSettingsController.cs index 79ce6afd..e9b5c032 100644 --- a/server/AyaNova/Controllers/GlobalBizSettingsController.cs +++ b/server/AyaNova/Controllers/GlobalBizSettingsController.cs @@ -46,9 +46,8 @@ namespace AyaNova.Api.Controllers { if (serverState.IsClosed) { - //Exception for manager account to handle licensing issues - if (UserIdFromContext.Id(HttpContext.Items) != 1) - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); } //Instantiate the business object handler @@ -102,7 +101,11 @@ namespace AyaNova.Api.Controllers public ActionResult GetClientGlobalBizSettings() { if (serverState.IsClosed) - return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + { + //Exception for manager account to handle licensing issues + if (UserIdFromContext.Id(HttpContext.Items) != 1) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); + } //Instantiate the business object handler // GlobalBizSettingsBiz biz = GlobalBizSettingsBiz.GetBiz(ct, HttpContext); @@ -118,10 +121,23 @@ namespace AyaNova.Api.Controllers // if (o == null) // return NotFound(new ApiErrorResponse(ApiErrorCode.NOT_FOUND)); + + + // Return a license state enumeration value + // 0 = No license at all of any kind + // 1 = trial license key + // 2 = purchased license key + // 3 = purchased but expired key (license itself is expired, not the maintenance, that's seperate) + // Note: this has nothing to do with whether there is an active license or not, merely that it's of a type + // this is so client can display appropriate UI + + + //new object with only relevant items in it var ret = new { - SearchCaseSensitiveOnly = AyaNova.Util.ServerGlobalBizSettings.SearchCaseSensitiveOnly + SearchCaseSensitiveOnly = AyaNova.Util.ServerGlobalBizSettings.SearchCaseSensitiveOnly, + LicenseState = AyaNova.Core.License.ActiveKey.Status }; return Ok(ApiOkResponse.Response(ret)); diff --git a/server/AyaNova/Controllers/NotifyController.cs b/server/AyaNova/Controllers/NotifyController.cs index 9f130e05..9e729bc5 100644 --- a/server/AyaNova/Controllers/NotifyController.cs +++ b/server/AyaNova/Controllers/NotifyController.cs @@ -43,10 +43,10 @@ namespace AyaNova.Api.Controllers [HttpGet("hello")] public ActionResult GetPreLoginPing() { - //note: this route is called by the client as the first action so it also acts like a ping to see if the server is up as well - // if (serverState.IsClosed) - // return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); - //todo: check this route for dos attack potential?? + //note: this route is called by the client to determine if it should display trial login ui + //and to see if the server is contactable + if (serverState.IsClosed) + return StatusCode(503, new ApiErrorResponse(serverState.ApiErrorCode, null, serverState.Reason)); return Ok(ApiOkResponse.Response(!AyaNova.Core.License.ActiveKey.TrialLicense)); } @@ -65,9 +65,9 @@ namespace AyaNova.Api.Controllers return Ok(ApiOkResponse.Response(69)); } -//TODO: See new count case for gist of it -//todo: see the core-notification.txt spec doc for details and -//todo: see seemingly countless Notification related cases for details :) + //TODO: See new count case for gist of it + //todo: see the core-notification.txt spec doc for details and + //todo: see seemingly countless Notification related cases for details :) //------------ diff --git a/server/AyaNova/util/License.cs b/server/AyaNova/util/License.cs index be5f20eb..35d78cf5 100644 --- a/server/AyaNova/util/License.cs +++ b/server/AyaNova/util/License.cs @@ -30,6 +30,9 @@ namespace AyaNova.Core // private const string LICENSE_SERVER_URL = "https://rockfish.ayanova.com/"; private const string LICENSE_SERVER_URL = "http://localhost:3001/"; + //Unlicensed token + private const string UNLICENSED_TOKEN = "UNLICENSED"; + //Scheduleable users private const string SERVICE_TECHS_FEATURE_NAME = "ServiceTechs"; @@ -70,10 +73,26 @@ namespace AyaNova.Core //DTO object for parsed key internal class AyaNovaLicenseKey { + // Return a license state enumeration value + // 0 = No license at all of any kind + // 1 = trial license key + // 2 = purchased license key + // 3 = purchased but expired key (license itself is expired, not the maintenance, that's seperate) + // Note: this has nothing to do with whether there is an active license or not, merely that it's of a type + // this is so client can display appropriate UI + public enum LicenseStatus + { + NONE = 0, + ActiveTrial = 1, + ExpiredTrial = 2, + ActivePurchased = 3, + ExpiredPurchased = 4 + } + public AyaNovaLicenseKey() { Features = new List(); - RegisteredTo = "UNLICENSED"; + RegisteredTo = UNLICENSED_TOKEN; Id = RegisteredTo; } @@ -130,9 +149,27 @@ namespace AyaNova.Core return false; } + public LicenseStatus Status + { + get + { + if (string.IsNullOrWhiteSpace(RegisteredTo) || RegisteredTo == UNLICENSED_TOKEN) + return LicenseStatus.NONE; + if (TrialLicense && !LicenseExpired) + return LicenseStatus.ActiveTrial; + if (TrialLicense && LicenseExpired) + return LicenseStatus.ExpiredTrial; + if (!TrialLicense && !LicenseExpired) + return LicenseStatus.ActivePurchased; + if (!TrialLicense && LicenseExpired) + return LicenseStatus.ExpiredPurchased; + throw new System.Exception("License::Status - unable to determine license status"); + } + } + //Has any kind of valid license that is active //used for auth route checking to allow for fixing this issue - public bool IsLicensed + public bool KeyDoesNotNeedAttention { get { @@ -141,6 +178,7 @@ namespace AyaNova.Core } + public bool IsEmpty { get @@ -257,7 +295,7 @@ namespace AyaNova.Core if (ActiveKey.IsEmpty) { - sb.AppendLine("UNLICENSED"); + sb.AppendLine(UNLICENSED_TOKEN); sb.AppendLine($"DB ID: {DbId}"); } else