first commit

This commit is contained in:
Meik
2025-11-11 11:12:05 +01:00
commit 69e2cda8cd
912 changed files with 428004 additions and 0 deletions

View File

@@ -0,0 +1,6 @@
using System;
using System.Collections.Generic;
namespace C4IT.Configuration
{
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

View File

@@ -0,0 +1,240 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Text;
using System.Threading.Tasks;
using C4IT.HTTP;
using C4IT.MsGraph;
using Newtonsoft.Json.Linq;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using C4IT.DataHistoryProvider;
namespace C4IT.FASD.Communication.Citrix
{
public class cCitrixCommunication : cHttpApiBase
{
public const int constMaxPageSize = 1000;
public const string constCitrixBaseUrl = "https://api.cloud.com/{Request}";
public const string constCitrixUserList = "monitorodata/Users?$top={top}&$skip={skip}&$select=Id,Sid,Upn,Domain&$filter=Domain ne ''";
public const string constCitrixUserSessions = "monitorodata/Sessions?$filter=UserId eq {UserId} and (EndDate eq null or StartDate ge {MinStartDate})&$expand=Machine($select=Id,DnsName,Name)&$select=SessionKey,StartDate,EndDate,ConnectionState";
public cCitrixCommunication() : base("Citrix ID tenant", "https://api.cloud.com/cctrustoauth2/{Tenant}/tokens/clients", "Citrix Comunication")
{
KnownAutoRetryErrors.Add(HttpStatusCode.Forbidden);
autoRetryCount = 2;
autoRetryDelay = 100;
}
private protected override List<KeyValuePair<string, string>> GetRequestHeaders(cOAuthLogonInfo privLogonInfo)
{
return new List<KeyValuePair<string, string>>()
{
new KeyValuePair<string, string>("Authorization", $"CwsAuth Bearer={AccessToken}"),
new KeyValuePair<string, string>("Citrix-CustomerId", privLogonInfo.Tenant),
new KeyValuePair<string, string>("Citrix-InstanceId", privLogonInfo.InstanceId)
};
}
public async Task<cCitrixResultBase> RequestAsync(string Request, eHttpMethod httpMethod = eHttpMethod.get, object JsonData = null, bool retryForbidden = false, string nameProperty = null, bool noAutoRelogon = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var strUrl = constCitrixBaseUrl;
strUrl = strUrl.Replace("{Request}", Request);
var data = await privRequestAsync(strUrl, httpMethod, JsonData, retryForbidden, noAutoRelogon: noAutoRelogon);
if (data == null)
return null;
if (data is bool isValid)
{
if (isValid)
return new cCitrixResultBase(null);
else
return null;
}
var RetVal = new cCitrixResultBase(data, nameProperty);
return RetVal;
}
catch (Exception E)
{
cLogManager.LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task<cCitrixResultList> RequestListAsync(string Request, bool loadPaged = false, bool retryForbidden = false)
{
try
{
// get the request url
var strUrl = constCitrixBaseUrl;
strUrl = strUrl.Replace("{Request}", Request);
var res = await privRequestAsync(strUrl, autoRetry: retryForbidden);
if (res != null)
{
var RetVal = new cCitrixResultList(retryForbidden);
RetVal.AddResult(res);
if (!RetVal.hasRemaining || loadPaged)
return RetVal;
while (RetVal.hasRemaining)
{
if (!await RequestNextAsync(RetVal))
return RetVal;
}
return RetVal;
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
return null;
}
public async Task<bool> RequestNextAsync(cCitrixResultList List)
{
try
{
var res = await privRequestAsync(List.NextResultUrl, autoRetry: List.retryForbidden);
if (res != null)
{
List.AddResult(res);
return true;
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
return false;
}
public class cCitrixResultList : List<cCitrixResultBase>
{
public string NextResultUrl { get; private set; } = null;
public bool retryForbidden { get; private set; } = false;
public cCitrixResultList(bool retryForbidden)
{
this.retryForbidden = retryForbidden;
}
public bool hasRemaining
{
get
{
return !string.IsNullOrEmpty(NextResultUrl);
}
}
public void AddResult(dynamic Result)
{
try
{
NextResultUrl = null;
if (Result.TryGetValue("@odata.nextLink", out JToken JT))
{
var JO = (JValue)JT;
NextResultUrl = Result["@odata.nextLink"];
}
if (Result.TryGetValue("value", out JToken JT2))
{
foreach (dynamic Entry in Result.value)
try
{
var val = new cCitrixResultBase(Entry);
this.Add(val);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
public class cCitrixResultBase
{
public string ID { get; private set; } = null;
public string ODataId { get; private set; } = null;
public string DisplayName { get; private set; } = null;
public string Context { get; private set; } = null;
public dynamic Result { get; private set; } = null;
public cCitrixResultBase(dynamic Result, string namePropery = null)
{
this.Result = Result;
try { ID = Result.Id; } catch { }
;
try
{
if (namePropery == null)
namePropery = "displayName";
if (Result.TryGetValue(namePropery, out JToken JT1))
{
var _ty = JT1.GetType().ToString();
if (JT1 is JValue _jVal)
DisplayName = _jVal.Value?.ToString();
}
else if (Result.TryGetValue("name", out JToken JT2))
DisplayName = Result.name;
}
catch { }
try { Context = Result["@odata.context"]; } catch { }
ODataId = GetStringFromDynamic(Result, "@odata.id");
if (string.IsNullOrEmpty(ODataId))
ODataId = @"https://api.cloud.com/" + ID;
}
public cCitrixResultBase(cCitrixResultBase Result)
{
if (Result == null)
return;
this.Result = Result.Result;
ID = Result.ID;
ODataId = Result.ODataId;
DisplayName = Result.DisplayName;
Context = Result.Context;
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
public static string GetStringFromDynamic(dynamic O, string ProperyName)
{
try
{
return (string)O[ProperyName];
}
catch { }
return null;
}
}
}
}

View File

@@ -0,0 +1,134 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Web;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.XML;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cConfigCacheEntry
{
public string FullPath { get; set; } = null;
public DateTime TimeStamp { get; set; }
public string Content { get; set; }
public static cConfigCacheEntry GetCacheEntry(enumFasdConfigurationType configType)
{
var output = new cConfigCacheEntry();
if (output.IsValidConfig(configType) && !string.IsNullOrEmpty(output.FullPath))
{
output.TimeStamp = File.GetLastWriteTimeUtc(output.FullPath);
output.Content = File.ReadAllText(output.FullPath);
return output;
}
return null;
}
public bool CheckIfNewerExists()
{
try
{
if (string.IsNullOrEmpty(FullPath))
return false;
if (File.GetLastWriteTimeUtc(FullPath) > TimeStamp)
return true;
}
catch (Exception E)
{
LogException(E);
}
return false;
}
private bool IsValidConfig(enumFasdConfigurationType configType)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var RetVal = cFasdBaseConfig.GetConfigByType(configType);
if (RetVal != null && RetVal.IsValid)
{
FullPath = RetVal.FilePath;
return true;
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
}
public static class cConfigCache
{
private static Dictionary<enumFasdConfigurationType, cConfigCacheEntry> Cache = new Dictionary<enumFasdConfigurationType, cConfigCacheEntry>();
public static cConfigCacheEntry Get(enumFasdConfigurationType configType)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (Cache.TryGetValue(configType, out var result))
{
if (!result.CheckIfNewerExists())
return result;
}
result = cConfigCacheEntry.GetCacheEntry(configType);
if (result != null)
Cache[configType] = result;
return result;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public static void Initialize()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _lst = Enum.GetValues(typeof(enumFasdConfigurationType)).Cast<enumFasdConfigurationType>();
foreach (var _item in _lst)
{
if (_item != enumFasdConfigurationType.unknown)
Get(_item);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,92 @@
using C4IT.FASD.Base;
using C4IT.Logging;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public static class cDataHistoryCollectorSearchTaskCache
{
private static Dictionary<Guid, cDataHistoryCollectorSearchTaskEntry> taskCache = new Dictionary<Guid, cDataHistoryCollectorSearchTaskEntry>();
public static Guid AddTask(CancellationTokenSource cancellationToken, Task<cFasdApiSearchResultCollection> task)
{
var retVal = Guid.NewGuid();
lock (taskCache)
taskCache[retVal] = new cDataHistoryCollectorSearchTaskEntry() { cancellationTokenSource = cancellationToken, task = task };
return retVal;
}
public static void StopTask(Guid taskID)
{
cDataHistoryCollectorSearchTaskEntry _taskInfo;
lock (taskCache)
{
if (!taskCache.TryGetValue(taskID, out _taskInfo))
{
LogEntry($"StopSearchTask: Could not find task with ID: {taskID}");
return;
}
taskCache.Remove(taskID);
}
try
{
LogEntry($"StopSearchTask: cancelling task: {taskID}");
_taskInfo.cancellationTokenSource.Cancel(true);
}
catch
{
}
}
public static async Task<cFasdApiSearchResultCollection> GetResultAsync(Guid taskID)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
cDataHistoryCollectorSearchTaskEntry _taskInfo;
lock (taskCache)
{
if (!taskCache.TryGetValue(taskID, out _taskInfo))
return null;
}
cFasdApiSearchResultCollection _result = null;
try
{
_result = await _taskInfo.task;
}
catch { }
lock (taskCache) { taskCache.Remove(taskID); }
return _result;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
internal class cDataHistoryCollectorSearchTaskEntry
{
public CancellationTokenSource cancellationTokenSource;
public Task<cFasdApiSearchResultCollection> task;
}
}

View File

@@ -0,0 +1,405 @@
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.Security;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryCollectorTokenCache
{
private const int timerCleanupInterval = 15 * 60 * 1000;
private System.Threading.Timer cleanupTimer;
private cDataHistoryCollector Collector;
private Dictionary<Guid, Dictionary<cF4SDTokenRegistration.enumTokenType, cTokenInfo>> dicToken = null;
public class cTokenInfo
{
public Guid id;
public cF4SDTokenRegistration.enumTokenType type;
public string name;
public string name2;
public string secret;
public DateTime validUntil;
public DateTime renewUntil;
public bool IsValid()
{
if (id == Guid.Empty)
return false;
if (validUntil < DateTime.UtcNow + TimeSpan.FromMinutes(cDataHistoryCollector.constMinutesUntilTokenIsInvalid))
return false;
return true;
}
public cTokenInfo GetNewInstance()
{
var _sec = secret;
if (HasTokenTypeLongLifetime(type))
_sec = cSecurePassword.Instance.Decode(secret);
var _ret = new cTokenInfo()
{
id = id,
type = type,
name = name,
name2 = name2,
secret = _sec,
validUntil = validUntil,
renewUntil = renewUntil
};
return _ret;
}
}
private static class TokenCacheCriticalSection
{
private static SemaphoreSlim Semaphore = new SemaphoreSlim(1, 1);
public static async Task EnterAsync()
{
await Semaphore.WaitAsync();
}
public static void Leave()
{
Semaphore.Release();
}
}
private static bool HasTokenTypeLongLifetime(cF4SDTokenRegistration.enumTokenType tokenType)
{
switch (tokenType)
{
case cF4SDTokenRegistration.enumTokenType.M42Api:
return true;
default:
return false;
}
}
public cDataHistoryCollectorTokenCache(cDataHistoryCollector Collector, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
this.Collector = Collector;
cleanupTimer = new System.Threading.Timer(async (x) => await DoCleanup(requestInfo, 0), null, timerCleanupInterval, timerCleanupInterval);
}
private bool privInsert(cTokenInfo info, bool overwite)
{
if (dicToken == null)
return false;
if (!dicToken.TryGetValue(info.id, out var _entyId))
{
_entyId = new Dictionary<cF4SDTokenRegistration.enumTokenType, cTokenInfo>();
dicToken.Add(info.id, _entyId);
}
if (!overwite && _entyId.ContainsKey(info.type))
return false;
_entyId[info.type] = info;
return true;
}
public async Task LoadAsync(cDbConnection DbConn, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
if (dicToken == null)
dicToken = new Dictionary<Guid, Dictionary<cF4SDTokenRegistration.enumTokenType, cTokenInfo>>();
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("GetAllExternalTokens", out var Query))
return;
var sqlerror = 0;
var sqlStartTime = DateTime.UtcNow;
await TokenCacheCriticalSection.EnterAsync();
try
{
dicToken.Clear();
using (var _reader = await DataHistorySqlHelper.GetDataReaderAsync(DbConn, Query, null, Token))
{
if (_reader != null)
try
{
if (_reader.HasRows)
{
var _toDelete = new List<cTokenInfo>();
while (await _reader.ReadAsync())
{
try
{
var _entry = new cTokenInfo();
_entry.id = _reader.GetGuid(0);
_entry.type = (cF4SDTokenRegistration.enumTokenType)_reader.GetInt32(1);
_entry.name = _reader.IsDBNull(2) ? null : _reader.GetString(2);
_entry.name2 = _reader.IsDBNull(3) ? null : _reader.GetString(3);
var _secret = _reader.IsDBNull(4) ? null : _reader.GetString(4);
if (HasTokenTypeLongLifetime(_entry.type))
_entry.secret = _secret;
else
_entry.secret = cSecurePassword.Instance.Decode(_secret);
_entry.validUntil = _reader.IsDBNull(5) ? DateTime.MinValue : _reader.GetDateTime(5);
_entry.renewUntil = _reader.IsDBNull(6) ? DateTime.MinValue : _reader.GetDateTime(6);
if (_entry.IsValid())
{
if (!privInsert(_entry, false))
_toDelete.Add(_entry);
}
else
_toDelete.Add(_entry);
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
if (Token.IsCancellationRequested)
return;
}
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
}
}
catch (Exception E)
{
sqlerror = E.HResult;
cLogManager.DefaultLogger.LogException(E);
}
finally
{
TokenCacheCriticalSection.Leave();
if (DataHistorySqlHelper.LogSql) DataHistorySqlHelper.SaveSqlTimingEntry(Query.Name, sqlStartTime, "", sqlerror);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task SetAsync(cF4SDTokenRegistration _tokenRegistration, cF4SDTokenValidityPeriod validityPeriod, CancellationToken Token, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
// encryption of the secret for non-temporary tokens
string _sec = _tokenRegistration.Secret;
string _secEnc = cSecurePassword.Instance.Encode(_tokenRegistration.Secret);
if (HasTokenTypeLongLifetime(_tokenRegistration.TokenType))
_sec = _secEnc;
var _tokenInfo = new cTokenInfo()
{
id = _tokenRegistration.UserId,
type = _tokenRegistration.TokenType,
name = _tokenRegistration.Name,
name2 = _tokenRegistration.Name2,
secret = _sec,
validUntil = validityPeriod.validUntil,
renewUntil = validityPeriod.renewUntil
};
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("InsertOrUpdateExternalToken", out var Query))
return;
var Params = new Dictionary<string, object>()
{
{ "Id", _tokenInfo.id },
{ "Type", (int)_tokenInfo.type },
{ "Name", _tokenInfo.name },
{ "Name2", _tokenInfo.name2 },
{ "Secret", _secEnc },
{ "ValidUntil", _tokenInfo.validUntil },
{ "RenewUntil", _tokenInfo.renewUntil },
};
var sqlerror = 0;
var sqlStartTime = DateTime.UtcNow;
await TokenCacheCriticalSection.EnterAsync();
try
{
privInsert(_tokenInfo, true);
using (var Conn = new cDbConnection(Collector.mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main database '{Collector.mainDbConnection.Database}', aborting query'", LogLevels.Error);
return;
}
await DataHistorySqlHelper.ExecuteAsync(Conn, Query, Params, requestInfo, Token);
}
}
catch (Exception E)
{
sqlerror = E.HResult;
LogException(E);
}
finally
{
TokenCacheCriticalSection.Leave();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
public async Task<cTokenInfo> GetAsync(Guid UserId, cF4SDTokenRegistration.enumTokenType TokenType, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (dicToken == null)
return null;
var doCleanup = false;
try
{
await TokenCacheCriticalSection.EnterAsync();
if (dicToken.TryGetValue(UserId, out var _entry))
if (_entry.TryGetValue(TokenType, out var _tokenInfo))
{
if (_tokenInfo.validUntil < DateTime.UtcNow)
return null;
return _tokenInfo.GetNewInstance();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
TokenCacheCriticalSection.Leave();
if (doCleanup)
await DoCleanup(requestInfo, LogDeep + 1);
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public async Task DoCleanup(cF4sdWebRequestInfo requestInfo, int LogDeep)
{
if (dicToken == null)
return;
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var _current = DateTime.UtcNow;
// remove all expiered tokens in the cache
await TokenCacheCriticalSection.EnterAsync();
cleanupTimer.Change(Timeout.Infinite, Timeout.Infinite);
var _toRemove1 = new List<Guid>();
foreach (var _entry in dicToken)
{
var _toRemove2 = new List<cF4SDTokenRegistration.enumTokenType>();
foreach (var _tokenInfoPair in _entry.Value)
{
if (_tokenInfoPair.Value.validUntil < _current)
_toRemove2.Add(_tokenInfoPair.Key);
}
foreach (var token in _toRemove2)
_entry.Value.Remove(token);
if (_entry.Value.Count == 0)
_toRemove1.Add(_entry.Key);
}
foreach (var _entry in _toRemove1)
dicToken.Remove(_entry);
// synchronize the sql table with the cache
if (!DataHistorySqlHelper.GetWellKnownSqlStatement("RemoveExpieredExternalTokens", out var Query))
return;
// remove the expired tokens
var Params = new Dictionary<string, object>()
{
{ "ValidUntil", _current }
};
var sqlStartTime = DateTime.UtcNow;
try
{
using (var Conn = new cDbConnection(Collector.mainDbConnection))
{
if (!Conn.IsOpen)
{
LogEntry($"Could not open main database '{Collector.mainDbConnection.Database}', aborting query'", LogLevels.Error);
return;
}
var _n = await DataHistorySqlHelper.ExecuteAsync(Conn, Query, Params, requestInfo, CancellationToken.None);
}
}
catch (Exception E)
{
LogException(E);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
TokenCacheCriticalSection.Leave();
cleanupTimer.Change(timerCleanupInterval, timerCleanupInterval);
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
}
}
}

View File

@@ -0,0 +1,647 @@
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigActiveDirectory : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public bool ScanPhoneNumbers { get; private set; } = false;
public cDataHistoryScanTiming ScanTiming { get; private set; } = null;
public Dictionary<string, cDataHistoryAdDomain> Domains { get; private set; } = new Dictionary<string, cDataHistoryAdDomain>();
public Dictionary<string, cDataHistoryAdScan> Scans { get; private set; } = new Dictionary<string, cDataHistoryAdScan>();
public cDataHistoryConfigActiveDirectory(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XNode2 = XNode.SelectSingleNode("Active-Directory");
if (!(XNode2 is XmlElement XRoot))
{
Parser.AddMessage(XNode, "Could not find a valid <Active-Directory> element.");
return;
}
Parser.EnterElement("Active-Directory");
try
{
ScanPhoneNumbers = cXmlParser.GetBoolFromXmlAttribute(XNode2, "ScanPhoneNumbers");
ScanTiming = new cDataHistoryScanTiming(XRoot, TimeSpan.FromHours(24), TimeSpan.FromMinutes(10), Parser);
Domains = cDataHistoryAdDomain.LoadFromXml(XRoot, Credentials, Parser);
if (Domains == null || Domains.Count == 0)
{
Parser.AddMessage(XNode, "The element <Active-Directory> has no valid <AD-Domain> entries.");
return;
}
Scans = cDataHistoryAdScan.LoadFromXml(XRoot, this, Parser);
if (Scans == null || Scans.Count == 0)
{
Parser.AddMessage(XNode, "The element <Active-Directory> has no valid <AD-Scan> entries.");
return;
}
IsValid = true;
}
finally
{
Parser.LeaveElement("Active-Directory");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryAdScan : cConfigNodeNamed
{
public enumFasdInformationClass Type { get; private set; }
public List<cDataHistoryAdScanNode> ScanNodes { get; private set; } = new List<cDataHistoryAdScanNode>();
internal cDataHistoryAdScan(XmlElement XNode, cDataHistoryConfigActiveDirectory AdConfig, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
Type = (enumFasdInformationClass)cXmlParser.GetEnumFromAttribute<enumFasdInformationClass>(XNode, "Type", enumFasdInformationClass.Unknown);
if (Type != enumFasdInformationClass.User && Type != enumFasdInformationClass.Computer)
{
Parser.AddInvalidAttribute(XNode, Name, "AD-Type");
return;
}
ScanNodes = cDataHistoryAdScanNode.LoadFromXml(XNode, AdConfig, this, Parser);
if (ScanNodes == null || ScanNodes.Count == 0)
{
Parser.AddMessage(XNode, "The <AD-Scan> element has no valid <AD-Scan-Node> entries.");
return;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryAdScan> LoadFromXml(XmlElement XNode, cDataHistoryConfigActiveDirectory AdConfig, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new Dictionary<string, cDataHistoryAdScan>();
try
{
var XRoot = XNode.SelectSingleNode("AD-Scans");
if (XRoot == null)
{
Parser.AddMessage(XNode, $"No <AD-Scans> element found within element <{XNode.Name}>.");
return null;
}
Parser.EnterElement("AD-Scans");
try
{
var XList = XRoot.SelectNodes("AD-Scan");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("AD-Scan");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryAdScan(XEntry, AdConfig, Parser);
if (Node.IsValid)
{
if (RetVal.ContainsKey(Node.Name))
{
Parser.AddDuplicateName(XEntry, Node.Name, LogLevels.Warning);
}
else
RetVal.Add(Node.Name, Node);
}
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("AD-Scan");
}
}
}
finally
{
Parser.LeaveElement("AD-Scans");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cDataHistoryAdScanNode : IConfigNodeValidation
{
public enum enumFilterPropery { unknown = 0, commonName, distinguishedName, samAccountName }
public bool IsValid { get; private set; } = false;
public cDataHistoryAdDomain AdDomain { get; private set; }
public string Path { get; private set; }
public string LdapFilter { get; private set; }
public enumFilterPropery FilterProperty { get; private set; } = enumFilterPropery.unknown;
public bool WildcardFilterNot { get; private set; } = false;
public Regex WildcardFilter { get; private set; }
public Regex RegExFilter { get; private set; }
public cDataHistoryAdScan parentScan { get; private set; }
internal cDataHistoryAdScanNode(XmlElement XNode, cDataHistoryConfigActiveDirectory AdConfig, cDataHistoryAdScan Scan, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
parentScan = Scan;
var strAdDomain = cXmlParser.GetStringFromXmlAttribute(XNode, "AD-Domain");
if (!AdConfig.Domains.TryGetValue(strAdDomain, out var AdD))
{
Parser.AddInvalidAttribute(XNode, null, "AD-Domain");
return;
}
AdDomain = AdD;
Path = cXmlParser.GetStringFromXmlAttribute(XNode, "Path", "");
LdapFilter = cXmlParser.GetStringFromXmlAttribute(XNode, "LDAP-Filter");
FilterProperty = cXmlParser.GetEnumFromAttribute<enumFilterPropery>(XNode, "Filter-Property", enumFilterPropery.unknown);
var strWildcardFilter = cXmlParser.GetStringFromXmlAttribute(XNode, "Wildcard-Filter");
if (!string.IsNullOrEmpty(strWildcardFilter))
{
if (strWildcardFilter.StartsWith("!"))
{
WildcardFilterNot = true;
strWildcardFilter.Remove(0, 1);
}
var _expression = "^" + Regex.Escape(strWildcardFilter)
.Replace("\\\\\\?", "??").Replace("\\?", ".").Replace("??", "\\?")
.Replace("\\\\\\*", "**").Replace("\\*", ".*").Replace("**", "\\*") + "$";
WildcardFilter = new Regex(_expression, RegexOptions.Compiled);
}
var strRexExFilter = cXmlParser.GetStringFromXmlAttribute(XNode, "RegEx-Filter");
if (!string.IsNullOrEmpty(strRexExFilter))
RegExFilter = new Regex(strRexExFilter, RegexOptions.Compiled);
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static List<cDataHistoryAdScanNode> LoadFromXml(XmlElement XNode, cDataHistoryConfigActiveDirectory AdConfig, cDataHistoryAdScan Scan, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new List<cDataHistoryAdScanNode>();
try
{
var XList = XNode.SelectNodes("AD-Scan-Node");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("AD-Scan-Node");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryAdScanNode(XEntry, AdConfig, Scan, Parser);
if (Node.IsValid)
RetVal.Add(Node);
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("AD-Scan-Node");
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cDataHistoryAdDomain : cConfigNodeNamed
{
public string FQDN { get; private set; } = null;
public cCredential Credential { get; private set; } = null;
public List<cDataHistoryAdServer> Servers { get; private set; } = new List<cDataHistoryAdServer>();
internal cDataHistoryAdDomain(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
FQDN = cXmlParser.GetStringFromXmlAttribute(XNode, "FQDN");
if (string.IsNullOrWhiteSpace(FQDN))
{
Parser.AddInvalidAttribute(XNode, null, "FQDN");
return;
}
var strCreds = cXmlParser.GetStringFromXmlAttribute(XNode, "Credential");
if (!string.IsNullOrWhiteSpace(strCreds))
{
if (Credentials.TryGetValue(strCreds, out var Cred))
Credential = Cred;
}
if (Credential == null)
{
Parser.AddInvalidAttribute(XNode, Name, "Credential");
return;
}
Servers = cDataHistoryAdServer.LoadFromXml(XNode, Parser);
if (Servers?.Count == 0)
{
Parser.AddInvalidAttribute(XNode, Name, "No valid <AD-Server> element could be found.");
return;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryAdDomain> LoadFromXml(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new Dictionary<string, cDataHistoryAdDomain>();
try
{
var XRoot = XNode.SelectSingleNode("AD-Domains");
if (XRoot == null)
{
Parser.AddMessage(XNode, $"No <AD-Domains> element found within element <{XNode.Name}>.");
return null;
}
Parser.EnterElement("AD-Domains");
try
{
var XList = XRoot.SelectNodes("AD-Domain");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("AD-Domain");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryAdDomain(XEntry, Credentials, Parser);
if (Node.IsValid)
{
if (RetVal.ContainsKey(Node.Name))
{
Parser.AddDuplicateName(XEntry, Node.Name, LogLevels.Warning);
}
else
RetVal.Add(Node.Name, Node);
}
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("AD-Domain");
}
}
}
finally
{
Parser.LeaveElement("AD-Domains");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cDataHistoryAdServer : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public string FQDN { get; private set; }
public int Port { get; private set; }
public bool useSSL { get; private set; }
internal cDataHistoryAdServer(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
FQDN = cXmlParser.GetStringFromXmlAttribute(XNode, "FQDN");
if (string.IsNullOrWhiteSpace(FQDN))
{
Parser.AddInvalidAttribute(XNode, null, "FQDN");
return;
}
Port = cXmlParser.GetIntegerFromXmlAttribute(XNode, "Port");
useSSL = cXmlParser.GetBoolFromXmlAttribute(XNode, "UseSSL");
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static List<cDataHistoryAdServer> LoadFromXml(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new List<cDataHistoryAdServer>();
try
{
var XList = XNode.SelectNodes("AD-Server");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("AD-Server");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryAdServer(XEntry, Parser);
if (Node.IsValid)
RetVal.Add(Node);
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("AD-Server");
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cDataHistoryAzureTenant : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public string Domain { get; private set; } = "";
public Guid TenantID { get; private set; } = Guid.Empty;
public cCredential Credential { get; private set; } = null;
public bool ScanIntuneDevices { get; private set; } = false;
public bool WithMobileDevices { get; private set; } = false;
internal cDataHistoryAzureTenant(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
Domain = cXmlParser.GetStringFromXmlAttribute(XNode, "Domain");
if (string.IsNullOrWhiteSpace(Domain))
{
Parser.AddInvalidAttribute(XNode, null, "Domain");
return;
}
TenantID = cXmlParser.GetGuidFromXmlAttribute(XNode, "TenantID");
if (TenantID == Guid.Empty)
{
Parser.AddInvalidAttribute(XNode, Domain, "TenantID");
return;
}
var strCreds = cXmlParser.GetStringFromXmlAttribute(XNode, "Credential");
if (!string.IsNullOrWhiteSpace(strCreds))
{
if (Credentials.TryGetValue(strCreds, out var Cred))
Credential = Cred;
}
if (Credential == null)
{
Parser.AddInvalidAttribute(XNode, Domain, "Credential");
return;
}
ScanIntuneDevices = cXmlParser.GetBoolFromXmlAttribute(XNode, "ScanIntuneDevices");
WithMobileDevices = cXmlParser.GetBoolFromXmlAttribute(XNode, "WithMobileDevices");
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryAzureTenant> LoadFromXml(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new Dictionary<string, cDataHistoryAzureTenant>();
try
{
var XRoot = XNode.SelectSingleNode("Azure-AD");
if (XRoot == null)
{
return null;
}
Parser.EnterElement("Azure-AD");
try
{
var XList = XRoot.SelectNodes("Azure-Tenant");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("Azure-Tenant");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryAzureTenant(XEntry, Credentials, Parser);
if (Node.IsValid)
{
if (RetVal.ContainsKey(Node.Domain))
{
Parser.AddDuplicateName(XEntry, Node.Domain, LogLevels.Warning);
}
else
RetVal.Add(Node.Domain, Node);
}
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("Azure-Tenant");
}
}
}
finally
{
Parser.LeaveElement("Azure-AD");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cWildcardPattern
{
private readonly string _expression;
private readonly Regex _regex;
public cWildcardPattern(string pattern)
{
if (string.IsNullOrEmpty(pattern)) throw new ArgumentNullException(nameof(pattern));
_expression = "^" + Regex.Escape(pattern)
.Replace("\\\\\\?", "??").Replace("\\?", ".").Replace("??", "\\?")
.Replace("\\\\\\*", "**").Replace("\\*", ".*").Replace("**", "\\*") + "$";
_regex = new Regex(_expression, RegexOptions.Compiled);
}
public bool IsMatch(string value)
{
return _regex.IsMatch(value);
}
}
}

View File

@@ -0,0 +1,188 @@
using C4IT.DataHistoryProvider;
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace C4IT_DataHistoryProvider
{
public class cDataHistoryConfigCitrix : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public string Domain { get; private set; } = "";
public string TenantID { get; private set; } = String.Empty;
public cCredential Credential { get; private set; } = null;
public cDataHistoryScanTiming ScanTiming { get; private set; } = null;
public cDataHistoryConfigCitrix(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XNode2 = XNode.SelectSingleNode("Citrix");
if (!(XNode2 is XmlElement XCitrix))
{
return;
}
Parser.EnterElement("Citrix");
try
{
ScanTiming = new cDataHistoryScanTiming(XCitrix, TimeSpan.FromHours(24), TimeSpan.FromMinutes(10), Parser);
IsValid = true;
}
finally
{
Parser.LeaveElement("Citrix");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public class cDataHistoryCitrixTenant : IConfigNodeValidation
{
public bool IsValid { get; private set; } = false;
public string Domain { get; private set; } = "";
public string TenantID { get; private set; } = String.Empty;
public string InstanceID { get; private set; } = String.Empty;
public cCredential Credential { get; private set; } = null;
internal cDataHistoryCitrixTenant(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
Domain = cXmlParser.GetStringFromXmlAttribute(XNode, "Domain");
if (string.IsNullOrWhiteSpace(Domain))
{
Parser.AddInvalidAttribute(XNode, null, "Domain");
return;
}
TenantID = cXmlParser.GetStringFromXmlAttribute(XNode, "TenantID");
if (TenantID == String.Empty)
{
Parser.AddInvalidAttribute(XNode, Domain, "TenantID");
return;
}
InstanceID = cXmlParser.GetStringFromXmlAttribute(XNode, "InstanceID");
if (InstanceID == String.Empty)
{
Parser.AddInvalidAttribute(XNode, Domain, "InstanceID");
return;
}
var strCreds = cXmlParser.GetStringFromXmlAttribute(XNode, "Credential");
if (!string.IsNullOrWhiteSpace(strCreds))
{
if (Credentials.TryGetValue(strCreds, out var Cred))
Credential = Cred;
}
if (Credential == null)
{
Parser.AddInvalidAttribute(XNode, Domain, "Credential");
return;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryCitrixTenant> LoadFromXml(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new Dictionary<string, cDataHistoryCitrixTenant>();
try
{
var XRoot = XNode.SelectSingleNode("Citrix");
if (XRoot == null)
{
return null;
}
Parser.EnterElement("Citrix");
try
{
var XList = XRoot.SelectNodes("Citrix-Tenant");
if (XList != null && XList.Count > 0)
{
Parser.EnterElement("Citrix-Tenant");
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryCitrixTenant(XEntry, Credentials, Parser);
if (Node.IsValid)
{
if (RetVal.ContainsKey(Node.Domain))
{
Parser.AddDuplicateName(XEntry, Node.Domain, LogLevels.Warning);
}
else
RetVal.Add(Node.Domain, Node);
}
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("Citrix-Tenant");
}
}
}
finally
{
Parser.LeaveElement("Citrix");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
}
}

View File

@@ -0,0 +1,229 @@
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigClientAgent : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public cDataHistoryConfigSqlConnection Connection { get; private set; } = null;
public Uri ServerUri { get; private set; } = null;
public int MaxDeviceAge { get; private set; } = 30;
public Uri ApiPath { get; private set; } = null;
public cCredential ApiCredential { get; private set; } = null;
public string ApiSecret { get; private set; } = null;
public string Organization { get; private set; } = null;
public cDataHistoryScanTiming ScanTiming { get; private set; } = null;
public List<cDataHistoryConfigLocalAccountAssignment> localAccountAssignments = null;
internal cDataHistoryConfigClientAgent(XmlElement XNode, Dictionary<string, cCredential> Credentials, Dictionary<string, cDataHistoryConfigDbConnection> DbConnections, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!(XNode.SelectSingleNode("ClientAgent") is XmlElement XNode2))
{
Parser.AddMessage(XNode, $"The root element <{XNode.Name}> does not have a <ClientAgent> element.");
return;
}
Parser.EnterElement("ClientAgent");
try
{
var strConnection = cXmlParser.GetStringFromXmlAttribute(XNode2, "DB-Connection");
if (string.IsNullOrWhiteSpace(strConnection))
{
Parser.AddMessage(XNode, $"The element <{XNode2.Name}> does not have a 'DB-Connection' attribute.");
return;
}
if (!DbConnections.TryGetValue(strConnection, out var Conn))
{
Parser.AddMessage(XNode, $"Could not find a DB connection '{strConnection}' in element <{XNode2.Name}>.");
return;
}
if (!(Conn is cDataHistoryConfigSqlConnection SqlConn))
{
Parser.AddMessage(XNode, $"The DB connection '{strConnection}' in element <{XNode2.Name}> has to be a SQL connection.");
return;
}
var strServerUri = cXmlParser.GetStringFromXmlAttribute(XNode2, "Server-Url", "");
if (!Uri.TryCreate(strServerUri, UriKind.Absolute, out var _uri))
{
Parser.AddMessage(XNode, $"The attribute 'Server-Url' in element <{XNode2.Name}> is not a valid URL.");
return;
}
ServerUri = _uri;
strServerUri = cXmlParser.GetStringFromXmlAttribute(XNode2, "Api-Path", "api/management");
if (!Uri.TryCreate(strServerUri, UriKind.Relative, out _uri))
{
Parser.AddMessage(XNode, $"The attribute 'Api-Path' in element <{XNode2.Name}> is not a valid URL path.");
return;
}
ApiPath = _uri;
Organization = cXmlParser.GetStringFromXmlAttribute(XNode2, "Organization");
MaxDeviceAge = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "MaxDeviceAge", 30);
if (MaxDeviceAge <= 0)
{
Parser.AddMessage(XNode, $"The attribute 'MaxDeviceAge' in element <{XNode2.Name}> is not a valid positive number of days.");
return;
}
Connection = SqlConn;
var strCredential = cXmlParser.GetStringFromXmlAttribute(XNode2, "Api-Credential");
if (string.IsNullOrWhiteSpace(strCredential))
{
Parser.AddInvalidAttribute(XNode, null, "Api-Credential");
return;
}
if (!Credentials.TryGetValue(strCredential, out var _Cred))
{
Parser.AddMessage(XNode, $"The credential attribute value '{strCredential}' of the element <{XNode.Name}> coud not be resolved.");
return;
}
ApiCredential = _Cred;
ApiSecret = cSecurePassword.Instance.Encode(_Cred.NwCredential.Password);
ScanTiming = new cDataHistoryScanTiming(XNode2, TimeSpan.FromHours(1), TimeSpan.FromMinutes(10), Parser);
localAccountAssignments = cDataHistoryConfigLocalAccountAssignment.LoadFromXml(XNode2, Parser);
IsValid = true;
}
finally
{
Parser.LeaveElement("ClientAgent");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryConfigLocalAccountAssignment : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public string Domain = null;
public string DomainDns = null;
public string RegExFilter = null;
public string AccountMask = null;
internal cDataHistoryConfigLocalAccountAssignment(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
Domain = cXmlParser.GetStringFromXmlAttribute(XNode, "Domain");
if (string.IsNullOrEmpty(Domain))
{
Parser.AddInvalidAttribute(XNode, null, "Domain", LogLevels.Warning);
return;
}
RegExFilter = cXmlParser.GetStringFromXmlAttribute(XNode, "RegExFilter");
AccountMask = cXmlParser.GetStringFromXmlAttribute(XNode, "AccountMask");
if (!string.IsNullOrEmpty(AccountMask) && !AccountMask.Contains("*"))
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> element with Domain='{Domain}' has no '*' placeholder in the 'AccountMask' attribute.", LogLevels.Warning);
return;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static List<cDataHistoryConfigLocalAccountAssignment> LoadFromXml(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XDataClusters = XNode.SelectNodes("Local-Account-Assignment");
if (XDataClusters == null || XDataClusters.Count <= 0)
return null;
Parser.EnterElement("Local-Account-Assignment");
var RetVal = new List<cDataHistoryConfigLocalAccountAssignment>(XDataClusters.Count);
try
{
foreach (XmlNode XNode2 in XDataClusters)
{
if (!(XNode2 is XmlElement XDataCluster))
continue;
var LocalAssignment = new cDataHistoryConfigLocalAccountAssignment(XDataCluster, Parser);
if ((LocalAssignment != null) && (LocalAssignment.IsValid))
{
RetVal.Add(LocalAssignment);
}
Parser.SelectElementNext();
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("Local-Account-Assignment");
}
if (RetVal.Count > 0)
return RetVal;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,171 @@
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public abstract class cDataHistoryConfigDbConnection : cConfigNodeNamed
{
internal cDataHistoryConfigDbConnection(XmlElement XNode, cXmlParser Parser) :
base(XNode, Parser)
{
}
static public Dictionary<string, cDataHistoryConfigDbConnection> LoadListFromXml(XmlElement XNode, cXmlParser Parser, Dictionary<string, cCredential> Credentials)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new Dictionary<string, cDataHistoryConfigDbConnection>();
try
{
XmlNode LRoot = XNode;
LRoot = XNode.SelectSingleNode("DB-Connections");
if (LRoot == null)
{
Parser.AddMessage(XNode, $"The <{XNode.Name}> does not contain a element 'DB-Connections'", LogLevels.Error);
return RetVal;
}
Parser.EnterElement("DB-Connections");
// cluster the db commections in a dictionary by db connection type (element node)
var XList = LRoot.SelectNodes("SQL-Connection");
var lstConnectionNodes = new Dictionary<string, List<XmlElement>>();
foreach (XmlNode Entry in XList)
{
if (!(Entry is XmlElement XDbNode))
continue;
if (!lstConnectionNodes.TryGetValue(XDbNode.Name, out var lstConn))
{
lstConn = new List<XmlElement>() { XDbNode };
lstConnectionNodes.Add(XDbNode.Name, lstConn);
}
else
lstConn.Add(XDbNode);
}
if (lstConnectionNodes.Count == 0)
{
Parser.AddMessage(XNode, "No valid DB connection entries could be found in the infrastructure configuration.", LogLevels.Error);
return RetVal;
}
// parse the clustered db connection nodes
foreach (var lstDbConn in lstConnectionNodes)
{
Parser.EnterElement(lstDbConn.Key);
foreach (var XDbConn in lstDbConn.Value)
{
cDataHistoryConfigDbConnection DbConn = null;
switch (lstDbConn.Key)
{
case "SQL-Connection":
DbConn = new cDataHistoryConfigSqlConnection(XDbConn, Credentials, Parser);
break;
default:
Parser.AddMessage(XDbConn, $"The element '<{lstDbConn.Key}>' is not a valid DB connection element.", LogLevels.Error);
break;
}
if (DbConn != null)
RetVal.Add(DbConn.Name, DbConn);
Parser.SelectElementNext();
}
Parser.LeaveElement(lstDbConn.Key);
}
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(E);
}
finally
{
Parser.LeaveElement("DB-Connections");
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
public class cDataHistoryConfigSqlConnection : cDataHistoryConfigDbConnection
{
public cCredential Credential { get; private set; } = null;
public bool NativeAccount { get; private set; }
public string Server { get; private set; }
public string Instance { get; private set; }
public string Database { get; private set; }
public int Timeout { get; private set; } = -1;
internal cDataHistoryConfigSqlConnection(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser) :
base(XNode, Parser)
{
try
{
if (!IsValid)
return;
IsValid = false;
NativeAccount = cXmlParser.GetBoolFromXmlAttribute(XNode, "NativeAccount");
Server = cXmlParser.GetStringFromXmlAttribute(XNode, "Server");
if (string.IsNullOrWhiteSpace(Server))
{
Parser.AddInvalidAttribute(XNode, Name, "Server");
return;
}
Instance = cXmlParser.GetStringFromXmlAttribute(XNode, "Instance");
Database = cXmlParser.GetStringFromXmlAttribute(XNode, "Database");
if (string.IsNullOrWhiteSpace(Server))
{
Parser.AddInvalidAttribute(XNode, Name, "Database");
return;
}
var strCredential = cXmlParser.GetStringFromXmlAttribute(XNode, "Credential");
if (string.IsNullOrWhiteSpace(strCredential))
{
Parser.AddInvalidAttribute(XNode, Name, "Credential");
return;
}
if (!Credentials.TryGetValue(strCredential, out var _Cred))
{
Parser.AddMessage(XNode, $"The credential attribute value '{strCredential}' of the element <{XNode.Name}> coud not be resolved.");
return;
}
Credential = _Cred;
Timeout = cXmlParser.GetIntegerFromXmlAttribute(XNode, "Timeout", -1);
if (Timeout < -1)
Timeout = -1;
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
}
}
}

View File

@@ -0,0 +1,337 @@
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using Newtonsoft.Json;
using C4IT.Configuration;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.XML;
using static C4IT.Logging.cLogManager;
using static C4IT.Configuration.cConfigRegistryHelper;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigGolabalParameters : cFasdBaseConfig
{
public const string constFileNameF4sdConfig = "F4SD-Global-Configuration.xml";
private const string constFileNameF4sdSchema = "F4SD-Global-Configuration.xsd";
private const string constConfigRootElement = "F4SD-Global-Configuration";
public cConfigHelperParameterList Parameters { get; private set; } = null;
private cDataHistoryConfigInfrastructure InfrastructureConfig = null;
internal cDataHistoryConfigGolabalParameters(cDataHistoryConfigInfrastructure configInfrastructure) :
base(constFileNameF4sdConfig, constFileNameF4sdSchema, constConfigRootElement, true)
{
InfrastructureConfig = configInfrastructure;
}
public override bool InstantiateProperties(XmlElement RootElement, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
Parameters = LoadParameters(RootElement, Parser );
var _s = JsonConvert.SerializeObject(Parameters, Newtonsoft.Json.Formatting.Indented);
this.IsValid = true;
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
private cConfigHelperParameterList LoadParameters (XmlElement XRoot, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var _result = new cConfigHelperParameterList();
try
{
var Items = XRoot.ChildNodes;
foreach (var _node in Items)
{
if (!(_node is XmlElement _item)) continue;
Parser.EnterElement(_item.Name);
try
{
var _attPolicy = _item.GetAttribute("Policy");
var _attValue = _item.GetAttribute("Value");
var _ElementCount = 0;
foreach (XmlNode _subNode in _item.ChildNodes)
{
if (_subNode is XmlElement)
_ElementCount++;
}
// check for special parameters
switch (_item.Name)
{
case "InformationClassSearchPriority":
var _val = getInformationClassSearchPriority(_item, Parser);
if (_val != null)
_result.Items[_val.Name] = _val;
continue;
}
if (_attPolicy != null && _attValue != null && _ElementCount == 0)
{
// we have a simple parameter
var _policy = cXmlParser.GetEnumFromAttribute<enumConfigPolicy>(_item, "Policy", enumConfigPolicy.Default);
var _value = cXmlParser.GetStringFromXmlAttribute(_item, "Value", String.Empty);
_result.Items[_item.Name] = new cConfigHelperParameterEntry()
{
Name = _item.Name,
Value = _value,
Policy = _policy.ToString(),
};
}
else if (string.IsNullOrEmpty(_attPolicy) && string.IsNullOrEmpty(_attValue) && _ElementCount > 0)
{
// we have a sublist
if (_result.SubItems == null)
_result.SubItems = new Dictionary<string, cConfigHelperParameterList>();
_result.SubItems[_item.Name] = LoadParameters(_item, Parser);
}
else
{
// we have an invalid entry
var _msg = $"Invalid entry in F4SD-Global-Configuration.xml: {_item.Name}";
Parser.AddMessage(_item, _msg, LogLevels.Warning);
LogEntry(_msg, LogLevels.Warning);
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement(_item.Name);
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return _result;
}
private cConfigHelperParameterEntry getInformationClassSearchPriority(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _xNodes = XNode.ChildNodes;
var _policy = cXmlParser.GetEnumFromAttribute<enumConfigPolicy>(XNode, "Policy", enumConfigPolicy.Default);
var _result = new List<string>();
foreach (var _xNode in _xNodes)
{
if (!(_xNode is XmlElement _item))
continue;
Parser.EnterElement(_item.Name);
try
{
if (_item.Name != "InformationClass")
{
// we have an invalid entry
var _msg = $"Invalid entry in F4SD-Global-Configuration.xml: {_item.Name}, should be <InformationClass/>";
Parser.AddMessage(_item, _msg, LogLevels.Warning);
LogEntry(_msg, LogLevels.Warning);
continue;
}
var _InfoClass = cXmlParser.GetEnumFromAttribute<enumFasdInformationClass>(_item, "Type", enumFasdInformationClass.Unknown);
if (_InfoClass == enumFasdInformationClass.Unknown)
{
// we have an invalid type attribute
var _strType = cXmlParser.GetStringFromXmlAttribute(_item, "Type", String.Empty);
var _msg = $"Invalid type attribute value ({_strType}) in entry {_item.Name}";
Parser.AddMessage(_item, _msg, LogLevels.Warning);
LogEntry(_msg, LogLevels.Warning);
continue;
}
var _strInfoClass = _InfoClass.ToString();
if (!_result.Contains(_strInfoClass))
_result.Add(_strInfoClass);
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement(_item.Name);
}
}
return new cConfigHelperParameterEntry()
{
Name = XNode.Name,
ValueList = _result,
Policy = _policy.ToString()
};
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
public override bool DoXmlUpdates(XmlElement XmlRoot, bool withM42Config = false, bool withIntuneConfig = false, bool withMobileDeviceConfig = false, bool withCitrixConfig = false)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = false;
try
{
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "ShouldSkipSlimView"
, "<ShouldSkipSlimView Policy=\"Default\" Value=\"false\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "SmallViewAlignment"
, "<SmallViewAlignment Policy=\"Default\" Value=\"Right\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "FavouriteBarAlignment"
, "<FavouriteBarAlignment Policy=\"Default\" Value=\"Right\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "InformationClassSearchPriority"
, "<InformationClassSearchPriority Policy=\"Default\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "InformationClassSearchPriority"
, "InformationClass[@Type='User']"
, "<InformationClass Type=\"User\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "InformationClassSearchPriority"
, "InformationClass[@Type='Computer']"
, "<InformationClass Type=\"Computer\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "InformationClassSearchPriority"
, "InformationClass[@Type='VirtualSession']"
, "<InformationClass Type=\"VirtualSession\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "InformationClassSearchPriority"
, "InformationClass[@Type='Ticket']"
, "<InformationClass Type=\"Ticket\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, ""
, "TicketConfiguration"
, "<TicketConfiguration />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "NotesMandatory"
, "<NotesMandatory Policy=\"Hidden\" Value=\"false\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "ShowOverview"
, "<ShowOverview Policy=\"Hidden\" Value=\"true\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "OverviewPollingPersonal"
, $"<OverviewPollingPersonal Policy=\"Hidden\" Value=\"{cF4sdTicketConfig.DefaultOverviewPollingPersonal}\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "OverviewPollingRole"
, $"<OverviewPollingRole Policy=\"Hidden\" Value=\"{cF4sdTicketConfig.DefaultOverviewPollingRoles}\" />"
);
#pragma warning disable CS0618 // Type or member is obsolete
var oldShowDocumentCaseDialog = InfrastructureConfig?.M42Wpm?.ShowDocumentCaseDialog ?? enumShowDocumentCaseDialog.ifRequired;
var oldDisableAutomaticTimeTracking = InfrastructureConfig?.M42Wpm?.DisableAutomaticTimeTracking ?? false;
#pragma warning restore CS0618 // Type or member is obsolete
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "CompletitionPolicy"
, $"<CompletitionPolicy Policy=\"Hidden\" Value=\"{oldShowDocumentCaseDialog.ToString()}\" />"
);
RetVal |= DoXmlInsertElement(XmlRoot
, "TicketConfiguration"
, "DisableAutomaticTimeTracking"
, $"<DisableAutomaticTimeTracking Policy=\"Mandatory\" Value=\"{oldDisableAutomaticTimeTracking.ToString()}\" />"
);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
}
}

View File

@@ -0,0 +1,949 @@
using C4IT.Configuration;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using C4IT_DataHistoryProvider;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using static C4IT.Logging.cLogManager;
using static C4IT_DataHistoryProvider.cDataHistoryConfigCitrix;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigInfrastructure : cFasdBaseConfig
{
private const string constFileNameF4sdConfig = "F4SD-Infrastructure-Configuration.xml";
private const string constFileNameF4sdSchema = "F4SD-Infrastructure-Configuration.xsd";
private const string constConfigRootElement = "F4SD-Infrastructure-Configuration";
public static readonly Guid ConfigId = new Guid("21CECFEE-0944-403F-A13F-11372BEE6905");
public Guid getId() { return ConfigId; }
public Dictionary<string, cCredential> Credentials { get; private set; } = new Dictionary<string, cCredential>();
public Dictionary<string, cDataHistoryConfigDbConnection> DbConnections { get; private set; } = new Dictionary<string, cDataHistoryConfigDbConnection>();
public cDataHistoryConfigDatabase HistoryDB { get; private set; } = null;
public cF4SDAnalyticsConfigDatabase F4SDAnalyticsDB { get; private set; } = null;
public cDataHistoryConfigClientAgent ClientAgent { get; private set; } = null;
public cDataHistoryConfigM42Wpm M42Wpm { get; private set; } = null;
public cDataHistoryConfigCitrix Citrix { get; private set; } = null;
public Dictionary<string, cDataHistoryCitrixTenant> CitrixTenants { get; private set; } = null;
public cDataHistoryConfigNexthink Nexthink { get; private set; } = null;
public cDataHistoryConfigActiveDirectory ActiveDirectory { get; private set; } = null;
public Dictionary<string, cDataHistoryAzureTenant> AzureTenants { get; private set; } = null;
public cF4SDAuthorisation Authorisation { get; private set; } = null;
internal cDataHistoryConfigInfrastructure() :
base(constFileNameF4sdConfig, constFileNameF4sdSchema, constConfigRootElement)
{
}
public override bool InstantiateProperties(XmlElement XRoot, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
// get the credentials
var Creds = cCredentialXml.LoadListFromXml(XRoot, Parser, "Credentials");
if (Creds == null || Creds.Count == 0 || Parser.LogMessages.Count > 0)
return false;
Credentials = Creds;
// get the db connections
var Conns = cDataHistoryConfigDbConnection.LoadListFromXml(XRoot, Parser, Creds);
if (Conns == null || Conns.Count == 0 || Parser.LogMessages.Count > 0)
return false;
DbConnections = Conns;
// get the history db config
var _db = new cDataHistoryConfigDatabase(XRoot, Conns, Parser);
if (_db == null || !_db.IsValid || Parser.LogMessages.Count > 0)
return false;
HistoryDB = _db;
var _db2 = new cF4SDAnalyticsConfigDatabase(XRoot, Conns, Parser);
if (_db2 != null && _db2.IsValid && Parser.LogMessages.Count == 0)
F4SDAnalyticsDB = _db2;
// get the active directory config
var _ad = new cDataHistoryConfigActiveDirectory(XRoot, Credentials, Parser);
if (_ad?.IsValid == true)
ActiveDirectory = _ad;
AzureTenants = cDataHistoryAzureTenant.LoadFromXml(XRoot, Credentials, Parser);
CitrixTenants = cDataHistoryCitrixTenant.LoadFromXml(XRoot, Credentials, Parser);
// get the client agent config
var _cla = new cDataHistoryConfigClientAgent(XRoot, Credentials, Conns, Parser);
if (_cla?.IsValid == true)
ClientAgent = _cla;
// get the M42 WPM config
var _m42wpm = new cDataHistoryConfigM42Wpm(XRoot, Credentials, Parser);
if (_m42wpm?.IsValid == true)
M42Wpm = _m42wpm;
var _citrix = new cDataHistoryConfigCitrix(XRoot, Credentials, Parser);
if (_citrix?.IsValid == true)
Citrix = _citrix;
// get the nexthink config
var _nxt = new cDataHistoryConfigNexthink(XRoot, Credentials, Parser);
if (_nxt?.IsValid == true)
Nexthink = _nxt;
var _auth = new cF4SDAuthorisation(XRoot, Parser, this);
if (_auth?.IsValid == true)
Authorisation = _auth;
IsValid = true;
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
}
public class cDataHistoryConfigDatabase : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public cDataHistoryConfigSqlConnection Connection { get; private set; } = null;
public bool SearchForPhoneNumbers { get; set; } = false;
public bool SearchWithLike { get; set; } = false;
public int DaysToCache { get; set; } = 60;
public List<cDataHistoryCleanupTimeFrame> CleanupTimeFrames = null;
internal cDataHistoryConfigDatabase(XmlElement XNode, Dictionary<string, cDataHistoryConfigDbConnection> DbConnections, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XNode2 = XNode.SelectSingleNode("DataHistory-DB");
if (!(XNode2 is XmlElement XNode3))
{
Parser.AddMessage(XNode, $"The root element <{XNode.Name}> does not have a <DataHistory-DB> element.");
return;
}
Parser.EnterElement("DataHistory-DB");
try
{
var strConnection = cXmlParser.GetStringFromXmlAttribute(XNode2, "DB-Connection");
if (string.IsNullOrWhiteSpace(strConnection))
{
Parser.AddMessage(XNode, $"The element <{XNode2.Name}> does not have a 'DB-Connection' attribute.");
return;
}
if (!DbConnections.TryGetValue(strConnection, out var Conn))
{
Parser.AddMessage(XNode, $"Could not find a DB connection '{strConnection}' in element <{XNode2.Name}>.");
return;
}
if (!(Conn is cDataHistoryConfigSqlConnection SqlConn))
{
Parser.AddMessage(XNode, $"The DB connection '{strConnection}' in element <{XNode2.Name}> has to be a SQL connection.");
return;
}
Connection = SqlConn;
SearchForPhoneNumbers = cXmlParser.GetBoolFromXmlAttribute(XNode2, "SearchForPhoneNumbers");
SearchWithLike = cXmlParser.GetBoolFromXmlAttribute(XNode2, "SearchWithLike");
DaysToCache = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "DaysToCache", DaysToCache);
CleanupTimeFrames = cDataHistoryCleanupTimeFrame.LoadFromXml(XNode3, Parser);
IsValid = true;
}
finally
{
Parser.LeaveElement("DataHistory-DB");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cF4SDAnalyticsConfigDatabase : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public bool AnonymousUser { get; set; }
public int SessionTimeout { get; set; } = 60;
public int CaseTimeout { get; set; } = 5;
public int SessionCheckInterval { get; set; } = 20;
public int CaseCheckInterval { get; set; } = 1;
public cDataHistoryConfigSqlConnection Connection { get; private set; } = null;
internal cF4SDAnalyticsConfigDatabase(XmlElement XNode, Dictionary<string, cDataHistoryConfigDbConnection> DbConnections, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XNode2 = XNode.SelectSingleNode("F4SDAnalytics-DB");
if (!(XNode2 is XmlElement XNode3))
{
Parser.AddMessage(XNode, $"The root element <{XNode.Name}> does not have a <F4SDAnalytics-DB> element.", LogLevels.Info);
return;
}
Parser.EnterElement("F4SDAnalytics-DB");
try
{
var strConnection = cXmlParser.GetStringFromXmlAttribute(XNode2, "DB-Connection");
if (string.IsNullOrWhiteSpace(strConnection))
{
Parser.AddMessage(XNode, $"The element <{XNode2.Name}> does not have a 'DB-Connection' attribute.");
return;
}
if (!DbConnections.TryGetValue(strConnection, out var Conn))
{
Parser.AddMessage(XNode, $"Could not find a DB connection '{strConnection}' in element <{XNode2.Name}>.");
return;
}
if (!(Conn is cDataHistoryConfigSqlConnection SqlConn))
{
Parser.AddMessage(XNode, $"The DB connection '{strConnection}' in element <{XNode2.Name}> has to be a SQL connection.");
return;
}
Connection = SqlConn;
AnonymousUser = !cXmlParser.GetBoolFromXmlAttribute(XNode2, "EnableUserId");
SessionTimeout = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "SessionTimeout", 60);
CaseTimeout = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "CaseTimeout", 5);
SessionCheckInterval = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "SessionCheckInterval", 20);
CaseCheckInterval = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "CaseCheckInterval", 2);
IsValid = true;
}
finally
{
Parser.LeaveElement("F4SDAnalytics-DB");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryCleanupTimeFrame : IConfigNodeValidation
{
private const string constXmlTag = "Cleanup-Timeframe";
public bool IsValid { get; set; } = false;
public int DowFrom = 0;
public int DowTo = 0;
public TimeSpan TimeFrom = new TimeSpan(0, 0, 0);
public TimeSpan TimeTo = new TimeSpan(23, 59, 59);
public TimeZoneInfo TimeZone = TimeZoneInfo.Utc;
internal cDataHistoryCleanupTimeFrame(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
TimeZone = cXmlParser.GetTimeZoneInfoFromAttribute(XNode, "Timezone");
if (TimeZone == null)
TimeZone = TimeZoneInfo.Utc;
var strFromDay = cXmlParser.GetStringFromXmlAttribute(XNode, "StartDay");
var fromTime = cXmlParser.GetTimeSpanFromAttribute(XNode, "StartTime", null);
var strToDay = cXmlParser.GetStringFromXmlAttribute(XNode, "StopDay");
var toTime = cXmlParser.GetTimeSpanFromAttribute(XNode, "StopTime", null);
if (fromTime == null || toTime == null)
return;
TimeFrom = (TimeSpan)fromTime;
TimeTo = (TimeSpan)toTime;
DowFrom = GetDayOfWeek(strFromDay);
if (DowFrom < 0)
return;
DowTo = GetDayOfWeek(strToDay);
if (DowTo < 0)
{
if (TimeTo <= TimeFrom)
DowTo = (DowFrom + 1) % 7;
else
DowTo = DowFrom;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
private int GetDayOfWeek(string Day)
{
try
{
int DayOfWeek = -1;
if (Day != null)
{
var strDow = Day.ToUpperInvariant();
switch (strDow)
{
case "MON":
DayOfWeek = 1;
break;
case "TUE":
DayOfWeek = 2;
break;
case "WED":
DayOfWeek = 3;
break;
case "THU":
DayOfWeek = 4;
break;
case "FRI":
DayOfWeek = 5;
break;
case "SAT":
DayOfWeek = 6;
break;
case "SUN":
DayOfWeek = 0;
break;
}
}
return DayOfWeek;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(LogLevels.Error, E);
}
return -1;
}
internal static List<cDataHistoryCleanupTimeFrame> LoadFromXml(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var RetVal = new List<cDataHistoryCleanupTimeFrame>();
try
{
var XList = XNode.SelectNodes(constXmlTag);
if (XList != null && XList.Count > 0)
{
Parser.EnterElement(constXmlTag);
try
{
foreach (var Entry in XList)
{
if (!(Entry is XmlElement XEntry))
continue;
var Node = new cDataHistoryCleanupTimeFrame(XEntry, Parser);
if (Node.IsValid)
RetVal.Add(Node);
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement(constXmlTag);
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return RetVal;
}
private static int Compare(int DowFrom, TimeSpan TimeFrom, int DowTo, TimeSpan TimeTo)
{
if (DowFrom == DowTo)
{
if (TimeTo > TimeFrom)
return 1;
else if (TimeTo < TimeFrom)
return -1;
else
return 0;
}
else if (DowTo > DowFrom)
return 1;
else
return -1;
}
public bool Check()
{
try
{
var Now = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, this.TimeZone);
var dow = (int)Now.DayOfWeek;
var time = Now.TimeOfDay;
var c0 = Compare(DowFrom, TimeFrom, DowTo, TimeTo);
var c1 = Compare(DowFrom, TimeFrom, dow, time);
var c2 = Compare(DowTo, TimeTo, dow, time);
if (c0 <= 0)
return c1 >= 0 || c2 <= 0;
else
return c1 >= 0 && c2 <= 0;
}
catch (Exception E)
{
cLogManager.DefaultLogger.LogException(LogLevels.Error, E);
}
return false;
}
}
public class cDataHistoryScanTiming : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public TimeSpan Interval { get; set; }
public TimeSpan Offset { get; set; }
public TimeZoneInfo Timezone { get; set; }
public cDataHistoryScanTiming()
{
}
internal cDataHistoryScanTiming(XmlElement XNode, TimeSpan DefaultInterval, TimeSpan DefaultOffset, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
Interval = DefaultInterval;
Offset = DefaultOffset;
Timezone = TimeZoneInfo.Local;
var XNode2 = XNode.SelectSingleNode("Scan-Timing");
if (XNode2 == null)
return;
Parser.EnterElement("Scan-Timing");
try
{
Interval = (TimeSpan)cXmlParser.GetTimeSpanFromAttribute(XNode2, "ScanInterval", Interval);
Offset = (TimeSpan)cXmlParser.GetTimeSpanFromAttribute(XNode2, "ScanOffset", Interval);
Timezone = cXmlParser.GetTimeZoneInfoFromAttribute(XNode2, "Timezone");
if (Timezone == null)
Timezone = TimeZoneInfo.Utc;
IsValid = true;
}
finally
{
Parser.LeaveElement("Scan-Timing");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cF4SDAuthorisation : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public cF4SDMembershipGroups MembershipGroups = null;
public Dictionary<string, cF4SDRole> Roles = null;
public cF4SDAuthorisation(XmlElement XNode, cXmlParser Parser, cDataHistoryConfigInfrastructure InfratructureConfig)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!(XNode.SelectSingleNode("Authorization") is XmlElement _xmlAuth))
return;
Parser.EnterElement("Authorization");
try
{
var _groups = new cF4SDMembershipGroups(_xmlAuth, Parser, InfratructureConfig);
if (_groups?.IsValid != true)
return;
MembershipGroups = _groups;
var _roles = cF4SDRole.LoadFromXml(_xmlAuth, Parser, MembershipGroups);
if (_roles?.Count > 0)
Roles = _roles;
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
Parser.LeaveElement("Authorization");
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cF4SDMembershipGroups : Dictionary<string, cF4SDMembershipGroup>, IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public Dictionary<string, cF4SDMembershipGroupsAd> GroupsAd = null;
public cF4SDMembershipGroupsM42 GroupsM42 = null;
public cF4SDMembershipGroups(XmlElement XNode, cXmlParser Parser, cDataHistoryConfigInfrastructure InfratructureConfig)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!(XNode.SelectSingleNode("Membership-Groups") is XmlElement _xmlGroups))
return;
Parser.EnterElement("Membership-Groups");
try
{
GroupsAd = cF4SDMembershipGroupsAd.LoadFromXml(_xmlGroups, Parser, InfratructureConfig?.ActiveDirectory?.Domains);
if (GroupsAd != null)
foreach (var _entry in GroupsAd.Values)
foreach (var _entry2 in _entry.Values)
this[_entry2.Name] = _entry2;
var _groupM42 = new cF4SDMembershipGroupsM42(_xmlGroups, Parser);
if (_groupM42?.IsValid == true)
{
GroupsM42 = _groupM42;
foreach (var _entry in GroupsM42)
this[_entry.Key] = _entry.Value;
}
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
Parser.LeaveElement("Membership-Groups");
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public abstract class cF4SDMembershipGroup : cConfigNodeNamed
{
public cF4SDMembershipGroup(XmlElement XNode, cXmlParser Parser) : base(XNode, Parser)
{
}
}
public class cF4SDMembershipGroupsAd : Dictionary<string, cF4SDMembershipGroupAd>, IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public string strDomain { get; private set; } = null;
public cDataHistoryAdDomain Domain { get; private set; } = null;
public cF4SDMembershipGroupsAd(XmlElement XNode, cXmlParser Parser, Dictionary<string, cDataHistoryAdDomain> Domains)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
strDomain = cXmlParser.GetStringFromXmlAttribute(XNode, "Domain");
if (!string.IsNullOrEmpty(strDomain))
{
if (Domains.TryGetValue(strDomain, out var _dom))
{
Domain = _dom;
var _xList = XNode.SelectNodes("Membership-Group-AD");
if (_xList != null && _xList.Count > 0)
{
Parser.EnterElement("Membership-Group-AD");
foreach (var _x in _xList)
{
if (!(_x is XmlElement _xEl))
continue;
var _grp = new cF4SDMembershipGroupAd(_xEl, Parser);
if (_grp?.IsValid == true)
this[_grp.Name] = _grp;
Parser.SelectElementNext();
}
Parser.LeaveElement("Membership-Group-AD");
}
IsValid = true;
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public static Dictionary<string, cF4SDMembershipGroupsAd> LoadFromXml(XmlElement XNode, cXmlParser Parser, Dictionary<string, cDataHistoryAdDomain> Domains)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var _retVal = new Dictionary<string, cF4SDMembershipGroupsAd>();
try
{
var _xmlList = XNode.SelectNodes("Membership-Groups-AD");
if (_xmlList != null && _xmlList.Count > 0)
{
Parser.EnterElement("Membership-Groups-AD");
foreach (var _xmlEntry in _xmlList)
{
if (!(_xmlEntry is XmlElement _xmlEl))
continue;
var _node = new cF4SDMembershipGroupsAd(_xmlEl, Parser, Domains);
if (_node?.IsValid == true)
_retVal[_node.Domain.Name] = _node;
Parser.SelectElementNext();
}
Parser.LeaveElement("Membership-Groups-AD");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return _retVal; ;
}
}
public class cF4SDMembershipGroupsM42 : Dictionary<string, cF4SDMembershipGroupM42>, IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public cF4SDMembershipGroupsM42(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!(XNode.SelectSingleNode("Membership-Groups-Matrix42") is XmlElement _xGroup))
return;
Parser.EnterElement("Membership-Groups-Matrix42");
var _xList = _xGroup.SelectNodes("Membership-Group-Matrix42");
if (_xList != null && _xList.Count > 0)
{
Parser.EnterElement("Membership-Group-Matrix42");
foreach (var _x in _xList)
{
if (!(_x is XmlElement _xEl))
continue;
var _grp = new cF4SDMembershipGroupM42(_xEl, Parser);
if (_grp?.IsValid == true)
this[_grp.Name] = _grp;
Parser.SelectElementNext();
}
Parser.LeaveElement("Membership-Group-Matrix42");
}
Parser.LeaveElement("Membership-Groups-Matrix42");
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cF4SDMembershipGroupAd : cF4SDMembershipGroup
{
public string Account { get; private set; } = null;
public string SID { get; set; } = null;
public cF4SDMembershipGroupAd(XmlElement XNode, cXmlParser Parser) : base(XNode, Parser)
{
try
{
if (!this.IsValid)
return;
IsValid = false;
Account = cXmlParser.GetStringFromXmlAttribute(XNode, "Account");
if (string.IsNullOrEmpty(Account))
return;
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
}
}
public class cF4SDMembershipGroupM42 : cF4SDMembershipGroup
{
public string RoleName { get; private set; } = null;
public Guid RoleId { get; private set; } = Guid.Empty;
public cF4SDMembershipGroupM42(XmlElement XNode, cXmlParser Parser) : base(XNode, Parser)
{
try
{
if (!this.IsValid)
return;
IsValid = false;
RoleName = cXmlParser.GetStringFromXmlAttribute(XNode, "RoleName");
if (string.IsNullOrEmpty(RoleName) || string.IsNullOrEmpty(Name))
return;
RoleId = cXmlParser.GetGuidFromXmlAttribute(XNode, "RoleID");
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
}
}
public class cF4SDRole : cConfigNodeNamed
{
public List<cF4SDMembershipGroup> MembershipGroups { get; private set; } = null;
public cF4SDRole(XmlElement XNode, cXmlParser Parser, cF4SDMembershipGroups _MembershipGroups) : base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
var _lstGroupNames = new List<string>();
var _strGroup = cXmlParser.GetStringFromXmlAttribute(XNode, "Group");
if (!string.IsNullOrEmpty(_strGroup))
_lstGroupNames.Add(_strGroup);
var _xmlGroups = XNode.SelectNodes("GroupRef");
if (_xmlGroups?.Count > 0)
{
Parser.EnterElement("GroupRef");
foreach (var _ref in _xmlGroups)
{
if (!(_ref is XmlElement _refGroup))
continue;
_strGroup = cXmlParser.GetStringFromXmlAttribute(_refGroup, "Name");
if (!string.IsNullOrEmpty(_strGroup) && !_lstGroupNames.Contains(_strGroup))
_lstGroupNames.Add(_strGroup);
Parser.SelectElementNext();
}
Parser.LeaveElement("GroupRef");
}
if (_lstGroupNames.Count > 0)
{
var _lstMembers = new List<cF4SDMembershipGroup>();
foreach (var _entry in _lstGroupNames)
{
if (_MembershipGroups.TryGetValue(_entry, out var _grp))
{
if (!_lstMembers.Contains(_grp))
_lstMembers.Add(_grp);
}
}
if (_lstMembers.Count > 0)
{
MembershipGroups = _lstMembers;
IsValid = true;
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
public static Dictionary<string, cF4SDRole> LoadFromXml(XmlElement XNode, cXmlParser Parser, cF4SDMembershipGroups MembershipGroups)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
var _retVal = new Dictionary<string, cF4SDRole>();
try
{
var _xmlNode2 = XNode.SelectSingleNode("Roles");
if (!(_xmlNode2 is XmlElement _xmlRoles))
return null;
Parser.EnterElement("Roles");
try
{
var _xmlListRoles = _xmlRoles.SelectNodes("Role");
if (!(_xmlListRoles?.Count > 0))
return null;
try
{
Parser.EnterElement("Role");
foreach (var _xmlEntry in _xmlListRoles)
{
if (!(_xmlEntry is XmlElement _xmlEl))
continue;
var _group = new cF4SDRole(_xmlEl, Parser, MembershipGroups);
if (_group?.IsValid == true)
_retVal[_group.Name] = _group;
Parser.SelectElementNext();
}
}
finally
{
Parser.LeaveElement("Role");
}
}
finally
{
Parser.LeaveElement("Roles");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return _retVal; ;
}
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT.MultiLanguage;
using C4IT.Security;
using C4IT.XML;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigM42Wpm : IConfigNodeValidation
{
public enum enumApiTokenLifetime
{
days30 = 30,
days90 = 90,
days180 = 180,
year1 = 360,
never = -1
};
public bool IsValid { get; private set; } = false;
public string Server { get; private set; } = null;
public cCredential Credential { get; private set; } = null;
public int ClosedTicketHistory { get; private set; } = 10;
public enumActivityQueueFilterOptions ActivityQueueFilterOption { get; private set; } = enumActivityQueueFilterOptions.showAll;
public List<cApiM42TicketQueueInfo> ActivityQueues { get; private set; } = new List<cApiM42TicketQueueInfo>();
[Obsolete("This property is no longer used and will be removed in future versions.")]
public bool DisableAutomaticTimeTracking { get; private set; } = false;
public cMultiLanguageDictionary DisplayNames { get; private set; } = new cMultiLanguageDictionary();
public enumApiTokenLifetime ApiLifetime { get; private set; } = enumApiTokenLifetime.never;
[Obsolete("This property is no longer used and will be removed in future versions.")]
public enumShowDocumentCaseDialog ShowDocumentCaseDialog { get; private set; } = enumShowDocumentCaseDialog.ifRequired;
internal cDataHistoryConfigM42Wpm(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null;
if (cLogManager.DefaultLogger.IsDebug)
{
CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
}
try
{
if (!(XNode.SelectSingleNode("Matrix42-WPM") is XmlElement XNode2))
return;
Parser.EnterElement("Matrix42-WPM");
try
{
Server = cXmlParser.GetStringFromXmlAttribute(XNode2, "Server", "");
if (string.IsNullOrWhiteSpace(Server))
{
Parser.AddMessage(XNode, $"The attribute 'Server' in element <{XNode2.Name}> is not set.");
return;
}
var strCredential = cXmlParser.GetStringFromXmlAttribute(XNode2, "Credential");
if (string.IsNullOrWhiteSpace(strCredential))
{
Parser.AddInvalidAttribute(XNode, null, "Credential");
return;
}
if (!Credentials.TryGetValue(strCredential, out var _Cred))
{
Parser.AddMessage(XNode, $"The credential attribute value '{strCredential}' of the element <{XNode.Name}> coud not be resolved.");
return;
}
Credential = _Cred;
ClosedTicketHistory = cXmlParser.GetIntegerFromXmlAttribute(XNode2, "ClosedTicketHistory", ClosedTicketHistory);
ActivityQueueFilterOption = cXmlParser.GetEnumFromAttribute(XNode2, "ActivityQueueFilter", enumActivityQueueFilterOptions.showAll);
if ((XNode2.SelectSingleNode("Queues") is XmlElement XNode3))
{
Parser.EnterElement("Queues");
try
{
ActivityQueues = cXmlParser.GetObjectsFromXml(
XNode3,
"Queue",
node =>
{
XmlAttributeCollection a = node.Attributes;
if (a == null) return null;
string name = a["QueueName"]?.Value;
string id = a["QueueID"]?.Value;
Guid guid;
if (string.IsNullOrWhiteSpace(name) || !Guid.TryParse(id, out guid))
return null;
return new cApiM42TicketQueueInfo
{
QueueName = name.Trim(),
QueueID = guid
};
}
);
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("Queues");
}
}
DisplayNames.LoadFromXmlAttributeList(XNode2, "DisplayName");
var _str = cXmlParser.GetStringFromXmlAttribute(XNode2, "ApiTokenLifetime")?.ToLowerInvariant();
switch (_str)
{
case "90 days":
ApiLifetime = enumApiTokenLifetime.days90;
break;
case "180 days":
ApiLifetime = enumApiTokenLifetime.days180;
break;
case "1 year":
ApiLifetime = enumApiTokenLifetime.year1;
break;
case "never":
ApiLifetime = enumApiTokenLifetime.never;
break;
default:
ApiLifetime = enumApiTokenLifetime.days30;
break;
}
parseMatrix42Ticket(XNode2, Parser);
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("Matrix42-WPM");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal void parseMatrix42Ticket(XmlElement XNode, cXmlParser Parser)
{
MethodBase CM = null;
if (cLogManager.DefaultLogger.IsDebug)
{
CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
}
try
{
if (!(XNode.SelectSingleNode("Matrix42-Ticket") is XmlElement XNode2))
return;
Parser.EnterElement("Matrix42-Ticket");
try
{
#pragma warning disable CS0618 // Type or member is obsolete
DisableAutomaticTimeTracking = cXmlParser.GetBoolFromXmlAttribute(XNode2, "DisableAutomaticTimeTracking");
ShowDocumentCaseDialog = cXmlParser.GetEnumFromAttribute(XNode2, "ShowDocumentCaseDialog", enumShowDocumentCaseDialog.ifRequired);
#pragma warning restore CS0618 // Type or member is obsolete
}
catch (Exception E)
{
LogException(E);
}
finally
{
Parser.LeaveElement("Matrix42-Ticket");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
}

View File

@@ -0,0 +1,258 @@
using C4IT.Logging;
using C4IT.Security;
using C4IT.XML;
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using static C4IT.Logging.cLogManager;
namespace C4IT.DataHistoryProvider
{
public class cDataHistoryConfigNexthink : IConfigNodeValidation
{
public bool IsValid { get; set; } = false;
public cDataHistoryScanTiming ScanTiming { get; private set; } = null;
public Dictionary<string, cDataHistoryNxtPortal> Portals = new Dictionary<string, cDataHistoryNxtPortal>();
internal cDataHistoryConfigNexthink(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var XNode2 = XNode.SelectSingleNode("Nexthink");
if (!(XNode2 is XmlElement XNexthink))
{
return;
}
Parser.EnterElement("Nexthink");
try
{
ScanTiming = new cDataHistoryScanTiming(XNexthink, TimeSpan.FromHours(24), TimeSpan.FromMinutes(10), Parser);
Portals = cDataHistoryNxtPortal.LoadFromXml(XNexthink, Credentials, Parser);
if (Portals != null && Portals.Count > 0)
IsValid = true;
}
finally
{
Parser.LeaveElement("Nexthink");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cDataHistoryNxtPortal : cConfigNodeNamed
{
public string Address { get; set; }
public cCredential Credential { get; set; }
public bool IsCloud { get; set; } = false;
public Dictionary<string, cDataHistoryNxtEngine> Engines = new Dictionary<string, cDataHistoryNxtEngine>();
internal cDataHistoryNxtPortal(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
Address = cXmlParser.GetStringFromXmlAttribute(XNode, "Address");
if (string.IsNullOrWhiteSpace(Address))
{
Parser.AddInvalidAttribute(XNode, Name, "Address");
return;
}
var _strCredential = cXmlParser.GetStringFromXmlAttribute(XNode, "Credential");
if (string.IsNullOrWhiteSpace(_strCredential))
{
Parser.AddInvalidAttribute(XNode, Name, "Credential");
return;
}
if (!Credentials.TryGetValue(_strCredential, out var _Cred))
{
Parser.AddMessage(XNode, $"Could not find the credential '{_strCredential}' in element <{XNode.Name}>");
return;
}
Credential = _Cred;
IsCloud = cXmlParser.GetBoolFromXmlAttribute(XNode, "IsCloud");
Engines = cDataHistoryNxtEngine.LoadFromXml(XNode, this, Parser);
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryNxtPortal> LoadFromXml(XmlElement XNode, Dictionary<string, cCredential> Credentials, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var lstXNode = XNode.SelectNodes("Nxt-Portal");
if (lstXNode == null || lstXNode.Count == 0)
{
Parser.AddMessage(XNode, "Could not find a valid <Nxt-Portal> element.");
return null;
}
Parser.EnterElement("Nxt-Portal");
try
{
var RetVal = new Dictionary<string, cDataHistoryNxtPortal>(lstXNode.Count);
foreach (var XENtry in lstXNode)
{
if (!(XENtry is XmlElement XPortal))
continue;
var Po = new cDataHistoryNxtPortal(XPortal, Credentials, Parser);
if (Po != null && Po.IsValid)
RetVal.Add(Po.Name, Po);
Parser.SelectElementNext();
}
return RetVal;
}
finally
{
Parser.LeaveElement("Nxt-Portal");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
public class cDataHistoryNxtEngine : cConfigNodeNamed
{
public string Address { get; set; }
public int Port { get; set; } = -1;
internal cDataHistoryNxtEngine(XmlElement XNode, cDataHistoryNxtPortal Portal, cXmlParser Parser) :
base(XNode, Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
if (!IsValid)
return;
IsValid = false;
Address = cXmlParser.GetStringFromXmlAttribute(XNode, "Address");
if (string.IsNullOrWhiteSpace(Address))
{
Parser.AddInvalidAttribute(XNode, Name, "Address");
return;
}
Port = 1671;
if (Portal.IsCloud)
Port = 443;
Port = cXmlParser.GetIntegerFromXmlAttribute(XNode, "Port", Port);
IsValid = true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
internal static Dictionary<string, cDataHistoryNxtEngine> LoadFromXml(XmlElement XNode, cDataHistoryNxtPortal Portal, cXmlParser Parser)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var lstXNode = XNode.SelectNodes("Nxt-Engine");
if (lstXNode == null || lstXNode.Count == 0)
{
Parser.AddMessage(XNode, "Could not find a valid <Nxt-Engine> element.");
return null;
}
Parser.EnterElement("Nxt-Engine");
try
{
var RetVal = new Dictionary<string, cDataHistoryNxtEngine>(lstXNode.Count);
foreach (var XENtry in lstXNode)
{
if (!(XENtry is XmlElement XPortal))
continue;
var En = new cDataHistoryNxtEngine(XPortal, Portal, Parser);
if (En != null && En.IsValid)
RetVal.Add(En.Name, En);
Parser.SelectElementNext();
}
return RetVal;
}
finally
{
Parser.LeaveElement("Nxt-Engine");
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,22 @@
using C4IT.FASD.Base;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace C4IT_DataHistoryProvider_Base.DataSources
{
public interface ISearchResultRelationProvider
{
HashSet<enumFasdInformationClass> GetSupportedInformationClasses();
/// <summary>
/// Find objects, which are somehow related to the given objects.
/// </summary>
/// <param name="ids">Identifies the objects for which relations should be searched</param>
/// <param name="informationClass">Determines the information class the objects have, for which relations should be searched.</param>
/// <param name="ageInDays">Specifies the time, in which the relations should be considered.</param>
/// <returns></returns>
Task<cF4sdStagedSearchResultRelations> GetRelationsAsync(IEnumerable<cF4sdIdentityEntry> ids, enumFasdInformationClass informationClass, int ageInDays, CancellationToken token = default);
}
}

View File

@@ -0,0 +1,185 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup Label="Globals">
<SccProjectName>SAK</SccProjectName>
<SccProvider>SAK</SccProvider>
<SccAuxPath>SAK</SccAuxPath>
<SccLocalPath>SAK</SccLocalPath>
</PropertyGroup>
<PropertyGroup>
<OutputType>Library</OutputType>
<RootNamespace>C4IT_DataHistoryProvider_Base</RootNamespace>
<Configurations>Debug;Debug-Demo;Release;Release-Demo</Configurations>
<Deterministic>false</Deterministic>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>TRACE;DEBUG;VITALSIGN_MONITORING</DefineConstants>
<NoWarn>MSB3305</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<OutputPath>bin\Release\</OutputPath>
<NoWarn>MSB3305</NoWarn>
</PropertyGroup>
<PropertyGroup>
<ApplicationIcon>C4IT_2016.ico</ApplicationIcon>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release-Demo|AnyCPU'">
<OutputPath>bin\Release-Demo\</OutputPath>
<DefineConstants>TRACE;DEMOLICENSE</DefineConstants>
<Optimize>true</Optimize>
<NoWarn>MSB3305</NoWarn>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug-Demo|AnyCPU'">
<DebugSymbols>true</DebugSymbols>
<OutputPath>bin\Debug-Demo\</OutputPath>
<DefineConstants>TRACE;DEBUG;DEMOLICENSE</DefineConstants>
<NoWarn>MSB3305</NoWarn>
</PropertyGroup>
<PropertyGroup>
<TargetFrameworks>netstandard2.0;net472</TargetFrameworks>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
<AssemblyTitle>F4SD Cockpit Server base library</AssemblyTitle>
</PropertyGroup>
<ItemGroup Condition="'$(TargetFramework)' == 'net472'">
<Reference Include="System.Web" />
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Web.Administration, Version=7.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>.\Microsoft.Web.Administration.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.F4SD.GlobalConfig.cs">
<Link>Common\C4IT.F4SD.GlobalConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.F4SD.HealthCardConfig.cs">
<Link>Common\C4IT.F4SD.HealthCardConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.F4SD.MenuItem.cs">
<Link>Common\C4IT.F4SD.MenuItem.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.Base.cs">
<Link>Common\C4IT.FASD.Base.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.Communication.Agent.cs">
<Link>Common\C4IT.FASD.Communication.Agent.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.ConfigBase.cs">
<Link>Common\C4IT.FASD.ConfigBase.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.CopyTemplatesConfig.cs">
<Link>Common\C4IT.FASD.CopyTemplatesConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.IconConfig.cs">
<Link>Common\C4IT.FASD.IconConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.MenuSectionConfig.cs">
<Link>Common\C4IT.FASD.MenuSectionConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.QuickActionConfig.cs">
<Link>Common\C4IT.FASD.QuickActionConfig.cs</Link>
</Compile>
<Compile Include="..\..\C4IT FASD\_Common\C4IT.FASD.Security.cs">
<Link>Common\C4IT.FASD.Security.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Configuration\C4IT.Configuration.ConfigHelper.cs">
<Link>Common\C4IT.Configuration.ConfigHelper.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\FileImport\C4IT.FileImport.CsvFile.cs">
<Link>Common\C4IT.FileImport.CsvFile.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Http\C4IT.HTTP.HttpApiBase.cs">
<Link>Common\C4IT.HTTP.HttpApiBase.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Http\C4IT.HttpHelper.cs">
<Link>Common\C4IT.HttpHelper.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Licensing\C4IT.Licensing.LicenseBase.cs">
<Link>Common\C4IT.Licensing.LicenseBase.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Logging\C4IT.Logging.LogManager.cs">
<Link>Common\C4IT.Logging.LogManager.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Logging\C4IT.Logging.LogNetwork.cs">
<Link>Common\C4IT.Logging.LogNetwork.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Logging\C4IT.Logging.LogPerformance.cs">
<Link>Common\C4IT.Logging.LogPerformance.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\MsCloud\C4IT.MsGraph.Base.cs">
<Link>Common\C4IT.MsGraph.Base.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\MultiLanguage\C4IT.MultiLanguage.MultiLanguageSupport.cs">
<Link>Common\C4IT.MultiLanguage.MultiLanguageSupport.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Security\C4IT.Security.Base32.cs">
<Link>Common\C4IT.Security.Base32.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Security\C4IT.Security.Credential.cs">
<Link>Common\C4IT.Security.Credential.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\Security\C4IT.Security.SecurePassword.cs">
<Link>Common\C4IT.Security.SecurePassword.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\XML\C4IT.XML.ConfigParsing.cs">
<Link>Common\C4IT.XML.ConfigParsing.cs</Link>
</Compile>
<Compile Include="..\..\Common Code\XML\C4IT.XML.Credentials.cs">
<Link>Common\C4IT.XML.Credentials.cs</Link>
</Compile>
<Compile Include="..\..\Matrix42\M42CommonCode\M42WebClient\C4IT.Matrix42.WebClient.cs">
<Link>Common\C4IT.Matrix42.WebClient.cs</Link>
</Compile>
<Compile Include="..\..\NexThink\NxCommonCode\NXQL\C4IT.Nexthink.NXQL.cs">
<Link>Common\C4IT.Nexthink.NXQL.cs</Link>
</Compile>
<Compile Include="..\..\NexThink\NxCommonCode\NXQL\C4IT.Nexthink.NxqlOrchestration.cs">
<Link>Common\C4IT.Nexthink.NxqlOrchestration.cs</Link>
</Compile>
<Compile Include="..\CommonAssemblyAttributes.cs">
<Link>Common\CommonAssemblyAttributes.cs</Link>
</Compile>
<Compile Include="..\CommonAssemblyInfo.cs">
<Link>Properties\CommonAssemblyInfo.cs</Link>
</Compile>
</ItemGroup>
<ItemGroup>
<Content Include="C4IT_2016.ico" />
<Content Include="Microsoft.Web.Administration.dll">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
</ItemGroup>
<ItemGroup>
<COMReference Include="ActiveDs">
<Guid>{97D25DB0-0363-11CF-ABC4-02608C9E7553}</Guid>
<VersionMajor>1</VersionMajor>
<VersionMinor>0</VersionMinor>
<Lcid>0</Lcid>
<WrapperTool>tlbimp</WrapperTool>
<Isolated>False</Isolated>
<EmbedInteropTypes>True</EmbedInteropTypes>
</COMReference>
</ItemGroup>
<ItemGroup>
<PackageReference Include="MaterialIcons" Version="1.0.3" NoWarn="NU1701" />
<PackageReference Include="Microsoft.Data.SqlClient" Version="6.1.0" />
<PackageReference Include="Microsoft.Win32.Registry" Version="5.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="System.DirectoryServices" Version="9.0.7" />
<PackageReference Include="System.DirectoryServices.AccountManagement" Version="9.0.7" />
<PackageReference Include="System.DirectoryServices.Protocols" Version="9.0.7" />
<PackageReference Include="System.Drawing.Common" Version="9.0.7" />
<PackageReference Include="System.IdentityModel.Tokens.Jwt" Version="8.13.0" />
<PackageReference Include="System.Runtime.CompilerServices.Unsafe" Version="6.1.2" />
<PackageReference Include="System.Security.Permissions" Version="9.0.7" />
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.7" />
</ItemGroup>
<Target Name="AfterBuild" AfterTargets="Build">
<PropertyGroup>
<FrameworkDirectory>net472/</FrameworkDirectory>
</PropertyGroup>
<Message Text="Start to publish component" Importance="high" />
<Copy SourceFiles="$(ProjectDir)$(OutputPath)$(FrameworkDirectory)$(AssemblyName).dll" DestinationFolder="$(ProjectDir)Publish$(TargetFramework)" />
</Target>
</Project>

View File

@@ -0,0 +1,48 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using C4IT.XML;
namespace C4IT.FASD.Base
{
public class cF4SDConfigGlobalParametersXml : cFasdBaseConfig
{
public const string constFileNameFasdConfig = "F4SD-Global-Configuration.xml";
private const string constFileNameFasdConfigSchema = "F4SD-Global-Configuration.xsd";
private const string constConfigRootElement = "F4SD-Global-Configuration";
private Dictionary<string, cConfigurationSubnode> Nodes = new Dictionary<string, cConfigurationSubnode>();
private Dictionary<string, cConfigurationValue> Values = new Dictionary<string, cConfigurationValue>();
public cF4SDConfigGlobalParametersXml(string fileNameConfig, string fileNameConfigSchema, string configRootElement) : base(fileNameConfig, fileNameConfigSchema, configRootElement)
{
}
public override bool InstantiateProperties(XmlElement RootElement, cXmlParser Parser)
{
return false;
}
private class cConfigurationSubnode : IConfigNodeNamed
{
public bool IsValid { get; private set; } = false;
public string Name { get; set; }
public string Description { get; set; }
}
private class cConfigurationValue : IConfigNodeNamed
{
public bool IsValid { get; private set; } = false;
public string Name { get; set; }
public string Description { get; set; }
}
}
}

View File

@@ -0,0 +1,294 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.InteropServices;
using System.Security.AccessControl;
using System.IO;
using FILETIME = System.Runtime.InteropServices.ComTypes.FILETIME;
using Microsoft.Win32;
using C4IT.Licensing;
using C4IT.Logging;
using C4IT.DataHistoryProvider;
using static C4IT.Logging.cLogManager;
namespace C4IT.FASD.Licensing
{
public class cF4SDLicense : cC4itLicenseBase
{
static public cF4SDLicense Instance = null;
public bool IsIntrinsic { get; private set; } = false;
static cF4SDLicense()
{
Instance = new cF4SDLicense
{
IsIntrinsic = true
};
//Instance.CreateIntrinsicModules();
//Instance.SetValid();
}
public cF4SDLicense() : base(new Guid("776D99A6-D341-4B70-BA4B-2CC55B76A079"))
{
if (Instance == null)
Instance = this;
}
public void SetValid()
{
this.StartDate = null;
this.EndDate = null;
this.licenseType = LicenseType.productive;
this.LicenseMetrics = new cLicenseMetrics()
{
MetricType = cLicenseMetrics.eLicenseMetricType.ManagedUsers,
Count = int.MaxValue
};
}
protected override cC4itLicenseBaseEntry CreateLicenseEntry()
{
return new cF4SDLicenseEntry();
}
public class cF4SDLicenseEntry : cC4itLicenseBaseEntry
{
public override bool Validate()
{
return true;
}
}
static public string GetProgramFolderLocation(Assembly ExecutingAssembly, string SubFolder, string Location)
{
try
{
var Ass = ExecutingAssembly;
if (Ass == null)
Ass = Assembly.GetEntryAssembly();
if (Ass == null)
return null;
var P = Path.GetFullPath(Path.Combine(Path.GetDirectoryName(Path.GetFullPath(Ass.Location))));
if (!string.IsNullOrEmpty(SubFolder))
P = Path.Combine(P, SubFolder);
var FullPath = Path.Combine(P, Location);
if (File.Exists(FullPath))
return FullPath;
P = Ass.CodeBase;
var uri = new Uri(P);
string path = uri.LocalPath;
path = Path.GetDirectoryName(path);
string webserviceProgramFolder = Path.GetFullPath(path);
if (!string.IsNullOrEmpty(SubFolder))
webserviceProgramFolder = Path.Combine(webserviceProgramFolder, SubFolder);
webserviceProgramFolder = Path.Combine(webserviceProgramFolder, Location);
webserviceProgramFolder = Path.GetFullPath(webserviceProgramFolder);
if (File.Exists(webserviceProgramFolder))
{
FullPath = webserviceProgramFolder;
return webserviceProgramFolder;
}
}
catch { }
return null;
}
public static class RegistryHelper
{
public const int KEY_WOW64_32KEY = 0x200;
[DllImport("advapi32.dll", EntryPoint = "RegQueryInfoKey", CallingConvention = CallingConvention.Winapi, SetLastError = true)]
private static extern int RegQueryInfoKey(
UIntPtr hkey,
out StringBuilder lpClass,
ref uint lpcbClass,
IntPtr lpReserved,
out uint lpcSubKeys,
out uint lpcbMaxSubKeyLen,
out uint lpcbMaxClassLen,
out uint lpcValues,
out uint lpcbMaxValueNameLen,
out uint lpcbMaxValueLen,
out uint lpcbSecurityDescriptor,
ref FILETIME lpftLastWriteTime);
[DllImport("advapi32.dll", SetLastError = true)]
private static extern int RegCloseKey(UIntPtr hKey);
[DllImport("advapi32.dll", CharSet = CharSet.Auto)]
private static extern int RegOpenKeyEx(
UIntPtr hKey,
string subKey,
int ulOptions,
int samDesired,
out UIntPtr hkResult);
private static DateTime ToDateTime(FILETIME ft)
{
IntPtr buf = IntPtr.Zero;
try
{
long[] longArray = new long[1];
int cb = Marshal.SizeOf(ft);
buf = Marshal.AllocHGlobal(cb);
Marshal.StructureToPtr(ft, buf, false);
Marshal.Copy(buf, longArray, 0, 1);
return DateTime.FromFileTime(longArray[0]);
}
finally
{
if (buf != IntPtr.Zero) Marshal.FreeHGlobal(buf);
}
}
public static DateTime? GetDateModified(RegistryHive registryHive, string path, bool use32Bit)
{
var lastModified = new FILETIME();
var lpcbClass = new uint();
var lpReserved = new IntPtr();
UIntPtr key = UIntPtr.Zero;
try
{
try
{
int samDesired = (int)RegistryRights.ReadKey;
if (use32Bit)
samDesired |= KEY_WOW64_32KEY;
var hive = new UIntPtr(unchecked((uint)registryHive));
if (RegOpenKeyEx(hive, path, 0, samDesired, out key) != 0)
{
return null;
}
if (RegQueryInfoKey(
key,
out StringBuilder sb,
ref lpcbClass,
lpReserved,
out uint lpcbSubKeys,
out uint lpcbMaxKeyLen,
out uint lpcbMaxClassLen,
out uint lpcValues,
out uint maxValueName,
out uint maxValueLen,
out uint securityDescriptor,
ref lastModified) != 0)
{
return null;
}
var result = ToDateTime(lastModified);
return result;
}
finally
{
if (key != UIntPtr.Zero)
RegCloseKey(key);
}
}
catch (Exception ex)
{
LogException(ex);
return null;
}
}
}
private void CreateIntrinsicModules()
{
if (!IsIntrinsic)
return;
if (this.Modules == null)
this.Modules = new Dictionary<Guid, cC4itLicenseBaseModule>(2);
var _mod = new cC4itLicenseBaseModule()
{
Name = cDataHistoryCollectorClientAgent.constConnectorName,
Id = new Guid(cDataHistoryCollectorClientAgent.constLicenseId)
};
this.Modules.Add(_mod.Id,_mod);
_mod = new cC4itLicenseBaseModule()
{
Name = cDataHistoryCollectorActiveDirectory.constConnectorName,
Id = new Guid(cDataHistoryCollectorActiveDirectory.constLicenseId)
};
this.Modules.Add(_mod.Id, _mod);
}
static public void CheckLicense(object sender, System.Timers.ElapsedEventArgs e)
{
var strLicPath = cF4SDLicense.GetProgramFolderLocation(Assembly.GetCallingAssembly(), "..\\License", "F4SD_License.xml");
if (!File.Exists(strLicPath))
strLicPath = cF4SDLicense.GetProgramFolderLocation(Assembly.GetCallingAssembly(), "License", "F4SD_License.xml");
if (File.Exists(strLicPath))
{
var Lic = new cF4SDLicense();
if (Lic.LoadFromFile(strLicPath, false))
cF4SDLicense.Instance = Lic;
}
if (cF4SDLicense.Instance.IsIntrinsic)
cLogManager.DefaultLogger.LogEntry(LogLevels.Info, $"Intrinsic license set");
}
static public List<string> LogLicenseState()
{
var s = new List<string>();
var _lic = Instance;
if (_lic == null)
return null;
if (_lic.IsIntrinsic)
s.Add("The F4SD license is intrinsic.");
if (_lic.IsValid && _lic.licenseType == LicenseType.productive)
s.Add("The F4SD License is valid.");
else if (_lic.IsValid)
s.Add($"The F4SD License is valid only for {_lic.licenseType.ToString().ToLowerInvariant()} purposes.");
else
s.Add("The F4SD License is invalid.");
if (_lic.IsValid || _lic.IsExpired)
{
s.Add($" Customer:{_lic.Customer}");
if (_lic.EndDate == null)
s.Add($" valid until: everytime");
else
s.Add($" valid until: {(DateTime)_lic.EndDate}");
if (_lic.LicenseMetrics != null)
s.Add($" license count {_lic.LicenseMetrics.Count}");
}
s.Add("");
s.Add("Licensed modules:");
if (_lic.Modules == null || _lic.Modules.Count == 0)
s.Add("- none -");
else
foreach (var _mod in _lic.Modules.Values)
s.Add($" {_mod.Name}");
return s;
}
}
}

View File

@@ -0,0 +1,119 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Web.Administration;
using C4IT.Logging;
using Microsoft.Win32;
using static C4IT.Logging.cLogManager;
namespace C4IT_DataHistoryProvider_Base
{
public static class IisConfigHelper
{
public static cIssConfiguration CheckIISConfiguration()
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _res = new cIssConfiguration();
CheckIISComponents(_res);
CheckIISConfiuration(_res);
return _res;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return null;
}
private static void CheckIISComponents(cIssConfiguration _issConfig)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _regBase = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64);
var _regKey = _regBase.OpenSubKey("SOFTWARE\\Microsoft\\InetStp\\Components", false);
if (_regKey != null)
{
var _regVal1 = _regKey.GetValue("WindowsAuthentication")?.ToString();
var _regVal2 = _regKey.GetValue("WindowsAuthenticationBinaries")?.ToString();
_issConfig.IsIssWindowsAuthenticationInstalled = _regVal1 == "1" && _regVal2 == "1";
var _regVal3 = _regKey.GetValue("WebSockets")?.ToString();
_issConfig.IsWebSocketInstalled = _regVal3 == "1";
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
private static void CheckIISConfiuration(cIssConfiguration _issConfig)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var _serverManager = new ServerManager();
var _siteCollections = _serverManager.Sites;
foreach (var _site in _siteCollections)
{
var _applications = _site.Applications;
foreach (var _application in _applications)
{
if (_application.Path.ToLowerInvariant() != "/f4sdcockpit")
continue;
var _appConfig = _application.GetWebConfiguration();
var _cfgWindowsAuthentication = _appConfig.GetSection("system.webServer/security/authentication/windowsAuthentication");
if (_cfgWindowsAuthentication != null)
{
var _attr = _cfgWindowsAuthentication.Attributes.FirstOrDefault(v => v.Name == "enabled");
if (_attr != null)
{
if (_attr.Value is bool _valWindowsAuthentication)
_issConfig.IsIssWindowsAuthenticationEnabled |= _valWindowsAuthentication;
}
}
}
}
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
}
}
public class cIssConfiguration
{
public bool IsIssWindowsAuthenticationInstalled = false;
public bool IsWebSocketInstalled = false;
public bool IsIssWindowsAuthenticationEnabled = false;
}
}

View File

@@ -0,0 +1,5 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
[assembly: ComVisible(false)]
[assembly: Guid("49452fc2-05ce-4077-8b40-8adf5eca212e")]

View File

@@ -0,0 +1,28 @@
using C4IT.FASD.Base;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace C4IT_DataHistoryProvider_Base.Services
{
public interface IStagedRelationService
{
/// <summary>
/// Triggers search for relations to given information objects.
/// </summary>
cF4sdStagedSearchResultRelationTaskId StartGatheringRelatedObjects(IEnumerable<cFasdApiSearchResultEntry> relatedTo, int ageInDays);
/// <summary>
/// Used after triggering search for related objects in <see cref="StartGatheringRelatedObjects"/> to retrieve the already found relations.
/// </summary>
/// <param name="id">Id returned by <see cref="StartGatheringRelatedObjects"/> to reference the results to a search term.</param>
Task<cF4sdStagedSearchResultRelations> GetRelatedObjectsAsync(Guid id, CancellationToken token);
/// <summary>
/// Cancels the gathering of related objects.
/// </summary>
/// <param name="id">Id returned by <see cref="StartGatheringRelatedObjects"/> to reference the gathering process.</param>
void StopGatheringRelatedObjects(Guid id);
}
}

View File

@@ -0,0 +1,168 @@
using C4IT.FASD.Base;
using C4IT.Logging;
using C4IT_DataHistoryProvider_Base.DataSources;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using static C4IT.Logging.cLogManager;
namespace C4IT_DataHistoryProvider_Base.Services
{
public class StagedRelationService : IStagedRelationService
{
private static readonly Dictionary<Guid, GatherRelatedObjectTask> _relationTasks = new Dictionary<Guid, GatherRelatedObjectTask>();
private readonly IEnumerable<ISearchResultRelationProvider> _providers;
private static readonly System.Timers.Timer _relationTaskCleanupTimer = new System.Timers.Timer(CleanupInterval);
private const int CleanupInterval = 5 * 60 * 1000;
private readonly TimeSpan RelationTaskExpiration = TimeSpan.FromMinutes(15);
public StagedRelationService(IEnumerable<ISearchResultRelationProvider> providers)
{
_providers = providers;
SetupCleanupTimer();
}
private void SetupCleanupTimer()
{
if (_relationTaskCleanupTimer.Enabled)
return;
_relationTaskCleanupTimer.Interval = CleanupInterval;
_relationTaskCleanupTimer.Elapsed += CleanUpRelationTasks;
_relationTaskCleanupTimer.Start();
}
public cF4sdStagedSearchResultRelationTaskId StartGatheringRelatedObjects(IEnumerable<cFasdApiSearchResultEntry> relatedTo, int age)
{
cF4sdStagedSearchResultRelationTaskId taskId = new cF4sdStagedSearchResultRelationTaskId();
try
{
if (relatedTo.Count() == 0)
return taskId;
GatherRelatedObjectTask relationTask = new GatherRelatedObjectTask() { RelatedObjectTasks = new List<(HashSet<enumFasdInformationClass> PendingInformationClasses, Task<cF4sdStagedSearchResultRelations> Task)>() };
enumFasdInformationClass relatedToInformationClass = cF4sdIdentityEntry.GetFromSearchResult(relatedTo.FirstOrDefault().Type);
List<cF4sdIdentityEntry> identities = relatedTo.Select(relation => new cF4sdIdentityEntry() { Id = relation.id, Class = relatedToInformationClass }).ToList();
foreach (var collectorModule in _providers)
{
taskId.PendingInformationClasses.UnionWith(collectorModule.GetSupportedInformationClasses());
Task<cF4sdStagedSearchResultRelations> task = Task.Run(() =>
collectorModule.GetRelationsAsync(identities, relatedToInformationClass, age, relationTask.TokenSource.Token));
relationTask.RelatedObjectTasks.Add((collectorModule.GetSupportedInformationClasses(), task));
}
taskId.Id = Guid.NewGuid();
_relationTasks.Add(taskId.Id, relationTask);
}
catch (Exception ex)
{
LogException(ex);
}
return taskId;
}
public async Task<cF4sdStagedSearchResultRelations> GetRelatedObjectsAsync(Guid id, CancellationToken token)
{
HashSet<enumFasdInformationClass> pendingInformationClasses = null;
try
{
if (!_relationTasks.TryGetValue(id, out var gatherRelatedTask))
{
LogEntry($"Could find any task find related objects with Id '{id}'", LogLevels.Info);
return null;
}
IEnumerable<Task<cF4sdStagedSearchResultRelations>> gatheringTasks = gatherRelatedTask.RelatedObjectTasks.Select(relatedObjectTask => relatedObjectTask.Task);
await Task.WhenAny(gatheringTasks);
lock (_relationTasks)
{
gatherRelatedTask.LastRetrievel = DateTime.UtcNow;
var completedTasks = gatherRelatedTask.RelatedObjectTasks.Where(t => t.Task.IsCompleted).ToArray();
foreach (var completedTask in completedTasks)
{
gatherRelatedTask.RelatedObjectTasks.Remove(completedTask);
}
pendingInformationClasses = new HashSet<enumFasdInformationClass>(gatherRelatedTask.RelatedObjectTasks.SelectMany(t => t.PendingInformationClasses));
var relations = completedTasks.SelectMany(t => t.Task.Result.Relations ?? Enumerable.Empty<cF4sdApiSearchResultRelation>());
return new cF4sdStagedSearchResultRelations() { Relations = relations, PendingInformationClasses = pendingInformationClasses };
}
}
catch (Exception ex)
{
LogException(ex);
}
finally
{
if (pendingInformationClasses?.Count == 0)
_relationTasks.Remove(id);
}
return new cF4sdStagedSearchResultRelations() { Relations = Enumerable.Empty<cF4sdApiSearchResultRelation>(), PendingInformationClasses = pendingInformationClasses };
}
public void StopGatheringRelatedObjects(Guid id)
{
try
{
if (!_relationTasks.TryGetValue(id, out var task))
return;
task.TokenSource.Cancel();
_relationTasks.Remove(id);
}
catch (Exception ex)
{
LogException(ex);
}
}
private void CleanUpRelationTasks(object sender, ElapsedEventArgs e)
{
try
{
DateTime currentTime = DateTime.UtcNow;
List<Guid> expiredTasks = new List<Guid>();
lock (_relationTasks)
{
foreach (var relationTask in _relationTasks)
{
if (currentTime - relationTask.Value.LastRetrievel < RelationTaskExpiration)
continue;
expiredTasks.Add(relationTask.Key);
}
expiredTasks.ForEach(task => _relationTasks.Remove(task));
}
}
catch (Exception ex)
{
LogException(ex);
}
}
private class GatherRelatedObjectTask
{
public CancellationTokenSource TokenSource { get; set; }
public DateTime LastRetrievel { get; set; }
public ICollection<(HashSet<enumFasdInformationClass> PendingInformationClasses, Task<cF4sdStagedSearchResultRelations> Task)> RelatedObjectTasks { get; set; }
public GatherRelatedObjectTask()
{
TokenSource = new CancellationTokenSource();
LastRetrievel = DateTime.UtcNow;
}
}
}
}

View File

@@ -0,0 +1,232 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Web;
using System.Threading.Tasks;
using C4IT.FASD.Base;
using C4IT.Logging;
using static C4IT.Logging.cLogManager;
using static C4IT.FASD.Base.cF4SDHealthCardRawData;
using System.Threading;
namespace C4IT.DataHistoryProvider
{
public class cSuccessorJob
{
public List<string> Tables = new List<string>();
public cF4SDHealthCardRawData data = null;
public Task<bool> task = null;
public CancellationToken Token = CancellationToken.None;
public bool Finished = false;
public DateTime FinishedTime;
public List<Int64> Usage = null;
}
public class SuccessorEntry : List<cSuccessorJob>
{
public List<Int64> UsageInfo = null;
}
public static class SuccessorCache
{
private static Timer _timerCache = new Timer(callbackTimerCache, null, 1000, 10000);
private static void callbackTimerCache(object state)
{
var myNow = DateTime.UtcNow;
lock (Cache)
{
var lstIds = new List<Guid>();
foreach (var Entry in Cache)
{
var lstJobs = new List<cSuccessorJob>();
foreach (var Job in Entry.Value)
{
if (Job.Finished && (myNow - Job.FinishedTime) > TimeSpan.FromSeconds(60))
lstJobs.Add(Job);
}
foreach (var Job in lstJobs)
Entry.Value.Remove(Job);
if (Entry.Value.Count == 0)
lstIds.Add(Entry.Key);
}
foreach (var id in lstIds)
Cache.Remove(id);
}
}
private static Dictionary<Guid, SuccessorEntry> Cache = new Dictionary<Guid, SuccessorEntry>();
public static bool AddTask(Guid Id, List<string> Tables, Task<List<cF4SDHealthCardRawData.cHealthCardTable>> task, List<Int64> UsageInfo, CancellationToken Token)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
try
{
var Job = new cSuccessorJob();
lock (Cache)
{
if (!Cache.TryGetValue(Id, out var lst))
{
lst = new SuccessorEntry() { Job };
Cache.Add(Id, lst);
}
else
lst.Add(Job);
if (UsageInfo != null)
lst.UsageInfo = UsageInfo;
}
Job.Tables = Tables;
Job.task = Task.Run<bool>(async () =>
{
try
{
var res = await task;
Dictionary<string, cHealthCardTable> tbls = null;
if (res != null)
tbls = res.ToDictionary(x => x.Name, x => x);
lock (Cache)
{
Job.task = null;
Job.data = new cF4SDHealthCardRawData()
{
Id = Id,
Tables = tbls
};
Job.Finished = true;
Job.FinishedTime = DateTime.UtcNow;
}
return true;
}
catch (Exception E)
{
LogException(E);
}
return false;
}, Token);
return true;
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (CM != null) LogMethodEnd(CM);
}
return false;
}
public static async Task<cF4SDHealthCardRawData> GetNextResult(cDataHistoryCollector Collector, Guid Id, bool noAwait, cF4sdWebRequestInfo requestInfo, int LogDeep)
{
MethodBase CM = null; if (cLogManager.DefaultLogger.IsDebug) { CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); }
if (cPerformanceLogger.IsActive && requestInfo != null) { if (CM == null) CM = MethodBase.GetCurrentMethod(); cPerformanceLogger.LogPerformanceStart(LogDeep, CM, requestInfo.id, requestInfo.created); }
var _startTime = DateTime.UtcNow;
try
{
var lstResults = new SuccessorEntry();
var lstTasks = new SuccessorEntry();
var lstWaitingTables = new List<string>();
lock (Cache)
{
if (!Cache.TryGetValue(Id, out var lstObj))
return null;
foreach (var Entry in lstObj)
{
if (Entry.Finished)
lstResults.Add(Entry);
else
{
lstTasks.Add(Entry);
lstWaitingTables.AddRange(Entry.Tables);
}
}
foreach (var Entry in lstResults)
lstObj.Remove(Entry);
}
if (lstTasks.Count == 0)
Cache.Remove(Id);
if (lstResults.Count > 0)
{
var RetVal = lstResults[0];
for (int i = 1; i < lstResults.Count; i++)
{
var res = lstResults[i];
if (res?.data?.Tables != null)
{
foreach (var Entry in res.data.Tables)
{
if (RetVal?.data?.Tables != null)
RetVal.data.Tables[Entry.Key] = Entry.Value;
else
{
}
}
}
else
{
}
}
foreach (var Table in lstWaitingTables)
{
var tbl = new cF4SDHealthCardRawData.cHealthCardTable()
{
Name = Table,
IsIncomplete = true,
};
if (RetVal?.data?.Tables != null)
RetVal.data.Tables[Table] = tbl;
}
// correct the result due to usage information
if (RetVal.data != null && lstTasks.UsageInfo != null)
cDataHistoryCollector.CorrectUsage(Collector, RetVal.data, lstTasks.UsageInfo);
return RetVal.data;
}
if (noAwait)
return null;
var arrTask = new Task<bool>[lstTasks.Count];
for (int i = 0; i < lstTasks.Count; i++)
arrTask[i] = lstTasks[i].task;
var tskFinished = await Task.WhenAny(arrTask);
return await GetNextResult(Collector, Id, true, requestInfo, LogDeep+1);
}
catch (Exception E)
{
LogException(E);
}
finally
{
if (cPerformanceLogger.IsActive && requestInfo != null) { cPerformanceLogger.LogPerformanceEnd(LogDeep, CM, requestInfo.id, requestInfo.created, _startTime); }
if (CM != null) LogMethodEnd(CM);
}
return null;
}
}
}

View File

@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Memory" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.2" newVersion="4.0.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Encodings.Web" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.0" newVersion="8.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.ValueTuple" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Threading.Tasks.Extensions" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.2.0.1" newVersion="4.2.0.1" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Bcl.AsyncInterfaces" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-7.0.0.0" newVersion="7.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Buffers" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.3.0" newVersion="4.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Runtime.CompilerServices.Unsafe" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.3.0" newVersion="6.0.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Text.Json" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-8.0.0.5" newVersion="8.0.0.5" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>