From f73dbf03d65c53ea0615c342cbc30b6da3720c61 Mon Sep 17 00:00:00 2001 From: jbe2277 Date: Tue, 21 Jan 2025 21:11:08 +0100 Subject: [PATCH] NewsReader: Workaround for Graph SDK and use MSAL Broker on Windows (#70) * NR: Adapt MSAL on Windows; update packages * NR: Rollback unit testing packages to previous version * NR: Use MSAL Broker on Windows * NR: Workaround for MS Graph to get the required driveId https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/2624 --- src/NewsReader/Directory.Build.props | 2 +- src/NewsReader/Directory.Packages.props | 8 +++---- .../NewsReader.Presentation/App.xaml.cs | 3 +++ .../NewsReader.Presentation.csproj | 2 +- .../Services/WebStorageService.cs | 24 ++++++++++++------- 5 files changed, 25 insertions(+), 14 deletions(-) diff --git a/src/NewsReader/Directory.Build.props b/src/NewsReader/Directory.Build.props index 565f222c..cee095db 100644 --- a/src/NewsReader/Directory.Build.props +++ b/src/NewsReader/Directory.Build.props @@ -1,6 +1,6 @@  - 9.0.21 + 9.0.22 en enable diff --git a/src/NewsReader/Directory.Packages.props b/src/NewsReader/Directory.Packages.props index e75f89fe..81ec3ec7 100644 --- a/src/NewsReader/Directory.Packages.props +++ b/src/NewsReader/Directory.Packages.props @@ -11,10 +11,10 @@ - - - - + + + + diff --git a/src/NewsReader/NewsReader.Presentation/App.xaml.cs b/src/NewsReader/NewsReader.Presentation/App.xaml.cs index 654ad8ae..0d7a23e6 100644 --- a/src/NewsReader/NewsReader.Presentation/App.xaml.cs +++ b/src/NewsReader/NewsReader.Presentation/App.xaml.cs @@ -43,6 +43,8 @@ public App(ISettingsService settingsService, IAppInfoService appInfoService, Laz public static string LogFileName { get; } = Path.Combine(FileSystem.CacheDirectory, "Logging", "AppLog.txt"); + public static Window? CurrentWindow { get; private set; } + protected override Window CreateWindow(IActivationState? activationState) { var window = new Window((Page)appController.MainView) @@ -56,6 +58,7 @@ protected override Window CreateWindow(IActivationState? activationState) window.Stopped += (_, _) => OnStopped(); window.Destroying += (_, _) => OnDestroying(); window.Resumed += (_, _) => OnResumed(); + CurrentWindow = window; return window; } diff --git a/src/NewsReader/NewsReader.Presentation/NewsReader.Presentation.csproj b/src/NewsReader/NewsReader.Presentation/NewsReader.Presentation.csproj index 23452585..3e6d4cd6 100644 --- a/src/NewsReader/NewsReader.Presentation/NewsReader.Presentation.csproj +++ b/src/NewsReader/NewsReader.Presentation/NewsReader.Presentation.csproj @@ -16,7 +16,7 @@ - + diff --git a/src/NewsReader/NewsReader.Presentation/Services/WebStorageService.cs b/src/NewsReader/NewsReader.Presentation/Services/WebStorageService.cs index 4d829721..6d23aa2f 100644 --- a/src/NewsReader/NewsReader.Presentation/Services/WebStorageService.cs +++ b/src/NewsReader/NewsReader.Presentation/Services/WebStorageService.cs @@ -2,7 +2,6 @@ using Microsoft.Graph.Models; using Microsoft.Graph.Models.ODataErrors; using Microsoft.Identity.Client; -using Microsoft.Identity.Client.Extensions.Msal; using Microsoft.Kiota.Abstractions.Authentication; using Waf.NewsReader.Applications.Services; @@ -41,6 +40,12 @@ public WebStorageService() builder.WithParentActivityOrWindow(() => Platform.CurrentActivity); #elif IOS builder.WithIosKeychainSecurityGroup(Foundation.NSBundle.MainBundle.BundleIdentifier); +#elif WINDOWS + Microsoft.Identity.Client.Broker.BrokerExtension.WithBroker(builder, new BrokerOptions(BrokerOptions.OperatingSystems.Windows) + { + Title = AppInfo.Name + }); + builder.WithParentActivityOrWindow(() => WinRT.Interop.WindowNative.GetWindowHandle(App.CurrentWindow!.Handler.PlatformView!)); #endif publicClient = builder.Build(); } @@ -61,8 +66,8 @@ public async Task TrySilentSignIn() if (!cacheInitialized && publicClient is not null) { cacheInitialized = true; - var storageProperties = new StorageCreationPropertiesBuilder("msal.dat", FileSystem.CacheDirectory).Build(); - var cacheHelper = await MsalCacheHelper.CreateAsync(storageProperties); + var storageProperties = new Microsoft.Identity.Client.Extensions.Msal.StorageCreationPropertiesBuilder("msal.dat", FileSystem.CacheDirectory).Build(); + var cacheHelper = await Microsoft.Identity.Client.Extensions.Msal.MsalCacheHelper.CreateAsync(storageProperties); cacheHelper.RegisterCache(publicClient.UserTokenCache); } #endif @@ -180,11 +185,14 @@ private async Task InitGraphClient() private async Task GetItemRequest(string fileName) { if (graphClient is null) throw new InvalidOperationException("graphClient is null"); - var driveItem = await graphClient.Me.Drive.GetAsync().ConfigureAwait(false); - ArgumentNullException.ThrowIfNull(driveItem); - var appRootFolder = await graphClient.Drives[driveItem.Id].Special["AppRoot"].GetAsync().ConfigureAwait(false); - ArgumentNullException.ThrowIfNull(appRootFolder); - return graphClient.Drives[driveItem.Id].Items[appRootFolder.Id].ItemWithPath(fileName); + + // Using workaround to get the driveId because AppFolder scope does not allow to the read Drive directly. https://github.com/microsoftgraph/msgraph-sdk-dotnet/issues/2624 + var result = await graphClient.Me.Drive.WithUrl($"{graphClient.RequestAdapter.BaseUrl}/drive/special/approot:/{fileName}").GetAsync().ConfigureAwait(false); + var driveId = result?.Id?.Split("!")[0] ?? throw new InvalidOperationException("graphClient: not able to get the driveId"); + + var appRootFolder = await graphClient.Drives[driveId].Special["AppRoot"].GetAsync().ConfigureAwait(false) + ?? throw new InvalidOperationException("graphClient: not able to get the appRootFolder"); + return graphClient.Drives[driveId].Items[appRootFolder.Id].ItemWithPath(fileName); } static partial void GetApplicationId(ref string? applicationId);