Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions src/Authentication/Authentication.Core/Common/GraphSession.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ namespace Microsoft.Graph.PowerShell.Authentication
{
using Microsoft.Graph.PowerShell.Authentication.Core;
using Microsoft.Graph.PowerShell.Authentication.Interfaces;

using System;
using System.Security;
using System.Threading;
Expand Down Expand Up @@ -200,5 +201,22 @@ public static void Reset()
throw new InvalidOperationException(ErrorConstants.Codes.SessionLockWriteDisposed, disposedException);
}
}

private IPSGraphOutputWriter _outputWriter;
/// <summary>
/// Provides Access to output methods provided by the Cmdlet
/// </summary>
public IPSGraphOutputWriter OutputWriter
{
get
{
if (_outputWriter == null)
{
throw new InvalidOperationException(ErrorConstants.Codes.OutputNotInitialized);
}
return _outputWriter;
}
set => _outputWriter = value;
}
}
}
1 change: 1 addition & 0 deletions src/Authentication/Authentication.Core/ErrorConstants.cs
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ internal static class Codes
internal const string SessionLockWriteDisposed = "sessionLockWriteDisposed";
internal const string SessionLockWriteRecursion = "sessionLockWriteRecursion";
internal const string InvalidJWT = "invalidJWT";
internal const string OutputNotInitialized = "outputNotInitialized";
}

public static class Message
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ public enum ContextScope
Process,
CurrentUser
}

public enum AuthProviderType
{
InteractiveAuthenticationProvider,
Expand All @@ -26,6 +27,7 @@ public enum AuthProviderType
ClientCredentialProvider,
UserProvidedToken
}

