fix: await exchange permission resolution
This commit is contained in:
@@ -23,12 +23,12 @@ namespace C4IT.LIAM
|
||||
public readonly ExchangeManager exchangeManager;
|
||||
internal readonly cActiveDirectoryBase activeDirectoryBase = new cActiveDirectoryBase();
|
||||
|
||||
private string exchangeUri;
|
||||
private PSCredential credential;
|
||||
private string organizationalUnit;
|
||||
private string lastErrorCode = string.Empty;
|
||||
private string lastErrorMessage;
|
||||
private bool isLoggedOn = false;
|
||||
private string exchangeUri;
|
||||
private PSCredential credential;
|
||||
private string organizationalUnit;
|
||||
private string lastErrorCode = string.Empty;
|
||||
private string lastErrorMessage;
|
||||
private bool isLoggedOn = false;
|
||||
|
||||
public cLiamProviderExchange(cLiamConfiguration LiamConfiguration, cLiamProviderData ProviderData) :
|
||||
base(LiamConfiguration, ProviderData)
|
||||
@@ -66,8 +66,8 @@ namespace C4IT.LIAM
|
||||
/// Extrahiert den GUID-Wert aus den Properties.
|
||||
/// Zunächst wird versucht, "objectGUID" zu lesen – ist dieser leer, wird "GUID" verwendet.
|
||||
/// </summary>
|
||||
internal static string ExtractObjectGuid(dynamic properties)
|
||||
{
|
||||
internal static string ExtractObjectGuid(dynamic properties)
|
||||
{
|
||||
// Erstversuch: objectGUID (wie in AD)
|
||||
var value = properties["objectGUID"]?.Value;
|
||||
if (value == null || string.IsNullOrEmpty(value.ToString()))
|
||||
@@ -79,80 +79,80 @@ namespace C4IT.LIAM
|
||||
return new Guid(guidBytes).ToString();
|
||||
if (value is Guid guid)
|
||||
return guid.ToString();
|
||||
return value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
public string GetLastErrorCode()
|
||||
{
|
||||
return lastErrorCode;
|
||||
}
|
||||
|
||||
private void ClearLastError()
|
||||
{
|
||||
lastErrorCode = string.Empty;
|
||||
lastErrorMessage = string.Empty;
|
||||
}
|
||||
|
||||
private void SetLastError(string code, string message)
|
||||
{
|
||||
lastErrorCode = string.IsNullOrWhiteSpace(code) ? "EXCH_UNKNOWN_ERROR" : code;
|
||||
lastErrorMessage = message ?? string.Empty;
|
||||
LogEntry($"[{lastErrorCode}] {lastErrorMessage}", LogLevels.Error);
|
||||
}
|
||||
return value?.ToString() ?? string.Empty;
|
||||
}
|
||||
|
||||
public override async Task<bool> LogonAsync()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_LOGON_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var testMailboxes = exchangeManager.GetSharedMailboxes(
|
||||
"Name -like '*'",
|
||||
out string errorCode,
|
||||
out string errorMessage);
|
||||
if (testMailboxes == null)
|
||||
{
|
||||
SetLastError(errorCode, $"Failed to connect to Exchange: {errorMessage}");
|
||||
isLoggedOn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (testMailboxes != null)
|
||||
{
|
||||
LogEntry("Successfully connected to Exchange", LogLevels.Info);
|
||||
isLoggedOn = true;
|
||||
ClearLastError();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
SetLastError("EXCH_LOGON_EXCEPTION", $"Failed to connect to Exchange: {ex.Message}");
|
||||
isLoggedOn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetLastError("EXCH_LOGON_FAILED", "Unknown error connecting to Exchange");
|
||||
return false;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_LOGON_EXCEPTION", $"Exception during Exchange logon: {E.Message}");
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
public string GetLastErrorCode()
|
||||
{
|
||||
return lastErrorCode;
|
||||
}
|
||||
|
||||
private void ClearLastError()
|
||||
{
|
||||
lastErrorCode = string.Empty;
|
||||
lastErrorMessage = string.Empty;
|
||||
}
|
||||
|
||||
private void SetLastError(string code, string message)
|
||||
{
|
||||
lastErrorCode = string.IsNullOrWhiteSpace(code) ? "EXCH_UNKNOWN_ERROR" : code;
|
||||
lastErrorMessage = message ?? string.Empty;
|
||||
LogEntry($"[{lastErrorCode}] {lastErrorMessage}", LogLevels.Error);
|
||||
}
|
||||
|
||||
public override async Task<bool> LogonAsync()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_LOGON_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return false;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var testMailboxes = exchangeManager.GetSharedMailboxes(
|
||||
"Name -like '*'",
|
||||
out string errorCode,
|
||||
out string errorMessage);
|
||||
if (testMailboxes == null)
|
||||
{
|
||||
SetLastError(errorCode, $"Failed to connect to Exchange: {errorMessage}");
|
||||
isLoggedOn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (testMailboxes != null)
|
||||
{
|
||||
LogEntry("Successfully connected to Exchange", LogLevels.Info);
|
||||
isLoggedOn = true;
|
||||
ClearLastError();
|
||||
return true;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogException(ex);
|
||||
SetLastError("EXCH_LOGON_EXCEPTION", $"Failed to connect to Exchange: {ex.Message}");
|
||||
isLoggedOn = false;
|
||||
return false;
|
||||
}
|
||||
|
||||
SetLastError("EXCH_LOGON_FAILED", "Unknown error connecting to Exchange");
|
||||
return false;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_LOGON_EXCEPTION", $"Exception during Exchange logon: {E.Message}");
|
||||
return false;
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
}
|
||||
@@ -162,88 +162,90 @@ namespace C4IT.LIAM
|
||||
return lastErrorMessage;
|
||||
}
|
||||
|
||||
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int MaxDepth = -1)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_GET_DATAAREAS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
if (!isLoggedOn && !await LogonAsync())
|
||||
return null;
|
||||
|
||||
var DataAreas = new List<cLiamDataAreaBase>();
|
||||
|
||||
// Shared Mailboxes
|
||||
var sharedMailboxes = exchangeManager.GetSharedMailboxes(
|
||||
null,
|
||||
out string sharedErrorCode,
|
||||
out string sharedErrorMessage);
|
||||
if (sharedMailboxes == null)
|
||||
{
|
||||
SetLastError(sharedErrorCode, $"Failed to read shared mailboxes: {sharedErrorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var mailbox in sharedMailboxes)
|
||||
{
|
||||
var displayName = mailbox.Properties["DisplayName"]?.Value?.ToString();
|
||||
var alias = mailbox.Properties["Alias"]?.Value?.ToString();
|
||||
var primarySmtpAddress = mailbox.Properties["PrimarySmtpAddress"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(mailbox.Properties);
|
||||
|
||||
// Filterung via Regex
|
||||
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
|
||||
!Regex.Match(displayName, this.DataAreaRegEx).Success)
|
||||
continue;
|
||||
|
||||
var exchangeMailbox = new cLiamExchangeSharedMailbox(this, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
DataAreas.Add(exchangeMailbox);
|
||||
}
|
||||
|
||||
// Distribution Groups
|
||||
var distributionGroups = exchangeManager.GetDistributionGroups(
|
||||
null,
|
||||
out string distErrorCode,
|
||||
out string distErrorMessage);
|
||||
if (distributionGroups == null)
|
||||
{
|
||||
SetLastError(distErrorCode, $"Failed to read distribution groups: {distErrorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var group in distributionGroups)
|
||||
{
|
||||
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
|
||||
var alias = group.Properties["Alias"]?.Value?.ToString();
|
||||
var primarySmtpAddress = group.Properties["PrimarySmtpAddress"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(group.Properties);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
|
||||
!Regex.Match(displayName, this.DataAreaRegEx).Success)
|
||||
continue;
|
||||
|
||||
var exchangeGroup = new cLiamExchangeDistributionGroup(this, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
DataAreas.Add(exchangeGroup);
|
||||
}
|
||||
|
||||
ClearLastError();
|
||||
return DataAreas;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_GET_DATAAREAS_EXCEPTION", E.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
public override async Task<List<cLiamDataAreaBase>> getDataAreasAsync(int MaxDepth = -1)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_GET_DATAAREAS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
if (!isLoggedOn && !await LogonAsync())
|
||||
return null;
|
||||
|
||||
var DataAreas = new List<cLiamDataAreaBase>();
|
||||
|
||||
// Shared Mailboxes
|
||||
var sharedMailboxes = exchangeManager.GetSharedMailboxes(
|
||||
null,
|
||||
out string sharedErrorCode,
|
||||
out string sharedErrorMessage);
|
||||
if (sharedMailboxes == null)
|
||||
{
|
||||
SetLastError(sharedErrorCode, $"Failed to read shared mailboxes: {sharedErrorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var mailbox in sharedMailboxes)
|
||||
{
|
||||
var displayName = mailbox.Properties["DisplayName"]?.Value?.ToString();
|
||||
var alias = mailbox.Properties["Alias"]?.Value?.ToString();
|
||||
var primarySmtpAddress = mailbox.Properties["PrimarySmtpAddress"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(mailbox.Properties);
|
||||
|
||||
// Filterung via Regex
|
||||
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
|
||||
!Regex.Match(displayName, this.DataAreaRegEx).Success)
|
||||
continue;
|
||||
|
||||
var exchangeMailbox = new cLiamExchangeSharedMailbox(this, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
await exchangeMailbox.ResolvePermissionGroupsAsync();
|
||||
DataAreas.Add(exchangeMailbox);
|
||||
}
|
||||
|
||||
// Distribution Groups
|
||||
var distributionGroups = exchangeManager.GetDistributionGroups(
|
||||
null,
|
||||
out string distErrorCode,
|
||||
out string distErrorMessage);
|
||||
if (distributionGroups == null)
|
||||
{
|
||||
SetLastError(distErrorCode, $"Failed to read distribution groups: {distErrorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var group in distributionGroups)
|
||||
{
|
||||
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
|
||||
var alias = group.Properties["Alias"]?.Value?.ToString();
|
||||
var primarySmtpAddress = group.Properties["PrimarySmtpAddress"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(group.Properties);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.DataAreaRegEx) &&
|
||||
!Regex.Match(displayName, this.DataAreaRegEx).Success)
|
||||
continue;
|
||||
|
||||
var exchangeGroup = new cLiamExchangeDistributionGroup(this, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
await exchangeGroup.ResolvePermissionGroupsAsync();
|
||||
DataAreas.Add(exchangeGroup);
|
||||
}
|
||||
|
||||
ClearLastError();
|
||||
return DataAreas;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_GET_DATAAREAS_EXCEPTION", E.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -289,59 +291,59 @@ namespace C4IT.LIAM
|
||||
}
|
||||
}
|
||||
|
||||
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_GET_SECURITYGROUPS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
if (!isLoggedOn && !await LogonAsync())
|
||||
return null;
|
||||
|
||||
var securityGroups = new List<cLiamDataAreaBase>();
|
||||
var groups = exchangeManager.GetSecurityGroups(
|
||||
groupFilter,
|
||||
out string errorCode,
|
||||
out string errorMessage);
|
||||
if (groups == null)
|
||||
{
|
||||
SetLastError(errorCode, $"Failed to read security groups: {errorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
|
||||
var sid = group.Properties["Sid"]?.Value?.ToString();
|
||||
var dn = group.Properties["DistinguishedName"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(group.Properties);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.GroupRegEx) &&
|
||||
!Regex.Match(displayName, this.GroupRegEx).Success)
|
||||
continue;
|
||||
|
||||
var securityGroup = new cLiamExchangeSecurityGroup(this, displayName, sid, dn, objectGuid);
|
||||
securityGroups.Add(securityGroup);
|
||||
}
|
||||
|
||||
ClearLastError();
|
||||
return securityGroups;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_GET_SECURITYGROUPS_EXCEPTION", E.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
public override async Task<List<cLiamDataAreaBase>> getSecurityGroupsAsync(string groupFilter)
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
try
|
||||
{
|
||||
ClearLastError();
|
||||
if (!cC4ITLicenseM42ESM.Instance.IsValid)
|
||||
{
|
||||
SetLastError("EXCH_GET_SECURITYGROUPS_LICENSE_INVALID", "License not valid or Exchange module not licensed");
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
if (!isLoggedOn && !await LogonAsync())
|
||||
return null;
|
||||
|
||||
var securityGroups = new List<cLiamDataAreaBase>();
|
||||
var groups = exchangeManager.GetSecurityGroups(
|
||||
groupFilter,
|
||||
out string errorCode,
|
||||
out string errorMessage);
|
||||
if (groups == null)
|
||||
{
|
||||
SetLastError(errorCode, $"Failed to read security groups: {errorMessage}");
|
||||
return null;
|
||||
}
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var displayName = group.Properties["DisplayName"]?.Value?.ToString();
|
||||
var sid = group.Properties["Sid"]?.Value?.ToString();
|
||||
var dn = group.Properties["DistinguishedName"]?.Value?.ToString();
|
||||
var objectGuid = ExtractObjectGuid(group.Properties);
|
||||
|
||||
if (!string.IsNullOrEmpty(this.GroupRegEx) &&
|
||||
!Regex.Match(displayName, this.GroupRegEx).Success)
|
||||
continue;
|
||||
|
||||
var securityGroup = new cLiamExchangeSecurityGroup(this, displayName, sid, dn, objectGuid);
|
||||
securityGroups.Add(securityGroup);
|
||||
}
|
||||
|
||||
ClearLastError();
|
||||
return securityGroups;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
LogException(E);
|
||||
SetLastError("EXCH_GET_SECURITYGROUPS_EXCEPTION", E.Message);
|
||||
}
|
||||
finally
|
||||
{
|
||||
LogMethodEnd(CM);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
@@ -496,7 +498,6 @@ namespace C4IT.LIAM
|
||||
this.DataType = eLiamDataAreaTypes.ExchangeSharedMailbox;
|
||||
this.SupportsOwners = true;
|
||||
this.SupportsPermissions = true;
|
||||
_ = assignPermissionGroups(Provider).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal static string getUID(string primarySmtpAddress)
|
||||
@@ -518,7 +519,9 @@ namespace C4IT.LIAM
|
||||
var alias = mailbox.Properties["Alias"]?.Value?.ToString();
|
||||
var objectGuid = cLiamProviderExchange.ExtractObjectGuid(mailbox.Properties);
|
||||
|
||||
return new cLiamExchangeSharedMailbox(Provider, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
var mailboxDataArea = new cLiamExchangeSharedMailbox(Provider, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
await mailboxDataArea.ResolvePermissionGroupsAsync();
|
||||
return mailboxDataArea;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -639,7 +642,7 @@ namespace C4IT.LIAM
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
private async Task assignPermissionGroups(cLiamProviderExchange Provider)
|
||||
public async Task ResolvePermissionGroupsAsync()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
@@ -745,7 +748,6 @@ namespace C4IT.LIAM
|
||||
this.DataType = eLiamDataAreaTypes.ExchangeDistributionGroup;
|
||||
this.SupportsOwners = true;
|
||||
this.SupportsPermissions = true;
|
||||
_ = assignPermissionGroups(Provider).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
internal static string getUID(string primarySmtpAddress)
|
||||
@@ -767,7 +769,9 @@ namespace C4IT.LIAM
|
||||
var alias = group.Properties["Alias"]?.Value?.ToString();
|
||||
var objectGuid = cLiamProviderExchange.ExtractObjectGuid(group.Properties);
|
||||
|
||||
return new cLiamExchangeDistributionGroup(Provider, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
var groupDataArea = new cLiamExchangeDistributionGroup(Provider, displayName, primarySmtpAddress, alias, objectGuid);
|
||||
await groupDataArea.ResolvePermissionGroupsAsync();
|
||||
return groupDataArea;
|
||||
}
|
||||
catch (Exception E)
|
||||
{
|
||||
@@ -875,7 +879,7 @@ namespace C4IT.LIAM
|
||||
return new List<cLiamDataAreaBase>();
|
||||
}
|
||||
|
||||
private async Task assignPermissionGroups(cLiamProviderExchange Provider)
|
||||
public async Task ResolvePermissionGroupsAsync()
|
||||
{
|
||||
var CM = MethodBase.GetCurrentMethod();
|
||||
LogMethodBegin(CM);
|
||||
|
||||
Reference in New Issue
Block a user