diff --git a/Guppi.Application/Guppi.Application.csproj b/Guppi.Application/Guppi.Application.csproj index 51244c1..d11822c 100644 --- a/Guppi.Application/Guppi.Application.csproj +++ b/Guppi.Application/Guppi.Application.csproj @@ -5,19 +5,19 @@ Rob Prouse Alteridem Consulting Guppi command line utility - Copyright (c) 2023 Rob Prouse + Copyright (c) 2024 Rob Prouse - - + + - + diff --git a/Guppi.Console/Guppi.Console.csproj b/Guppi.Console/Guppi.Console.csproj index 2993bea..5f0b1c7 100644 --- a/Guppi.Console/Guppi.Console.csproj +++ b/Guppi.Console/Guppi.Console.csproj @@ -8,12 +8,12 @@ Rob Prouse Alteridem Consulting Guppi command line utility - Copyright (c) 2023 Rob Prouse + Copyright (c) 2024 Rob Prouse LICENSE https://github.com/rprouse/guppi https://github.com/rprouse/guppi dotnet-guppi - 5.1.0 + 5.1.1 true guppi ./nupkg @@ -44,7 +44,7 @@ - + diff --git a/Guppi.Console/Properties/launchSettings.json b/Guppi.Console/Properties/launchSettings.json index af2a703..38705d8 100644 --- a/Guppi.Console/Properties/launchSettings.json +++ b/Guppi.Console/Properties/launchSettings.json @@ -1,8 +1,8 @@ { "profiles": { "Guppi.Console": { - "commandName": "Project", - "commandLineArgs": "weather daily" + "commandName": "Project", + "commandLineArgs": "cal agenda" } } -} +} \ No newline at end of file diff --git a/Guppi.Infrastructure/DependencyInjection.cs b/Guppi.Infrastructure/DependencyInjection.cs index afe9204..8bce757 100644 --- a/Guppi.Infrastructure/DependencyInjection.cs +++ b/Guppi.Infrastructure/DependencyInjection.cs @@ -23,7 +23,6 @@ public static IServiceCollection AddInfrastructure(this IServiceCollection servi return client; }) .AddTransient() - .AddTransient() .AddTransient() .AddTransient() .AddTransient() diff --git a/Guppi.Infrastructure/Guppi.Infrastructure.csproj b/Guppi.Infrastructure/Guppi.Infrastructure.csproj index fbb3a7d..e374686 100644 --- a/Guppi.Infrastructure/Guppi.Infrastructure.csproj +++ b/Guppi.Infrastructure/Guppi.Infrastructure.csproj @@ -9,19 +9,16 @@ - - - - + - + - - - - + + + + diff --git a/Guppi.Infrastructure/Services/Calendar/CalendarConfiguration.cs b/Guppi.Infrastructure/Services/Calendar/CalendarConfiguration.cs deleted file mode 100644 index 91d4ed8..0000000 --- a/Guppi.Infrastructure/Services/Calendar/CalendarConfiguration.cs +++ /dev/null @@ -1,6 +0,0 @@ -namespace Guppi.Infrastructure.Services.Calendar -{ - internal class CalendarConfiguration - { - } -} \ No newline at end of file diff --git a/Guppi.Infrastructure/Services/Calendar/Office365CalendarService.cs b/Guppi.Infrastructure/Services/Calendar/Office365CalendarService.cs deleted file mode 100644 index 515666a..0000000 --- a/Guppi.Infrastructure/Services/Calendar/Office365CalendarService.cs +++ /dev/null @@ -1,130 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Net.Http.Headers; -using System.Threading.Tasks; -using Guppi.Application.Exceptions; -using Guppi.Domain.Interfaces; -using Microsoft.Graph; -using Microsoft.Identity.Client; -using Event = Guppi.Domain.Entities.Calendar.Event; - -namespace Guppi.Infrastructure.Services.Calendar -{ - internal sealed class Office365CalendarService : ICalendarService - { - const string ClientId = "b4b31f71-ccd0-4161-98d5-30871f959ec5"; - public string Name => "Office 365 Calendar"; - - public async Task> GetCalendarEvents(DateTime? minDate, DateTime? maxDate) - { - string accessToken = await Login(); - - var graphClient = new GraphServiceClient( - new DelegateAuthenticationProvider((requestMessage) => - { - requestMessage - .Headers - .Authorization = new AuthenticationHeaderValue("bearer", accessToken); - - return Task.CompletedTask; - })); - - var calendars = await graphClient.Me.Calendars - .Request() - .GetAsync(); - - // TODO: Configure which calendar - var calendar = calendars.FirstOrDefault(c => c.IsDefaultCalendar == true); - - var start = (minDate ?? DateTime.Now).ToString("O"); - var end = (maxDate ?? DateTime.Now.AddDays(1)).ToString("O"); - var queryOptions = new List() - { - new ("startDateTime", start), - new ("endDateTime", end), - new ("top", "100"), - }; - var calendarView = await graphClient.Me.Calendars[calendar?.Id].CalendarView - .Request(queryOptions) - .GetAsync(); - - return calendarView - .Select(item => new Event - { - Start = DateTime.Parse(item.Start.DateTime).ToLocalTime(), - End = DateTime.Parse(item.End.DateTime).ToLocalTime(), - Summary = item.Subject, - MeetingUrl = item.OnlineMeetingUrl, - }) - .ToList(); - } - - private static async Task Login() - { - IPublicClientApplication publicClientApp = await CreatePublicClientApplication(); - - var scopes = new[] { "calendars.read" }; - var accounts = await publicClientApp.GetAccountsAsync(); - var firstAccount = accounts.FirstOrDefault(); - AuthenticationResult result; - try - { - result = await publicClientApp - .AcquireTokenSilent(scopes, firstAccount) - .ExecuteAsync(); - } - catch (MsalUiRequiredException) - { - try - { - result = await publicClientApp - .AcquireTokenInteractive(scopes) - .WithAccount(firstAccount) - .WithPrompt(Microsoft.Identity.Client.Prompt.SelectAccount) - .ExecuteAsync(); - } - catch (MsalException msalex) - { - throw new UnauthorizedException($"Failed to login to Office 365: {msalex.Message}"); - } - } - catch (Exception ex) - { - throw new UnauthorizedException($"Failed to login to Office 365: {ex.Message}"); - } - - var accessToken = result.AccessToken; - return accessToken; - } - - public async Task Logout() - { - IPublicClientApplication publicClientApp = await CreatePublicClientApplication(); - var accounts = await publicClientApp.GetAccountsAsync(); - if (accounts.Any()) - { - try - { - await publicClientApp.RemoveAsync(accounts.FirstOrDefault()); - } - catch (MsalException ex) - { - return $"Failed to sign out of Office 365: {ex.Message}"; - } - } - return "Signed out of Office 365"; - } - - private static async Task CreatePublicClientApplication() - { - var app = PublicClientApplicationBuilder - .Create(ClientId) - .WithRedirectUri("http://localhost") - .Build(); - - await TokenCacheHelper.RegisterCache(app.UserTokenCache); - return app; - } - } -} diff --git a/Guppi.Infrastructure/Services/Calendar/TokenCacheHelper.cs b/Guppi.Infrastructure/Services/Calendar/TokenCacheHelper.cs deleted file mode 100644 index 317948a..0000000 --- a/Guppi.Infrastructure/Services/Calendar/TokenCacheHelper.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System.IO; -using System.Threading.Tasks; -using Guppi.Application; -using Microsoft.Identity.Client; -using Microsoft.Identity.Client.Extensions.Msal; - -namespace Guppi.Infrastructure.Services.Calendar -{ - static class TokenCacheHelper - { - internal static async Task RegisterCache(ITokenCache tokenCache) - { - var cacheFile = Configuration.GetConfigurationFile("o365.msalcache", "bin"); - var cacheFileName = Path.GetFileName(cacheFile); - var cachePath = Path.GetDirectoryName(cacheFile); - var storageProperties = new StorageCreationPropertiesBuilder(cacheFileName, cachePath).Build(); - var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties); - cacheHelper.RegisterCache(tokenCache); - } - } -} diff --git a/Guppi.Tests/Guppi.Tests.csproj b/Guppi.Tests/Guppi.Tests.csproj index 4e0f71d..39d434e 100644 --- a/Guppi.Tests/Guppi.Tests.csproj +++ b/Guppi.Tests/Guppi.Tests.csproj @@ -13,13 +13,13 @@ - - - + + + all runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/LICENSE b/LICENSE index ad1d580..9a9d07c 100644 --- a/LICENSE +++ b/LICENSE @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2023 Rob Prouse +Copyright (c) 2024 Rob Prouse Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal