-
Notifications
You must be signed in to change notification settings - Fork 0
/
msgraph.cs
107 lines (95 loc) · 4.28 KB
/
msgraph.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
using Microsoft.Extensions.Azure;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Graph;
using Microsoft.Graph.Drives.Item.Items.Item.Workbook.Functions.Duration;
using Microsoft.Graph.Models;
using Microsoft.Identity.Client;
using Microsoft.Identity.Web;
using System.Text.RegularExpressions;
namespace msgraph;
public interface IClient
{
Task<List<task.Task>> TimesheetItems(string userPrincipalName, DateTime dateFrom, DateTime dateTo);
}
public class Client : IClient
{
private GraphServiceClient graphclient;
public static (IClient? client, string? error) New(azure.Auth auth)
{
TokenAcquirerFactory tokenAcquirerFactory = TokenAcquirerFactory.GetDefaultInstance();
IServiceCollection services = tokenAcquirerFactory.Services;
services
.AddMicrosoftGraph();
// Ensure that the tokenAcquirerFactory has the required authentication configuration.
var C = tokenAcquirerFactory.Configuration;
C["AzureAd:Instance"] = auth.Instance;
C["AzureAd:TenantId"] = auth.TenantId;
C["AzureAd:ClientId"] = auth.ClientId;
C["AzureAd:ClientCredentials:0:SourceType"] = "ClientSecret";
C["AzureAd:ClientCredentials:0:ClientSecret"] = auth.ClientSecret;
var serviceProvider = tokenAcquirerFactory.Build();
if(serviceProvider == null)
return (null, "Could not create service provider");
var graphclient = serviceProvider.GetService<GraphServiceClient>();
if(graphclient == null)
return(null, "Could not create graph service client");
return (new Client(graphclient), null);
}
public Client(GraphServiceClient graphclient)
{
this.graphclient = graphclient;
}
// TimesheetItems returns those MS Graph calendar tasks that
// start between the given dates and whose description matches
// the pattern: project (- group) - description.
public async Task<List<task.Task>> TimesheetItems(string userPrincipalName, DateTime dateFrom, DateTime dateTo){
var tasks = new List<task.Task>();
var users = await graphclient.Users.GetAsync(
r => r.Options.WithAppOnly()
);
if(users == null || users.Value == null)
return tasks;
User? targetUser = null;
foreach (var user in users.Value) {
if (user.UserPrincipalName == userPrincipalName)
targetUser = user;
}
if (targetUser != null) {
var events = await graphclient
.Users[$"{targetUser.Id}"]
.Calendar.Events.GetAsync(r => {
r.QueryParameters.Select = new []{"subject", "start", "end"};
// Microsoft graph stores datetimes in UTC. So convert our range to UTC.
var start = dateFrom.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.0000000");
var end = dateTo.ToUniversalTime().ToString("yyyy-MM-ddTHH:mm:ss.0000000");
r.QueryParameters.Filter = $"start/DateTime ge '{start}' and start/DateTime le '{end}' and IsAllDay eq false";
r.QueryParameters.Top = 999;
r.Options.WithAppOnly();
});
if (events == null || events.Value == null)
return tasks;
var eventList = events.Value.ToList();
foreach (var ev in eventList)
{
if(ev == null || ev.Subject == null)
continue;
// proj (- group) - description
var pat = @"^\s*([\w/]+)(?:\s*-\s*([\w/]+))?\s*-\s*(.*)";
var m = Regex.Match(ev.Subject, pat) ;
if (m.Success){
string proj = m.Groups[1].Value;
string group = m.Groups[2].Value;
string desc = m.Groups[3].Value;
// Convert back to local time.
DateTime start = ev.Start.ToDateTime().ToLocalTime();
DateTime end = ev.End.ToDateTime().ToLocalTime();
TimeSpan duration = end.Subtract(start);
tasks.Add (new task.Task(proj, group, desc, start, duration));
}
}
return tasks;
}
return tasks;
}
}