This commit is contained in:
@@ -444,6 +444,7 @@ namespace AyaNova.Api.Controllers
|
||||
DBSchemaVersion = AySchema.currentSchema,
|
||||
ServerLocalTime = DateUtil.ServerDateTimeString(System.DateTime.UtcNow),
|
||||
ServerTimeZone = TimeZoneInfo.Local.Id,
|
||||
ServerDbId= AyaNova.Core.License.ServerDbId,
|
||||
License = AyaNova.Core.License.LicenseInfoAsJson
|
||||
}
|
||||
});
|
||||
|
||||
@@ -5,7 +5,8 @@ namespace AyaNova.Models
|
||||
{
|
||||
public partial class AyContext : DbContext
|
||||
{
|
||||
public virtual DbSet<MetricMM> MetricMM { get; set; }
|
||||
public virtual DbSet<SchemaVersion> SchemaVersion { get; set; }
|
||||
public virtual DbSet<MetricMM> MetricMM { get; set; }
|
||||
public virtual DbSet<MetricDD> MetricDD { get; set; }
|
||||
public virtual DbSet<User> User { get; set; }
|
||||
public virtual DbSet<UserOptions> UserOptions { get; set; }
|
||||
@@ -127,7 +128,7 @@ namespace AyaNova.Models
|
||||
modelBuilder.Entity<PM>().Property(z => z.Serial).UseIdentityByDefaultColumn();
|
||||
//modelBuilder.Entity<PurchaseOrder>().Property(z => z.Serial).UseIdentityByDefaultColumn();
|
||||
|
||||
|
||||
|
||||
//modelBuilder.Entity<MetricCPU>().HasNoKey();
|
||||
|
||||
///////////////////////////////////////////////////////////////////////
|
||||
|
||||
24
server/AyaNova/models/SchemaVersion.cs
Normal file
24
server/AyaNova/models/SchemaVersion.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System;
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
|
||||
namespace AyaNova.Models
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// AyaNova Schema version table
|
||||
/// </summary>
|
||||
public class SchemaVersion
|
||||
{
|
||||
[Required]
|
||||
[Key]
|
||||
public Guid Id { get; set; }
|
||||
public int Schema { get; set; }
|
||||
|
||||
|
||||
|
||||
//ef core requires this
|
||||
public SchemaVersion() { }
|
||||
|
||||
|
||||
}//eoc
|
||||
}//eons
|
||||
@@ -22,7 +22,7 @@ namespace AyaNova.Util
|
||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||
private const int DESIRED_SCHEMA_LEVEL = 11;
|
||||
|
||||
internal const long EXPECTED_COLUMN_COUNT = 323;
|
||||
internal const long EXPECTED_COLUMN_COUNT = 324;
|
||||
internal const long EXPECTED_INDEX_COUNT = 134;
|
||||
|
||||
//!!!!WARNING: BE SURE TO UPDATE THE DbUtil::EmptyBizDataFromDatabaseForSeedingOrImporting WHEN NEW TABLES ADDED!!!!
|
||||
@@ -173,10 +173,10 @@ namespace AyaNova.Util
|
||||
using (var cm = ct.Database.GetDbConnection().CreateCommand())
|
||||
{
|
||||
await ct.Database.OpenConnectionAsync();
|
||||
cm.CommandText = "CREATE TABLE aschemaversion (schema INTEGER NOT NULL);";
|
||||
cm.CommandText = "CREATE TABLE aschemaversion (schema INTEGER NOT NULL, id uuid not null);";
|
||||
await cm.ExecuteNonQueryAsync();
|
||||
|
||||
cm.CommandText = "insert into aschemaversion (schema) values (1);";
|
||||
cm.CommandText = $"insert into aschemaversion (schema, id) values (1,'{Guid.NewGuid()}');";
|
||||
await cm.ExecuteNonQueryAsync();
|
||||
|
||||
await ct.Database.CloseConnectionAsync();
|
||||
|
||||
@@ -52,15 +52,15 @@ namespace AyaNova.Core
|
||||
|
||||
|
||||
//Trial key magic number for development and testing, all other guids will be fully licensed
|
||||
private static Guid TEST_TRIAL_KEY_DBID = new Guid("{A6D18A8A-5613-4979-99DA-80D07641A2FE}");
|
||||
// private static Guid TEST_TRIAL_KEY_DBID = new Guid("{A6D18A8A-5613-4979-99DA-80D07641A2FE}");
|
||||
|
||||
|
||||
|
||||
//Current license key, can be empty
|
||||
private static AyaNovaLicenseKey _ActiveLicense = new AyaNovaLicenseKey();
|
||||
|
||||
//The one and only DBID
|
||||
private static Guid DbId { get; set; }
|
||||
//The license dbid, separate from teh server dbid
|
||||
private static Guid LicenseDbId { get; set; }
|
||||
|
||||
#region license classes
|
||||
|
||||
@@ -153,7 +153,6 @@ namespace AyaNova.Core
|
||||
{
|
||||
get
|
||||
{
|
||||
return LicenseStatus.Revoked;
|
||||
|
||||
if (string.IsNullOrWhiteSpace(RegisteredTo) || RegisteredTo == UNLICENSED_TOKEN)
|
||||
return LicenseStatus.NONE;
|
||||
@@ -287,7 +286,8 @@ namespace AyaNova.Core
|
||||
|
||||
#region Exposed properties
|
||||
|
||||
|
||||
//The database id value stored in the schema table
|
||||
internal static Guid ServerDbId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fetch a summary of the license key for displaying to the end user
|
||||
@@ -302,7 +302,7 @@ namespace AyaNova.Core
|
||||
if (ActiveKey.IsEmpty)
|
||||
{
|
||||
sb.AppendLine(UNLICENSED_TOKEN);
|
||||
sb.AppendLine($"DB ID: {DbId}");
|
||||
sb.AppendLine($"DB ID: {LicenseDbId}");
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -311,7 +311,7 @@ namespace AyaNova.Core
|
||||
|
||||
sb.AppendLine($"Registered to: {ActiveKey.RegisteredTo}");
|
||||
sb.AppendLine($"Key ID: {ActiveKey.Id}");
|
||||
sb.AppendLine($"DB ID: {DbId}");
|
||||
sb.AppendLine($"DB ID: {LicenseDbId}");
|
||||
sb.AppendLine($"Type: {(ActiveKey.RentalLicense ? "Service" : "Perpetual")}");
|
||||
if (ActiveKey.WillExpire)
|
||||
sb.AppendLine($"License expires: {DateUtil.ServerDateTimeString(ActiveKey.LicenseExpiration)}");
|
||||
@@ -347,7 +347,7 @@ namespace AyaNova.Core
|
||||
|
||||
if (ActiveKey.IsEmpty)
|
||||
{
|
||||
return $"UNLICENSED, DB ID: {DbId}";
|
||||
return $"UNLICENSED, DB ID: {LicenseDbId}";
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -357,7 +357,7 @@ namespace AyaNova.Core
|
||||
|
||||
sb.Append($"regto: {ActiveKey.RegisteredTo}, ");
|
||||
sb.Append($"keyid: {ActiveKey.Id}, ");
|
||||
sb.Append($"dbid: {DbId}, ");
|
||||
sb.Append($"dbid: {LicenseDbId}, ");
|
||||
sb.Append($"type: {(ActiveKey.RentalLicense ? "service" : "perpetual")}, ");
|
||||
if (ActiveKey.WillExpire)
|
||||
sb.Append($"exp: {DateUtil.ServerDateTimeString(ActiveKey.LicenseExpiration)}, ");
|
||||
@@ -438,27 +438,16 @@ namespace AyaNova.Core
|
||||
/// <returns>Result string</returns>
|
||||
internal static async Task<string> RequestTrialAsync(string email, string regto, ILogger log)
|
||||
{
|
||||
//BEFORE_RELEASE: DO THE FOLLOWING BEFORE RELEASE:
|
||||
//TODO: TESTING REMOVE BEFORE RELEASE
|
||||
//for test purposes if this route is hit and this code executed then the dbid is temporarily changed to the special trial request
|
||||
//dbid so I can test remotely without hassle
|
||||
//TO USE: just hit the trial key request route once then the license fetch route and it should be easy peasy
|
||||
log.LogCritical("WARNING License::RequestTrial - DEVELOPMENT TEST FORCING TRIAL DB KEY ID. UPDATE BEFORE RELEASE!!");
|
||||
DbId = TEST_TRIAL_KEY_DBID;
|
||||
//TESTING
|
||||
|
||||
|
||||
|
||||
Microsoft.AspNetCore.Http.Extensions.QueryBuilder q = new Microsoft.AspNetCore.Http.Extensions.QueryBuilder();
|
||||
q.Add("dbid", DbId.ToString());
|
||||
q.Add("dbid", LicenseDbId.ToString());
|
||||
q.Add("email", email);
|
||||
q.Add("regto", regto);
|
||||
|
||||
log.LogDebug($"Requesting trial license for DBID {DbId.ToString()}");
|
||||
log.LogDebug($"Requesting trial license for DBID {LicenseDbId.ToString()}");
|
||||
string sUrl = $"{LICENSE_SERVER_URL}rvr" + q.ToQueryString();
|
||||
try
|
||||
{
|
||||
//var res = await _Client.GetStringAsync(sUrl);
|
||||
var res = await ServiceProviderProvider.HttpClientFactory.CreateClient().GetStringAsync(sUrl);
|
||||
return res;
|
||||
}
|
||||
@@ -467,7 +456,6 @@ namespace AyaNova.Core
|
||||
var msg = "E1020 - Error requesting trial license key see log for details";
|
||||
log.LogError(ex, msg);
|
||||
return msg;
|
||||
// throw new ApplicationException(msg, ex);
|
||||
}
|
||||
}
|
||||
#endregion trial license request handling
|
||||
@@ -482,18 +470,9 @@ namespace AyaNova.Core
|
||||
/// <returns>Result string</returns>
|
||||
internal static async Task FetchKeyAsync(AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, AyContext ct, ILogger log)
|
||||
{
|
||||
log.LogDebug($"Fetching license for DBID {DbId.ToString()}");
|
||||
string sUrl = $"{LICENSE_SERVER_URL}rvf/{DbId.ToString()}";
|
||||
log.LogDebug($"Fetching license for DBID {LicenseDbId.ToString()}");
|
||||
string sUrl = $"{LICENSE_SERVER_URL}rvf/{LicenseDbId.ToString()}";
|
||||
|
||||
//##########################################################################################################
|
||||
//TODO: RELEASE WARNING: this needs to be dealt with before production release
|
||||
if (ServerBootConfig.AYANOVA_SERVER_TEST_MODE)
|
||||
{
|
||||
log.LogInformation("Server is in test mode, fetching trial key");
|
||||
sUrl = $"{LICENSE_SERVER_URL}rvf/{TEST_TRIAL_KEY_DBID.ToString()}";
|
||||
// log.LogInformation(sUrl);
|
||||
}
|
||||
//##########################################################################################################
|
||||
|
||||
try
|
||||
{
|
||||
@@ -519,8 +498,8 @@ namespace AyaNova.Core
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initialize the key
|
||||
/// Handle if first boot scenario to tag DB ID etc
|
||||
/// Initialize the license
|
||||
///
|
||||
/// </summary>
|
||||
internal static async Task InitializeAsync(AyaNova.Api.ControllerHelpers.ApiServerState apiServerState, AyContext ct, ILogger log)
|
||||
{
|
||||
@@ -528,6 +507,18 @@ namespace AyaNova.Core
|
||||
|
||||
try
|
||||
{
|
||||
//First fetch the schema db id for the servers database, the license must match
|
||||
var schema = await ct.SchemaVersion.AsNoTracking().SingleOrDefaultAsync();
|
||||
if (schema == null || schema.Id == Guid.Empty)
|
||||
{
|
||||
//cryptic message deliberately, this is probably caused by someone trying to circumvent licensing
|
||||
var msg = "E1030 - Database integrity check failed (2). Contact support.";
|
||||
apiServerState.SetOpsOnly(msg);
|
||||
log.LogCritical(msg);
|
||||
return;
|
||||
}
|
||||
ServerDbId = schema.Id;
|
||||
|
||||
//Fetch key from db as no tracking so doesn't hang round if need to immediately clear and then re-add the key
|
||||
Models.License ldb = await ct.License.AsNoTracking().SingleOrDefaultAsync();
|
||||
|
||||
@@ -535,7 +526,7 @@ namespace AyaNova.Core
|
||||
if (ldb == null)
|
||||
{
|
||||
ldb = new Models.License();
|
||||
ldb.DbId = Guid.NewGuid();//<--Permanent and unchanging DB ID for this database, the license must match this
|
||||
ldb.DbId = ServerDbId;
|
||||
ldb.Key = "none";
|
||||
ct.License.Add(ldb);
|
||||
await ct.SaveChangesAsync();
|
||||
@@ -544,7 +535,7 @@ namespace AyaNova.Core
|
||||
//ensure DB ID
|
||||
if (ldb.DbId == Guid.Empty)
|
||||
{
|
||||
ldb.DbId = Guid.NewGuid();//<--Permanent and unchanging DB ID for this database, the license must match this
|
||||
ldb.DbId = ServerDbId;
|
||||
//Convert the no tracking record fetched above to tracking
|
||||
//this is required because a prior call to initialize before dumping the db would mean the license is still in memory in the context
|
||||
ct.Entry(ldb).State = Microsoft.EntityFrameworkCore.EntityState.Modified;
|
||||
@@ -552,7 +543,7 @@ namespace AyaNova.Core
|
||||
}
|
||||
|
||||
//Get it early and set it here so that it can be displayed early to the user even if not licensed
|
||||
DbId = ldb.DbId;
|
||||
LicenseDbId = ldb.DbId;
|
||||
|
||||
if (ldb.Key == "none")
|
||||
{
|
||||
@@ -739,6 +730,8 @@ EQIDAQAB
|
||||
key.Id = (string)token.SelectToken("Key.Id");
|
||||
key.RegisteredTo = (string)token.SelectToken("Key.RegisteredTo");
|
||||
key.DbId = (Guid)token.SelectToken("Key.DBID");
|
||||
if (key.DbId != ServerDbId)
|
||||
throw new ApplicationException($"E1020 - License.Parse -> License key does not match this server");
|
||||
key.LicenseExpiration = (DateTime)token.SelectToken("Key.LicenseExpiration");
|
||||
key.MaintenanceExpiration = (DateTime)token.SelectToken("Key.MaintenanceExpiration");
|
||||
|
||||
|
||||
Reference in New Issue
Block a user