public interface IAuthContext
{
string ClientId { get; set; }
Expand All @@ -40,4 +42,4 @@ public interface IAuthContext
ContextScope ContextScope { get; set; }
X509Certificate2 Certificate { get; set; }
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;

namespace Microsoft.Graph.PowerShell.Authentication
{
public interface IPSGraphOutputWriter
{
Action<string> WriteObject { get; set; }
Action<string> WriteDebug { get; set; }
Action<Exception, string, int, object> WriteError { get; set; }
Action<object, string> WriteInformation { get; set; }
Action<string> WriteVerbose { get; set; }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,11 @@ public static IAuthenticationProvider GetAuthProvider(IAuthContext authContext)
case AuthProviderType.DeviceCodeProvider:
case AuthProviderType.DeviceCodeProviderFallBack:
authProvider = new DeviceCodeProvider(publicClientApp, authContext.Scopes,
async result => { await Console.Out.WriteLineAsync(result.Message); });
result =>
{
GraphSession.Instance.OutputWriter.WriteObject(result.Message);
return Task.CompletedTask;
});
break;
case AuthProviderType.InteractiveAuthenticationProvider:
authProvider = new InteractiveAuthenticationProvider(publicClientApp, authContext.Scopes);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,23 @@
namespace Microsoft.Graph.Authentication.Test.Helpers
using Microsoft.Graph.PowerShell.Authentication.Common;
using Microsoft.Graph.PowerShell.Authentication.Models;

using Xunit.Abstractions;

namespace Microsoft.Graph.Authentication.Test.Helpers
{
using Microsoft.Graph.PowerShell.Authentication;

using System;

using Xunit;
public class GraphSessionTests
{
private readonly ITestOutputHelper _helper;

public GraphSessionTests(ITestOutputHelper helper)
{
_helper = helper;
}
[Fact]
public void GraphSessionShouldBeInitilizedAfterInitializerIsCalled()
{
Expand All @@ -16,7 +29,7 @@ public void GraphSessionShouldBeInitilizedAfterInitializerIsCalled()
// reset static instance.
GraphSession.Reset();
}

[Fact]
public void ShouldOverwriteExistingGraphSession()
{
Expand All @@ -30,8 +43,8 @@ public void ShouldOverwriteExistingGraphSession()

// reset static instance.
GraphSession.Reset();
}
}

[Fact]
public void ShouldNotOverwriteExistingGraphSession()
{
Expand All @@ -54,6 +67,38 @@ public void ShouldThrowExceptionWhenSessionIsNotInitialized()

Assert.Equal(PowerShell.Authentication.Core.ErrorConstants.Codes.SessionNotInitialized, exception.Message);

// reset static instance.
GraphSession.Reset();
}
[Fact]
public void ShouldThrowExceptionWhenOutputIsNotInitialized()
{
GraphSession.Initialize(() => new GraphSession());
InvalidOperationException exception = Assert.Throws<InvalidOperationException>(() => GraphSession.Instance.OutputWriter.WriteObject("Output"));

Assert.NotNull(GraphSession.Instance);
Assert.Null(GraphSession.Instance.AuthContext);

// reset static instance.
GraphSession.Reset();
}
[Fact]
public void ShouldInitializeOutputWriter()
{
GraphSessionInitializer.InitializeSession();
GraphSessionInitializer.InitializeOutput(new PsGraphOutputWriter
{
WriteError = (exception1, s, arg3, arg4) => _helper.WriteLine(exception1.Message),
WriteObject = _helper.WriteLine,
WriteDebug = _helper.WriteLine,
WriteInformation = (o, s) => _helper.WriteLine(s),
WriteVerbose = _helper.WriteLine
});
GraphSession.Instance.OutputWriter.WriteObject("Output");

Assert.NotNull(GraphSession.Instance.OutputWriter);
Assert.NotNull(GraphSession.Instance.OutputWriter.WriteObject);

// reset static instance.
GraphSession.Reset();
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,21 +1,36 @@
namespace Microsoft.Graph.Authentication.Test.TokenCache
{
using Microsoft.Graph.PowerShell.Authentication;
using Microsoft.Graph.PowerShell.Authentication.Models;
using Microsoft.Graph.PowerShell.Authentication.Common;
using Microsoft.Graph.PowerShell.Authentication.TokenCache;

using System;
using System.Text;
using System.Threading;

using Xunit;
using Xunit.Abstractions;

public class ProcessTokenCacheStorageTests: IDisposable
public class ProcessTokenCacheStorageTests : IDisposable
{
// Defaults to process context scope.
private IAuthContext _testAppContext1;
public ProcessTokenCacheStorageTests()
public ProcessTokenCacheStorageTests(ITestOutputHelper outputHelper)
{
_testAppContext1 = new AuthContext { ClientId = "test_app_id_1" };
GraphSessionInitializer.InitializeSession();
GraphSessionInitializer.InitializeOutput(new PsGraphOutputWriter
{
WriteError = (exception, s, arg3, arg4) =>
{
outputHelper.WriteLine(exception.Message);
},
WriteDebug = outputHelper.WriteLine,
WriteInformation = (o, strings) => outputHelper.WriteLine(o.ToString()),
WriteObject = outputHelper.WriteLine,
WriteVerbose = outputHelper.WriteLine
});
}

[Fact]
Expand Down Expand Up @@ -93,7 +108,8 @@ public void ProccessTokenCacheShouldBeThreadSafe()
// Act
for (int i = 0; i < threads.Length; i++)
{
threads[i] = new Thread(() => {
threads[i] = new Thread(() =>
{
byte[] contentBuffer = Encoding.UTF8.GetBytes(i.ToString());
TokenCacheStorage.SetToken(_testAppContext1, contentBuffer);
Thread.Sleep(2000);
Expand Down
5 changes: 3 additions & 2 deletions src/Authentication/Authentication/Cmdlets/ConnectMgGraph.cs
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,8 @@ protected override void ProcessRecord()
{
using (var asyncCommandRuntime = new CustomAsyncCommandRuntime(this, _cancellationTokenSource.Token))
{
// Init output to this Cmdlet
GraphSessionInitializer.InitializeOutput(asyncCommandRuntime);
asyncCommandRuntime.Wait(ProcessRecordAsync(), _cancellationTokenSource.Token);
}
}
Expand Down Expand Up @@ -174,7 +176,6 @@ private async Task ProcessRecordAsync()
IAuthContext authContext = new AuthContext { TenantId = TenantId };
// Set selected environment to the session object.
GraphSession.Instance.Environment = environment;

switch (ParameterSetName)
{
case Constants.UserParameterSet:
Expand Down Expand Up @@ -225,7 +226,7 @@ private async Task ProcessRecordAsync()
_cancellationTokenSource.Token,
() => { WriteWarning(Resources.DeviceCodeFallback); });
}
catch(Exception ex)
catch (Exception ex)
{
throw ex;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,14 @@
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

using System;
using Microsoft.Graph.PowerShell.Authentication.Helpers;
using Microsoft.Graph.PowerShell.Authentication.Models;

namespace Microsoft.Graph.PowerShell.Authentication.Common
{
using System.Management.Automation;

using Microsoft.Graph.PowerShell.Authentication.Interfaces;

public static class GraphSessionInitializer
Expand All @@ -15,7 +21,6 @@ public static void InitializeSession()
{
GraphSession.Initialize(() => CreateInstance());
}

/// <summary>
/// Creates a new instance of a <see cref="GraphSession"/>.
/// </summary>
Expand All @@ -27,5 +32,44 @@ internal static GraphSession CreateInstance(IDataStore dataStore = null)
DataStore = dataStore ?? new DiskDataStore()
};
}
/// <summary>
/// Initializes <see cref="GraphSession"/>. with Output via Cmdlet methods
/// </summary>
/// <param name="cmdLet"></param>
internal static void InitializeOutput(CustomAsyncCommandRuntime cmdLet)
{
var outputWriter = new PsGraphOutputWriter
{
WriteDebug = cmdLet.WriteDebug,
WriteInformation = (o, strings) =>
{
cmdLet.WriteInformation(new InformationRecord(o, strings));
},
WriteObject = cmdLet.WriteObject,
WriteVerbose = cmdLet.WriteVerbose,
WriteError = (exception, errorId, errorCategory, targetObject) =>
{
var parseResult = Enum.TryParse(errorCategory.ToString(), out ErrorCategory result);
if (!parseResult)
{
result = ErrorCategory.NotSpecified;
}
var errorRecord = new ErrorRecord(exception, errorId, result, targetObject);
cmdLet.WriteError(errorRecord);
}
};
InitializeOutput(outputWriter);
}
/// <summary>
/// Initializes <see cref="GraphSession"/>. with Output via Cmdlet methods
/// </summary>
/// <param name="outputWriter"></param>
internal static void InitializeOutput(IPSGraphOutputWriter outputWriter)
{
GraphSession.Modify(session =>
{
session.OutputWriter = outputWriter;
});
}
}
}
8 changes: 3 additions & 5 deletions src/Authentication/Authentication/Helpers/AttachDebugger.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,19 +16,17 @@ internal static void Break(this PSCmdlet invokedCmdLet)
{
while (!Debugger.IsAttached)
{
Console.Error.WriteLine($"Waiting for debugger to attach to process {Process.GetCurrentProcess().Id}");
invokedCmdLet.WriteWarning($"Waiting for debugger to attach to process {Process.GetCurrentProcess().Id}");
for (var i = 0; i < 50; i++)
{
if (Debugger.IsAttached)
{
break;
}

Thread.Sleep(100);
Console.Error.Write(".");
invokedCmdLet.WriteProgress(new ProgressRecord(0, "Waiting for Debugger",
"Waiting for Debugger to attach to process"));
}

Console.Error.WriteLine();
}

Debugger.Break();
Expand Down
17 changes: 17 additions & 0 deletions src/Authentication/Authentication/Models/PsGraphOutputWriter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// ------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All Rights Reserved. Licensed under the MIT License. See License in the project root for license information.
// ------------------------------------------------------------------------------

namespace Microsoft.Graph.PowerShell.Authentication.Models
{
using System;

internal class PsGraphOutputWriter : IPSGraphOutputWriter
{
public Action<string> WriteObject { get; set; }
public Action<string> WriteDebug { get; set; }
public Action<Exception, string, int, object> WriteError { get; set; }
public Action<object, string> WriteInformation { get; set; }
public Action<string> WriteVerbose { get; set; }
}
}