Files
Epi2Exchange2/Epi2O365/O365Connector.cs
2025-02-12 12:10:56 +01:00

166 lines
6.0 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Graph;
using Microsoft.Identity.Client;
using Microsoft.Graph.Models;
using Microsoft.Kiota.Abstractions.Authentication;
using System.ComponentModel.Design;
using log4net;
using System.Threading;
namespace Epi2Exchange2
{
internal class O365Connector
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(O365Connector));
private string clientID;
private string clientSecret;
private string tenantID;
private string BaseUrl;
public O365Connector(string clientID, string clientSecret, string tenantID, string BaseUrl)
{
this.clientID = clientID;
this.clientSecret = clientSecret;
this.tenantID = tenantID;
this.BaseUrl = BaseUrl;
}
public async Task SyncContact(Contact contact, string destinationAccountPrimaryAddress)
{
try
{
var graphClient = await GetGraphClient();
if (await DoesContactExist(contact, destinationAccountPrimaryAddress, graphClient))
{
Logger.Info("Contact " + contact.DisplayName + " found in O365");
string O365ContactID = await GetContactIdByNickName(graphClient, destinationAccountPrimaryAddress, contact.NickName);
if (!string.IsNullOrEmpty(O365ContactID))
{
await graphClient.Users[destinationAccountPrimaryAddress]
.Contacts[O365ContactID]
.PatchAsync(contact);
Logger.Info($"Contact with ID '{O365ContactID}' successfully updated.");
}
else
{
Logger.Warn("No valid contact ID found for update.");
}
}
else
{
Logger.Info("Contact " + contact.DisplayName + " NOT found in O365");
Logger.Info("Creating new Contact");
await graphClient.Users[destinationAccountPrimaryAddress].Contacts.PostAsync(contact);
}
}
catch (Exception ex)
{
Logger.Error("Error while synchronizing contact: " + ex.Message);
}
}
private async Task<string> GetContactIdByNickName(GraphServiceClient graphClient, string userPrimaryMail, string nickName)
{
try
{
var contacts = await graphClient.Users[userPrimaryMail]
.Contacts
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter = $"NickName eq '{nickName}'";
});
var contact = contacts?.Value?.FirstOrDefault();
return contact?.Id;
}
catch (Exception ex)
{
Logger.Error($"Error retrieving contact with NickName '{nickName}': {ex.Message}");
return null;
}
}
private async Task<GraphServiceClient> GetGraphClient()
{
try
{
var clientApp = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri($"{BaseUrl}/{tenantID}"))
.Build();
var accessTokenProvider = new TokenAcquisitionProvider(clientApp);
var authProvider = new BaseBearerTokenAuthenticationProvider(accessTokenProvider);
return new GraphServiceClient(authProvider);
}
catch (Exception ex)
{
Logger.Error("Error initializing GraphServiceClient: " + ex.Message);
throw;
}
}
private async Task<bool> DoesContactExist(Contact contact, string userPrimaryMail, GraphServiceClient graphClient)
{
string NickName = contact.NickName;
if (string.IsNullOrWhiteSpace(NickName))
{
Logger.Warn("No valid NickName found for the given contact.");
return false;
}
try
{
var contacts = await graphClient.Users[userPrimaryMail]
.Contacts
.GetAsync(requestConfiguration =>
{
requestConfiguration.QueryParameters.Filter = $"NickName eq '{NickName}'";
});
bool exists = contacts?.Value != null && contacts.Value.Any();
Logger.Info($"Contact with NickName '{NickName}' exists: {exists}");
return exists;
}
catch (Exception ex)
{
Logger.Error($"Error checking contacts: {ex.Message}");
return false;
}
}
}
public class TokenAcquisitionProvider : IAccessTokenProvider
{
private readonly IConfidentialClientApplication _clientApp;
public TokenAcquisitionProvider(IConfidentialClientApplication clientApp)
{
_clientApp = clientApp;
}
public async Task<string> GetAuthorizationTokenAsync(Uri uri, Dictionary<string, object> additionalAuthenticationContext = default, CancellationToken cancellationToken = default)
{
try
{
var result = await _clientApp.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" })
.ExecuteAsync(cancellationToken);
return result.AccessToken;
}
catch (Exception ex)
{
Logger.Error("Error acquiring token: " + ex.Message);
throw;
}
}
public AllowedHostsValidator AllowedHostsValidator { get; } = new AllowedHostsValidator();
}
}