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 ProviderCacheByID = new Dictionary(); private static readonly Dictionary ProviderCacheByObjectID = new Dictionary(); 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 dataAdditional, IEnumerable dataNamingConvention = null, IEnumerable 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(); 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> 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(); } 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(); } var SGs = new List(); 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> 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(); } 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(); } return lstDataAreas .Select(DataArea => { var ntfsPermissionArea = DataArea as cLiamNtfsPermissionDataAreaBase; 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 ?? ntfsPermissionArea?.OwnerGroupIdentifier ?? string.Empty; // 2) Write‑SID // - Shared Mailbox: FullAccessGroupSid // - Distribution Group: MemberGroupSid // - AD-Group: UID // - NTFS-Folder: WriteGroupIdentifier string write = exchMB != null ? exchMB.FullAccessGroupSid : exchDL != null ? exchDL.MemberGroupSid : adGrp?.UID ?? ntfsPermissionArea?.WriteGroupIdentifier ?? string.Empty; // 3) Read‑SID // - Shared Mailbox: SendAsGroupSid // - Distribution Group: (nicht verwendet) // - NTFS-Folder: ReadGroupIdentifier string read = exchMB != null ? exchMB.SendAsGroupSid : ntfsPermissionArea?.ReadGroupIdentifier ?? string.Empty; // 4) Traverse nur NTFS-Objekte string traverse = ntfsPermissionArea?.TraverseGroupIdentifier ?? string.Empty; // 5) CreatedDate nur NTFS-Objekte string created = ntfsPermissionArea?.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 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 getDataAreaFromId(Guid DataAreaClassID) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { var ConfigID = dataProvider.GetFragmentValue(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(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> 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(); } var ConfigID = dataProvider.GetFragmentValue(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(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 getPersonsFromUsers(List Users) { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { var ListOwners = new List(); foreach (var OwnerEntry in Users) { if (string.IsNullOrEmpty(OwnerEntry.UserPrincipalName)) continue; var FilterValues = new List() { 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(constFragmentNameUserBase, OwnerID, "ID"); var UserObjectID = dataProvider.GetFragmentValue(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 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(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(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(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); } } /// /// Erstellt eine Distribution Group samt zugehöriger AD-Gruppen (Member, Owner) über den konfigurierten Provider. /// 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); } } /// /// Erstellt eine Shared Mailbox samt zugehöriger AD-Gruppen (FullAccess, SendAs, Owner) über den konfigurierten Provider. /// 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 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 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(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(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 getLicensedModules() { var CM = MethodBase.GetCurrentMethod(); LogMethodBegin(CM); try { if (cC4ITLicenseM42ESM.Instance == null) LoadLicensingInformation(); if (!cC4ITLicenseM42ESM.Instance.IsValid) return new List(); List rs = new List(); 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 rs2 = new List(); 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; } */ } }