2023-10-31 11:47:27 -04:00

291 lines
11 KiB
C#
Executable File

//
// IOmsProviderBase.cs
//
// Author:
// Michael Becker <alcexhim@gmail.com>
//
// Copyright (c) 2021 Mike Becker's Software
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
using System;
using System.Collections.Generic;
using Mocha.Core;
namespace Mocha.OMS
{
public abstract class Oms
{
protected abstract bool IsConnectedInternal();
public bool IsConnected { get { return IsConnectedInternal(); } }
public OmsEnvironment Environment { get; set; } = null;
public string TenantName { get { return Environment.StorageProvider.DefaultTenantName; } set { Environment.StorageProvider.DefaultTenantName = value; } }
public int GetInstanceIndex(Instance instance)
{
if (_instanceIndices == null)
{
UpdateInstanceIndices();
}
if (!_instanceIndices.ContainsKey(TenantName))
{
UpdateInstanceIndices();
}
if (instance != null)
{
if (_instanceIndices[TenantName].ContainsKey(instance.GlobalIdentifier))
{
return _instanceIndices[TenantName][instance.GlobalIdentifier];
}
}
return 0;
}
private Dictionary<string, Dictionary<Guid, int>> _instanceIndices = null;
private void UpdateInstanceIndices()
{
if (_instanceIndices == null)
{
_instanceIndices = new Dictionary<string, Dictionary<Guid, int>>();
}
lock (_instanceIndices)
{
if (!_instanceIndices.ContainsKey(TenantName))
{
_instanceIndices[TenantName] = new Dictionary<Guid, int>();
}
}
Instance[] instClasses = GetInstances(GetInstance(KnownInstanceGuids.Classes.Class));
for (int i = 0; i < instClasses.Length; i++)
{
int index = i + 1;
decimal? indexV = null; // (this.GetAttributeValue(instClasses[i], KnownAttributeGuids.Numeric.Index) as decimal?);
if (indexV != null)
{
index = (int)indexV.GetValueOrDefault();
}
UpdateInstanceIndices(instClasses[i], index);
}
}
private void UpdateInstanceIndices(Instance inst)
{
Instance instClass = GetRelatedInstance(inst, KnownRelationshipGuids.Instance__for__Class);
if (!_instanceIndices[TenantName].ContainsKey(inst.GlobalIdentifier))
{
int index = 0;
Instance[] instInstances = GetRelatedInstances(instClass, KnownRelationshipGuids.Class__has__Instance);
index = instInstances.Length;
decimal? indexV = null; // (this.GetAttributeValue(inst, KnownAttributeGuids.Numeric.Index) as decimal?);
if (indexV != null)
{
index = (int)indexV.GetValueOrDefault();
}
_instanceIndices[TenantName][inst.GlobalIdentifier] = index;
}
}
private void UpdateInstanceIndices(Instance inst, int index)
{
_instanceIndices[TenantName][inst.GlobalIdentifier] = index;
if (inst.GlobalIdentifier == KnownInstanceGuids.Classes.Class)
return;
/*
Instance[] insts2 = oms.GetRelatedInstances(inst, KnownRelationshipGuids.Class__has_sub__Class);
for (int j = 0; j < insts2.Length; j++)
{
UpdateInstanceIndices(oms, insts2[j], index + j + 1);
}
*/
Instance[] insts2 = GetRelatedInstances(inst, KnownRelationshipGuids.Class__has__Instance);
for (int j = 0; j < insts2.Length; j++)
{
int indexWV = j + 1;
decimal? indexW = null; // (this.GetAttributeValue(insts2[j], KnownAttributeGuids.Numeric.Index) as decimal?);
if (indexW != null)
{
indexWV = (int)indexW.GetValueOrDefault();
}
_instanceIndices[TenantName][insts2[j].GlobalIdentifier] = indexWV;
}
}
public string GetAttachmentUrl(Instance inst, System.Collections.Generic.Dictionary<InstanceKey, byte[]> entropy)
{
string accessKey = this.BuildAccessKeyForOmsAttachment(inst, entropy);
return String.Format("/{0}/attachment/{1}/{2}", this.TenantName, this.GetInstanceKey(inst), accessKey);
}
protected abstract Instance CreateInstanceInternal();
public Instance CreateInstance(Guid classInstanceId)
{
Instance inst = CreateInstanceInternal();
InstanceKey ikClass = this.GetInstanceKey(GetInstance(classInstanceId));
InstanceKey ikInst = this.GetInstanceKey(inst);
AssignRelationship(inst, KnownRelationshipGuids.Instance__for__Class, new Guid[] { classInstanceId });
AssignRelationship(GetInstance(classInstanceId), KnownRelationshipGuids.Class__has__Instance, new Guid[] { inst.GlobalIdentifier });
UpdateInstanceIndices(inst);
ikClass = this.GetInstanceKey(GetInstance(classInstanceId));
ikInst = this.GetInstanceKey(inst);
return inst;
}
protected abstract Instance GetInstanceInternal(Guid globalIdentifier);
public Instance GetInstance(Guid globalIdentifier)
{
return GetInstanceInternal(globalIdentifier);
}
public Instance[] GetInstances(Instance parentClassInstance = null, bool searchSubclasses = false)
{
List<Instance> list = new List<Instance>();
if (parentClassInstance == null)
{
return null;
// we are NOT returning every single gddmn instance on the database. that would be HELL
// return Environment.StorageProvider.GetInstances();
}
Instance[] insts = GetRelatedInstances(parentClassInstance, KnownRelationshipGuids.Class__has__Instance, OmsSearchOption.None);
list.AddRange(insts);
if (searchSubclasses)
{
Instance[] subClasses = GetRelatedInstances(parentClassInstance, KnownRelationshipGuids.Class__has_sub__Class, OmsSearchOption.None);
for (int i = 0; i < subClasses.Length; i++)
{
if (subClasses[i].GlobalIdentifier == parentClassInstance.GlobalIdentifier)
{
continue;
}
Instance[] insts2 = GetInstances(subClasses[i], true);
list.AddRange(insts2);
}
}
return list.ToArray();
}
protected abstract Instance[] GetRelatedInstancesInternal(Instance target, Guid relationshipID, OmsSearchOption searchOption);
public Instance[] GetRelatedInstances(Instance target, Guid relationshipID, OmsSearchOption searchOption = OmsSearchOption.None)
{
return GetRelatedInstancesInternal(target, relationshipID, searchOption);
}
public Instance GetRelatedInstance(Instance target, Guid relationshipID, OmsSearchOption searchOption = OmsSearchOption.None)
{
Instance[] rels = GetRelatedInstances(target, relationshipID, searchOption);
if (rels.Length > 0)
{
return rels[0];
}
return null;
}
protected abstract object GetAttributeValueInternal(Instance instTarget, Guid instAttributeID, object defaultValue, DateTime effectiveDate);
public object GetAttributeValue(Instance instTarget, Guid instAttributeID)
{
return GetAttributeValue(instTarget, instAttributeID, null);
}
public object GetAttributeValue(Instance instTarget, Guid instAttributeID, object defaultValue)
{
return GetAttributeValue(instTarget, instAttributeID, defaultValue, DateTime.Now);
}
public object GetAttributeValue(Instance instTarget, Guid instAttributeID, object defaultValue, DateTime effectiveDate)
{
object value = GetAttributeValueInternal(instTarget, instAttributeID, defaultValue, effectiveDate);
value = this.CastAttributeValue(value, this.GetParentClass(this.GetInstance(instAttributeID)));
return value;
}
protected abstract void AssignRelationshipInternal(Instance sourceInstance, Guid relationshipInstanceId, Guid[] targetInstanceIds, DateTime effectiveDate);
public void AssignRelationship(Instance sourceInstance, Guid relationshipInstanceId, Guid[] targetInstanceIds, DateTime effectiveDate)
{
AssignRelationshipInternal(sourceInstance, relationshipInstanceId, targetInstanceIds, effectiveDate);
}
public void AssignRelationship(Instance sourceInstance, Guid relationshipInstanceId, Guid[] targetInstanceIds)
{
AssignRelationship(sourceInstance, relationshipInstanceId, targetInstanceIds, DateTime.Now);
}
internal Instance GetTranslation(Instance inst, Instance instRelationshipOrTTC)
{
throw new NotImplementedException();
}
protected abstract void SetAttributeValueInternal(Instance sourceInstance, Guid attributeInstanceId, object value, DateTime effectiveDate);
public void SetAttributeValue(Instance sourceInstance, Guid attributeInstanceId, object value, DateTime effectiveDate)
{
SetAttributeValueInternal(sourceInstance, attributeInstanceId, value, effectiveDate);
}
public void SetAttributeValue(Instance sourceInstance, Guid attributeInstanceId, object value)
{
SetAttributeValue(sourceInstance, attributeInstanceId, value, DateTime.Now);
}
private string const_co = "SSBkb24ndCBrbm93IHdoeSB0aGlzIHBhcmFtZXRlciBpcyBoZXJlLiBJZiB5b3Uga25vdyB3aGF0\nIHRoaXMgaXMgdXNlZCBmb3IsIHBsZWFzZSB0ZWxsIG1lIHNvIEkgY2FuIGZpeCBpdC4gSGVsbG8g\nZnJvbSBYcHJlc3NPIQo=";
public bool VerifyAccessKeyForOmsAttachment(Instance inst, string accessKey, System.Collections.Generic.Dictionary<InstanceKey, byte[]> entropy)
{
if (!entropy.ContainsKey(this.GetInstanceKey(inst)))
{
byte[] entropyData = new byte[256];
random.NextBytes(entropyData);
entropy[this.GetInstanceKey(inst)] = entropyData;
}
string entropy_co = Convert.ToBase64String(entropy[this.GetInstanceKey(inst)]);
string base64 = MBS.Framework.Conversion.UrlSafeBase64ToBase64(accessKey);
string ft_co = System.Text.Encoding.UTF8.GetString(Convert.FromBase64String(base64));
string originalFileName = this.GetAttributeValue<string>(inst, KnownAttributeGuids.Text.Name);
string[] ft_parms = ft_co.Split(new char[] { '?' });
if (ft_parms.Length == 5 && ft_parms[0] == entropy_co /* && ft_parms[4] == originalFileName */)
return true;
return false;
}
private Random random = new Random();
public string BuildAccessKeyForOmsAttachment(Instance inst, System.Collections.Generic.Dictionary<InstanceKey, byte[]> entropy)
{
if (!entropy.ContainsKey(this.GetInstanceKey(inst)))
{
byte[] entropyData = new byte[256];
random.NextBytes(entropyData);
entropy[this.GetInstanceKey(inst)] = entropyData;
}
string entropy_co = Convert.ToBase64String(entropy[this.GetInstanceKey(inst)]);
string guid = inst.GlobalIdentifier.ToString();
long timestamp = DateTime.Now.Ticks;
string originalFileName = this.GetAttributeValue<string>(inst, KnownAttributeGuids.Text.Name);
string ft_co = String.Format("{0}?oms-attachments/{1}?{2}??{3}", entropy_co, guid, timestamp, originalFileName);
string base64 = Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(ft_co));
string safeBase64 = MBS.Framework.Conversion.Base64ToUrlSafeBase64(base64);
return safeBase64;
}
}
}