Files
EpiAutoReminder/EpiAutoReminder/O365Connector.cs

177 lines
5.9 KiB
C#

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using log4net;
using Microsoft.Graph;
using Microsoft.Graph.Models;
using Microsoft.Identity.Client;
using Microsoft.Kiota.Abstractions.Authentication;
namespace EpiAutoReminder
{
internal class O365Connector
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(O365Connector));
private readonly string clientID;
private readonly string clientSecret;
private readonly string tenantID;
private readonly 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<string> CreateDraftMailAsync(
string to,
string sender,
string subject,
string body,
string cc = null,
string bcc = null)
{
try
{
Logger.Info("CreateDraftMailAsync gestartet.");
if (string.IsNullOrWhiteSpace(to))
throw new ArgumentException("TO darf nicht leer sein.", nameof(to));
if (string.IsNullOrWhiteSpace(sender))
throw new ArgumentException("Sender darf nicht leer sein.", nameof(sender));
var graphClient = await GetGraphClient();
var message = new Message
{
Subject = subject ?? string.Empty,
Body = new ItemBody
{
ContentType = BodyType.Text,
Content = body ?? string.Empty
},
ToRecipients = new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = to.Trim()
}
}
},
CcRecipients = string.IsNullOrWhiteSpace(cc)
? new List<Recipient>()
: new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = cc.Trim()
}
}
},
BccRecipients = string.IsNullOrWhiteSpace(bcc)
? new List<Recipient>()
: new List<Recipient>
{
new Recipient
{
EmailAddress = new EmailAddress
{
Address = bcc.Trim()
}
}
}
};
Logger.Info($"Erstelle Draft für Sender '{sender}' an '{to}'.");
var createdDraft = await graphClient
.Users[sender]
.Messages
.PostAsync(message);
if (createdDraft == null || string.IsNullOrWhiteSpace(createdDraft.Id))
throw new Exception("Entwurf konnte nicht erstellt werden.");
Logger.Info($"Draft mail created for '{sender}' with id '{createdDraft.Id}'.");
return createdDraft.Id;
}
catch (Exception ex)
{
Logger.Error("Fehler beim Draft erstellen", ex);
throw;
}
}
private async Task<GraphServiceClient> GetGraphClient()
{
try
{
Logger.Info("Initialisiere GraphServiceClient...");
var clientApp = ConfidentialClientApplicationBuilder.Create(clientID)
.WithClientSecret(clientSecret)
.WithAuthority(new Uri($"{baseUrl}/{tenantID}"))
.Build();
var accessTokenProvider = new TokenAcquisitionProvider(clientApp);
var authProvider = new BaseBearerTokenAuthenticationProvider(accessTokenProvider);
Logger.Info("GraphServiceClient erfolgreich initialisiert.");
return new GraphServiceClient(authProvider);
}
catch (Exception ex)
{
Logger.Error("Error initializing GraphServiceClient: " + ex.Message, ex);
throw;
}
}
}
public class TokenAcquisitionProvider : IAccessTokenProvider
{
private static readonly ILog Logger = LogManager.GetLogger(typeof(TokenAcquisitionProvider));
private readonly IConfidentialClientApplication _clientApp;
public TokenAcquisitionProvider(IConfidentialClientApplication clientApp)
{
_clientApp = clientApp;
}
public async Task<string> GetAuthorizationTokenAsync(
Uri uri,
Dictionary<string, object>? additionalAuthenticationContext = null,
CancellationToken cancellationToken = default)
{
try
{
Logger.Info("Fordere Access Token für Microsoft Graph an...");
var result = await _clientApp
.AcquireTokenForClient(new[] { "https://graph.microsoft.com/.default" })
.ExecuteAsync(cancellationToken);
Logger.Info("Access Token erfolgreich geholt.");
return result.AccessToken;
}
catch (Exception ex)
{
Logger.Error("Error acquiring token: " + ex.Message, ex);
throw;
}
}
public AllowedHostsValidator AllowedHostsValidator { get; } = new AllowedHostsValidator();
}
}