166 lines
6.0 KiB
C#
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();
|
|
}
|
|
}
|