- update multiple LIAM projects and solution/config files - add LiamWorkflowDiagnostics app sources and generated outputs - include current workspace state (dependencies and build outputs)
1891 lines
79 KiB
C#
1891 lines
79 KiB
C#
using System;
|
|
using System.Reflection;
|
|
using System.Threading.Tasks;
|
|
using System.Web.Http;
|
|
using System.Data;
|
|
using System.Collections.Generic;
|
|
using System.Xml;
|
|
using System.IO;
|
|
|
|
using Newtonsoft.Json;
|
|
|
|
using Matrix42.Common;
|
|
using update4u.SPS.DataLayer;
|
|
using update4u.SPS.Security;
|
|
|
|
using C4IT.Logging;
|
|
using static C4IT.Logging.cLogManager;
|
|
using System.Web.Http.Controllers;
|
|
using C4IT.Matrix42.ServerInfo;
|
|
using System.Dynamic;
|
|
using C4IT.Licensing;
|
|
using System.ComponentModel;
|
|
using System.Linq;
|
|
using System.Globalization;
|
|
using System.Data.SqlClient;
|
|
using System.Net.Sockets;
|
|
using update4u.SPS.DataLayer.Command;
|
|
using update4u.SPS.DataLayer.Transaction;
|
|
using System.Net.Http;
|
|
using System.Net;
|
|
using System.Text;
|
|
using System.Net.Http.Headers;
|
|
using Matrix42.Pandora.Contracts.Action;
|
|
|
|
namespace C4IT.LIAM
|
|
{
|
|
public static class cLiamM42Helper
|
|
{
|
|
public static dynamic ToDynamic(this object value)
|
|
{
|
|
IDictionary<string, object> expando = new ExpandoObject();
|
|
|
|
foreach (PropertyDescriptor property in TypeDescriptor.GetProperties(value.GetType()))
|
|
expando.Add(property.Name, property.GetValue(value));
|
|
|
|
return expando as ExpandoObject;
|
|
}
|
|
}
|
|
|
|
[RoutePrefix("api/C4ITLiamWebApi")]
|
|
public class LiamM42WebApiController : ApiController
|
|
{
|
|
public const string LiamProductGuid = "28757DE2-690F-4D3B-9AB7-4AB7FB630901";
|
|
|
|
public const string constFragmentNameDataAreaTargetPickupType = "C4IT_DataAreaTargetPickupType";
|
|
|
|
public const string constFragmentNameDataAreaMain = "C4IT_DataAreaClassBase";
|
|
public const string constFragmentNameConfigProviderMain = "C4IT_GCC_DataArea_Collector";
|
|
public const string constFragmentNameAddonConfigClassBase = "C4IT_AddonConfigClassBase";
|
|
public const string constFragmentNameConfigProviderBase = "SPSGenericConnectorConfigurationClassBase";
|
|
public const string constFragmentNameConfigProviderAdditionalAttributes = "C4IT_GCC_DataArea_Collector_AdditionalAttributes";
|
|
public const string constFragmentNameCustomTagBase = "C4IT_DataAreaCustomTagClassBase";
|
|
public const string constFragmentNameNamingConvention = "C4IT_LIAMNamingConvention";
|
|
public const string constFragmentNameConfigNamingConvention = "C4IT_LIAMConfigNamingConvention";
|
|
public const string constTypeNameConfigProvider = "C4IT_GCC_DataAreaCollectorType";
|
|
public const string constFragmentNameAccountAd = "SPSAccountClassAD";
|
|
public const string constFragmentNameAccountBase = "SPSAccountClassBase";
|
|
public const string constFragmentNameUserBase = "SPSUserClassBase";
|
|
public const string constFragmentNameCommon = "SPSCommonClassBase";
|
|
public const string constFragmentNameSVCServiceBookingClassBase = "SVCServiceBookingClassBase";
|
|
public const string sqlCSVBookingData = @"
|
|
select
|
|
da.technicalName as TechnicalName, -- TechnicalName
|
|
s.Name as ServiceName, -- ServiceName
|
|
u.LastName + ', ' + u.FirstName as ConsumerName, -- ConsumerName
|
|
a.NBAccountName as AccountName,
|
|
s.ArticleID, -- ArticleID
|
|
o.TicketNumber as OrderNumber, -- OrderNumber
|
|
b.BookingID, -- BookingID
|
|
b.ProvisionedDate, -- ProvisionedDate
|
|
da.ID as ID_noexport, -- Technisch notwendig, wird aber nicht exportiert
|
|
b.Uninstalled as Deprovisioned,
|
|
bu.ProvisionedDate as DeProvisioningDate
|
|
from SVCServiceBookingClassBase b WITH (NOLOCK)
|
|
left join SPSSelfServiceOrderItemClassBase o WITH (NOLOCK) on o.ID = b.[Order]
|
|
left join SVCServiceBookingClassBase bu on bu.InstallationBooking = b.ID
|
|
left join SPSArticleClassBase s WITH (NOLOCK) on b.[Service] = s.ID
|
|
left join SPSCommonClassBase sf WITH (NOLOCK) on s.ServiceForm = sf.ID
|
|
left join C4IT_DataAreaServiceConfigurationClassBase sc WITH (NOLOCK) on sc.[Expression-ObjectID] = sf.[Expression-ObjectID]
|
|
left join C4IT_DataAreaSecurityGroupClassBase sg WITH (NOLOCK) on sc.SecurityGroup = sg.ID
|
|
left join C4IT_DataAreaClassBase da WITH (NOLOCK) on (da.[Read] = sg.ID OR da.Write = sg.ID OR da.[Owner] = sg.ID)
|
|
left join SPSUserClassBase u WITH (NOLOCK) on b.Consumer = u.ID
|
|
left join SPSTargetingClassTarget t on b.[Target] = t.ID
|
|
left join SPSAccountClassAD a on a.[Expression-ObjectID] = t.[Expression-ObjectID]
|
|
where ";
|
|
|
|
|
|
private static readonly Dictionary<Guid, ProviderCacheEntry> ProviderCacheByID = new Dictionary<Guid, ProviderCacheEntry>();
|
|
private static readonly Dictionary<Guid, ProviderCacheEntry> ProviderCacheByObjectID = new Dictionary<Guid, ProviderCacheEntry>();
|
|
|
|
public static bool IsInitialized { get; private set; } = false;
|
|
|
|
private static readonly object initLock = new object();
|
|
|
|
protected override void Initialize(HttpControllerContext controllerContext)
|
|
{
|
|
base.Initialize(controllerContext);
|
|
try
|
|
{
|
|
if (IsInitialized)
|
|
return;
|
|
|
|
lock (initLock)
|
|
{
|
|
if (IsInitialized)
|
|
return;
|
|
|
|
var Ass = Assembly.GetExecutingAssembly();
|
|
var LM = cLogManagerFile.CreateInstance(LocalMachine: true, A: Ass);
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
cLogManager.DefaultLogger.LogAssemblyInfo(Ass);
|
|
IsInitialized = true;
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
catch { }
|
|
}
|
|
|
|
[HttpGet]
|
|
[Route("loadLicense")]
|
|
public bool LoadLicensingInformation(bool force = false)
|
|
{
|
|
if (force)
|
|
cC4ITLicenseM42ESM.Instance = null;
|
|
|
|
if (cC4ITLicenseM42ESM.Instance == null)
|
|
{
|
|
new cC4ITLicenseM42ESM(new Guid(LiamProductGuid));
|
|
var strLicense = getLicenseString();
|
|
if (!string.IsNullOrEmpty(strLicense))
|
|
cC4ITLicenseM42ESM.Instance.LoadFromString(strLicense);
|
|
}
|
|
return cC4ITLicenseM42ESM.Instance.IsValid;
|
|
}
|
|
|
|
private string getLicenseString()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameAddonConfigClassBase);
|
|
LogEntry($"Addon Config class ID: {ClassID}", LogLevels.Debug);
|
|
var dataTable = FragmentRequest.SimpleLoad(ClassID, "license", "UsedInTypeC4IT_LIAMConfigurationType is not null");
|
|
if (dataTable?.Rows == null || dataTable.Rows.Count <= 0)
|
|
{
|
|
LogEntry($"Addon Config fragment not found: ClassID={ClassID}", LogLevels.Debug);
|
|
return null;
|
|
}
|
|
var license = cLIAMHelper.getStringFromObject(dataTable.Rows[0]["license"]);
|
|
LogEntry($"Addon Config license: {license}", LogLevels.Debug);
|
|
return license;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
// Neue Methode
|
|
[HttpPost]
|
|
[Route("getCSVBookingData")]
|
|
public HttpResponseMessage getCSVBookingData(ActionExecuteData actionExecuteData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
var csvBuilder = new StringBuilder();
|
|
string serviceNameForFile = string.Empty;
|
|
var distinctDataAreaIds = new HashSet<Guid>();
|
|
try
|
|
{
|
|
if (actionExecuteData?.Objects == null || actionExecuteData.Objects.Length == 0)
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.BadRequest)
|
|
{
|
|
Content = new StringContent("Keine ObjectIds übergeben.")
|
|
};
|
|
}
|
|
List<Guid> dataAreaIds = new List<Guid>();
|
|
foreach (ActionExecuteDataEntry entry in actionExecuteData.Objects)
|
|
{
|
|
if (entry.ObjectIds != null)
|
|
{
|
|
dataAreaIds.AddRange(entry.ObjectIds);
|
|
}
|
|
}
|
|
if (dataAreaIds.Count == 0)
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.BadRequest)
|
|
{
|
|
Content = new StringContent("Keine gültigen ObjectIds gefunden.")
|
|
};
|
|
}
|
|
var parameterNames = new List<string>();
|
|
for (int i = 0; i < dataAreaIds.Count; i++)
|
|
{
|
|
parameterNames.Add($"@dataareaid{i}");
|
|
}
|
|
string whereClause = "da.[Expression-ObjectId] IN (" + string.Join(", ", parameterNames) + ")";
|
|
string sqlQuery = sqlCSVBookingData + whereClause;
|
|
using (var sqlCommand = new SqlCommand(sqlQuery))
|
|
{
|
|
for (int i = 0; i < dataAreaIds.Count; i++)
|
|
{
|
|
sqlCommand.Parameters.AddWithValue($"@dataareaid{i}", dataAreaIds[i]);
|
|
}
|
|
using (var sPSTransactionScope = new SPSTransactionScope()) using (IDataReader dataReader = DirectDbCommand.ExecuteReader(sqlCommand))
|
|
{ // Spaltennamen ermitteln, Spalten mit '_noexport' ausschließen
|
|
var columnNames = new List<string>();
|
|
for (int i = 0; i < dataReader.FieldCount; i++)
|
|
{
|
|
string columnName = dataReader.GetName(i);
|
|
if (!columnName.EndsWith("_noexport"))
|
|
{
|
|
columnNames.Add(columnName);
|
|
}
|
|
} // CSV-Header erstellen
|
|
csvBuilder.AppendLine("sep=;");
|
|
csvBuilder.AppendLine(string.Join(";", columnNames));
|
|
bool isFirstRow = true;
|
|
while (dataReader.Read())
|
|
{ // Zugriff auf 'ID_noexport' für interne Logik, ohne Export
|
|
if (dataReader["ID_noexport"] != DBNull.Value)
|
|
{
|
|
distinctDataAreaIds.Add((Guid)dataReader["ID_noexport"]);
|
|
}
|
|
if (isFirstRow)
|
|
{
|
|
if (dataReader["ServiceName"] != DBNull.Value)
|
|
{
|
|
serviceNameForFile = dataReader["ServiceName"].ToString();
|
|
}
|
|
isFirstRow = false;
|
|
} // Werte nur der exportierten Spalten sammeln
|
|
var rowValues = new List<string>();
|
|
foreach (var columnName in columnNames)
|
|
{
|
|
var value = dataReader[columnName];
|
|
var stringValue = value == DBNull.Value ? string.Empty : value.ToString();
|
|
rowValues.Add(EscapeForCsv(stringValue));
|
|
}
|
|
csvBuilder.AppendLine(string.Join(";", rowValues));
|
|
}
|
|
sPSTransactionScope.Complete();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
|
|
{
|
|
Content = new StringContent("Fehler bei der Verarbeitung der Anfrage.")
|
|
};
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
} // Dateinamen erstellen
|
|
string fileName;
|
|
if (distinctDataAreaIds.Count == 1)
|
|
{
|
|
int index = serviceNameForFile.IndexOf('[');
|
|
if (index > 0)
|
|
{
|
|
serviceNameForFile = serviceNameForFile.Substring(0, index).TrimEnd(' ', '-');
|
|
}
|
|
var safeServiceName = CleanFileName(serviceNameForFile);
|
|
fileName = $"Servicebuchungen_{safeServiceName}_{DateTime.Now:yyyyMMdd}.csv";
|
|
}
|
|
else
|
|
{
|
|
fileName = $"Servicebuchungen_{DateTime.Now:yyyyMMdd}.csv";
|
|
}
|
|
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
Content = new StringContent(csvBuilder.ToString(), Encoding.UTF8, "text/csv")
|
|
};
|
|
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
|
{
|
|
FileName = fileName
|
|
};
|
|
return response;
|
|
}
|
|
/* Neue Methode
|
|
[HttpPost]
|
|
[Route("getCSVBookingData")]
|
|
public HttpResponseMessage getCSVBookingData(ActionExecuteData actionExecuteData)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
var csvBuilder = new StringBuilder();
|
|
string serviceNameForFile = string.Empty;
|
|
var distinctDataAreaIds = new HashSet<Guid>();
|
|
|
|
try
|
|
{
|
|
if (actionExecuteData?.Objects == null || actionExecuteData.Objects.Length == 0)
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.BadRequest)
|
|
{
|
|
Content = new StringContent("Keine ObjectIds übergeben.")
|
|
};
|
|
}
|
|
|
|
List<Guid> dataAreaIds = new List<Guid>();
|
|
foreach (ActionExecuteDataEntry entry in actionExecuteData.Objects)
|
|
{
|
|
if (entry.ObjectIds != null)
|
|
{
|
|
dataAreaIds.AddRange(entry.ObjectIds);
|
|
}
|
|
}
|
|
|
|
if (dataAreaIds.Count == 0)
|
|
{
|
|
return new HttpResponseMessage(HttpStatusCode.BadRequest)
|
|
{
|
|
Content = new StringContent("Keine gültigen ObjectIds gefunden.")
|
|
};
|
|
}
|
|
|
|
var parameterNames = new List<string>();
|
|
for (int i = 0; i < dataAreaIds.Count; i++)
|
|
{
|
|
parameterNames.Add($"@dataareaid{i}");
|
|
}
|
|
string whereClause = "da.[Expression-ObjectID] IN (" + string.Join(", ", parameterNames) + ")";
|
|
string sqlQuery = sqlCSVBookingData + whereClause;
|
|
|
|
// CSV-Aufbau
|
|
var columnNames = new List<string>();
|
|
bool headerWritten = false;
|
|
bool firstRow = true;
|
|
|
|
DirectDbCommand.ExecuteReader(
|
|
dbCmd =>
|
|
{
|
|
dbCmd.CommandText = sqlQuery;
|
|
|
|
for (int i = 0; i < dataAreaIds.Count; i++)
|
|
{
|
|
var p = dbCmd.CreateParameter();
|
|
p.ParameterName = $"@dataareaid{i}";
|
|
p.DbType = DbType.Guid;
|
|
p.Value = dataAreaIds[i];
|
|
dbCmd.Parameters.Add(p);
|
|
}
|
|
},
|
|
reader =>
|
|
{
|
|
// Header einmalig aus dem ersten gelesenen Datensatz ableiten
|
|
if (!headerWritten)
|
|
{
|
|
for (int i = 0; i < reader.FieldCount; i++)
|
|
{
|
|
var name = reader.GetName(i);
|
|
if (!name.EndsWith("_noexport", StringComparison.OrdinalIgnoreCase))
|
|
columnNames.Add(name);
|
|
}
|
|
|
|
csvBuilder.AppendLine("sep=;");
|
|
csvBuilder.AppendLine(string.Join(";", columnNames));
|
|
headerWritten = true;
|
|
}
|
|
|
|
// interne Logik mit ID_noexport (wird nicht exportiert)
|
|
int idxNoExport = reader.GetOrdinal("ID_noexport");
|
|
if (!reader.IsDBNull(idxNoExport))
|
|
distinctDataAreaIds.Add(reader.GetGuid(idxNoExport));
|
|
|
|
// Dateiname: ServiceName aus erster Zeile merken
|
|
if (firstRow)
|
|
{
|
|
int idxServiceName = reader.GetOrdinal("ServiceName");
|
|
if (!reader.IsDBNull(idxServiceName))
|
|
serviceNameForFile = reader.GetString(idxServiceName);
|
|
firstRow = false;
|
|
}
|
|
|
|
// Werte der exportierten Spalten schreiben
|
|
var rowValues = new List<string>(columnNames.Count);
|
|
foreach (var col in columnNames)
|
|
{
|
|
var val = reader[col];
|
|
rowValues.Add(EscapeForCsv(val == DBNull.Value ? string.Empty : Convert.ToString(val)));
|
|
}
|
|
csvBuilder.AppendLine(string.Join(";", rowValues));
|
|
}
|
|
);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
return new HttpResponseMessage(HttpStatusCode.InternalServerError)
|
|
{
|
|
Content = new StringContent("Fehler bei der Verarbeitung der Anfrage.")
|
|
};
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
|
|
// Dateinamen erstellen
|
|
string fileName;
|
|
if (distinctDataAreaIds.Count == 1)
|
|
{
|
|
int index = serviceNameForFile.IndexOf('[');
|
|
if (index > 0)
|
|
{
|
|
serviceNameForFile = serviceNameForFile.Substring(0, index).TrimEnd(' ', '-');
|
|
}
|
|
var safeServiceName = CleanFileName(serviceNameForFile);
|
|
fileName = $"Servicebuchungen_{safeServiceName}_{DateTime.Now:yyyyMMdd}.csv";
|
|
}
|
|
else
|
|
{
|
|
fileName = $"Servicebuchungen_{DateTime.Now:yyyyMMdd}.csv";
|
|
}
|
|
|
|
var response = new HttpResponseMessage(HttpStatusCode.OK)
|
|
{
|
|
Content = new StringContent(csvBuilder.ToString(), Encoding.UTF8, "text/csv")
|
|
};
|
|
|
|
response.Content.Headers.ContentDisposition = new ContentDispositionHeaderValue("attachment")
|
|
{
|
|
FileName = fileName
|
|
};
|
|
|
|
return response;
|
|
}
|
|
*/
|
|
|
|
// Hilfsmethoden
|
|
private string EscapeForCsv(string field)
|
|
{
|
|
if (field.Contains(";") || field.Contains("\"") || field.Contains("\n") || field.Contains("\r"))
|
|
{
|
|
field = field.Replace("\"", "\"\"");
|
|
field = $"\"{field}\"";
|
|
}
|
|
return field;
|
|
}
|
|
|
|
private string CleanFileName(string fileName)
|
|
{
|
|
foreach (char c in Path.GetInvalidFileNameChars())
|
|
{
|
|
fileName = fileName.Replace(c.ToString(), string.Empty);
|
|
}
|
|
return fileName;
|
|
}
|
|
|
|
|
|
private cLiamProviderBase CreateProviderInstance(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData)
|
|
{
|
|
LoadLicensingInformation();
|
|
ProviderData.ReplaceCustomTags();
|
|
switch (ProviderData.ProviderType)
|
|
{
|
|
case eLiamProviderTypes.MsTeams:
|
|
return new cLiamProviderMsTeams(LiamConfiguration, ProviderData);
|
|
case eLiamProviderTypes.Ntfs:
|
|
return new cLiamProviderNtfs(LiamConfiguration, ProviderData);
|
|
case eLiamProviderTypes.ActiveDirectory:
|
|
return new cLiamProviderAD(LiamConfiguration, ProviderData);
|
|
}
|
|
return null;
|
|
}
|
|
|
|
private static ProviderCacheEntry AddCache(Guid ID, Guid ObjectID, cLiamProviderBase Provider)
|
|
{
|
|
var Entry = new ProviderCacheEntry()
|
|
{
|
|
ID = ID,
|
|
ObjectID = ObjectID,
|
|
ValidUntil = DateTime.UtcNow + TimeSpan.FromMinutes(15),
|
|
Provider = Provider
|
|
};
|
|
|
|
ProviderCacheByID[ID] = Entry;
|
|
ProviderCacheByObjectID[ObjectID] = Entry;
|
|
|
|
return Entry;
|
|
}
|
|
|
|
private static ProviderCacheEntry GetCacheByID(Guid ID)
|
|
{
|
|
if (!ProviderCacheByID.TryGetValue(ID, out var Entry))
|
|
return null;
|
|
|
|
if (Entry.ValidUntil < DateTime.UtcNow)
|
|
{
|
|
ProviderCacheByID.Remove(ID);
|
|
ProviderCacheByObjectID.Remove(Entry.ObjectID);
|
|
return null;
|
|
}
|
|
|
|
return Entry;
|
|
}
|
|
|
|
private static ProviderCacheEntry GetCacheByObjectID(Guid ObjectID)
|
|
{
|
|
if (!ProviderCacheByObjectID.TryGetValue(ObjectID, out var Entry))
|
|
return null;
|
|
|
|
if (Entry.ValidUntil < DateTime.UtcNow)
|
|
{
|
|
ProviderCacheByID.Remove(Entry.ID);
|
|
ProviderCacheByObjectID.Remove(ObjectID);
|
|
return null;
|
|
}
|
|
|
|
return Entry;
|
|
}
|
|
|
|
[Route("getVersionInfo"), HttpGet]
|
|
public LiamApiVersionInfo getVersionInfo()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
var RetVal = new LiamApiVersionInfo();
|
|
try
|
|
{
|
|
var A = Assembly.GetExecutingAssembly();
|
|
RetVal.ProductVersion = A.GetCustomAttribute<AssemblyInformationalVersionAttribute>()?.InformationalVersion;
|
|
RetVal.AssemblyVersion = A.GetName().Version.ToString();
|
|
RetVal.ProductName = A.GetCustomAttribute<AssemblyProductAttribute>()?.Product;
|
|
RetVal.AssemblyName = A.ManifestModule.ToString();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
return RetVal;
|
|
}
|
|
|
|
private bool TryLoadProviderFragments(Guid providerConfigClassID, out Guid objectId, out DataTable tblMain, out DataTable tblBase, out DataTable tblAdditionalAttr, out DataTable tblNamingConvention, out DataTable tblCustomTags)
|
|
{
|
|
objectId = Guid.Empty;
|
|
tblMain = null;
|
|
tblBase = null;
|
|
tblAdditionalAttr = null;
|
|
tblNamingConvention = null;
|
|
tblCustomTags = null;
|
|
|
|
try
|
|
{
|
|
var classID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameConfigProviderMain);
|
|
LogEntry($"Config provider class ID: {classID}", LogLevels.Debug);
|
|
var fragment = FragmentRequest.GetSPSFragment(classID, providerConfigClassID);
|
|
if (fragment == null)
|
|
{
|
|
LogEntry($"Provider config fragment not found: ClassID={classID}, FragmentId={providerConfigClassID}", LogLevels.Debug);
|
|
return false;
|
|
}
|
|
|
|
objectId = fragment.ObjectID;
|
|
if (objectId == Guid.Empty)
|
|
{
|
|
LogEntry($"Provider config fragment not found: ClassID={classID}, FragmentId={providerConfigClassID}", LogLevels.Debug);
|
|
return false;
|
|
}
|
|
|
|
tblMain = fragment.FragmentTable;
|
|
LogEntry($"Config provider object ID: {objectId}", LogLevels.Debug);
|
|
|
|
classID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameConfigProviderBase);
|
|
LogEntry($"Config provider base class ID: {classID}", LogLevels.Debug);
|
|
|
|
Guid[] ids = { objectId };
|
|
tblBase = FragmentRequestBase.SimpleLoad(classID,
|
|
"Account, Password",
|
|
AsqlHelper.BuildInCondition("[Expression-ObjectID]", ids));
|
|
if (tblBase?.Rows == null || tblBase.Rows.Count <= 0)
|
|
{
|
|
LogEntry($"Provider config base fragment not found: ClassId={classID}, ObjectId={objectId}", LogLevels.Debug);
|
|
return false;
|
|
}
|
|
|
|
classID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameConfigProviderAdditionalAttributes);
|
|
LogEntry($"Config provider additional config class ID: {classID}", LogLevels.Debug);
|
|
tblAdditionalAttr = FragmentRequestBase.SimpleLoad(classID,
|
|
"Name, Value",
|
|
AsqlHelper.BuildInCondition("[Expression-ObjectID]", ids));
|
|
if (tblAdditionalAttr == null)
|
|
{
|
|
LogEntry($"Provider additional config class fragment not found: ClassId={classID}, ObjectId={objectId}", LogLevels.Debug);
|
|
return false;
|
|
}
|
|
|
|
classID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameCustomTagBase);
|
|
LogEntry($"Custom Tag class ID: {classID}", LogLevels.Debug);
|
|
tblCustomTags = FragmentRequestBase.SimpleLoad(classID, "Key, Name", $"[Expression-ObjectID]='{objectId}'") ?? new DataTable();
|
|
|
|
classID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameConfigNamingConvention);
|
|
LogEntry($"Naming convention config class ID: {classID}", LogLevels.Debug);
|
|
tblNamingConvention = FragmentRequestBase.SimpleLoad(classID,
|
|
"ID, Usage, NamingConvention.Description as Description, NamingConvention.DescriptionTemplate as DescriptionTemplate, " +
|
|
"NamingConvention.Name as Name, NamingConvention.NamingTemplate as NamingTemplate, NamingConvention.Wildcard as Wildcard",
|
|
$"[Expression-ObjectID]='{objectId}'") ?? new DataTable();
|
|
|
|
return true;
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
LogException(e);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
private cLiamProviderData buildProviderData(DataTable dtMain, DataTable dtBase, DataTable dtAdditional, DataTable dtNamingConvention, DataTable dtCustomTag, bool includeSecret, out string sanitizedJson)
|
|
{
|
|
sanitizedJson = null;
|
|
if (dtMain?.Rows == null || dtMain.Rows.Count <= 0)
|
|
return null;
|
|
if (dtBase?.Rows == null || dtBase.Rows.Count <= 0)
|
|
return null;
|
|
if (dtAdditional == null)
|
|
return null;
|
|
|
|
var dataMain = dtMain.Rows[0];
|
|
var dataBase = dtBase.Rows[0];
|
|
|
|
var encPW = cLIAMHelper.getStringFromObject(dataBase["Password"]);
|
|
if (!CryptoManager.Instance.TryDecryptDBText(encPW, out string password))
|
|
password = encPW;
|
|
|
|
var providerData = new cLiamProviderData()
|
|
{
|
|
Domain = cLIAMHelper.getStringFromObject(dataMain["GCCDomain"]),
|
|
Credential = new cLiamCredential()
|
|
{
|
|
Domain = cLIAMHelper.getStringFromObject(dataMain["GCCDomain"]),
|
|
Identification = cLIAMHelper.getStringFromObject(dataBase["Account"]),
|
|
Secret = "***"
|
|
},
|
|
RootPath = cLIAMHelper.getStringFromObject(dataMain["GCCTarget"]),
|
|
MaxDepth = cLIAMHelper.getIntFromObject(dataMain["GCCMaxDepth"]),
|
|
GroupFilter = cLIAMHelper.getStringFromObject(dataMain["GCCgroupLDAPFilter"]),
|
|
GroupPath = cLIAMHelper.getStringFromObject(dataMain["GCCgroupOUPath"]),
|
|
GroupStrategy = (eLiamGroupStrategies)cLIAMHelper.getIntFromObject(dataMain["GCCPermissionGroupStrategy"]),
|
|
ProviderType = (eLiamProviderTypes)cLIAMHelper.getIntFromObject(dataMain["GCCtargetType"])
|
|
};
|
|
|
|
if (dtAdditional?.Rows != null)
|
|
{
|
|
foreach (DataRow row in dtAdditional.Rows)
|
|
{
|
|
var name = cLIAMHelper.getStringFromObject(row["Name"]);
|
|
var value = cLIAMHelper.getStringFromObject(row["Value"]);
|
|
if (!string.IsNullOrEmpty(name))
|
|
providerData.AdditionalConfiguration[name] = value;
|
|
}
|
|
}
|
|
|
|
if (dtCustomTag?.Rows != null)
|
|
{
|
|
foreach (DataRow row in dtCustomTag.Rows)
|
|
{
|
|
var name = cLIAMHelper.getStringFromObject(row["Key"]);
|
|
var value = cLIAMHelper.getStringFromObject(row["Name"]);
|
|
if (!string.IsNullOrEmpty(name))
|
|
providerData.CustomTags[name] = value;
|
|
}
|
|
}
|
|
|
|
if (dtNamingConvention?.Rows != null)
|
|
{
|
|
foreach (DataRow row in dtNamingConvention.Rows)
|
|
{
|
|
var usage = cLIAMHelper.getIntFromObject(row["Usage"]);
|
|
var accessRole = eLiamAccessRoles.Read;
|
|
var scope = eLiamAccessRoleScopes.Unknown;
|
|
switch (usage)
|
|
{
|
|
case -10:
|
|
accessRole = eLiamAccessRoles.Traverse;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 10:
|
|
accessRole = eLiamAccessRoles.Read;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 20:
|
|
accessRole = eLiamAccessRoles.Write;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 30:
|
|
accessRole = eLiamAccessRoles.Owner;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 40:
|
|
accessRole = eLiamAccessRoles.Read;
|
|
scope = eLiamAccessRoleScopes.DomainLocal;
|
|
break;
|
|
case 50:
|
|
accessRole = eLiamAccessRoles.Write;
|
|
scope = eLiamAccessRoleScopes.DomainLocal;
|
|
break;
|
|
case 60:
|
|
accessRole = eLiamAccessRoles.Owner;
|
|
scope = eLiamAccessRoleScopes.DomainLocal;
|
|
break;
|
|
case 100:
|
|
accessRole = eLiamAccessRoles.ADOwner;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 110:
|
|
accessRole = eLiamAccessRoles.ADMember;
|
|
scope = eLiamAccessRoleScopes.Global;
|
|
break;
|
|
case 200:
|
|
accessRole = eLiamAccessRoles.ExchangeMLMember;
|
|
scope = eLiamAccessRoleScopes.Universal;
|
|
break;
|
|
case 210:
|
|
accessRole = eLiamAccessRoles.ExchangeMLOwner;
|
|
scope = eLiamAccessRoleScopes.Universal;
|
|
break;
|
|
case 250:
|
|
accessRole = eLiamAccessRoles.ExchangeSMBFullAccess;
|
|
scope = eLiamAccessRoleScopes.Universal;
|
|
break;
|
|
case 260:
|
|
accessRole = eLiamAccessRoles.ExchangeSMBSendAs;
|
|
scope = eLiamAccessRoleScopes.Universal;
|
|
break;
|
|
case 270:
|
|
accessRole = eLiamAccessRoles.ExchangeSMBOwner;
|
|
scope = eLiamAccessRoleScopes.Universal;
|
|
break;
|
|
}
|
|
|
|
providerData.NamingConventions.Add(new cLiamNamingConvention()
|
|
{
|
|
AccessRole = accessRole,
|
|
Scope = scope,
|
|
Description = cLIAMHelper.getStringFromObject(row["Description"]),
|
|
DescriptionTemplate = cLIAMHelper.getStringFromObject(row["DescriptionTemplate"]),
|
|
Name = cLIAMHelper.getStringFromObject(row["Name"]),
|
|
NamingTemplate = cLIAMHelper.getStringFromObject(row["NamingTemplate"]),
|
|
Wildcard = cLIAMHelper.getStringFromObject(row["Wildcard"])
|
|
});
|
|
}
|
|
}
|
|
|
|
sanitizedJson = JsonConvert.SerializeObject(providerData, Newtonsoft.Json.Formatting.Indented);
|
|
|
|
if (includeSecret && providerData.Credential != null)
|
|
providerData.Credential.Secret = password;
|
|
|
|
return providerData;
|
|
}
|
|
|
|
private cLiamProviderBase createProvider(DataTable dtMain, DataTable dtBase, DataTable dtAdditional, DataTable dtNamingConvention = null, DataTable dtCustomTag = null)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var DataProviderData = buildProviderData(dtMain, dtBase, dtAdditional, dtNamingConvention, dtCustomTag, includeSecret: true, out var sanitizedJson);
|
|
if (DataProviderData == null)
|
|
return null;
|
|
|
|
LogEntry("Provider configuration (sanitized JSON, copy for diagnostics tool):", LogLevels.Info);
|
|
LogEntry(sanitizedJson, LogLevels.Info);
|
|
|
|
var DataProvider = CreateProviderInstance(new cLiamConfiguration(), DataProviderData);
|
|
|
|
return DataProvider;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("initializeDataProvider"), HttpGet]
|
|
public async Task<bool> initializeDataProvider(Guid ProviderConfigClassID, bool force = false)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (cC4ITLicenseM42ESM.Instance == null)
|
|
LoadLicensingInformation();
|
|
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return false;
|
|
}
|
|
var DataProvider = await getDataProvider(ProviderConfigClassID, force);
|
|
return DataProvider != null;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("exportProviderConfiguration"), HttpGet]
|
|
public IHttpActionResult exportProviderConfiguration(Guid ProviderConfigClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (cC4ITLicenseM42ESM.Instance == null)
|
|
LoadLicensingInformation();
|
|
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return Content(HttpStatusCode.Forbidden, "License not valid");
|
|
}
|
|
|
|
if (!TryLoadProviderFragments(ProviderConfigClassID, out var objectId, out var tblMain, out var tblBase, out var tblAdditionalAttr, out var tblNamingConvention, out var tblCustomTags))
|
|
{
|
|
return Content(HttpStatusCode.NotFound, $"Provider configuration '{ProviderConfigClassID}' not found.");
|
|
}
|
|
|
|
var providerData = buildProviderData(tblMain, tblBase, tblAdditionalAttr, tblNamingConvention, tblCustomTags, includeSecret: false, out var sanitizedJson);
|
|
if (providerData == null)
|
|
return Content(HttpStatusCode.InternalServerError, "Provider configuration could not be loaded.");
|
|
|
|
var export = new ProviderConfigurationExport
|
|
{
|
|
ProviderConfigClassID = ProviderConfigClassID,
|
|
ProviderConfigObjectID = objectId,
|
|
SanitizedJson = sanitizedJson,
|
|
Configuration = providerData,
|
|
GeneratedAtUtc = DateTime.UtcNow
|
|
};
|
|
|
|
return Ok(export);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return InternalServerError(E);
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
private async Task<ProviderCacheEntry> getDataProvider(Guid ProviderConfigClassID, bool force = false)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!force)
|
|
{
|
|
var Provider = GetCacheByID(ProviderConfigClassID);
|
|
if (Provider != null)
|
|
{
|
|
LogEntry($"provider already cached", LogLevels.Debug);
|
|
return Provider;
|
|
}
|
|
}
|
|
if (!TryLoadProviderFragments(ProviderConfigClassID, out var ObjectID, out var tblMain, out var tblBase, out var tblAdditionalAttr, out var tblNamingConvention, out var tblCustomTags))
|
|
return null;
|
|
|
|
var DataProvider = createProvider(tblMain, tblBase, tblAdditionalAttr, tblNamingConvention, tblCustomTags);
|
|
if (DataProvider == null)
|
|
{
|
|
LogEntry($"Provider configuration '{ProviderConfigClassID}' could not be materialized.", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var validLogon = await DataProvider.LogonAsync();
|
|
if (!validLogon)
|
|
return null;
|
|
|
|
var RetVal = AddCache(ProviderConfigClassID, ObjectID, DataProvider);
|
|
|
|
return RetVal;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("initializeDataProviderByObjectID"), HttpGet]
|
|
public async Task<Guid> initializeDataProviderByObjectID(Guid ObjectID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (cC4ITLicenseM42ESM.Instance == null)
|
|
LoadLicensingInformation();
|
|
|
|
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
|
{
|
|
LogEntry($"Error: License not valid", LogLevels.Error);
|
|
return Guid.Empty;
|
|
}
|
|
var Provider = GetCacheByObjectID(ObjectID);
|
|
if (Provider != null)
|
|
{
|
|
LogEntry($"provider already cached", LogLevels.Debug);
|
|
return Provider.ID;
|
|
}
|
|
|
|
var TypeID = SPSDataEngineSchemaReader.TypeGetIDFromName(constTypeNameConfigProvider);
|
|
LogEntry($"Config provider class ID: {TypeID}", LogLevels.Debug);
|
|
SPSObject spsObject = ObjectRequest.GetSPSObject(TypeID, ObjectID);
|
|
if (spsObject == null)
|
|
{
|
|
LogEntry($"Provider config type not found: TypeID={TypeID}, ObjectID={ObjectID}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
|
|
var tblMain = spsObject.ClassTable[constFragmentNameConfigProviderMain];
|
|
if (tblMain == null)
|
|
{
|
|
LogEntry($"Provider config class not found: Type={constFragmentNameConfigProviderMain}, ObjectID={ObjectID}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
var tblBase = spsObject.ClassTable[constFragmentNameConfigProviderBase];
|
|
if (tblBase == null)
|
|
{
|
|
LogEntry($"Provider config class not found: Type={constFragmentNameConfigProviderBase}, ObjectID={ObjectID}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
var tblAdditionalAttributes = spsObject.ClassTable[constFragmentNameConfigProviderAdditionalAttributes];
|
|
if (tblAdditionalAttributes == null)
|
|
{
|
|
LogEntry($"Provider additional config class not found: Type={constFragmentNameConfigProviderAdditionalAttributes}, ObjectID={ObjectID}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
|
|
var DataProvider = createProvider(tblMain, tblBase, tblAdditionalAttributes);
|
|
|
|
var RetVal = await DataProvider.LogonAsync();
|
|
if (!RetVal)
|
|
return Guid.Empty;
|
|
|
|
var ID = cLIAMHelper.getGuidFromObject(tblMain.Rows[0]["ID"]);
|
|
|
|
AddCache(ID, ObjectID, DataProvider);
|
|
|
|
return ID;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return Guid.Empty;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
[Route("getDataAreasOwner"), HttpGet]
|
|
public async Task<string> getDataAreasOwner(Guid ProviderConfigClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return "";
|
|
}
|
|
|
|
var ProviderEntry = await getDataProvider(ProviderConfigClassID);
|
|
if (ProviderEntry == null)
|
|
{
|
|
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var lstDataAreas = await ProviderEntry.Provider.getDataAreasAsync(ProviderEntry.Provider.MaxDepth);
|
|
if (lstDataAreas == null || lstDataAreas.Count == 0)
|
|
{
|
|
LogEntry($"No data areas found for Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var xDoc = new XmlDocument();
|
|
xDoc.LoadXml("<DataAreaOwners xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\"><Owners/></DataAreaOwners>");
|
|
var xNode = xDoc.SelectSingleNode("DataAreaOwners/Owners");
|
|
|
|
foreach (var DA in lstDataAreas)
|
|
{
|
|
var Users = await DA.GetOwnersAsync();
|
|
if (Users == null)
|
|
continue;
|
|
|
|
var Persons = getPersonsFromUsers(Users);
|
|
foreach (var Person in Persons)
|
|
{
|
|
var xItem = xDoc.CreateElement("Owner");
|
|
xNode.AppendChild(xItem);
|
|
|
|
cLIAMHelper.AddXmlElement(xItem, "DataAreaTechnicalName", DA.UID);
|
|
cLIAMHelper.AddXmlElement(xItem, "PersonID", Person.ToString());
|
|
}
|
|
}
|
|
|
|
using (var sw = new StringWriter())
|
|
{
|
|
using (var xw = new XmlTextWriter(sw))
|
|
{
|
|
xDoc.WriteTo(xw);
|
|
return sw.ToString();
|
|
}
|
|
}
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getSecurityGroupsFromProvider"), HttpGet]
|
|
public async Task<IEnumerable<SecurityGroupEntry>> getSecurityGroupsFromProvider(Guid ProviderConfigClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new List<SecurityGroupEntry>();
|
|
}
|
|
|
|
var ProviderEntry = await getDataProvider(ProviderConfigClassID);
|
|
if (ProviderEntry == null)
|
|
{
|
|
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return new List<SecurityGroupEntry>();
|
|
}
|
|
|
|
var lstSecurityGroups = await ProviderEntry.Provider.getSecurityGroupsAsync(ProviderEntry.Provider.GroupFilter);
|
|
if (lstSecurityGroups == null || lstSecurityGroups.Count == 0)
|
|
{
|
|
LogEntry($"No security groups found for Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return new List<SecurityGroupEntry>();
|
|
}
|
|
|
|
var SGs = new List<SecurityGroupEntry>();
|
|
foreach (var SecurityGroup in lstSecurityGroups)
|
|
{
|
|
string uid = null;
|
|
string scope = null;
|
|
|
|
if (SecurityGroup is cLiamAdGroup adGroup)
|
|
{
|
|
uid = adGroup.dn;
|
|
scope = adGroup.scope;
|
|
}
|
|
else if (SecurityGroup is cLiamAdGroup2 adGroup2)
|
|
{
|
|
uid = adGroup2.dn;
|
|
scope = adGroup2.scope;
|
|
}
|
|
|
|
SGs.Add(new SecurityGroupEntry()
|
|
{
|
|
DisplayName = SecurityGroup.TechnicalName,
|
|
TechnicalName = SecurityGroup.UID,
|
|
TargetType = ((int)SecurityGroup.Provider.ProviderType).ToString(),
|
|
UID = uid,
|
|
Scope = scope
|
|
});
|
|
}
|
|
return SGs;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<SecurityGroupEntry>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getDataAreasFromProvider"), HttpGet]
|
|
public async Task<IEnumerable<DataAreaEntry>> getDataAreasFromProvider(Guid ProviderConfigClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return Enumerable.Empty<DataAreaEntry>();
|
|
}
|
|
|
|
var ProviderEntry = await getDataProvider(ProviderConfigClassID);
|
|
if (ProviderEntry == null)
|
|
{
|
|
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return Enumerable.Empty<DataAreaEntry>();
|
|
}
|
|
|
|
var lstDataAreas = await ProviderEntry.Provider.getDataAreasAsync(ProviderEntry.Provider.MaxDepth);
|
|
if (lstDataAreas == null || lstDataAreas.Count == 0)
|
|
{
|
|
LogEntry($"No data areas found for Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
|
|
return Enumerable.Empty<DataAreaEntry>();
|
|
}
|
|
|
|
return lstDataAreas.Select(DataArea =>
|
|
{
|
|
var DataAreaNtfsFolder = DataArea as cLiamNtfsFolder;
|
|
var DataAreaADGroup = DataArea as cLiamAdGroupAsDataArea;
|
|
|
|
string owner = DataAreaADGroup?.ManagedBySID ?? DataAreaNtfsFolder?.OwnerGroupIdentifier ?? string.Empty;
|
|
string write = DataAreaADGroup?.UID ?? DataAreaNtfsFolder?.WriteGroupIdentifier ?? string.Empty;
|
|
return new DataAreaEntry
|
|
{
|
|
DisplayName = DataArea.DisplayName ?? string.Empty,
|
|
UID = DataArea.UID,
|
|
TechnicalName = DataArea.TechnicalName,
|
|
Description = DataAreaADGroup?.Description ?? string.Empty,
|
|
TargetType = ((int)DataArea.Provider.ProviderType).ToString(),
|
|
ParentUID = DataArea.ParentUID ?? string.Empty,
|
|
Level = DataArea.Level.ToString(),
|
|
ConfigurationId = ProviderEntry.ObjectID.ToString(),
|
|
DataAreaType = DataArea.DataType.ToString(),
|
|
Owner = owner,
|
|
Write = write,
|
|
Read = DataAreaNtfsFolder?.ReadGroupIdentifier ?? string.Empty,
|
|
Traverse = DataAreaNtfsFolder?.TraverseGroupIdentifier ?? string.Empty,
|
|
CreatedDate = DataAreaNtfsFolder?.CreatedDate ?? DateTime.MinValue.ToString("o"),
|
|
};
|
|
}).ToList();
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return Enumerable.Empty<DataAreaEntry>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
private async Task<cLiamDataAreaBase> getDataAreaFromUID(string UID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var ProviderID = cLIAMHelper.getUidItem(ref UID);
|
|
if (!Guid.TryParse(ProviderID, out var ProviderGuid))
|
|
{
|
|
LogEntry($"No valid Provider config class ID in UID: {UID}", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var ProviderEntry = await getDataProvider(ProviderGuid);
|
|
if (ProviderEntry == null)
|
|
{
|
|
LogEntry($"Could not initialize Provider config class with ID {ProviderGuid}", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var DA = await ProviderEntry.Provider.LoadDataArea(UID);
|
|
if (DA == null)
|
|
{
|
|
LogEntry($"Could not load data area with UID '{UID}' from provider with ID '{ProviderGuid}'", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
return DA;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getChildsFromUID"), HttpGet]
|
|
public async Task<List<LiamDataAreaEntry>> getChildsFromUID(string UID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
|
|
var myUID = UID;
|
|
|
|
var DA = await getDataAreaFromUID(UID);
|
|
if (DA == null)
|
|
return new List<LiamDataAreaEntry>();
|
|
|
|
var Childs = await DA.getChildrenAsync(0);
|
|
if (Childs == null)
|
|
{
|
|
LogEntry($"Error while resolving data area children for UID: {UID}", LogLevels.Warning);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
|
|
var ProviderID = cLIAMHelper.getUidItem(ref myUID);
|
|
var RetVal = Childs.Select(ChildEntry => new LiamDataAreaEntry
|
|
{
|
|
UID = $"{ProviderID} | {ChildEntry.UID}",
|
|
DisplayName = ChildEntry.TechnicalName,
|
|
SupportsPermissions = ChildEntry.SupportsPermissions
|
|
}).ToList();
|
|
|
|
return RetVal;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getChildsFromDataArea"), HttpGet]
|
|
public async Task<List<LiamDataAreaEntry>> getChildsFromDataArea(Guid DataAreaClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
|
|
var DA = await getDataAreaFromId(DataAreaClassID);
|
|
if (DA == null)
|
|
return new List<LiamDataAreaEntry>();
|
|
|
|
var lstChilds = await DA.dataArea.getChildrenAsync();
|
|
if (lstChilds == null)
|
|
{
|
|
LogEntry($"Error getting children of data area with UID: {DA.dataArea.UID}", LogLevels.Warning);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
|
|
LogEntry($"Number of children: {lstChilds.Count}", LogLevels.Debug);
|
|
|
|
var RetVal = lstChilds.Select(ChildEntry => new LiamDataAreaEntry
|
|
{
|
|
UID = $"{DA.configId} | {ChildEntry.UID}",
|
|
DisplayName = ChildEntry.TechnicalName,
|
|
SupportsPermissions = ChildEntry.SupportsPermissions
|
|
}).ToList();
|
|
|
|
return RetVal;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<LiamDataAreaEntry>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
internal class cGetDataAreaResult
|
|
{
|
|
internal cLiamDataAreaBase dataArea;
|
|
internal Guid configId;
|
|
}
|
|
|
|
private async Task<cGetDataAreaResult> getDataAreaFromId(Guid DataAreaClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameDataAreaMain);
|
|
LogEntry($"Data area class ID: {ClassID}", LogLevels.Debug);
|
|
var FragDataArea = FragmentRequest.GetSPSFragment(ClassID, DataAreaClassID, "DataAreaConfiguration,technicalName, Owner.uniqueID as ownerRef");
|
|
if (FragDataArea == null)
|
|
{
|
|
LogEntry($"Data area fragment not found: ClassID={ClassID}, FragmentId={DataAreaClassID}", LogLevels.Debug);
|
|
return null;
|
|
}
|
|
|
|
var ConfigID = cLIAMHelper.getGuidFromObject(FragDataArea["DataAreaConfiguration"]);
|
|
if (ConfigID == Guid.Empty)
|
|
{
|
|
LogEntry("DataAreaConfiguration value not found.", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
LogEntry($"Config provider class ID: {ConfigID}", LogLevels.Debug);
|
|
|
|
var ConfigProviderEntry = await getDataProvider(ConfigID);
|
|
if (ConfigProviderEntry == null)
|
|
{
|
|
LogEntry($"Could not load Config Provider from cache with ID: {ConfigID}", LogLevels.Debug);
|
|
return null;
|
|
}
|
|
|
|
var UID = cLIAMHelper.getStringFromObject(FragDataArea["technicalName"]);
|
|
LogEntry($"Data area UID: {UID}", LogLevels.Debug);
|
|
|
|
var DA = await ConfigProviderEntry.Provider.LoadDataArea(UID);
|
|
DA.OwnerRef = cLIAMHelper.getStringFromObject(FragDataArea["ownerRef"]);
|
|
if (DA == null)
|
|
{
|
|
LogEntry($"Could not find LIAM data area with UID: {UID}", LogLevels.Debug);
|
|
return null;
|
|
}
|
|
|
|
return new cGetDataAreaResult
|
|
{
|
|
dataArea = DA,
|
|
configId = ConfigID
|
|
};
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getOwnerInfosFromDataArea"), HttpGet]
|
|
public async Task<List<cLiamUserInfo>> getOwnerInfosFromDataArea(Guid DataAreaClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new List<cLiamUserInfo>();
|
|
}
|
|
|
|
var DAResult = await getDataAreaFromId(DataAreaClassID);
|
|
if (DAResult == null)
|
|
return new List<cLiamUserInfo>();
|
|
|
|
var lstOwners = await DAResult.dataArea.GetOwnersAsync();
|
|
if (lstOwners == null)
|
|
{
|
|
LogEntry($"Error getting owners of data area with UID: {DAResult.dataArea.UID}", LogLevels.Warning);
|
|
return new List<cLiamUserInfo>();
|
|
}
|
|
LogEntry($"Number of owners: {lstOwners.Count}", LogLevels.Debug);
|
|
|
|
return lstOwners;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<cLiamUserInfo>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
private List<Guid> getPersonsFromUsers(List<cLiamUserInfo> Users)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var AccountAdClassId = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameAccountAd);
|
|
var AccountBaseClassId = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameAccountBase);
|
|
var UserBaseClassId = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameUserBase);
|
|
var CommonClassId = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameCommon);
|
|
|
|
var ListOwners = new List<Guid>();
|
|
foreach (var OwnerEntry in Users)
|
|
{
|
|
if (string.IsNullOrEmpty(OwnerEntry.UserPrincipalName))
|
|
continue;
|
|
|
|
var FilterValues = new List<string> { OwnerEntry.UserPrincipalName };
|
|
var Filter = AsqlHelper.BuildInCondition("UserPrincipalName", FilterValues);
|
|
LogEntry($"ASql Filter: {Filter}");
|
|
|
|
var tbl = FragmentRequestBase.SimpleLoad(AccountAdClassId, "[Expression-ObjectID] as Id, UserPrincipalName", Filter);
|
|
if (tbl?.Rows == null)
|
|
{
|
|
LogEntry($"No AD account entry list found with UserPrincipalName='{OwnerEntry.UserPrincipalName}'", LogLevels.Warning);
|
|
continue;
|
|
}
|
|
|
|
foreach (DataRow AdEntry in tbl.Rows)
|
|
{
|
|
var AdId = cLIAMHelper.getGuidFromObject(AdEntry["ID"]);
|
|
if (AdId == Guid.Empty)
|
|
{
|
|
LogEntry("No expression object ID found for AccountAd entry", LogLevels.Warning);
|
|
continue;
|
|
}
|
|
|
|
Guid[] ids2 = { AdId };
|
|
var tbl2 = FragmentRequestBase.SimpleLoad(AccountBaseClassId, "Owner", AsqlHelper.BuildInCondition("[Expression-ObjectID]", ids2));
|
|
if (tbl2?.Rows == null || tbl2.Rows.Count == 0)
|
|
{
|
|
LogEntry($"Account class base fragment not found: ClassId={AccountBaseClassId}, ObjectId={AdId}", LogLevels.Debug);
|
|
continue;
|
|
}
|
|
|
|
var OwnerID = cLIAMHelper.getGuidFromObject(tbl2.Rows[0]["Owner"]);
|
|
if (OwnerID == Guid.Empty)
|
|
{
|
|
LogEntry($"Could not get Owner ID for account class base: ObjectId={AdId}", LogLevels.Debug);
|
|
continue;
|
|
}
|
|
|
|
var FragUserBase = FragmentRequest.GetSPSFragment(UserBaseClassId, OwnerID);
|
|
if (FragUserBase == null)
|
|
{
|
|
LogEntry($"User class base entry not found: ClassID={UserBaseClassId}, FragmentId={OwnerID}", LogLevels.Debug);
|
|
continue;
|
|
}
|
|
var UserID = cLIAMHelper.getGuidFromObject(FragUserBase["ID"]);
|
|
var UserObjectID = cLIAMHelper.getGuidFromObject(FragUserBase["Expression-ObjectID"]);
|
|
|
|
Guid[] ids3 = { UserObjectID };
|
|
var tbl3 = FragmentRequestBase.SimpleLoad(CommonClassId, "State", AsqlHelper.BuildInCondition("[Expression-ObjectID]", ids3));
|
|
if (tbl3?.Rows == null || tbl3.Rows.Count == 0)
|
|
{
|
|
LogEntry($"Common class base fragment not found: ClassId={CommonClassId}, ObjectId={UserObjectID}", LogLevels.Debug);
|
|
continue;
|
|
}
|
|
var State = cLIAMHelper.getIntFromObject(tbl3.Rows[0]["State"]);
|
|
LogEntry($"User found: ID={UserID}, ObjectID={UserObjectID}, State={State}", LogLevels.Debug);
|
|
if (State == 2023)
|
|
ListOwners.Add(UserID);
|
|
else
|
|
LogEntry("User is not active", LogLevels.Debug);
|
|
}
|
|
}
|
|
return ListOwners;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<Guid>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getOwnersFromDataArea"), HttpGet]
|
|
public async Task<List<Guid>> getOwnersFromDataArea(Guid DataAreaClassID)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
var OwnersInfo = await getOwnerInfosFromDataArea(DataAreaClassID);
|
|
if (OwnersInfo == null)
|
|
return new List<Guid>();
|
|
|
|
return getPersonsFromUsers(OwnersInfo);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return new List<Guid>();
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
#if DEBUG
|
|
[Route("grantPermissionByEMail_Debug"), HttpGet]
|
|
public async Task<cLiamPermissionResult> grantPermissionByEMail_Debug(string UID, string EMail, int AccessType)
|
|
{
|
|
return await grantPermissionByEMail(UID, EMail, AccessType);
|
|
}
|
|
#endif //DEBUG
|
|
|
|
[Route("grantPermission"), HttpPost]
|
|
public async Task<cLiamPermissionResult> grantPermission(Guid DataAreaId, Guid PersonId, int AccessType, Guid AccoundId)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new cLiamPermissionResult { Valid = false };
|
|
}
|
|
|
|
var DA = await getDataAreaFromId(DataAreaId);
|
|
if (DA == null)
|
|
return null;
|
|
|
|
var UPN = GetUserPrincipalName(PersonId, AccoundId);
|
|
if (string.IsNullOrEmpty(UPN))
|
|
return null;
|
|
|
|
var User = new cLiamUserInfo
|
|
{
|
|
EMail = UPN,
|
|
UserPrincipalName = UPN
|
|
};
|
|
|
|
return await DA.dataArea.GrantPermissionAsync(User, (eLiamAccessRoles)AccessType);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("grantPermission"), HttpPost]
|
|
public async Task<cLiamPermissionResult> grantPermission(Guid DataAreaId, Guid PersonId, int AccessType)
|
|
{
|
|
return await grantPermission(DataAreaId, PersonId, AccessType, Guid.Empty);
|
|
}
|
|
|
|
public class RevokePermissionResponse
|
|
{
|
|
public bool success { get; set; }
|
|
public string error { get; set; } // null wenn success=true
|
|
}
|
|
|
|
[Route("revokePermission"), HttpPost]
|
|
public async Task<RevokePermissionResponse> revokePermission(Guid DataAreaId, Guid PersonId, int AccessType, Guid AccoundId)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new RevokePermissionResponse { success = false, error = "License not valid" };
|
|
}
|
|
|
|
var DA = await getDataAreaFromId(DataAreaId);
|
|
if (DA == null)
|
|
return new RevokePermissionResponse { success = false, error = "DataArea not found" };
|
|
|
|
var UPN = GetUserPrincipalName(PersonId, AccoundId);
|
|
if (string.IsNullOrEmpty(UPN))
|
|
return new RevokePermissionResponse { success = false, error = "UPN not found" };
|
|
|
|
// Optional: Enum-Validierung, verhindert interne Fehler
|
|
if (!Enum.IsDefined(typeof(eLiamAccessRoles), AccessType))
|
|
return new RevokePermissionResponse { success = false, error = "Invalid AccessType" };
|
|
|
|
var user = new cLiamUserInfo { EMail = UPN, UserPrincipalName = UPN };
|
|
|
|
var ok = await DA.dataArea.RevokePermissionAsync(user, (eLiamAccessRoles)AccessType);
|
|
return new RevokePermissionResponse { success = ok, error = ok ? null : "RevokePermissionAsync failed" };
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
LogException(ex);
|
|
return new RevokePermissionResponse { success = false, error = ex.Message };
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
[Route("revokePermission"), HttpPost]
|
|
public async Task<RevokePermissionResponse> revokePermission(Guid DataAreaId, Guid PersonId, int AccessType)
|
|
{
|
|
return await revokePermission(DataAreaId, PersonId, AccessType, Guid.Empty);
|
|
}
|
|
|
|
[Route("grantPermissionByEMail"), HttpPost]
|
|
public async Task<cLiamPermissionResult> grantPermissionByEMail(string UID, string EMail, int AccessType)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return new cLiamPermissionResult { Valid = false };
|
|
}
|
|
|
|
var DA = await getDataAreaFromUID(UID);
|
|
if (DA == null)
|
|
return null;
|
|
|
|
var User = new cLiamUserInfo { EMail = EMail };
|
|
|
|
return await DA.GrantPermissionAsync(User, (eLiamAccessRoles)AccessType);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("revokePermissionByEMail"), HttpPost]
|
|
public async Task<bool> revokePermissionByEMail(string UID, string EMail, int AccessType)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
{
|
|
LogEntry("Error: License not valid", LogLevels.Error);
|
|
return false;
|
|
}
|
|
|
|
var DA = await getDataAreaFromUID(UID);
|
|
if (DA == null)
|
|
return false;
|
|
|
|
var User = new cLiamUserInfo { EMail = EMail };
|
|
|
|
return await DA.RevokePermissionAsync(User, (eLiamAccessRoles)AccessType);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return false;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("encryptPassword"), HttpGet]
|
|
public string encryptPassword(string Password)
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
return CryptoManager.Instance.EncryptDBText(Password);
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getLicenseInformation"), HttpGet]
|
|
public cC4ITLicenseM42ESM getLicenseInformation()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
return null;
|
|
return cC4ITLicenseM42ESM.Instance;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
[Route("getLicensedModules"), HttpGet]
|
|
public List<dynamic> getLicensedModules()
|
|
{
|
|
var CM = MethodBase.GetCurrentMethod();
|
|
LogMethodBegin(CM);
|
|
try
|
|
{
|
|
if (!LoadLicensingInformation())
|
|
return new List<dynamic>();
|
|
|
|
var modules = cC4ITLicenseM42ESM.Instance?.Modules;
|
|
if (modules == null || !cC4ITLicenseM42ESM.Instance.IsValid)
|
|
return new List<dynamic>();
|
|
|
|
var rs = modules.Keys.Select(k => k.ToString()).ToList();
|
|
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameDataAreaTargetPickupType);
|
|
LogEntry($"Addon Config class ID: {ClassID}", LogLevels.Debug);
|
|
|
|
var dataTable = FragmentRequest.SimpleLoad(ClassID, "Id, Value", AsqlHelper.BuildInCondition("ID", rs));
|
|
if (dataTable?.Rows == null || dataTable.Rows.Count == 0)
|
|
{
|
|
LogEntry($"Addon Config fragment not found: ClassID={ClassID}", LogLevels.Debug);
|
|
return null;
|
|
}
|
|
|
|
var rs2 = new List<dynamic>();
|
|
foreach (DataRow p in dataTable.Rows)
|
|
{
|
|
var moduleId = cLIAMHelper.getGuidFromObject(p["Id"]);
|
|
var module = cC4ITLicenseM42ESM.Instance.Modules[moduleId];
|
|
var obj = cLiamM42Helper.ToDynamic(module);
|
|
obj.Value = cLIAMHelper.getStringFromObject(p["Value"]);
|
|
rs2.Add(obj);
|
|
}
|
|
return rs2;
|
|
}
|
|
catch (Exception E)
|
|
{
|
|
LogException(E);
|
|
return null;
|
|
}
|
|
finally
|
|
{
|
|
LogMethodEnd(CM);
|
|
}
|
|
}
|
|
|
|
private string GetUserPrincipalName(Guid PersonId, Guid AccoundId)
|
|
{
|
|
Guid myAccountId = AccoundId != Guid.Empty ? AccoundId : GetPrimaryAccountId(PersonId);
|
|
if (myAccountId == Guid.Empty)
|
|
return null;
|
|
|
|
var accountEoid = GetAccountEOID(myAccountId);
|
|
if (accountEoid == Guid.Empty)
|
|
return null;
|
|
|
|
return GetUserPrincipalNameFromEOID(accountEoid);
|
|
}
|
|
|
|
private Guid GetPrimaryAccountId(Guid PersonId)
|
|
{
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameUserBase);
|
|
LogEntry($"Data area class ID: {ClassID}", LogLevels.Debug);
|
|
var FragDataArea = FragmentRequest.GetSPSFragment(ClassID, PersonId);
|
|
if (FragDataArea == null)
|
|
{
|
|
LogEntry($"Data area fragment not found: ClassID={ClassID}, FragmentId={PersonId}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
|
|
var myAccountId = cLIAMHelper.getGuidFromObject(FragDataArea["PrimaryAccount"]);
|
|
if (myAccountId == Guid.Empty)
|
|
LogEntry("Account value not found.", LogLevels.Warning);
|
|
else
|
|
LogEntry($"Account class ID: {myAccountId}", LogLevels.Debug);
|
|
|
|
return myAccountId;
|
|
}
|
|
|
|
private Guid GetAccountEOID(Guid myAccountId)
|
|
{
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameAccountBase);
|
|
LogEntry($"Data area class ID: {ClassID}", LogLevels.Debug);
|
|
var FragDataArea = FragmentRequest.GetSPSFragment(ClassID, myAccountId);
|
|
if (FragDataArea == null)
|
|
{
|
|
LogEntry($"Data area fragment not found: ClassID={ClassID}, FragmentId={myAccountId}", LogLevels.Debug);
|
|
return Guid.Empty;
|
|
}
|
|
|
|
var accountEoid = cLIAMHelper.getGuidFromObject(FragDataArea["Expression-ObjectId"]);
|
|
if (accountEoid == Guid.Empty)
|
|
LogEntry("Account EOID value not found.", LogLevels.Warning);
|
|
else
|
|
LogEntry($"Account EOID: {accountEoid}", LogLevels.Debug);
|
|
|
|
return accountEoid;
|
|
}
|
|
|
|
private string GetUserPrincipalNameFromEOID(Guid accountEoid)
|
|
{
|
|
var ClassID = SPSDataEngineSchemaReader.ClassGetIDFromName(constFragmentNameAccountAd);
|
|
LogEntry($"Data area class ID: {ClassID}", LogLevels.Debug);
|
|
var tbl = FragmentRequestBase.SimpleLoad(ClassID, "UserPrincipalName", $"[Expression-ObjectId]='{accountEoid}'");
|
|
if (tbl?.Rows == null || tbl.Rows.Count == 0)
|
|
{
|
|
LogEntry($"No AD account entry list found with eoid='{accountEoid}'", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
|
|
var UPN = cLIAMHelper.getStringFromObject(tbl.Rows[0]["UserPrincipalName"]);
|
|
if (string.IsNullOrEmpty(UPN))
|
|
{
|
|
LogEntry("No UserPrincipalName found for AccountAd entry", LogLevels.Warning);
|
|
return null;
|
|
}
|
|
return UPN;
|
|
}
|
|
|
|
public class ProviderConfigurationExport
|
|
{
|
|
public Guid ProviderConfigClassID { get; set; }
|
|
public Guid ProviderConfigObjectID { get; set; }
|
|
public string SanitizedJson { get; set; }
|
|
public cLiamProviderData Configuration { get; set; }
|
|
public DateTime GeneratedAtUtc { get; set; }
|
|
}
|
|
}
|
|
}
|
|
|