-
Notifications
You must be signed in to change notification settings - Fork 9
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #23 from Regenhardt/master
Upgrade to Microsoft To Do and .NET 8
- Loading branch information
Showing
27 changed files
with
719 additions
and
441 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
39 changes: 21 additions & 18 deletions
39
src/Todo.CLI/Auth/TodoCliAuthenticationProviderFactory.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,26 +1,29 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Text; | ||
using Microsoft.Graph; | ||
using Microsoft.Graph.Auth; | ||
|
||
namespace Todo.CLI.Auth; | ||
|
||
using Microsoft.Extensions.DependencyInjection; | ||
using Microsoft.Identity.Client; | ||
using Microsoft.Kiota.Abstractions.Authentication; | ||
|
||
namespace Todo.CLI.Auth | ||
static class TodoCliAuthenticationProviderFactory | ||
{ | ||
static class TodoCliAuthenticationProviderFactory | ||
public static IAuthenticationProvider GetAuthenticationProvider(IServiceProvider factory) | ||
{ | ||
public static IAuthenticationProvider GetAuthenticationProvider(IServiceProvider factory) | ||
{ | ||
var config = (TodoCliConfiguration)factory.GetService(typeof(TodoCliConfiguration)); | ||
var config = factory.GetRequiredService<TodoCliConfiguration>(); | ||
|
||
IPublicClientApplication app = PublicClientApplicationBuilder | ||
.Create(config.ClientId) | ||
.WithRedirectUri("http://localhost") // Only loopback redirect uri is supported, see https://aka.ms/msal-net-os-browser for details | ||
.Build(); | ||
|
||
TokenCacheHelper.EnableSerialization(app.UserTokenCache); | ||
|
||
IPublicClientApplication app = PublicClientApplicationBuilder | ||
.Create(config.ClientId) | ||
.WithRedirectUri("http://localhost") // Only loopback redirect uri is supported, see https://aka.ms/msal-net-os-browser for details | ||
.Build(); | ||
|
||
TokenCacheHelper.EnableSerialization(app.UserTokenCache); | ||
var login = app.AcquireTokenInteractive(config.Scopes).WithPrompt(Prompt.NoPrompt).ExecuteAsync() | ||
.GetAwaiter().GetResult(); | ||
var token = login.AccessToken; | ||
|
||
return new InteractiveAuthenticationProvider(app, config.Scopes); | ||
} | ||
return new ApiKeyAuthenticationProvider("Bearer " + token, "Authorization", | ||
ApiKeyAuthenticationProvider.KeyLocation.Header); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,55 +1,51 @@ | ||
using Microsoft.Identity.Client; | ||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Security.Cryptography; | ||
using System.Text; | ||
|
||
namespace Todo.CLI.Auth | ||
namespace Todo.CLI.Auth; | ||
|
||
static class TokenCacheHelper | ||
{ | ||
static class TokenCacheHelper | ||
public static void EnableSerialization(ITokenCache tokenCache) | ||
{ | ||
public static void EnableSerialization(ITokenCache tokenCache) | ||
{ | ||
tokenCache.SetBeforeAccess(BeforeAccessNotification); | ||
tokenCache.SetAfterAccess(AfterAccessNotification); | ||
} | ||
tokenCache.SetBeforeAccess(BeforeAccessNotification); | ||
tokenCache.SetAfterAccess(AfterAccessNotification); | ||
} | ||
|
||
/// <summary> | ||
/// Path to the token cache | ||
/// </summary> | ||
public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin3"; | ||
/// <summary> | ||
/// Path to the token cache | ||
/// </summary> | ||
public static readonly string CacheFilePath = System.Reflection.Assembly.GetExecutingAssembly().Location + ".msalcache.bin"; | ||
|
||
private static readonly object FileLock = new object(); | ||
private static readonly object FileLock = new object(); | ||
|
||
|
||
private static void BeforeAccessNotification(TokenCacheNotificationArgs args) | ||
private static void BeforeAccessNotification(TokenCacheNotificationArgs args) | ||
{ | ||
lock (FileLock) | ||
{ | ||
lock (FileLock) | ||
{ | ||
args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath) | ||
? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath), | ||
null, | ||
DataProtectionScope.CurrentUser) | ||
: null); | ||
} | ||
args.TokenCache.DeserializeMsalV3(File.Exists(CacheFilePath) | ||
? ProtectedData.Unprotect(File.ReadAllBytes(CacheFilePath), | ||
null, | ||
DataProtectionScope.CurrentUser) | ||
: null); | ||
} | ||
} | ||
|
||
private static void AfterAccessNotification(TokenCacheNotificationArgs args) | ||
private static void AfterAccessNotification(TokenCacheNotificationArgs args) | ||
{ | ||
// if the access operation resulted in a cache update | ||
if (args.HasStateChanged) | ||
{ | ||
// if the access operation resulted in a cache update | ||
if (args.HasStateChanged) | ||
lock (FileLock) | ||
{ | ||
lock (FileLock) | ||
{ | ||
// reflect changesgs in the persistent store | ||
File.WriteAllBytes(CacheFilePath, | ||
ProtectedData.Protect(args.TokenCache.SerializeMsalV3(), | ||
null, | ||
DataProtectionScope.CurrentUser) | ||
); | ||
} | ||
// reflect changesgs in the persistent store | ||
File.WriteAllBytes(CacheFilePath, | ||
ProtectedData.Protect(args.TokenCache.SerializeMsalV3(), | ||
null, | ||
DataProtectionScope.CurrentUser) | ||
); | ||
} | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,29 +1,40 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.CommandLine; | ||
using System.Text; | ||
using Todo.CLI.Handlers; | ||
|
||
namespace Todo.CLI.Commands | ||
namespace Todo.CLI.Commands; | ||
|
||
public class AddCommand : Command | ||
{ | ||
public class AddCommand : Command | ||
public AddCommand(IServiceProvider serviceProvider) : base("add", "Adds a to do item or list.") | ||
{ | ||
public AddCommand(IServiceProvider serviceProvider) : base("add") | ||
{ | ||
Description = "Adds a to do item."; | ||
Add(new AddListCommand(serviceProvider)); | ||
Add(new AddItemCommand(serviceProvider)); | ||
} | ||
|
||
internal class AddListCommand : Command | ||
{ | ||
private static readonly Argument<string> NameArgument = new("name", "The name of the new to do list."); | ||
|
||
AddArgument(GetSubjectArgument()); | ||
public AddListCommand(IServiceProvider serviceProvider) : base("list", "Adds a new to do list.") | ||
{ | ||
AddArgument(NameArgument); | ||
|
||
Handler = AddCommandHandler.Create(serviceProvider); | ||
this.SetHandler(AddCommandHandler.List.Create(serviceProvider), NameArgument); | ||
} | ||
} | ||
|
||
private Argument GetSubjectArgument() | ||
internal class AddItemCommand : Command | ||
{ | ||
private static readonly Argument<string> ListArgument = new("list", "The list to add the to do item to."); | ||
private static readonly Argument<string> SubjectArgument = new("subject", "The subject of the new to do item."); | ||
|
||
public AddItemCommand(IServiceProvider serviceProvider) : base("item", "Adds a new to do item to the given list.") | ||
{ | ||
return new Argument("subject") | ||
{ | ||
Description = "The subject of the new to do item.", | ||
ArgumentType = typeof(string) | ||
}; | ||
AddArgument(ListArgument); | ||
AddArgument(SubjectArgument); | ||
|
||
this.SetHandler(AddCommandHandler.Item.Create(serviceProvider), ListArgument, SubjectArgument); | ||
} | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,25 +1,25 @@ | ||
using System; | ||
using System.CommandLine; | ||
using Todo.CLI.Handlers; | ||
using Todo.Core; | ||
using Todo.Core.Model; | ||
|
||
namespace Todo.CLI.Commands | ||
namespace Todo.CLI.Commands; | ||
|
||
public class CompleteCommand : Command | ||
{ | ||
public class CompleteCommand : Command | ||
{ | ||
public CompleteCommand(IServiceProvider serviceProvider) : base("complete") | ||
{ | ||
Description = "Completes a to do item."; | ||
private static readonly Argument<string> ItemArg = | ||
new("name", | ||
"The name of the todo item to complete. If multiple lists have this item, the first one will be completed.") | ||
{ Arity = ArgumentArity.ZeroOrOne }; | ||
private static readonly Option<string> ListOpt = new(["--list", "-l"], "The name of the list to complete the item in.") | ||
{ Arity = ArgumentArity.ZeroOrOne }; | ||
|
||
AddOption(GetItemOption()); | ||
public CompleteCommand(IServiceProvider serviceProvider) : base("complete") | ||
{ | ||
Description = "Completes a to do item."; | ||
|
||
Handler = CompleteCommandHandler.Create(serviceProvider); | ||
} | ||
Add(ItemArg); | ||
Add(ListOpt); | ||
|
||
private Option GetItemOption() | ||
{ | ||
return new Option(new string[] { "id", "item-id" }, "The unique identifier of the todo item to complete."); | ||
} | ||
this.SetHandler(CompleteCommandHandler.Create(serviceProvider), ItemArg, ListOpt); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,31 +1,35 @@ | ||
using System; | ||
using System.CommandLine; | ||
using Todo.CLI.Handlers; | ||
using Todo.Core; | ||
|
||
namespace Todo.CLI.Commands | ||
namespace Todo.CLI.Commands; | ||
|
||
public class ListCommand : Command | ||
{ | ||
public class ListCommand : Command | ||
{ | ||
public ListCommand(IServiceProvider serviceProvider) : base("list") | ||
{ | ||
Description = "Retrieves a list of the to do items."; | ||
private static readonly Option<bool> GetAllOption = | ||
new(["-a", "--all"], "Lists all to do items including the completed ones."); | ||
|
||
private static readonly Option<bool> NoStatusOption = new(["--no-status"], | ||
"Suppresses the bullet indicating whether the item is completed or not."); | ||
|
||
AddOption(GetAllOption()); | ||
AddOption(GetNoStatusOption()); | ||
private static readonly Option<DateTime?> OlderThanOption = | ||
new(["--older-than"], "Only items completed before this date."); | ||
|
||
private static readonly Argument<string> ListNameArgument = new("list-name", "Only list tasks of this To-Do list.") | ||
{ | ||
Arity = ArgumentArity.ZeroOrOne | ||
}; | ||
|
||
Handler = ListCommandHandler.Create(serviceProvider); | ||
} | ||
|
||
private Option GetAllOption() | ||
{ | ||
return new Option(new string[] { "-a", "--all" }, "Lists all to do items including the completed ones."); | ||
} | ||
public ListCommand(IServiceProvider serviceProvider) : base("list") | ||
{ | ||
Description = "Retrieves a list of the to do items across all To-Do lists."; | ||
|
||
private Option GetNoStatusOption() | ||
{ | ||
return new Option(new string[] { "--no-status" }, "Suppresses the bullet indicating whether the item is completed or not."); | ||
} | ||
Add(GetAllOption); | ||
Add(NoStatusOption); | ||
Add(OlderThanOption); | ||
Add(ListNameArgument); | ||
|
||
this.SetHandler(ListCommandHandler.Create(serviceProvider), GetAllOption, NoStatusOption, OlderThanOption, ListNameArgument); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,17 +1,17 @@ | ||
using System; | ||
using System.CommandLine; | ||
using Todo.CLI.Handlers; | ||
using Todo.Core; | ||
using Todo.Core.Model; | ||
|
||
namespace Todo.CLI.Commands | ||
namespace Todo.CLI.Commands; | ||
|
||
public class RemoveCommand : Command | ||
{ | ||
public class RemoveCommand : Command | ||
private static readonly Option<string> ListOpt = new(["--list", "-l"], "The name of the list to remove the item from."); | ||
private static readonly Option<DateTime?> OlderThanOpt = new(new[] { "--older-than" }, "Only items completed before this date."); | ||
public RemoveCommand(IServiceProvider serviceProvider) : base("remove", "Deletes a to do item.") | ||
{ | ||
public RemoveCommand(IServiceProvider serviceProvider) : base("remove") | ||
{ | ||
Description = "Deletes a to do item."; | ||
Handler = RemoveCommandHandler.Create(serviceProvider); | ||
} | ||
Add(ListOpt); | ||
Add(OlderThanOpt); | ||
this.SetHandler(RemoveCommandHandler.Create(serviceProvider), ListOpt, OlderThanOpt); | ||
} | ||
} |
Oops, something went wrong.