diff --git a/sdk/README.md b/sdk/README.md index 32ba9ba..a7d097d 100644 --- a/sdk/README.md +++ b/sdk/README.md @@ -37,8 +37,11 @@ Perform the following task to correctly configure the Azure AD application for u 4. Sign in to the [Azure management portal](https://portal.azure.com) using the same credentials from step 1. 5. Click on the _Azure Active Directory_ icon in the toolbar. 6. Click _App registrations_ -> Select _All apps_ from the drop down -> Click on the application created in step 3. -7. Click _Settings_ and then click _Redirect URIs_ -8. Add **urn:ietf:wg:oauth:2.0:oob** as one of the available Redirect URIs. Be sure to click the _Save_ button to ensure the changes are saved. +7. Click _Authentication_ from left menu blade and then click _Add Platform_ +8. In the Right popup blade, Click on _Mobile and Desktop Applications_ +8. Select **https://login.microsoftonline.com/common/oauth2/nativeclient** as one of the available Redirect URIs ( You need to add a custom redirectUri too. Add **http://localhost** but we will be using the one added earlier ). +9. Click _Configure_. Your set of redirect Uris will be added under Platform **Mobile and Desktop Applications**. +10. Be sure to click the _Save_ button to ensure the changes are saved. ## What to Change @@ -65,6 +68,7 @@ The following settings must be modified, so that each scenario functions as exce The following settings must be updated, so that each scenario functions as expected - **ApplicationId**: Your Azure Active Directory application identifier, used for authentication +- **Domain**: The Azure Active Directory domain where the Azure AD application was created Do not change the following configurations diff --git a/sdk/SdkSamples/App.config b/sdk/SdkSamples/App.config index 3f7d5aa..211cfec 100644 --- a/sdk/SdkSamples/App.config +++ b/sdk/SdkSamples/App.config @@ -22,10 +22,15 @@ + + - + + diff --git a/sdk/SdkSamples/Configuration/UserAuthenticationSection.cs b/sdk/SdkSamples/Configuration/UserAuthenticationSection.cs index c34e1d9..acfa3ff 100644 --- a/sdk/SdkSamples/Configuration/UserAuthenticationSection.cs +++ b/sdk/SdkSamples/Configuration/UserAuthenticationSection.cs @@ -32,6 +32,17 @@ namespace Microsoft.Store.PartnerCenter.Samples.Configuration } } + /// + /// Gets AAD Domain which hosts the application. + /// + public string Domain + { + get + { + return this.ConfigurationSection["Domain"]; + } + } + /// /// Gets the resource the application is attempting to access, i.e. the partner API service. /// diff --git a/sdk/SdkSamples/Context/ScenarioContext.cs b/sdk/SdkSamples/Context/ScenarioContext.cs index 4a26a96..8c998a0 100644 --- a/sdk/SdkSamples/Context/ScenarioContext.cs +++ b/sdk/SdkSamples/Context/ScenarioContext.cs @@ -7,11 +7,12 @@ namespace Microsoft.Store.PartnerCenter.Samples.Context { using System; + using System.Linq; using System.Threading.Tasks; using Configuration; using Extensions; using Helpers; - using IdentityModel.Clients.ActiveDirectory; + using Identity.Client; /// /// Scenario context implementation class. @@ -91,7 +92,7 @@ namespace Microsoft.Store.PartnerCenter.Samples.Context { this.ConsoleHelper.StartProgress("Authenticating user"); - AuthenticationResult aadAuthenticationResult = this.LoginUserToAad(); + AuthenticationResult aadAuthenticationResult = Task.Run(() => this.LoginUserToAad()).Result; // Authenticate by user context with the partner service IPartnerCredentials userCredentials = PartnerCredentials.Instance.GenerateByUserCredentials( @@ -103,7 +104,7 @@ namespace Microsoft.Store.PartnerCenter.Samples.Context { // token has expired, re-Login to Azure Active Directory this.ConsoleHelper.StartProgress("Token expired. Re-authenticating user"); - AuthenticationResult aadToken = this.LoginUserToAad(); + AuthenticationResult aadToken = Task.Run(() => this.LoginUserToAad()).Result; this.ConsoleHelper.StopProgress(); // give the partner SDK the new add token information @@ -124,21 +125,47 @@ namespace Microsoft.Store.PartnerCenter.Samples.Context /// Logs in to AAD as a user and obtains the user authentication token. /// /// The user authentication result. - private AuthenticationResult LoginUserToAad() + private async Task LoginUserToAad() { - UriBuilder addAuthority = new UriBuilder(this.Configuration.PartnerService.AuthenticationAuthorityEndpoint) + var tenantDomain = string.IsNullOrWhiteSpace(Configuration.UserAuthentication.Domain) ? this.Configuration.PartnerService.CommonDomain : this.Configuration.UserAuthentication.Domain; + + var scopes = new string[] { $"{Configuration.UserAuthentication.ResourceUrl.OriginalString}/.default" }; + AuthenticationResult result = null; + + var app = PublicClientApplicationBuilder.Create(Configuration.UserAuthentication.ApplicationId) + .WithAuthority(this.Configuration.PartnerService.AuthenticationAuthorityEndpoint.OriginalString, tenantDomain, true) + .WithRedirectUri(this.Configuration.UserAuthentication.RedirectUrl.OriginalString) + .Build(); + + var accounts = await app.GetAccountsAsync(); + + try { - Path = this.Configuration.PartnerService.CommonDomain - }; + result = await app.AcquireTokenSilent(scopes, accounts.FirstOrDefault()) + .ExecuteAsync(); + } + catch (MsalUiRequiredException ex) + { + // A MsalUiRequiredException happened on AcquireTokenSilent. + // This indicates you need to call AcquireTokenInteractive to acquire a token + System.Diagnostics.Debug.WriteLine($"MsalUiRequiredException: {ex.Message}"); - AuthenticationContext authContext = new AuthenticationContext(addAuthority.Uri.AbsoluteUri); + try + { + result = await app.AcquireTokenInteractive(scopes) + .ExecuteAsync(); + } + catch (MsalException msalex) + { + throw msalex; + } + } + catch (Exception ex) + { + throw ex; + } - return Task.Run(() => authContext.AcquireTokenAsync( - Configuration.UserAuthentication.ResourceUrl.OriginalString, - Configuration.UserAuthentication.ApplicationId, - redirectUri, - new PlatformParameters(PromptBehavior.Always), - UserIdentifier.AnyUser)).Result; + return result; } } } \ No newline at end of file diff --git a/sdk/SdkSamples/Customers/CreateCustomerQualification.cs b/sdk/SdkSamples/Customers/CreateCustomerQualification.cs index 0a07cdd..a264597 100644 --- a/sdk/SdkSamples/Customers/CreateCustomerQualification.cs +++ b/sdk/SdkSamples/Customers/CreateCustomerQualification.cs @@ -32,7 +32,14 @@ namespace Microsoft.Store.PartnerCenter.Samples.Customers var partnerOperations = this.Context.UserPartnerOperations; this.Context.ConsoleHelper.StartProgress("Creating customer qualification"); - var customerQualification = new Models.Customers.V2.CustomerQualification { Qualification = "education" }; + /* This variable can be set to any allowed qualification, for example: + * (1) "education" + * (2) "GovernmentCommunityCloud" <- this has to be paired with a ValidationCode, see sample in "CreateCustomerQualificationWithGCC.cs" + * (3) "StateOwnedEntity" + */ + var qualificationToCreate = "education"; + + var customerQualification = new Models.Customers.V2.CustomerQualification { Qualification = qualificationToCreate }; var createCustomerQualification = partnerOperations.Customers.ById(customerIdToRetrieve).Qualification.CreateQualifications(customerQualification); diff --git a/sdk/SdkSamples/Customers/GetCustomerQualification.cs b/sdk/SdkSamples/Customers/GetCustomerQualification.cs deleted file mode 100644 index 080bc9f..0000000 --- a/sdk/SdkSamples/Customers/GetCustomerQualification.cs +++ /dev/null @@ -1,38 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// ----------------------------------------------------------------------- - -namespace Microsoft.Store.PartnerCenter.Samples.Customers -{ - /// - /// Gets a single customer qualification. - /// - public class GetCustomerQualification : BasePartnerScenario - { - /// - /// Initializes a new instance of the class. - /// - /// The scenario context. - public GetCustomerQualification(IScenarioContext context) : base("Get customer qualification", context) - { - } - - /// - /// Executes the get customer qualification scenario. - /// - protected override void RunScenario() - { - string customerIdToRetrieve = this.ObtainCustomerId("Enter the ID of the customer to retrieve qualification for"); - - var partnerOperations = this.Context.UserPartnerOperations; - this.Context.ConsoleHelper.StartProgress("Retrieving customer qualification"); - - var customerQualification = partnerOperations.Customers.ById(customerIdToRetrieve).Qualification.Get(); - - this.Context.ConsoleHelper.StopProgress(); - this.Context.ConsoleHelper.WriteObject(customerQualification, "Customer Qualification"); - } - } -} diff --git a/sdk/SdkSamples/Customers/UpdateCustomerQualification.cs b/sdk/SdkSamples/Customers/UpdateCustomerQualification.cs deleted file mode 100644 index c1a4695..0000000 --- a/sdk/SdkSamples/Customers/UpdateCustomerQualification.cs +++ /dev/null @@ -1,42 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// ----------------------------------------------------------------------- - -namespace Microsoft.Store.PartnerCenter.Samples.Customers -{ - using Microsoft.Store.PartnerCenter.Models.Customers; - - /// - /// Updates a single customer qualification. - /// - public class UpdateCustomerQualification : BasePartnerScenario - { - /// - /// Initializes a new instance of the class. - /// - /// The scenario context. - public UpdateCustomerQualification(IScenarioContext context) : base("Update customer qualification", context) - { - } - - /// - /// Executes the update customer qualification scenario. - /// - protected override void RunScenario() - { - string customerIdToRetrieve = this.ObtainCustomerId($"Enter the ID of the customer to update qualification to {CustomerQualification.Education}"); - - var partnerOperations = this.Context.UserPartnerOperations; - this.Context.ConsoleHelper.StartProgress("Updating customer qualification"); - - var customerQualification = - partnerOperations.Customers.ById(customerIdToRetrieve) - .Qualification.Update(CustomerQualification.Education); - - this.Context.ConsoleHelper.StopProgress(); - this.Context.ConsoleHelper.WriteObject(customerQualification, "Customer Qualification"); - } - } -} diff --git a/sdk/SdkSamples/Customers/UpdateCustomerQualificationWithGCC.cs b/sdk/SdkSamples/Customers/UpdateCustomerQualificationWithGCC.cs deleted file mode 100644 index 4e6f757..0000000 --- a/sdk/SdkSamples/Customers/UpdateCustomerQualificationWithGCC.cs +++ /dev/null @@ -1,72 +0,0 @@ -// ----------------------------------------------------------------------- -// -// Copyright (c) Microsoft Corporation. All rights reserved. -// -// ----------------------------------------------------------------------- - -namespace Microsoft.Store.PartnerCenter.Samples.Customers -{ - using Microsoft.Store.PartnerCenter.Models.Customers; - using Microsoft.Store.PartnerCenter.Models.ValidationCodes; - using System.Collections.Generic; - - /// - /// Updates a single customer qualification to GCC. - /// - public class UpdateCustomerQualificationWithGCC : BasePartnerScenario - { - /// - /// Initializes a new instance of the class. - /// - /// The scenario context. - public UpdateCustomerQualificationWithGCC(IScenarioContext context) : base("Update customer qualification with GCC", context) - { - } - - /// - /// Executes the update customer qualification scenario. - /// - protected override void RunScenario() - { - string customerIdToRetrieve = this.ObtainCustomerId($"Enter the ID of the customer to update qualification to {CustomerQualification.GovernmentCommunityCloud}"); - - var partnerOperations = this.Context.UserPartnerOperations; - - this.Context.ConsoleHelper.StartProgress("Retrieving validation codes"); - var validations = partnerOperations.Validations.GetValidationCodes(); - this.Context.ConsoleHelper.StopProgress(); - - this.Context.ConsoleHelper.Success("Success!"); - - this.Context.ConsoleHelper.WriteObject(validations, "Validations"); - - string validationCodeToRetrieve = this.ObtainQuantity("Enter validation code to use by ValidationId"); - - ValidationCode code = null; - - foreach(ValidationCode c in validations) - { - if(c.ValidationId == validationCodeToRetrieve) - { - code = c; - break; - } - } - - if(code == null) - { - this.Context.ConsoleHelper.Error("Code not found"); - } - - this.Context.ConsoleHelper.StartProgress("Updating customer qualification"); - - - var customerQualification = - partnerOperations.Customers.ById(customerIdToRetrieve) - .Qualification.Update(CustomerQualification.GovernmentCommunityCloud, code); - - this.Context.ConsoleHelper.StopProgress(); - this.Context.ConsoleHelper.WriteObject(customerQualification, "Customer Qualification"); - } - } -} diff --git a/sdk/SdkSamples/Program.cs b/sdk/SdkSamples/Program.cs index f609135..bf076dd 100644 --- a/sdk/SdkSamples/Program.cs +++ b/sdk/SdkSamples/Program.cs @@ -238,10 +238,7 @@ namespace Microsoft.Store.PartnerCenter.Samples new GetPagedCustomers(context, context.Configuration.Scenario.CustomerPageSize), new AggregatePartnerScenario("Customer filtering", customerFilteringScenarios, context), new GetCustomerDetails(context), - new GetCustomerQualification(context), new GetCustomerQualifications(context), - new UpdateCustomerQualification(context), - new UpdateCustomerQualificationWithGCC(context), new CreateCustomerQualification(context), new CreateCustomerQualificationWithGCC(context), new DeleteCustomerFromTipAccount(context), diff --git a/sdk/SdkSamples/SdkSamples.csproj b/sdk/SdkSamples/SdkSamples.csproj index 75b0f58..7040703 100644 --- a/sdk/SdkSamples/SdkSamples.csproj +++ b/sdk/SdkSamples/SdkSamples.csproj @@ -42,17 +42,17 @@ bin\Release\Microsoft.Store.PartnerCenter.Samples.xml - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.0\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + ..\packages\Microsoft.Identity.Client.4.31.0\lib\net461\Microsoft.Identity.Client.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.17.0\lib\netstandard2.0\Microsoft.Store.PartnerCenter.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.17.0\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Extensions.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Extensions.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.17.0\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Models.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Models.dll ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll @@ -136,9 +136,7 @@ - - @@ -148,7 +146,6 @@ - diff --git a/sdk/SdkSamples/Validations/AddressValidation.cs b/sdk/SdkSamples/Validations/AddressValidation.cs index 89d64c1..b0d48c7 100644 --- a/sdk/SdkSamples/Validations/AddressValidation.cs +++ b/sdk/SdkSamples/Validations/AddressValidation.cs @@ -6,7 +6,10 @@ namespace Microsoft.Store.PartnerCenter.Samples.Validations { - using System; + using System; + using System.Collections.Generic; + using System.Linq; + using System.Text; using Models; /// @@ -41,32 +44,30 @@ namespace Microsoft.Store.PartnerCenter.Samples.Validations }; this.Context.ConsoleHelper.StartProgress("Validating address"); + var addressValidationResult = partnerOperations.Validations.IsAddressValid(address); + this.Context.ConsoleHelper.StopProgress(); - try - { - // Validate the address - var validationResult = partnerOperations.Validations.IsAddressValidAsync(address).Result; - this.Context.ConsoleHelper.StopProgress(); - Console.WriteLine(validationResult ? "The address is valid." : "Invalid address"); - } - catch (Exception exception) - { - this.Context.ConsoleHelper.StopProgress(); - Console.WriteLine("Address is invalid"); - var innerException = exception.InnerException; - if (innerException != null) - { - while (innerException != null) - { - this.Context.ConsoleHelper.WriteObject(innerException.Message); - innerException = innerException.InnerException; - } - } - else if (!string.IsNullOrWhiteSpace(exception.Message)) - { - this.Context.ConsoleHelper.WriteObject(exception.Message); - } + Console.WriteLine($"Status: {addressValidationResult.Status}"); + Console.WriteLine($"Original Address:\n{this.DisplayAddress(addressValidationResult.OriginalAddress)}"); + Console.WriteLine($"Validation Message Returned: {addressValidationResult.ValidationMessage ?? "No message returned."}"); + Console.WriteLine($"Suggested Addresses Returned: {addressValidationResult.SuggestedAddresses?.Count}"); + + if (addressValidationResult.SuggestedAddresses != null && addressValidationResult.SuggestedAddresses.Any()) + { + addressValidationResult.SuggestedAddresses.ForEach(a => Console.WriteLine(this.DisplayAddress(a))); } } + + private string DisplayAddress(Address address) + { + StringBuilder sb = new StringBuilder(); + + foreach (var property in address.GetType().GetProperties()) + { + sb.AppendLine($"{property.Name}: {property.GetValue(address) ?? "None to Display."}"); + } + + return sb.ToString(); + } } } diff --git a/sdk/SdkSamples/packages.config b/sdk/SdkSamples/packages.config index 0a25861..a3a2bd3 100644 --- a/sdk/SdkSamples/packages.config +++ b/sdk/SdkSamples/packages.config @@ -1,7 +1,7 @@  - - + + diff --git a/secure-app-model/keyvault/CPVApplication/App.config b/secure-app-model/keyvault/CPVApplication/App.config index 7392c1b..e2fcd7c 100644 --- a/secure-app-model/keyvault/CPVApplication/App.config +++ b/secure-app-model/keyvault/CPVApplication/App.config @@ -30,10 +30,6 @@ - - - - @@ -42,6 +38,10 @@ + + + + \ No newline at end of file diff --git a/secure-app-model/keyvault/CPVApplication/CPVApplication.csproj b/secure-app-model/keyvault/CPVApplication/CPVApplication.csproj index f329597..a03e181 100644 --- a/secure-app-model/keyvault/CPVApplication/CPVApplication.csproj +++ b/secure-app-model/keyvault/CPVApplication/CPVApplication.csproj @@ -38,8 +38,8 @@ ..\packages\Microsoft.Azure.KeyVault.WebKey.3.0.4\lib\net461\Microsoft.Azure.KeyVault.WebKey.dll - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.0\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + ..\packages\Microsoft.Identity.Client.4.31.0\lib\net461\Microsoft.Identity.Client.dll ..\packages\Microsoft.Rest.ClientRuntime.2.3.20\lib\net461\Microsoft.Rest.ClientRuntime.dll @@ -47,19 +47,23 @@ ..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.19\lib\net461\Microsoft.Rest.ClientRuntime.Azure.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.Extensions.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Extensions.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.Models.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Models.dll ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + diff --git a/secure-app-model/keyvault/CPVApplication/packages.config b/secure-app-model/keyvault/CPVApplication/packages.config index 14fea19..b132b61 100644 --- a/secure-app-model/keyvault/CPVApplication/packages.config +++ b/secure-app-model/keyvault/CPVApplication/packages.config @@ -2,11 +2,13 @@ - + - + + + diff --git a/secure-app-model/keyvault/CSPApplication/App.config b/secure-app-model/keyvault/CSPApplication/App.config index 2d8e224..eab6de0 100644 --- a/secure-app-model/keyvault/CSPApplication/App.config +++ b/secure-app-model/keyvault/CSPApplication/App.config @@ -29,10 +29,6 @@ - - - - @@ -41,6 +37,10 @@ + + + + \ No newline at end of file diff --git a/secure-app-model/keyvault/CSPApplication/CSPApplication.csproj b/secure-app-model/keyvault/CSPApplication/CSPApplication.csproj index 066b2cc..c50a3ba 100644 --- a/secure-app-model/keyvault/CSPApplication/CSPApplication.csproj +++ b/secure-app-model/keyvault/CSPApplication/CSPApplication.csproj @@ -38,8 +38,8 @@ ..\packages\Microsoft.Azure.KeyVault.WebKey.3.0.4\lib\net461\Microsoft.Azure.KeyVault.WebKey.dll - - ..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.5.2.0\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll + + ..\packages\Microsoft.Identity.Client.4.31.0\lib\net461\Microsoft.Identity.Client.dll ..\packages\Microsoft.Rest.ClientRuntime.2.3.20\lib\net461\Microsoft.Rest.ClientRuntime.dll @@ -47,19 +47,23 @@ ..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.19\lib\net461\Microsoft.Rest.ClientRuntime.Azure.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.Extensions.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Extensions.dll - - ..\packages\Microsoft.Store.PartnerCenter.1.13.1\lib\Net45\Microsoft.Store.PartnerCenter.Models.dll + + ..\packages\Microsoft.Store.PartnerCenter.2.0.1\lib\netstandard2.0\Microsoft.Store.PartnerCenter.Models.dll ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll + + ..\packages\System.ComponentModel.Annotations.4.7.0\lib\net461\System.ComponentModel.Annotations.dll + + diff --git a/secure-app-model/keyvault/CSPApplication/packages.config b/secure-app-model/keyvault/CSPApplication/packages.config index 14fea19..b132b61 100644 --- a/secure-app-model/keyvault/CSPApplication/packages.config +++ b/secure-app-model/keyvault/CSPApplication/packages.config @@ -2,11 +2,13 @@ - + - + + +