maintenance expiration vs build date checking code

This commit is contained in:
2022-08-05 23:31:37 +00:00
parent 379ba76b31
commit d95510cf48
8 changed files with 96 additions and 14 deletions

View File

@@ -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>

View File

@@ -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
{

View File

@@ -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");

View File

@@ -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

View File

@@ -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

View File

@@ -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