Skip to content

Commit fcae286

Browse files
committed
Add unit tests.
1 parent ddb2d97 commit fcae286

File tree

2 files changed

+160
-10
lines changed

2 files changed

+160
-10
lines changed
Lines changed: 130 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,130 @@
1+
namespace Microsoft.Graph.Authentication.Test.Helpers
2+
{
3+
using Microsoft.Graph.Auth;
4+
using Microsoft.Graph.PowerShell.Authentication;
5+
using Microsoft.Graph.PowerShell.Authentication.Helpers;
6+
using System;
7+
using System.Linq;
8+
using System.Net;
9+
using System.Net.Http;
10+
using System.Security.Cryptography;
11+
using System.Security.Cryptography.X509Certificates;
12+
using System.Threading.Tasks;
13+
using Xunit;
14+
public class AuthenticationHelpersTests
15+
{
16+
public AuthenticationHelpersTests()
17+
{
18+
GraphSession.Initialize(() => new GraphSession());
19+
}
20+
21+
[Fact]
22+
public async Task ShouldUseDelegateAuthProviderWhenUserAccessTokenIsProvidedAsync()
23+
{
24+
// Arrange
25+
string accessToken = "ACCESS_TOKEN_VIA_DELEGATE_PROVIDER";
26+
GraphSession.Instance.UserProvidedToken = new NetworkCredential(string.Empty, accessToken).SecurePassword;
27+
AuthContext userProvidedAuthContext = new AuthContext
28+
{
29+
AuthType = AuthenticationType.UserProvidedAccessToken,
30+
ContextScope = ContextScope.Process
31+
};
32+
33+
IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(userProvidedAuthContext);
34+
HttpRequestMessage requestMessage = new HttpRequestMessage();
35+
36+
// Act
37+
await authProvider.AuthenticateRequestAsync(requestMessage);
38+
39+
// Assert
40+
Assert.IsType<DelegateAuthenticationProvider>(authProvider);
41+
Assert.Equal("Bearer", requestMessage.Headers.Authorization.Scheme);
42+
Assert.Equal(accessToken, requestMessage.Headers.Authorization.Parameter);
43+
44+
// reset static instance.
45+
GraphSession.Reset();
46+
}
47+
48+
[Fact]
49+
public void ShouldUseDeviceCodeProviderWhenDelegatedContextIsProvided()
50+
{
51+
// Arrange
52+
AuthContext delegatedAuthContext = new AuthContext
53+
{
54+
AuthType = AuthenticationType.Delegated,
55+
Scopes = new string[] { "User.Read" },
56+
ContextScope = ContextScope.Process
57+
};
58+
59+
// Act
60+
IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(delegatedAuthContext);
61+
62+
// Assert
63+
Assert.IsType<DeviceCodeProvider>(authProvider);
64+
65+
// reset static instance.
66+
GraphSession.Reset();
67+
}
68+
69+
[Fact]
70+
public void ShouldUseClientCredentialProviderWhenAppOnlyContextIsProvided()
71+
{
72+
// Arrange
73+
AuthContext appOnlyAuthContext = new AuthContext
74+
{
75+
AuthType = AuthenticationType.AppOnly,
76+
ClientId = Guid.NewGuid().ToString(),
77+
CertificateName = "cn=dummyCert",
78+
ContextScope = ContextScope.Process
79+
};
80+
CreateSelfSignedCert(appOnlyAuthContext.CertificateName);
81+
82+
// Act
83+
IAuthenticationProvider authProvider = AuthenticationHelpers.GetAuthProvider(appOnlyAuthContext);
84+
85+
// Assert
86+
Assert.IsType<ClientCredentialProvider>(authProvider);
87+
88+
// reset
89+
DeleteSelfSignedCert(appOnlyAuthContext.CertificateName);
90+
GraphSession.Reset();
91+
92+
}
93+
94+
private void CreateSelfSignedCert(string certName)
95+
{
96+
ECDsa ecdsaKey = ECDsa.Create();
97+
CertificateRequest certificateRequest = new CertificateRequest(certName, ecdsaKey, HashAlgorithmName.SHA256);
98+
// We have to export cert to dummy cert since `CreateSelfSigned` creates a cert without a private key.
99+
X509Certificate2 cert = certificateRequest.CreateSelfSigned(DateTimeOffset.Now, DateTimeOffset.Now.AddYears(5));
100+
X509Certificate2 dummyCert = new X509Certificate2(cert.Export(X509ContentType.Pfx, "P@55w0rd"), "P@55w0rd", X509KeyStorageFlags.PersistKeySet);
101+
using (X509Store store = new X509Store(StoreName.My, StoreLocation.CurrentUser))
102+
{
103+
store.Open(OpenFlags.ReadWrite);
104+
105+
store.Add(dummyCert);
106+
}
107+
}
108+
109+
private void DeleteSelfSignedCert(string certificateName)
110+
{
111+
using (X509Store xStore = new X509Store(StoreName.My, StoreLocation.CurrentUser))
112+
{
113+
xStore.Open(OpenFlags.ReadWrite);
114+
115+
X509Certificate2Collection unexpiredCerts = xStore.Certificates
116+
.Find(X509FindType.FindByTimeValid, DateTime.Now, false)
117+
.Find(X509FindType.FindBySubjectDistinguishedName, certificateName, false);
118+
119+
// Only return current cert.
120+
var xCertificate = unexpiredCerts
121+
.OfType<X509Certificate2>()
122+
.OrderByDescending(c => c.NotBefore)
123+
.FirstOrDefault();
124+
125+
xStore.Remove(xCertificate);
126+
}
127+
}
128+
129+
}
130+
}

src/Authentication/Authentication/Cmdlets/ConnectGraph.cs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -192,19 +192,39 @@ protected override void StopProcessing()
192192

193193
private void ValidateParameters()
194194
{
195-
if (ParameterSetName == Constants.AppParameterSet)
195+
switch (ParameterSetName)
196196
{
197-
// Client Id
198-
if (string.IsNullOrEmpty(ClientId))
199-
ThrowParameterError(nameof(ClientId));
197+
case Constants.AppParameterSet:
198+
{
199+
// Client Id
200+
if (string.IsNullOrEmpty(ClientId))
201+
{
202+
ThrowParameterError(nameof(ClientId));
203+
}
200204

201-
// Certificate Thumbprint or name
202-
if (string.IsNullOrEmpty(CertificateThumbprint) && string.IsNullOrEmpty(CertificateName))
203-
ThrowParameterError($"{nameof(CertificateThumbprint)} or {nameof(CertificateName)}");
205+
// Certificate Thumbprint or name
206+
if (string.IsNullOrEmpty(CertificateThumbprint) && string.IsNullOrEmpty(CertificateName))
207+
{
208+
ThrowParameterError($"{nameof(CertificateThumbprint)} or {nameof(CertificateName)}");
209+
}
210+
211+
// Tenant Id
212+
if (string.IsNullOrEmpty(TenantId))
213+
{
214+
ThrowParameterError(nameof(TenantId));
215+
}
204216

205-
// Tenant Id
206-
if (string.IsNullOrEmpty(TenantId))
207-
ThrowParameterError(nameof(TenantId));
217+
}
218+
break;
219+
case Constants.AccessTokenParameterSet:
220+
{
221+
// AccessToken
222+
if (string.IsNullOrEmpty(AccessToken))
223+
{
224+
ThrowParameterError(nameof(AccessToken));
225+
}
226+
}
227+
break;
208228
}
209229
}
210230

0 commit comments

Comments
 (0)