Skip to content
This repository was archived by the owner on Jul 22, 2024. It is now read-only.

Commit 4963f89

Browse files
author
Isaiah Williams
authored
Performance update (#241)
1 parent f0828b9 commit 4963f89

43 files changed

Lines changed: 422 additions & 82 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

ChangeLog.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,11 @@
2323
## Upcoming Release
2424

2525
* Authentication
26+
* Added the [Register-PartnerTokenCache](https://docs.microsoft.com/powershell/module/partnercenter/Register-PartnerTokenCache) to create, and delete, the control file that determines if a in-memory token cache should be used instead of the default persistent token cache
27+
* Addressed an issue where an InvalidOperationException exception was being encountering with the [Connect-PartnerCenter](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerAccessToken) and [New-PartnerAccessToken](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerAccessToken) commands when specifying an environment
2628
* Addressed issue [#234](https://github.com/microsoft/Partner-Center-PowerShell/issues/234) that was preventing the [New-PartnerAccessToken](https://docs.microsoft.com/powershell/module/partnercenter/New-PartnerAccessToken) command from executing successfully when being invoked through an Azure Function app
29+
* Product Upgrades
30+
* Addressed an issue with starting the upgrade process for an Azure Plan
2731
* Subscription
2832
* Added the `PartnerId` parameter to the [Set-PartnerCustomerSubscription](https://docs.microsoft.com/powershell/module/partnercenter/Set-PartnerCustomerSubscription) command
2933
* Addressed issue [#228](https://github.com/microsoft/Partner-Center-PowerShell/issues/228) that was causing issues with enabling and suspend an Azure subscription that is part of an Azure Plan

docs/help/PartnerCenter.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -296,6 +296,9 @@ Creates a product upgrade request for the specified customer.
296296
### [New-PartnerServiceRequest](New-PartnerServiceRequest.md)
297297
Creates a service request at the partner level.
298298

299+
### [Register-PartnerTokenCache](Register-PartnerTokenCache.md)
300+
Registers the specified token cache for the module.
301+
299302
### [Remove-PartnerCustomerConfigurationPolicy](Remove-PartnerCustomerConfigurationPolicy.md)
300303
Removes the specified configuration policy.
301304

@@ -376,3 +379,4 @@ Tests if the specified domain name is available for creating a new tenant.
376379

377380
### [Test-PartnerSecurityRequirement](Test-PartnerSecurityRequirement.md)
378381
Tests the account, used during authentication, if multi-factor authentication was enforced.
382+
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
---
2+
content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Register-PartnerTokenCache.md
3+
external help file: Microsoft.Store.PartnerCenter.PowerShell.dll-Help.xml
4+
Module Name: PartnerCenter
5+
online version: https://docs.microsoft.com/powershell/module/partnercenter/Register-PartnerTokenCache
6+
original_content_git_url: https://github.com/Microsoft/Partner-Center-PowerShell/blob/master/docs/help/Register-PartnerTokenCache.md
7+
schema: 2.0.0
8+
---
9+
10+
# Register-PartnerTokenCache
11+
12+
## SYNOPSIS
13+
Registers the specified token cache for the module.
14+
15+
## SYNTAX
16+
17+
### ByPersistent (Default)
18+
```powershell
19+
Register-PartnerTokenCache [-Persistent] [<CommonParameters>]
20+
```
21+
22+
### ByInMemory
23+
```powershell
24+
Register-PartnerTokenCache [-InMemory] [<CommonParameters>]
25+
```
26+
27+
## DESCRIPTION
28+
Registers the specified token cache for the module.
29+
30+
## EXAMPLES
31+
32+
### Example 1
33+
```powershell
34+
PS C:\> Register-PartnerTokenCache -InMemory
35+
```
36+
37+
Registers the in-memory token cache for the module.
38+
39+
### Example 2
40+
```powershell
41+
PS C:\> Register-PartnerTokenCache -Persistent
42+
```
43+
44+
Registers the persistent token cache for the module.
45+
46+
## PARAMETERS
47+
48+
### -InMemory
49+
A flag indicating that the in-memory token cache should be registered.
50+
51+
```yaml
52+
Type: SwitchParameter
53+
Parameter Sets: ByInMemory
54+
Aliases:
55+
56+
Required: True
57+
Position: Named
58+
Default value: None
59+
Accept pipeline input: False
60+
Accept wildcard characters: False
61+
```
62+
63+
### -Persistent
64+
A flag indicating that the persistent token cache should be registered.
65+
66+
```yaml
67+
Type: SwitchParameter
68+
Parameter Sets: ByPersistent
69+
Aliases:
70+
71+
Required: True
72+
Position: Named
73+
Default value: None
74+
Accept pipeline input: False
75+
Accept wildcard characters: False
76+
```
77+
78+
### CommonParameters
79+
This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216).
80+
81+
## INPUTS
82+
83+
### None
84+
85+
## OUTPUTS
86+
87+
### System.Object
88+
## NOTES
89+
90+
## RELATED LINKS

src/PowerShell/Attributes/BreakingChangeBaseAttribute.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,8 @@ protected virtual string GetAttributeSpecificMessage()
115115
/// <returns>The name of the command from the type.</returns>
116116
public static string GetNameFromCmdletType(Type type)
117117
{
118+
type.AssertNotNull(nameof(type));
119+
118120
string cmdletName = null;
119121
CmdletAttribute cmdletAttrib = (CmdletAttribute)type.GetCustomAttributes(typeof(CmdletAttribute), false).FirstOrDefault();
120122

src/PowerShell/Authenticators/AccessTokenAuthenticator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public override async Task<AuthenticationResult> AuthenticateAsync(Authenticatio
5252
throw new PartnerException("The access token has expired. Generate a new one and try again.");
5353
}
5454

55-
await Task.CompletedTask;
55+
await Task.CompletedTask.ConfigureAwait(false);
5656

5757
ServiceClientTracing.Information("[AccessTokenAuthenticator] Constructing the authentication result based on the specified access token");
5858

src/PowerShell/Authenticators/DefaultAuthenticatorBuilder.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,8 @@ public DefaultAuthenticatorBuilder()
3434
/// <param name="constructor">Delegate to initialize the authenticator.</param>
3535
public void AppendAuthenticator(Func<IAuthenticator> constructor)
3636
{
37+
constructor.AssertNotNull(nameof(constructor));
38+
3739
if (null == Authenticator)
3840
{
3941
Authenticator = constructor();

src/PowerShell/Authenticators/DelegatingAuthenticator.cs

Lines changed: 39 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public IClientApplicationBase GetClient(PartnerAccount account, PartnerEnvironme
5252
if (account.IsPropertySet(PartnerAccountPropertyType.CertificateThumbprint) || account.IsPropertySet(PartnerAccountPropertyType.ServicePrincipalSecret))
5353
{
5454
app = CreateConfidentialClient(
55-
$"{environment.ActiveDirectoryAuthority}{account.Tenant}",
55+
GetAzureCloudInstance(environment),
5656
account.GetProperty(PartnerAccountPropertyType.ApplicationId),
5757
account.GetProperty(PartnerAccountPropertyType.ServicePrincipalSecret),
5858
GetCertificate(account.GetProperty(PartnerAccountPropertyType.CertificateThumbprint)),
@@ -62,7 +62,7 @@ public IClientApplicationBase GetClient(PartnerAccount account, PartnerEnvironme
6262
else
6363
{
6464
app = CreatePublicClient(
65-
$"{environment.ActiveDirectoryAuthority}{account.Tenant}",
65+
GetAzureCloudInstance(environment),
6666
account.GetProperty(PartnerAccountPropertyType.ApplicationId),
6767
redirectUri,
6868
account.Tenant);
@@ -95,15 +95,15 @@ public async Task<AuthenticationResult> TryAuthenticateAsync(AuthenticationParam
9595
/// <summary>
9696
/// Creates a confidential client used for generating tokens.
9797
/// </summary>
98-
/// <param name="authority">Address of the authority to issue the token</param>
98+
/// <param name="cloudInstance">The cloud instance used for authentication.</param>
9999
/// <param name="clientId">Identifier of the client requesting the token.</param>
100100
/// <param name="certificate">Certificate used by the client requesting the token.</param>
101101
/// <param name="clientSecret">Secret of the client requesting the token.</param>
102102
/// <param name="redirectUri">The redirect URI for the client.</param>
103103
/// <param name="tenantId">Identifier of the tenant requesting the token.</param>
104104
/// <returns>An aptly configured confidential client.</returns>
105105
private static IConfidentialClientApplication CreateConfidentialClient(
106-
string authority = null,
106+
AzureCloudInstance cloudInstance,
107107
string clientId = null,
108108
string clientSecret = null,
109109
X509Certificate2 certificate = null,
@@ -112,10 +112,7 @@ private static IConfidentialClientApplication CreateConfidentialClient(
112112
{
113113
ConfidentialClientApplicationBuilder builder = ConfidentialClientApplicationBuilder.Create(clientId);
114114

115-
if (!string.IsNullOrEmpty(authority))
116-
{
117-
builder = builder.WithAuthority(authority);
118-
}
115+
builder = builder.WithAuthority(cloudInstance, tenantId);
119116

120117
if (!string.IsNullOrEmpty(clientSecret))
121118
{
@@ -153,23 +150,20 @@ private static IConfidentialClientApplication CreateConfidentialClient(
153150
/// <summary>
154151
/// Creates a public client used for generating tokens.
155152
/// </summary>
156-
/// <param name="authority">Address of the authority to issue the token</param>
153+
/// <param name="cloudInstance">The cloud instance used for authentication.</param>
157154
/// <param name="clientId">Identifier of the client requesting the token.</param>
158155
/// <param name="redirectUri">The redirect URI for the client.</param>
159156
/// <param name="tenantId">Identifier of the tenant requesting the token.</param>
160157
/// <returns>An aptly configured public client.</returns>
161158
private static IPublicClientApplication CreatePublicClient(
162-
string authority = null,
159+
AzureCloudInstance cloudInstance,
163160
string clientId = null,
164161
string redirectUri = null,
165162
string tenantId = null)
166163
{
167164
PublicClientApplicationBuilder builder = PublicClientApplicationBuilder.Create(clientId);
168165

169-
if (!string.IsNullOrEmpty(authority))
170-
{
171-
builder = builder.WithAuthority(authority);
172-
}
166+
builder = builder.WithAuthority(cloudInstance, tenantId);
173167

174168
if (!string.IsNullOrEmpty(redirectUri))
175169
{
@@ -195,12 +189,41 @@ private static IPublicClientApplication CreatePublicClient(
195189
return client;
196190
}
197191

192+
/// <summary>
193+
/// Gets the Azure cloud instance based an instance of the <see cref="PartnerEnvironment" /> class.
194+
/// </summary>
195+
/// <param name="environment">The environment information used to be generate the Azure Cloud instance.</param>
196+
/// <returns>The Azure cloud instance based an instance of the <see cref="PartnerEnvironment" /> class.</returns>
197+
private static AzureCloudInstance GetAzureCloudInstance(PartnerEnvironment environment)
198+
{
199+
environment.AssertNotNull(nameof(environment));
200+
201+
if (environment.EnvironmentName == EnvironmentName.AzureChinaCloud)
202+
{
203+
return AzureCloudInstance.AzureChina;
204+
}
205+
else if (environment.EnvironmentName == EnvironmentName.AzureGermanCloud)
206+
{
207+
return AzureCloudInstance.AzureGermany;
208+
}
209+
else if (environment.EnvironmentName == EnvironmentName.AzureCloud)
210+
{
211+
return AzureCloudInstance.AzurePublic;
212+
}
213+
else if (environment.EnvironmentName == EnvironmentName.AzureUSGovernment)
214+
{
215+
return AzureCloudInstance.AzureUsGovernment;
216+
}
217+
218+
return AzureCloudInstance.None;
219+
}
220+
198221
/// <summary>
199222
/// Gets the specified certificate.
200223
/// </summary>
201224
/// <param name="thumbprint">Thumbprint of the certificate to be located.</param>
202225
/// <returns>An instance of the <see cref="X509Certificate2"/> class that represents the certificate.</returns>
203-
private X509Certificate2 GetCertificate(string thumbprint)
226+
private static X509Certificate2 GetCertificate(string thumbprint)
204227
{
205228
if (string.IsNullOrEmpty(thumbprint))
206229
{
@@ -222,7 +245,7 @@ private X509Certificate2 GetCertificate(string thumbprint)
222245
/// <param name="thumbprint">Thumbprint of the certificate to be located.</param>
223246
/// <param name="storeLocation">The location of the X.509 certifcate store.</param>
224247
/// <returns><c>true</c> if the certificate was found; otherwise <c>false</c>.</returns>
225-
private bool FindCertificateByThumbprint(string thumbprint, StoreLocation storeLocation, out X509Certificate2 certificate)
248+
private static bool FindCertificateByThumbprint(string thumbprint, StoreLocation storeLocation, out X509Certificate2 certificate)
226249
{
227250
X509Store store = null;
228251
X509Certificate2Collection col;

src/PowerShell/Authenticators/DeviceCodeAuthenticator.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ public override async Task<AuthenticationResult> AuthenticateAsync(Authenticatio
3030
IClientApplicationBase app = GetClient(parameters.Account, parameters.Environment);
3131

3232
ServiceClientTracing.Information($"[DeviceCodeAuthenticator] Calling AcquireTokenWithDeviceCode - Scopes: '{string.Join(", ", parameters.Scopes)}'");
33-
33+
3434
return await app.AsPublicClient().AcquireTokenWithDeviceCode(parameters.Scopes, deviceCodeResult =>
3535
{
3636
WriteWarning(deviceCodeResult.Message);

src/PowerShell/Authenticators/InteractiveUserAuthenticator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
55
{
66
using System;
77
using System.Collections.Specialized;
8+
using System.Globalization;
89
using System.Net;
910
using System.Net.Sockets;
1011
using System.Threading;
@@ -46,7 +47,7 @@ public override async Task<AuthenticationResult> AuthenticateAsync(Authenticatio
4647
{
4748
listener = new TcpListener(IPAddress.Loopback, port);
4849
listener.Start();
49-
redirectUri = string.Format("http://localhost:{0}/", port);
50+
redirectUri = $"http://localhost:{port}/";
5051
listener.Stop();
5152
break;
5253
}
@@ -80,7 +81,7 @@ await app.AsConfidentialClient().GetAuthorizationRequestUrl(parameters.Scopes).E
8081
}
8182
else
8283
{
83-
ServiceClientTracing.Information(string.Format("[InteractiveUserAuthenticator] Calling AcquireTokenInteractive - Scopes: '{0}'", string.Join(",", parameters.Scopes)));
84+
ServiceClientTracing.Information(string.Format(CultureInfo.InvariantCulture, "[InteractiveUserAuthenticator] Calling AcquireTokenInteractive - Scopes: '{0}'", string.Join(",", parameters.Scopes)));
8485

8586
authResult = await app.AsPublicClient().AcquireTokenInteractive(parameters.Scopes)
8687
.WithCustomWebUi(new DefaultOsBrowserWebUi(interactiveParameters.Message))

src/PowerShell/Authenticators/SilentAuthenticator.cs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
namespace Microsoft.Store.PartnerCenter.PowerShell.Authenticators
55
{
6+
using System;
67
using System.Collections.Generic;
78
using System.Linq;
89
using System.Threading;
@@ -28,13 +29,13 @@ public override async Task<AuthenticationResult> AuthenticateAsync(Authenticatio
2829
{
2930
IClientApplicationBase app = GetClient(parameters.Account, parameters.Environment);
3031

31-
ServiceClientTracing.Information(string.Format("[SilentAuthenticator] Calling GetAccountsAsync"));
32+
ServiceClientTracing.Information("[SilentAuthenticator] Calling GetAccountsAsync");
3233
IEnumerable<IAccount> accounts = await app.AsPublicClient().GetAccountsAsync().ConfigureAwait(false);
3334

3435
ServiceClientTracing.Information($"[SilentAuthenticator] Calling AcquireTokenSilent - Scopes: '{string.Join(",", parameters.Scopes)}', UserId: '{((SilentParameters)parameters).UserId}', Number of accounts: '{accounts.Count()}'");
3536
AuthenticationResult authResult = await app.AsPublicClient().AcquireTokenSilent(
3637
parameters.Scopes,
37-
accounts.FirstOrDefault(a => a.HomeAccountId.ObjectId.Equals(((SilentParameters)parameters).UserId)))
38+
accounts.FirstOrDefault(a => a.HomeAccountId.ObjectId.Equals(((SilentParameters)parameters).UserId, StringComparison.InvariantCultureIgnoreCase)))
3839
.ExecuteAsync(cancellationToken).ConfigureAwait(false);
3940

4041
return authResult;

0 commit comments

Comments
 (0)