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

Commit 0297e0b

Browse files
idwilliams-2joelst
authored andcommitted
Added the ability to perform the partner consent process. Also, included functionality to get an access token using a refresh token. (#47)
1 parent e935880 commit 0297e0b

28 files changed

Lines changed: 2416 additions & 210 deletions

docs/help/Connect-PartnerCenter.md

Lines changed: 3 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -17,19 +17,19 @@ Connect to Partner Center with an authenticated account for use with cmdlet requ
1717
### UserCredential (Default)
1818
```
1919
Connect-PartnerCenter -ApplicationId <String> [-Credential <PSCredential>] [-Environment <EnvironmentName>]
20-
[-TokenCache <TokenCache>] [<CommonParameters>]
20+
[<CommonParameters>]
2121
```
2222

2323
### AccessToken
2424
```
2525
Connect-PartnerCenter -AccessToken <String> -AccessTokenExpiresOn <DateTimeOffset> -ApplicationId <String>
26-
[-Environment <EnvironmentName>] -TenantId <String> [-TokenCache <TokenCache>] [<CommonParameters>]
26+
[-Environment <EnvironmentName>] -TenantId <String> [<CommonParameters>]
2727
```
2828

2929
### ServicePrincipal
3030
```
3131
Connect-PartnerCenter -Credential <PSCredential> [-Environment <EnvironmentName>] [-ServicePrincipal]
32-
-TenantId <String> [-TokenCache <TokenCache>] [<CommonParameters>]
32+
-TenantId <String> [<CommonParameters>]
3333
```
3434

3535
## DESCRIPTION
@@ -183,21 +183,6 @@ Accept pipeline input: False
183183
Accept wildcard characters: False
184184
```
185185
186-
### -TokenCache
187-
The cache used to lookup cached tokens.
188-
189-
```yaml
190-
Type: TokenCache
191-
Parameter Sets: (All)
192-
Aliases:
193-
194-
Required: False
195-
Position: Named
196-
Default value: None
197-
Accept pipeline input: False
198-
Accept wildcard characters: False
199-
```
200-
201186
### CommonParameters
202187
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).
203188

docs/help/New-PartnerAccessToken.md

Lines changed: 45 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,15 @@ Generate a new access token that can be used to access Partner Center.
1616

1717
### UserCredential (Default)
1818
```
19-
New-PartnerAccessToken -ApplicationId <String> [-Credential <PSCredential>] [-Environment <EnvironmentName>]
20-
[-TokenCache <TokenCache>] [<CommonParameters>]
19+
New-PartnerAccessToken -ApplicationId <String> [-Consent] [-Credential <PSCredential>]
20+
[-Environment <EnvironmentName>] [-RefreshToken <String>] -Resource <String> [-TenantId <String>]
21+
[<CommonParameters>]
2122
```
2223

2324
### ServicePrincipal
2425
```
25-
New-PartnerAccessToken -Credential <PSCredential> [-Environment <EnvironmentName>] [-ServicePrincipal]
26-
-TenantId <String> [-TokenCache <TokenCache>] [<CommonParameters>]
26+
New-PartnerAccessToken [-Consent] -Credential <PSCredential> [-Environment <EnvironmentName>]
27+
[-RefreshToken <String>] -Resource <String> [-ServicePrincipal] [-TenantId <String>] [<CommonParameters>]
2728
```
2829

2930
## DESCRIPTION
@@ -66,6 +67,21 @@ Accept pipeline input: False
6667
Accept wildcard characters: False
6768
```
6869
70+
### -Consent
71+
A flag that indicates that the intention is to perform the partner consent process.
72+
73+
```yaml
74+
Type: SwitchParameter
75+
Parameter Sets: (All)
76+
Aliases:
77+
78+
Required: False
79+
Position: Named
80+
Default value: None
81+
Accept pipeline input: False
82+
Accept wildcard characters: False
83+
```
84+
6985
### -Credential
7086
Credentials that represents the service principal.
7187
@@ -109,26 +125,41 @@ Accept pipeline input: False
109125
Accept wildcard characters: False
110126
```
111127
112-
### -ServicePrincipal
113-
A flag indicating that a service principal will be used to authenticate.
128+
### -RefreshToken
129+
The refresh token to use in the refresh flow.
114130
115131
```yaml
116-
Type: SwitchParameter
117-
Parameter Sets: ServicePrincipal
132+
Type: String
133+
Parameter Sets: (All)
118134
Aliases:
119135

120-
Required: True
136+
Required: False
121137
Position: Named
122138
Default value: None
123139
Accept pipeline input: False
124140
Accept wildcard characters: False
125141
```
126142
127-
### -TenantId
128-
The Azure AD domain or tenant identifier.
143+
### -Resource
144+
The identifier of the target resource that is the recipient of the requested token.
129145
130146
```yaml
131147
Type: String
148+
Parameter Sets: (All)
149+
Aliases:
150+
151+
Required: True
152+
Position: Named
153+
Default value: None
154+
Accept pipeline input: False
155+
Accept wildcard characters: False
156+
```
157+
158+
### -ServicePrincipal
159+
A flag indicating that a service principal will be used to authenticate.
160+
161+
```yaml
162+
Type: SwitchParameter
132163
Parameter Sets: ServicePrincipal
133164
Aliases:
134165

@@ -139,11 +170,11 @@ Accept pipeline input: False
139170
Accept wildcard characters: False
140171
```
141172
142-
### -TokenCache
143-
The token cache to be used when requesting an access token.
173+
### -TenantId
174+
The Azure AD domain or tenant identifier.
144175
145176
```yaml
146-
Type: TokenCache
177+
Type: String
147178
Parameter Sets: (All)
148179
Aliases:
149180

docs/help/Set-PartnerCustomerSubscription.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,7 @@ The billing cycle for the subscription.
6464
Type: BillingCycleType
6565
Parameter Sets: (All)
6666
Aliases:
67+
Accepted values: Annual, Monthly
6768

6869
Required: False
6970
Position: Named
@@ -139,7 +140,7 @@ The status of the subscription.
139140
Type: SubscriptionStatus
140141
Parameter Sets: (All)
141142
Aliases:
142-
Accepted values: None, Active, Suspended, Deleted
143+
Accepted values: Active, Suspended
143144

144145
Required: False
145146
Position: Named

src/PowerShell/Commands/ConnectPartnerCenter.cs

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
1414
using System.Text.RegularExpressions;
1515
using Common;
1616
using Factories;
17-
using IdentityModel.Clients.ActiveDirectory;
1817
using PartnerCenter.Models.Partners;
1918
using Profile;
2019
using Properties;
@@ -117,13 +116,6 @@ public class ConnectPartnerCenter : PSCmdlet, IModuleAssemblyInitializer
117116
[ValidateNotNullOrEmpty]
118117
public string TenantId { get; set; }
119118

120-
/// <summary>
121-
/// Gets or sets the cache used to lookup cached tokens.
122-
/// </summary>
123-
[Parameter(HelpMessage = "The cache used to lookup cached tokens.", Mandatory = false)]
124-
[ValidateNotNull]
125-
public TokenCache TokenCache { get; set; }
126-
127119
/// <summary>
128120
/// Operations that happen before the cmdlet is executed.
129121
/// </summary>
@@ -207,8 +199,7 @@ protected override void ProcessRecord()
207199
{
208200
Account = account,
209201
ApplicationId = ApplicationId,
210-
Environment = Environment,
211-
TokenCache = TokenCache ?? TokenCache.DefaultShared
202+
Environment = Environment
212203
};
213204

214205
PartnerSession.Instance.AuthenticationFactory.Authenticate(context, password);

src/PowerShell/Commands/NewPartnerAccessToken.cs

Lines changed: 79 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,12 @@ namespace Microsoft.Store.PartnerCenter.PowerShell.Commands
88
{
99
using System;
1010
using System.Management.Automation;
11-
using System.Security;
1211
using System.Text.RegularExpressions;
12+
using System.Web;
1313
using Common;
14-
using IdentityModel.Clients.ActiveDirectory;
14+
using Models.Authentication;
15+
using Network;
16+
using Platform;
1517
using Profile;
1618

1719
[Cmdlet(VerbsCommon.New, "PartnerAccessToken", DefaultParameterSetName = "UserCredential")]
@@ -23,13 +25,29 @@ public class NewPartnerAccessToken : PSCmdlet
2325
/// </summary>
2426
private const string CommonEndpoint = "common";
2527

28+
/// <summary>
29+
/// The value for the redirect URI.
30+
/// </summary>
31+
private const string redirectUriValue = "urn:ietf:wg:oauth:2.0:oob";
32+
33+
/// <summary>
34+
/// The redirect URI used when requesting an access token.
35+
/// </summary>
36+
private readonly Uri redirectUri = new Uri(redirectUriValue);
37+
2638
/// <summary>
2739
/// Gets or sets the application identifier.
2840
/// </summary>
2941
[Parameter(HelpMessage = "The application identifier used to access Partner Center.", Mandatory = true, ParameterSetName = "UserCredential")]
3042
[ValidatePattern(@"^(\{){0,1}[0-9a-fA-F]{8}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{4}\-[0-9a-fA-F]{12}(\}){0,1}$", Options = RegexOptions.Compiled | RegexOptions.IgnoreCase)]
3143
public string ApplicationId { get; set; }
3244

45+
/// <summary>
46+
/// Gets or sets a flag indicating that the intention is to perform the partner consent process.
47+
/// </summary>
48+
[Parameter(HelpMessage = "A flag that indicates that the intention is to perform the partner consent process.", Mandatory = false)]
49+
public SwitchParameter Consent { get; set; }
50+
3351
/// <summary>
3452
/// Gets or sets the credentials.
3553
/// </summary>
@@ -45,6 +63,20 @@ public class NewPartnerAccessToken : PSCmdlet
4563
[ValidateNotNullOrEmpty]
4664
public EnvironmentName Environment { get; set; }
4765

66+
/// <summary>
67+
/// Gets or sets the refresh token to use in the refresh flow.
68+
/// </summary>
69+
[Parameter(HelpMessage = "The refresh token to use in the refresh flow.", Mandatory = false)]
70+
[ValidateNotNullOrEmpty]
71+
public string RefreshToken { get; set; }
72+
73+
/// <summary>
74+
/// Gets or sets the identifier of the target resource that is the recipient of the requested token.
75+
/// </summary>
76+
[Parameter(HelpMessage = "The identifier of the target resource that is the recipient of the requested token.", Mandatory = true)]
77+
[ValidateNotNullOrEmpty]
78+
public string Resource { get; set; }
79+
4880
/// <summary>
4981
/// Gets or sets a flag indicating that a service principal will be used to authenticate.
5082
/// </summary
@@ -54,26 +86,22 @@ public class NewPartnerAccessToken : PSCmdlet
5486
/// <summary>
5587
/// Gets or sets the tenant identifier.
5688
/// </summary>
57-
[Parameter(HelpMessage = "The Azure AD domain or tenant identifier.", Mandatory = true, ParameterSetName = "ServicePrincipal")]
89+
[Parameter(HelpMessage = "The Azure AD domain or tenant identifier.", Mandatory = false)]
5890
[ValidateNotNullOrEmpty]
5991
public string TenantId { get; set; }
6092

61-
/// <summary>
62-
/// Gets or sets the token cache.
63-
/// </summary>
64-
[Parameter(HelpMessage = "The token cache to be used when requesting an access token.", Mandatory = false)]
65-
[ValidateNotNull]
66-
public TokenCache TokenCache { get; set; }
67-
6893
/// <summary>
6994
/// Performs the execution of the command.
7095
/// </summary>
7196
protected override void ProcessRecord()
7297
{
7398
AuthenticationResult authResult;
7499
AzureAccount account = new AzureAccount();
75-
SecureString password = null;
76-
100+
IPartnerServiceClient client;
101+
PartnerEnvironment environment;
102+
AuthorizationResult authorizationResult;
103+
string authority;
104+
string clientId;
77105

78106
if (ParameterSetName.Equals("ServicePrincipal", StringComparison.InvariantCultureIgnoreCase))
79107
{
@@ -85,20 +113,48 @@ protected override void ProcessRecord()
85113
account.Type = AccountType.User;
86114
}
87115

88-
if (Credential != null)
116+
account.Properties[AzureAccountPropertyType.Tenant] = string.IsNullOrEmpty(TenantId) ? CommonEndpoint : TenantId;
117+
environment = PartnerEnvironment.PublicEnvironments[Environment];
118+
119+
client = new PartnerServiceClient(new Uri(environment.PartnerCenterEndpoint));
120+
authority = $"{environment.ActiveDirectoryAuthority}{account.Properties[AzureAccountPropertyType.Tenant]}/oauth2/token";
121+
122+
clientId = account.Type == AccountType.ServicePrincipal ? Credential.UserName : ApplicationId;
123+
124+
if (!string.IsNullOrEmpty(RefreshToken))
89125
{
90-
account.Id = Credential.UserName;
91-
password = Credential.Password;
126+
authResult = client.RefreshAccessTokenAsync(
127+
authority,
128+
Resource,
129+
RefreshToken,
130+
clientId,
131+
Credential?.Password.ConvertToString()).GetAwaiter().GetResult();
92132
}
133+
else if (account.Type == AccountType.ServicePrincipal && !Consent.IsPresent || Consent.ToBool() == false)
134+
{
135+
authResult = client.AcquireTokenAsync(
136+
authority,
137+
Resource,
138+
clientId,
139+
Credential.Password.ConvertToString()).GetAwaiter().GetResult();
140+
}
141+
else
142+
{
143+
using (WindowsFormsWebAuthenticationDialog dialog = new WindowsFormsWebAuthenticationDialog(null))
144+
{
145+
authorizationResult = dialog.AuthenticateAAD(
146+
new Uri($"{environment.ActiveDirectoryAuthority}{account.Properties[AzureAccountPropertyType.Tenant]}/oauth2/authorize?resource={HttpUtility.UrlEncode(Resource)}&client_id={clientId}&response_type=code&haschrome=1&redirect_uri={HttpUtility.UrlEncode(redirectUriValue)}&response_mode=form_post&prompt=login"),
147+
redirectUri);
148+
}
93149

94-
account.Properties[AzureAccountPropertyType.Tenant] = string.IsNullOrEmpty(TenantId) ? CommonEndpoint : TenantId;
95-
96-
authResult = PartnerSession.Instance.AuthenticationFactory.Authenticate(
97-
ApplicationId,
98-
account,
99-
password,
100-
Environment,
101-
TokenCache ?? TokenCache.DefaultShared);
150+
authResult = client.AcquireTokenByAuthorizationCodeAsync(
151+
authority,
152+
Resource,
153+
redirectUri,
154+
authorizationResult.Code,
155+
clientId,
156+
Credential?.Password.ConvertToString()).GetAwaiter().GetResult();
157+
}
102158

103159
WriteObject(authResult);
104160
}

0 commit comments

Comments
 (0)