diff --git a/.vscode/launch.json b/.vscode/launch.json index d0d01c5..fd81e61 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -4,6 +4,7 @@ // For further information visit https://github.com/OmniSharp/omnisharp-vscode/blob/master/debugger-launchjson.md "version": "0.2.0", "configurations": [ + { "name": ".NET Core Launch (console)", @@ -11,9 +12,10 @@ "request": "launch", "preLaunchTask": "build", // If you have changed target frameworks, make sure to update the program path. - "program": "${workspaceFolder}/sample/ManualTestApp/bin/Debug/netcoreapp3.0/ManualTestApp.dll", + //"program": "${workspaceFolder}/sample/ManualTestApp/bin/Debug/netcoreapp3.0/ManualTestApp.dll", + "program": "${workspaceFolder}/tests/KeyChainTestApp/bin/Debug/netcoreapp3.1/StorageTestApp.dll", "args": [], - "cwd": "${workspaceFolder}/sample/ManualTestApp", + "cwd": "${workspaceFolder}/tests/KeyChainTestApp", // For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console "console": "integratedTerminal", "stopAtEntry": false diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7a73a41 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,2 @@ +{ +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 59d77d1..31c32bd 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -1,101 +1,20 @@ { + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format "version": "2.0.0", "tasks": [ { "label": "build", "command": "dotnet", - "type": "process", - "args": [ - "build", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "build", - "command": "dotnet", - "type": "process", + "type": "shell", "args": [ "build", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "publish", - "command": "dotnet", - "type": "process", - "args": [ - "publish", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", - "/property:GenerateFullPaths=true", - "/consoleloggerparameters:NoSummary" - ], - "problemMatcher": "$msCompile" - }, - { - "label": "watch", - "command": "dotnet", - "type": "process", - "args": [ - "watch", - "run", - "${workspaceFolder}/tests/ManualTestApp/ManualTestApp.csproj", + // Ask dotnet build to generate full paths for file names. "/property:GenerateFullPaths=true", + // Do not generate summary otherwise it leads to duplicate errors in Problems panel "/consoleloggerparameters:NoSummary" ], - "problemMatcher": "$msCompile" - }, - { - "label": "build", - "command": "dotnet build", - "type": "shell", - "group": { - "kind": "build", - "isDefault": true - }, - "presentation": { - "reveal": "silent" - }, - "problemMatcher": "$msCompile" - }, - { - "label": "test", - "command": "dotnet test", - "type": "shell", - "group": { - "kind": "test", - "isDefault": true - }, + "group": "build", "presentation": { "reveal": "silent" }, diff --git a/MsalNetExt.sln b/MsalNetExt.sln index 4eb4740..fb85528 100644 --- a/MsalNetExt.sln +++ b/MsalNetExt.sln @@ -37,6 +37,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ManualTestApp", "sample\Man EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FileLockApp", "tests\FileLockApp\FileLockApp.csproj", "{F713BC0E-2F3F-42E3-8F92-93A3A1CE1114}" EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "StorageTestApp", "tests\KeyChainTestApp\StorageTestApp.csproj", "{0D6962D9-26E2-4A12-868A-DEC8F5788D7F}" +EndProject Global GlobalSection(SharedMSBuildProjectFiles) = preSolution src\Shared\Shared.projitems*{9a526f06-5464-43ff-9303-d6cafad088f8}*SharedItemsImports = 5 @@ -136,6 +138,18 @@ Global {F713BC0E-2F3F-42E3-8F92-93A3A1CE1114}.Release|x64.Build.0 = Release|Any CPU {F713BC0E-2F3F-42E3-8F92-93A3A1CE1114}.Release|x86.ActiveCfg = Release|Any CPU {F713BC0E-2F3F-42E3-8F92-93A3A1CE1114}.Release|x86.Build.0 = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|Any CPU.Build.0 = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|x64.ActiveCfg = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|x64.Build.0 = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|x86.ActiveCfg = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Debug|x86.Build.0 = Debug|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|Any CPU.ActiveCfg = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|Any CPU.Build.0 = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|x64.ActiveCfg = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|x64.Build.0 = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|x86.ActiveCfg = Release|Any CPU + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F}.Release|x86.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -149,6 +163,7 @@ Global {963834D9-B679-4976-84DC-66638CF4CA0F} = {B8139910-E45E-4FC3-AD98-FDE9FEAFD45D} {649D26B1-91AD-4E66-9AC9-96410C07E88A} = {52B68846-402C-4756-BC5A-617C860A9590} {F713BC0E-2F3F-42E3-8F92-93A3A1CE1114} = {B8139910-E45E-4FC3-AD98-FDE9FEAFD45D} + {0D6962D9-26E2-4A12-868A-DEC8F5788D7F} = {B8139910-E45E-4FC3-AD98-FDE9FEAFD45D} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {92BA1502-D540-4EF8-93F0-4D7EA682B10B} diff --git a/src/Microsoft.Identity.Client.Extensions.Msal/Accessors/MacKeyChainAccessor.cs b/src/Microsoft.Identity.Client.Extensions.Msal/Accessors/MacKeyChainAccessor.cs index 1b18c23..c27ddd0 100644 --- a/src/Microsoft.Identity.Client.Extensions.Msal/Accessors/MacKeyChainAccessor.cs +++ b/src/Microsoft.Identity.Client.Extensions.Msal/Accessors/MacKeyChainAccessor.cs @@ -83,5 +83,10 @@ public ICacheAccessor CreateForPersistenceValidation() _account, _logger); } + + public override string ToString() + { + return $"MacKeyChain accessor pointing to: service {_service}, account {_account}, file {_cacheFilePath}"; + } } } diff --git a/src/Microsoft.Identity.Client.Extensions.Msal/Properties/InternalsVisibleTo.cs b/src/Microsoft.Identity.Client.Extensions.Msal/Properties/InternalsVisibleTo.cs index bb6ddd7..76c0965 100644 --- a/src/Microsoft.Identity.Client.Extensions.Msal/Properties/InternalsVisibleTo.cs +++ b/src/Microsoft.Identity.Client.Extensions.Msal/Properties/InternalsVisibleTo.cs @@ -7,3 +7,4 @@ [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")] [assembly: InternalsVisibleTo("Automation.TestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002d96616729b54f6d013d71559a017f50aa4861487226c523959d1579b93f3fdf71c08b980fd3130062b03d3de115c4b84e7ac46aef5e192a40e7457d5f3a08f66ceab71143807f2c3cb0da5e23b38f0559769978406f6e5d30ceadd7985fc73a5a609a8b74a1df0a29399074a003a226c943d480fec96dbec7106a87896539ad")] [assembly: InternalsVisibleTo("FileLockApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002d96616729b54f6d013d71559a017f50aa4861487226c523959d1579b93f3fdf71c08b980fd3130062b03d3de115c4b84e7ac46aef5e192a40e7457d5f3a08f66ceab71143807f2c3cb0da5e23b38f0559769978406f6e5d30ceadd7985fc73a5a609a8b74a1df0a29399074a003a226c943d480fec96dbec7106a87896539ad")] +[assembly: InternalsVisibleTo("StorageTestApp, PublicKey=00240000048000009400000006020000002400005253413100040000010001002d96616729b54f6d013d71559a017f50aa4861487226c523959d1579b93f3fdf71c08b980fd3130062b03d3de115c4b84e7ac46aef5e192a40e7457d5f3a08f66ceab71143807f2c3cb0da5e23b38f0559769978406f6e5d30ceadd7985fc73a5a609a8b74a1df0a29399074a003a226c943d480fec96dbec7106a87896539ad")] diff --git a/tests/KeyChainTestApp/Program.cs b/tests/KeyChainTestApp/Program.cs new file mode 100644 index 0000000..f9fd585 --- /dev/null +++ b/tests/KeyChainTestApp/Program.cs @@ -0,0 +1,153 @@ +using System; +using System.Text; +using Microsoft.Identity.Client.Extensions.Msal; + +namespace KeyChainTestApp +{ + class Program + { + private static TraceSourceLogger s_logger = + new TraceSourceLogger(new System.Diagnostics.TraceSource("CacheExt.TestApp")); + + private static byte[] s_payload = Encoding.UTF8.GetBytes("Hello world from the MSAL cache test app"); + static void Main(string[] args) + { + if (!SharedUtilities.IsMacPlatform()) + { + Console.WriteLine("This app should run on a Mac"); + Console.ReadLine(); + return; + } + + while (true) + { + // Display menu + Console.WriteLine($@" + 1. Test KeyChain entry similar to PowerShell + 2. Test KeyChain entry different location (read - write - read - delete) + + Enter your Selection: "); + char.TryParse(Console.ReadLine(), out var selection); + try + { + switch (selection)  + { + case '1': + MacKeychainAccessor macKeychainAccessor1 = + new MacKeychainAccessor( + cacheFilePath: "~/.local/.IdentityService", + keyChainServiceName: "Microsoft.Developer.IdentityService", + keyChainAccountName: "msal.cache", + s_logger); + + TestAccessors(macKeychainAccessor1); + + + break; + case '2': + + Console.WriteLine("Type a keychain service or Enter to use `Microsoft.Developer.IdentityService` "); + string service = Console.ReadLine(); + if (string.IsNullOrEmpty(service)) + { + service = "Microsoft.Developer.IdentityService"; + + } + + Console.WriteLine("Type a keychain account or Enter to use `msal.cache` "); + string account = Console.ReadLine(); + if (string.IsNullOrEmpty(account)) + { + account = $"msal.cache"; + } + + Console.WriteLine($"Using Account {account} and Service: {service}"); + + MacKeychainAccessor macKeychainAccessor2 = + new MacKeychainAccessor( + cacheFilePath: "~/.local/microsoft.test.txt", + keyChainServiceName: service, + keyChainAccountName: account, + s_logger); + + ReadOrReadWriteClear(macKeychainAccessor2); + + break; + + + + + + } + } + catch (Exception ex) + { + PrintException(ex); + } + } + } + + private static void PrintException(Exception ex) + { + Console.ForegroundColor = ConsoleColor.Red; + Console.WriteLine("Exception : " + ex); + Console.ResetColor(); + Console.WriteLine("Hit Enter to continue"); + + Console.Read(); + } + + private static void TestAccessors(ICacheAccessor macKeychainAccessor1) + { + var persistenceValidator = macKeychainAccessor1.CreateForPersistenceValidation(); + try + { + Console.WriteLine("Trying the location used for validation first .. "); + ReadOrReadWriteClear(persistenceValidator); + + } + catch (Exception e) + { + PrintException(e); + } + + try + { + Console.WriteLine("Trying the real location"); + ReadOrReadWriteClear(macKeychainAccessor1); + } + catch (Exception e) + { + PrintException(e); + } + } + + + + private static void ReadOrReadWriteClear(ICacheAccessor accessor) + { + + Console.WriteLine(accessor.ToString()); + var bytes = accessor.Read(); + if (bytes == null || bytes.Length == 0) + { + Console.WriteLine("No data found, writing some"); + accessor.Write(s_payload); + var bytes2 = accessor.Read(); + accessor.Clear(); + Console.WriteLine("All good"); + + } + else + { + string s = Encoding.UTF8.GetString(bytes) ; + Console.WriteLine($"Found some data ... {s.Substring(0,20)}..."); + + Console.WriteLine("Stopping"); + + } + + + } + } +} diff --git a/tests/KeyChainTestApp/StorageTestApp.csproj b/tests/KeyChainTestApp/StorageTestApp.csproj new file mode 100644 index 0000000..9f2a745 --- /dev/null +++ b/tests/KeyChainTestApp/StorageTestApp.csproj @@ -0,0 +1,12 @@ + + + + Exe + netcoreapp3.1 + + + + + + +