maintenance expiration vs build date checking code
This commit is contained in:
@@ -12,7 +12,12 @@ Updates:
|
||||
it should also have some license route fetch prevention i.e. license has updates end date so server won't send if expired? Or something along those lines??
|
||||
Or maybe that would be bad if they downgrade and want to put back in the license they paid for (restore from backup?)
|
||||
|
||||
|
||||
Update scenarios to handle
|
||||
boot with newer version than licensed and no db at all
|
||||
in this case it's ok to do the schema update and install the fresh empty db then fetch the license
|
||||
LICENSE FETCH SHOULD COMPARE DATES BEFORE INSTALLING A FETCHED LICENSE AND BALK IF MISMATCH
|
||||
Boot with newer version and have existing db with outdated schema
|
||||
TODO: it should check the license version *before* the schema update in order to not break anything
|
||||
|
||||
|
||||
todo: RELEASE FINAL RELEASE
|
||||
@@ -23,7 +28,7 @@ todo: RELEASE FINAL RELEASE
|
||||
test carefully once done reversion everything to 8.0.1 for official release
|
||||
Post in /next download folder for testing before posting fully
|
||||
Re-run the smoke tests and e2e tests before posting 8.0.1 officially
|
||||
|
||||
todo: test on every platform every installer and be certain they work as advertised, yes this is a pain but it's necessary
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ theme:
|
||||
site_name: AyaNova manual
|
||||
site_dir: '../../../server/AyaNova/wwwroot/docs'
|
||||
strict: true
|
||||
copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-08-04
|
||||
copyright: Copyright © 2022 Ground Zero Tech-Works Inc. REV-2022-08-05
|
||||
extra:
|
||||
generator: false
|
||||
# Extensions
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
<ApplicationIcon>ayanova.ico</ApplicationIcon>
|
||||
<DocumentationFile>bin\$(Configuration)\$(TargetFramework)\$(AssemblyName).xml</DocumentationFile>
|
||||
<noWarn>1591</noWarn>
|
||||
<Deterministic>False</Deterministic>
|
||||
</PropertyGroup>
|
||||
<!-- https://andrewlock.net/version-vs-versionsuffix-vs-packageversion-what-do-they-all-mean/ -->
|
||||
<ItemGroup>
|
||||
|
||||
@@ -208,6 +208,11 @@ namespace AyaNova
|
||||
logger.Info($"AYANOVA SERVER {AyaNovaVersion.VersionString} BOOTING");
|
||||
|
||||
|
||||
#if (DEBUG)
|
||||
logger.Info($"### Linker timestamp is {Util.FileUtil.GetLinkerTimestampUtc(System.Reflection.Assembly.GetExecutingAssembly())}");
|
||||
|
||||
#endif
|
||||
|
||||
//log configuration
|
||||
logger.Info($"Config {DiagConfig}");
|
||||
logger.Debug($"Full configuration is {config.GetDebugView()}");
|
||||
@@ -294,7 +299,7 @@ namespace AyaNova
|
||||
catch (Exception e)
|
||||
{
|
||||
logger.Fatal(e, "E1090 - AyaNova server can't start due to unexpected exception during initialization");
|
||||
throw;
|
||||
//throw;
|
||||
}
|
||||
finally
|
||||
{
|
||||
|
||||
@@ -593,7 +593,35 @@ namespace AyaNova
|
||||
//log each item individually from runtime parameters
|
||||
|
||||
|
||||
|
||||
//Initialize license unless it doesn't exist yet then wait and do it after schema update and fingerprint
|
||||
//this is necessary to accomodate checking build date against subscription and preventing schema update if they upgrade but are not entitled to
|
||||
//so they don't fuck their database
|
||||
//if there is a build date issue or a license issue it will fail with an exception, log to log file, log to console and not go beyond the license check preserving the db
|
||||
//Note: case 4160 is to build an external license fetcher utility to allow a user to upgrade without uninstalling the newer version by purchasing a new sub and installing the key out of AyaNova
|
||||
//If they don't want to purchase then they must downgrade
|
||||
var tempSchema = dbContext.SchemaVersion.AsNoTracking().SingleOrDefault();
|
||||
var tempLicense = dbContext.License.AsNoTracking().SingleOrDefault();
|
||||
bool licenseChecked = false;
|
||||
if (tempSchema != null && tempLicense != null && !string.IsNullOrWhiteSpace(tempSchema.Id))
|
||||
{
|
||||
//we have a schema and a license, check it now thus triggering build date vs maintenance expiry check
|
||||
try
|
||||
{
|
||||
AyaNova.Core.License.InitializeAsync(apiServerState, dbContext, _newLog).Wait();
|
||||
licenseChecked = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
//Only re-throw if it's a 1020 error with the text VERSION-TOO-NEW included, any other error allow it to keep doing it's thing below before the second license init
|
||||
//our exception is buried inside multiple inner exceptions but it's the innermost so drill down into it
|
||||
while (ex.InnerException != null)
|
||||
ex = ex.InnerException;
|
||||
if (ex.Message.Contains("1020") && ex.Message.Contains("VERSION-TOO-NEW "))
|
||||
{
|
||||
throw new Exception("AyaNova did not start to protect the integrity of your data, see the console and / or error log for details");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -602,7 +630,6 @@ namespace AyaNova
|
||||
AySchema.CheckAndUpdateAsync(dbContext, _newLog).Wait();
|
||||
|
||||
|
||||
|
||||
//Check database integrity
|
||||
_newLog.LogDebug("DB integrity check");
|
||||
DbUtil.CheckFingerPrintAsync(AySchema.EXPECTED_COLUMN_COUNT,
|
||||
@@ -613,8 +640,9 @@ namespace AyaNova
|
||||
AySchema.EXPECTED_ROUTINES,
|
||||
_newLog).Wait();
|
||||
|
||||
//Initialize license
|
||||
AyaNova.Core.License.InitializeAsync(apiServerState, dbContext, _newLog).Wait();
|
||||
//Initialize license if not already done (due to there being no db at all yet)
|
||||
if (!licenseChecked)
|
||||
AyaNova.Core.License.InitializeAsync(apiServerState, dbContext, _newLog).Wait();
|
||||
|
||||
//Set static global biz settings
|
||||
_newLog.LogDebug("Global settings");
|
||||
|
||||
@@ -8,6 +8,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using AyaNova.Models;
|
||||
using AyaNova.Biz;
|
||||
using System.Reflection;
|
||||
|
||||
namespace AyaNova.Util
|
||||
{
|
||||
@@ -481,7 +482,7 @@ namespace AyaNova.Util
|
||||
AttachToAType = attachToObject.AType,
|
||||
LastModified = lastModified,
|
||||
Size = FileSize,
|
||||
AttachedByUserId=attachedByUserId
|
||||
AttachedByUserId = attachedByUserId
|
||||
|
||||
};
|
||||
|
||||
@@ -828,7 +829,7 @@ namespace AyaNova.Util
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
|
||||
//Linux ~ home folder special handling here
|
||||
if (path.Contains('~'))
|
||||
{
|
||||
@@ -841,6 +842,34 @@ namespace AyaNova.Util
|
||||
}
|
||||
#endregion general utilities
|
||||
|
||||
|
||||
#region licensing related utility to qualify upgradability
|
||||
//https://www.meziantou.net/getting-the-date-of-build-of-a-dotnet-assembly-at-runtime.htm
|
||||
public static DateTime GetLinkerTimestampUtc(Assembly assembly)
|
||||
{
|
||||
var location = assembly.Location;
|
||||
return GetLinkerTimestampUtc(location);
|
||||
}
|
||||
|
||||
public static DateTime GetLinkerTimestampUtc(string filePath)
|
||||
{
|
||||
const int peHeaderOffset = 60;
|
||||
const int linkerTimestampOffset = 8;
|
||||
var bytes = new byte[2048];
|
||||
|
||||
using (var file = new FileStream(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
|
||||
{
|
||||
file.Read(bytes, 0, bytes.Length);
|
||||
}
|
||||
|
||||
var headerPos = BitConverter.ToInt32(bytes, peHeaderOffset);
|
||||
var secondsSince1970 = BitConverter.ToInt32(bytes, headerPos + linkerTimestampOffset);
|
||||
var dt = new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
|
||||
return dt.AddSeconds(secondsSince1970);
|
||||
}
|
||||
#endregion
|
||||
|
||||
|
||||
}//eoc
|
||||
|
||||
}//eons
|
||||
@@ -1,8 +1,6 @@
|
||||
using System;
|
||||
using System.Reflection;
|
||||
using System.Linq;
|
||||
using System.Collections.Generic;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
||||
namespace AyaNova.Util
|
||||
{
|
||||
@@ -63,7 +61,8 @@ namespace AyaNova.Util
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}//eoc
|
||||
|
||||
|
||||
@@ -799,7 +799,7 @@ namespace AyaNova.Core
|
||||
throw new ApplicationException("E1020 - Can't install a trial key into a non empty AyaNova database. Erase the database first.");
|
||||
}
|
||||
|
||||
//TODO: TECHCOUNT - new license causes exceeding count?
|
||||
//TECHCOUNT - new license causes exceeding count?
|
||||
long NewTechCount = ParsedNewKey.GetLicenseFeature(SERVICE_TECHS_FEATURE_NAME).Count;
|
||||
if (await AyaNova.Biz.UserBiz.ActiveCountAsync() > NewTechCount)
|
||||
{
|
||||
@@ -925,6 +925,15 @@ EQIDAQAB
|
||||
|
||||
|
||||
#endregion get values
|
||||
|
||||
//Check if attempting to use a build of AyaNova that is newer than maintenance subscription expiry
|
||||
if (MExBB(Util.FileUtil.GetLinkerTimestampUtc(System.Reflection.Assembly.GetExecutingAssembly()), key))
|
||||
{
|
||||
Console.WriteLine("E1020 - Not licensed for this version of AyaNova. Fix: downgrade back to previous version in use or contact technical support for options.");
|
||||
|
||||
//NOTE: VERSION-TOO-NEW bit below is checked for in startup.cs DO NOT remove this without fixing the side effects
|
||||
throw new ApplicationException("E1020 VERSION-TOO-NEW - Not licensed for this version of AyaNova. Fix: downgrade back to previous version in use or contact technical support for options.");
|
||||
}
|
||||
//All is well return key
|
||||
return key;
|
||||
|
||||
@@ -942,6 +951,12 @@ EQIDAQAB
|
||||
|
||||
|
||||
|
||||
#region Validate Build date against maintenance date in license
|
||||
//MaintenanceExpirationBeforeBuild?
|
||||
internal static bool MExBB(DateTime dtB, AyaNovaLicenseKey k) => k.MaintenanceExpiration < dtB;
|
||||
#endregion
|
||||
|
||||
|
||||
|
||||
}//eoc
|
||||
|
||||
|
||||
Reference in New Issue
Block a user