Files
LIAM/LiamWorkflowActivities/C4IT.LIAM.WorkflowactivityBase.cs
Meik 3d4f60d83e chore: sync LIAM solution snapshot incl. diagnostics tooling
- update multiple LIAM projects and solution/config files

- add LiamWorkflowDiagnostics app sources and generated outputs

- include current workspace state (dependencies and build outputs)
2026-02-27 09:12:34 +01:00

1296 lines
53 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
using C4IT.Logging;
using System;
using System.Activities;
using System.ComponentModel;
using System.Reflection;
using static C4IT.Logging.cLogManager;
using Matrix42.Contracts.Platform.Data;
using Matrix42.ServiceRepository.Contracts.Components;
using Matrix42.Workflows.Contracts;
using System.Linq;
using Matrix42.Contracts.Platform.General;
using System.Json;
using Newtonsoft.Json;
using System.Collections.Generic;
using Matrix42.Workflows.Activities.Common.Data;
using System.Activities.Validation;
using System.Threading.Tasks;
using C4IT.Matrix42.ServerInfo;
using C4IT.LIAM;
using System.Data;
using System.Xml;
using System.IO;
using System.Runtime.Remoting.Contexts;
using Matrix42.Common;
using C4IT.MsGraph;
namespace LiamWorkflowActivities
{
public abstract class cLIAMM42BaseActivity : NativeActivity
{
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";
private static readonly Dictionary<Guid, ProviderCacheEntry> ProviderCacheByID = new Dictionary<Guid, ProviderCacheEntry>();
private static readonly Dictionary<Guid, ProviderCacheEntry> ProviderCacheByObjectID = new Dictionary<Guid, ProviderCacheEntry>();
internal IExtensionExecutor executor;
internal ISchemaReaderProvider schemaReader;
internal IDataReaderProvider dataProvider;
public static bool IsInitialized { get; private set; } = false;
private static Object initLock = new object();
protected string LastOperationErrorCode { get; private set; } = string.Empty;
protected string LastOperationErrorMessage { get; private set; } = string.Empty;
protected void ClearOperationError()
{
LastOperationErrorCode = string.Empty;
LastOperationErrorMessage = string.Empty;
}
protected void SetOperationError(string code, string message)
{
LastOperationErrorCode = string.IsNullOrWhiteSpace(code) ? "WF_OPERATION_FAILED" : code;
LastOperationErrorMessage = message ?? string.Empty;
LogEntry($"[{LastOperationErrorCode}] {LastOperationErrorMessage}", LogLevels.Error);
}
protected void SetOperationErrorFromProvider(cLiamProviderBase provider, string fallbackCode, string fallbackMessage)
{
if (provider is cLiamProviderExchange exProvider)
{
var code = exProvider.GetLastErrorCode();
var message = exProvider.GetLastErrorMessage();
if (!string.IsNullOrWhiteSpace(code) || !string.IsNullOrWhiteSpace(message))
{
SetOperationError(
string.IsNullOrWhiteSpace(code) ? fallbackCode : code,
string.IsNullOrWhiteSpace(message) ? fallbackMessage : message);
return;
}
}
var providerMessage = provider?.GetLastErrorMessage();
SetOperationError(
fallbackCode,
string.IsNullOrWhiteSpace(providerMessage) ? fallbackMessage : providerMessage);
}
protected void Initialize(NativeActivityContext context)
{
try
{
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 { };
}
public bool LoadLicensingInformation(bool force = false)
{
if (cC4ITLicenseM42ESM.Instance == null || force)
{
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 dataRows = dataProvider.GetDataList(constFragmentNameAddonConfigClassBase, "license",
"UsedInTypeC4IT_LIAMConfigurationType is not null"
);
if (dataRows.Length <= 0)
{
LogEntry($"Addon Config fragment not found", LogLevels.Debug);
return null;
}
var license = cLIAMHelper.getStringFromObject(dataRows[0]["license"]);
LogEntry($"Addon Config license: {license}", LogLevels.Debug);
return license;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
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);
case eLiamProviderTypes.Exchange:
return new cLiamProviderExchange(LiamConfiguration, ProviderData);
}
return null;
}
internal 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
};
if (ProviderCacheByID.ContainsKey(ID))
ProviderCacheByID[ID] = Entry;
else
ProviderCacheByID.Add(ID, Entry);
if (ProviderCacheByObjectID.ContainsKey(ObjectID))
ProviderCacheByObjectID[ObjectID] = Entry;
else
ProviderCacheByObjectID.Add(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;
}
public cLiamProviderBase createProvider(DataRow dataMain, DataRow dataBase, IEnumerable<DataRow> dataAdditional, IEnumerable<DataRow> dataNamingConvention = null, IEnumerable<DataRow> dataCustomTag = null, SecureData secureData = null)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var PW = secureData?.Value;
var DataProviderData = 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 (dataAdditional != null)
{
foreach (DataRow row in dataAdditional)
{
var Name = cLIAMHelper.getStringFromObject(row["Name"]);
var Value = cLIAMHelper.getStringFromObject(row["Value"]);
DataProviderData.AdditionalConfiguration[Name] = Value;
}
}
if (dataCustomTag != null)
{
foreach (DataRow row in dataCustomTag)
{
var Name = cLIAMHelper.getStringFromObject(row["Key"]);
var Value = cLIAMHelper.getStringFromObject(row["Name"]);
DataProviderData.CustomTags[Name] = Value;
}
}
var namingConventions = new List<cLiamNamingConvention>();
if (dataNamingConvention != null)
{
foreach (DataRow row in dataNamingConvention)
{
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;
}
DataProviderData.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"])
});
}
}
var sanitizedJson = JsonConvert.SerializeObject(DataProviderData, Newtonsoft.Json.Formatting.Indented);
LogEntry("Provider configuration (sanitized JSON, copy for diagnostics tool):", LogLevels.Info);
LogEntry(sanitizedJson, LogLevels.Info);
DataProviderData.Credential.Secret = PW;
var DataProvider = CreateProviderInstance(new cLiamConfiguration(), DataProviderData);
return DataProvider;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public ProviderCacheEntry getDataProvider(Guid ProviderConfigClassID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var Provider = GetCacheByID(ProviderConfigClassID);
if (Provider == null)
Provider = GetCacheByObjectID(ProviderConfigClassID);
if (Provider != null)
{
LogEntry($"provider already cached", LogLevels.Debug);
return Provider;
}
else
return null;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<IEnumerable<SecurityGroupEntry>> getSecurityGroupsFromProvider(Guid ProviderConfigClassID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
ClearOperationError();
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry($"Error: License not valid", LogLevels.Error);
SetOperationError("WF_GET_SECURITYGROUPS_LICENSE_INVALID", "License not valid");
return new List<SecurityGroupEntry>();
}
var ProviderEntry = getDataProvider(ProviderConfigClassID);
if (ProviderEntry == null)
{
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
SetOperationError("WF_GET_SECURITYGROUPS_PROVIDER_NOT_FOUND", $"Could not initialize Provider config class with ID {ProviderConfigClassID}");
return null;
}
var lstSecurityGroups = await ProviderEntry.Provider.getSecurityGroupsAsync(ProviderEntry.Provider.GroupFilter);
if (lstSecurityGroups == null)
{
SetOperationErrorFromProvider(
ProviderEntry.Provider,
"WF_GET_SECURITYGROUPS_PROVIDER_CALL_FAILED",
"Provider returned null while reading security groups.");
return null;
}
if (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 sg in lstSecurityGroups)
{
var entry = new SecurityGroupEntry
{
DisplayName = sg.TechnicalName,
TechnicalName = sg.UID,
TargetType = ((int)sg.Provider.ProviderType).ToString()
};
switch (sg)
{
case cLiamAdGroup adGroup:
entry.UID = adGroup.dn;
entry.Scope = adGroup.scope;
break;
case cLiamAdGroup2 adGroup:
entry.UID = adGroup.dn;
entry.Scope = adGroup.scope;
break;
case cLiamExchangeSecurityGroup exGroup:
entry.UID = exGroup.dn; // SID der Exchange-Gruppe
//entry.Scope = exGroup.dn; // Distinguished Name der Exchange-Gruppe
break;
}
SGs.Add(entry);
}
return SGs;
}
catch (Exception E)
{
LogException(E);
SetOperationError("WF_GET_SECURITYGROUPS_EXCEPTION", E.Message);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<IEnumerable<DataAreaEntry>> getDataAreasFromProvider(Guid ProviderConfigClassID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
ClearOperationError();
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry($"Error: License not valid", LogLevels.Error);
SetOperationError("WF_GET_DATAAREAS_LICENSE_INVALID", "License not valid");
return new List<DataAreaEntry>();
}
var ProviderEntry = getDataProvider(ProviderConfigClassID);
if (ProviderEntry == null)
{
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
SetOperationError("WF_GET_DATAAREAS_PROVIDER_NOT_FOUND", $"Could not initialize Provider config class with ID {ProviderConfigClassID}");
return null;
}
var lstDataAreas = await ProviderEntry.Provider.getDataAreasAsync(ProviderEntry.Provider.MaxDepth);
if (lstDataAreas == null)
{
SetOperationErrorFromProvider(
ProviderEntry.Provider,
"WF_GET_DATAAREAS_PROVIDER_CALL_FAILED",
"Provider returned null while reading data areas.");
return null;
}
if (lstDataAreas.Count <= 0)
{
LogEntry($"No data areas found for Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
return new List<DataAreaEntry>();
}
return lstDataAreas
.Select(DataArea =>
{
var ntfs = DataArea as cLiamNtfsFolder;
var adGrp = DataArea as cLiamAdGroupAsDataArea;
var exchMB = DataArea as cLiamExchangeSharedMailbox;
var exchDL = DataArea as cLiamExchangeDistributionGroup;
// 1) Owner
// - Shared Mailbox: OwnerGroupIdentifier
// - Distribution Group: OwnerGroupIdentifier
// - AD-Group: ManagedBySID
// - NTFS-Folder: OwnerGroupIdentifier
string owner = exchMB?.OwnerGroupIdentifier
?? exchDL?.OwnerGroupIdentifier
?? adGrp?.ManagedBySID
?? ntfs?.OwnerGroupIdentifier
?? string.Empty;
// 2) WriteSID
// - Shared Mailbox: FullAccessGroupSid
// - Distribution Group: MemberGroupSid
// - AD-Group: UID
// - NTFS-Folder: WriteGroupIdentifier
string write = exchMB != null
? exchMB.FullAccessGroupSid
: exchDL != null
? exchDL.MemberGroupSid
: adGrp?.UID
?? ntfs?.WriteGroupIdentifier
?? string.Empty;
// 3) ReadSID
// - Shared Mailbox: SendAsGroupSid
// - Distribution Group: (nicht verwendet)
// - NTFS-Folder: ReadGroupIdentifier
string read = exchMB != null
? exchMB.SendAsGroupSid
: ntfs?.ReadGroupIdentifier
?? string.Empty;
// 4) Traverse nur NTFS-Folder
string traverse = ntfs?.TraverseGroupIdentifier ?? string.Empty;
// 5) CreatedDate nur NTFS-Folder
string created = ntfs?.CreatedDate ?? DateTime.MinValue.ToString("o");
// 6) Description: nur AD-Group
string desc = adGrp?.Description ?? string.Empty;
return new DataAreaEntry
{
DisplayName = DataArea.DisplayName ?? string.Empty,
UID = DataArea.UID,
TechnicalName = DataArea.TechnicalName,
Description = desc,
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 = read,
Traverse = traverse,
CreatedDate = created,
};
})
.ToList();
}
catch (Exception E)
{
LogException(E);
SetOperationError("WF_GET_DATAAREAS_EXCEPTION", E.Message);
return null;
}
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 = 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);
}
}
internal class cGetDataAreaResult
{
internal cLiamDataAreaBase dataArea;
internal Guid configId;
}
private async Task<cGetDataAreaResult> getDataAreaFromId(Guid DataAreaClassID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
var ConfigID = dataProvider.GetFragmentValue<Guid>(constFragmentNameDataAreaMain, DataAreaClassID, "DataAreaConfiguration");
if (ConfigID == Guid.Empty)
{
LogEntry($"DataAreaConfiguration value not found.", LogLevels.Warning);
return null;
}
LogEntry($"Config provider class ID: {ConfigID}", LogLevels.Debug);
var ConfigProviderEntry = getDataProvider(ConfigID);
if (ConfigProviderEntry == null)
{
LogEntry($"Could not load Config Provider from cache with ID: {ConfigID}", LogLevels.Debug);
return null;
}
var UID = dataProvider.GetFragmentValue<string>(constFragmentNameDataAreaMain, DataAreaClassID, "technicalName");
LogEntry($"Data area UID: {UID}", LogLevels.Debug);
var DA = await ConfigProviderEntry.Provider.LoadDataArea(UID);
if (DA == null)
{
LogEntry($"Could not found 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);
}
}
public async Task<List<cLiamUserInfo>> getOwnerInfosFromDataArea(Guid DataAreaClassID)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new List<cLiamUserInfo>();
}
var ConfigID = dataProvider.GetFragmentValue<Guid>(constFragmentNameDataAreaMain, DataAreaClassID, "DataAreaConfiguration");
if (ConfigID == Guid.Empty)
{
LogEntry($"DataAreaConfiguration value not found.", LogLevels.Warning);
return null;
}
LogEntry($"Config provider class ID: {ConfigID}", LogLevels.Debug);
var ConfigProviderEntry = getDataProvider(ConfigID);
if (ConfigProviderEntry == null)
{
LogEntry($"Could not load Config Provider from cache with ID: {ConfigID}", LogLevels.Debug);
return null;
}
var UID = dataProvider.GetFragmentValue<string>(constFragmentNameDataAreaMain, DataAreaClassID, "technicalName");
LogEntry($"Data area UID: {UID}", LogLevels.Debug);
var DA = await ConfigProviderEntry.Provider.LoadDataArea(UID);
if (DA == null)
{
LogEntry($"Could not found LIAM data area with UID: {UID}", LogLevels.Debug);
return null;
}
var lstOwners = await DA.GetOwnersAsync();
if (lstOwners == null)
{
LogEntry($"Error getting owners of data area with UID: {UID}", LogLevels.Warning);
return null;
}
LogEntry($"Number of owners: {lstOwners.Count}", LogLevels.Debug);
return lstOwners;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
internal List<Guid> getPersonsFromUsers(List<cLiamUserInfo> Users)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
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 Rows = dataProvider.GetDataList(constFragmentNameAccountAd, "[Expression-ObjectID] as Id, UserPrincipalName",
Filter
);
if (Rows == null)
{
LogEntry($"no rows in account entry list found with UserPrincipalName='{OwnerEntry.UserPrincipalName}'", LogLevels.Warning);
return null;
}
LogEntry($"ASql Filter: {Filter}");
foreach (DataRow AdEntry in Rows)
{
// get the expression object id for the account
var AdId = cLIAMHelper.getGuidFromObject(AdEntry["ID"]);
if (AdId == Guid.Empty)
{
LogEntry($"no expression object id found for AccountAd entry", LogLevels.Warning);
continue;
}
// get the account class base & ID of the user class base
Guid[] ids2 = { AdId };
var rows2 = dataProvider.GetDataList(constFragmentNameAccountBase, "Owner",
AsqlHelper.BuildInCondition("[Expression-ObjectID]",
ids2)
);
if (rows2 == null || Rows.Length <= 0)
{
LogEntry($"account class base fragment not found, ObjectId={AdId}", LogLevels.Debug);
continue;
}
var OwnerID = cLIAMHelper.getGuidFromObject(rows2[0]["Owner"]);
if (OwnerID == Guid.Empty)
{
LogEntry($"Could not get Owner ID for account class base: ObjectId={AdId}", LogLevels.Debug);
continue;
}
// get the SPSUserClassBase entry
var UserID = dataProvider.GetFragmentValue<Guid>(constFragmentNameUserBase, OwnerID, "ID");
var UserObjectID = dataProvider.GetFragmentValue<Guid>(constFragmentNameUserBase, OwnerID, "Expression-ObjectID");
// get the user common class base & check the state for 2001
Guid[] ids3 = { UserObjectID };
var rows3 = dataProvider.GetDataList(constFragmentNameCommon, "State",
AsqlHelper.BuildInCondition("[Expression-ObjectID]",
ids3));
if (rows3 == null || rows3.Length <= 0)
{
LogEntry($"account class base fragment not found: ObjectId={AdId}", LogLevels.Debug);
continue;
}
var State = cLIAMHelper.getIntFromObject(rows3[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 null;
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<cLiamPermissionResult> grantPermission(Guid DataAreaId, Guid PersonId, int AccessType, Guid AccoundId)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry($"Error: License not valid", LogLevels.Error);
return new cLiamPermissionResult()
{
Valid = false
};
}
var DA = await getDataAreaFromId(DataAreaId);
if (DA == null)
return null;
Guid myAccountId;
if (AccoundId != null && AccoundId != Guid.Empty)
myAccountId = (Guid)AccoundId;
else
{
myAccountId = dataProvider.GetFragmentValue<Guid>(constFragmentNameUserBase, PersonId, "PrimaryAccount");
if (myAccountId == Guid.Empty)
{
LogEntry($"Account value not found.", LogLevels.Warning);
return null;
}
LogEntry($"Account class ID: {myAccountId}", LogLevels.Debug);
}
var accountEoid = dataProvider.GetFragmentValue<Guid>(constFragmentNameAccountBase, myAccountId, "Expression-ObjectId");
if (accountEoid == Guid.Empty)
{
LogEntry($"Account EOID value not found.", LogLevels.Warning);
return null;
}
LogEntry($"Account EOID: {accountEoid}", LogLevels.Debug);
// get the expression object id for the account
var UPN = dataProvider.GetFragmentValue<string>(constFragmentNameAccountAd, accountEoid, "UserPrincipalName");
if (string.IsNullOrEmpty(UPN))
{
LogEntry($"no UserPrincipalName found for AccountAd entry", LogLevels.Warning);
return null;
}
var User = new cLiamUserInfo()
{
EMail = UPN,
UserPrincipalName = UPN
};
var RetVal = await DA.dataArea.GrantPermissionAsync(User, (eLiamAccessRoles)AccessType);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return null;
}
finally
{
LogMethodEnd(CM);
}
}
/// <summary>
/// Erstellt eine Distribution Group samt zugehöriger AD-Gruppen (Member, Owner) über den konfigurierten Provider.
/// </summary>
public bool createDistributionGroup(
Guid ProviderConfigClassID,
string name,
string alias,
string displayName = null,
string primarySmtpAddress = null)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Lizenz prüfen (falls nötig analog zu cloneTeam)
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry("Error: License not valid", LogLevels.Error);
return false;
}
// DataProvider holen
var providerEntry = getDataProvider(ProviderConfigClassID);
if (providerEntry == null)
{
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
return false;
}
// Auf den konkreten Exchange-Provider casten
if (providerEntry.Provider is cLiamProviderExchange exProv)
{
// Aufruf der Methode im Provider
var result = exProv.exchangeManager.CreateDistributionGroupWithOwnershipGroups(
name,
alias,
displayName,
primarySmtpAddress,
out string errorCode,
out string errorMessage
);
if (result == null)
{
LogEntry(
$"createDistributionGroup failed [{errorCode}] {errorMessage}",
LogLevels.Error);
return false;
}
LogEntry(
$"createDistributionGroup succeeded. ObjectGuid='{result.Item1}', GroupCount='{result.Item2?.Count ?? 0}'",
LogLevels.Info);
return true;
}
LogEntry($"Provider is not a cLiamProviderExchange, but {providerEntry.Provider.GetType().Name}", LogLevels.Warning);
return false;
}
catch (Exception e)
{
LogException(e);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
/// <summary>
/// Erstellt eine Shared Mailbox samt zugehöriger AD-Gruppen (FullAccess, SendAs, Owner) über den konfigurierten Provider.
/// </summary>
public bool createSharedMailbox(
Guid ProviderConfigClassID,
string name,
string alias,
string displayName = null,
string primarySmtpAddress = null)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
// Lizenz prüfen (falls nötig analog zu cloneTeam)
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry("Error: License not valid", LogLevels.Error);
return false;
}
// DataProvider holen
var providerEntry = getDataProvider(ProviderConfigClassID);
if (providerEntry == null)
{
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
return false;
}
// Auf den konkreten Exchange-Provider casten
if (providerEntry.Provider is cLiamProviderExchange exProv)
{
// Aufruf der Methode im Provider
var result = exProv.exchangeManager.CreateSharedMailboxWithOwnershipGroups(
name,
alias,
displayName,
primarySmtpAddress,
out string errorCode,
out string errorMessage
);
if (result == null)
{
LogEntry(
$"createSharedMailbox failed [{errorCode}] {errorMessage}",
LogLevels.Error);
return false;
}
LogEntry(
$"createSharedMailbox succeeded. ObjectGuid='{result.Item1}', GroupCount='{result.Item2?.Count ?? 0}'",
LogLevels.Info);
return true;
}
LogEntry($"Provider is not a cLiamProviderExchange, but {providerEntry.Provider.GetType().Name}", LogLevels.Warning);
return false;
}
catch (Exception e)
{
LogException(e);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<cMsGraphResultBase> cloneTeam(Guid ProviderConfigClassID, string teamId, string name, string description, int visibility, int partsToClone, string additionalMembers, string additionalOwners)
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
{
LogEntry($"Error: License not valid", LogLevels.Error);
return null;
}
var ProviderEntry = getDataProvider(ProviderConfigClassID);
if (ProviderEntry == null)
{
LogEntry($"Could not initialize Provider config class with ID {ProviderConfigClassID}", LogLevels.Warning);
return null;
}
// Prüfen ob ProviderEntry vom Typ cLiamProviderMsTeams ist
if (ProviderEntry.Provider is cLiamProviderMsTeams msTeamsProvider)
{
// Aufruf von cloneTeam mit allen Parametern außer ProviderConfigClassID
return await msTeamsProvider.cloneTeam(teamId, name, description, visibility, partsToClone, additionalMembers, additionalOwners);
}
// Falls nicht cLiamProviderMsTeams, false zurückgeben
return null;
}
catch (Exception E)
{
LogException(E);
return null; // Geändert von null zu false, da Rückgabetyp bool ist
}
finally
{
LogMethodEnd(CM);
}
}
public async Task<bool> revokePermission(Guid DataAreaId, Guid PersonId, int AccessType, Guid AccoundId)
{
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 DA = await getDataAreaFromId(DataAreaId);
if (DA == null)
return false;
Guid myAccountId;
if (AccoundId != null && AccoundId != Guid.Empty)
myAccountId = (Guid)AccoundId;
else
{
myAccountId = dataProvider.GetFragmentValue<Guid>(constFragmentNameUserBase, PersonId, "PrimaryAccount");
if (myAccountId == Guid.Empty)
{
LogEntry($"Account value not found.", LogLevels.Warning);
return false;
}
LogEntry($"Account class ID: {myAccountId}", LogLevels.Debug);
}
var accountEoid = dataProvider.GetFragmentValue<Guid>(constFragmentNameAccountBase, myAccountId, "Expression-ObjectId");
if (accountEoid == Guid.Empty)
{
LogEntry($"Account EOID value not found.", LogLevels.Warning);
return false;
}
LogEntry($"Account EOID: {accountEoid}", LogLevels.Debug);
var Rows = dataProvider.GetDataList(constFragmentNameAccountAd, "UserPrincipalName",
string.Format("[Expression-ObjectId]='{0}'", accountEoid)
);
if (Rows == null)
{
LogEntry($"no ad account entry list found with eoid='{accountEoid}'", LogLevels.Warning);
return false;
}
if (Rows == null || Rows.Length == 0)
{
LogEntry($"no rows in account entry list found with eoid='{accountEoid}'", LogLevels.Warning);
return false;
}
// get the expression object id for the account
var UPN = cLIAMHelper.getStringFromObject(Rows[0]["UserPrincipalName"]);
if (string.IsNullOrEmpty(UPN))
{
LogEntry($"no UserPrincipalName found for AccountAd entry", LogLevels.Warning);
return false;
}
var User = new cLiamUserInfo()
{
EMail = UPN,
UserPrincipalName = UPN
};
var RetVal = await DA.dataArea.RevokePermissionAsync(User, (eLiamAccessRoles)AccessType);
return RetVal;
}
catch (Exception E)
{
LogException(E);
return false;
}
finally
{
LogMethodEnd(CM);
}
}
/*
[Route("getLicenseInformation"), HttpGet]
public cC4ITLicenseM42ESM getLicenseInformation()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
return cC4ITLicenseM42ESM.Instance;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
[Route("getLicensedModules"), HttpGet]
public List<dynamic> getLicensedModules()
{
var CM = MethodBase.GetCurrentMethod();
LogMethodBegin(CM);
try
{
if (cC4ITLicenseM42ESM.Instance == null)
LoadLicensingInformation();
if (!cC4ITLicenseM42ESM.Instance.IsValid)
return new List<dynamic>();
List<string> rs = new List<string>();
foreach (var key in cC4ITLicenseM42ESM.Instance?.Modules.Keys)
{
rs.Add(key.ToString());
}
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;
}
List<dynamic> rs2 = new List<dynamic>();
foreach (DataRow p in dataTable.Rows)
{
var obj = cLiamM42Helper.ToDynamic(cC4ITLicenseM42ESM.Instance.Modules[cLIAMHelper.getGuidFromObject(p["Id"])]);
obj.Value = cLIAMHelper.getStringFromObject(p["Value"]);
rs2.Add(obj);
}
return rs2;
}
catch (Exception E)
{
LogException(E);
}
finally
{
LogMethodEnd(CM);
}
return null;
}
*/
}
}