This commit is contained in:
Isaiah Williams 2017-12-18 20:53:33 +00:00
Родитель 38c628b8f9
Коммит 392aca0105
37 изменённых файлов: 658 добавлений и 637 удалений

79
.editorconfig Normal file
Просмотреть файл

@ -0,0 +1,79 @@
# EditorConfig is awesome:http://EditorConfig.org
# top-most EditorConfig file
root = true
# Don't use tabs for indentation.
[*]
indent_style = space
end_of_line = crlf
# (Please don't specify an indent_size here; that has too many unintended consequences.)
# Code files
[*.{cs,csx,vb,vbx}]
indent_size = 4
# Xml project files
[*.{csproj,vbproj,vcxproj,vcxproj.filters,proj,projitems,shproj}]
indent_size = 2
# Xml config files
[*.{props,targets,ruleset,config,nuspec,resx,vsixmanifest,vsct}]
indent_size = 2
# JSON files
[*.json]
indent_size = 2
# Dotnet code style settings:
[*.{cs, vb}]
# Sort using and Import directives with System.* appearing first
dotnet_sort_system_directives_first = true
# Avoid "this." and "Me." if not necessary
dotnet_style_qualification_for_field = false:suggestion
dotnet_style_qualification_for_property = false:suggestion
dotnet_style_qualification_for_method = false:suggestion
dotnet_style_qualification_for_event = false:suggestion
# Use language keywords instead of framework type names for type references
dotnet_style_predefined_type_for_locals_parameters_members = true:suggestion
dotnet_style_predefined_type_for_member_access = true:suggestion
# Suggest more modern language features when available
dotnet_style_object_initializer = true:suggestion
dotnet_style_collection_initializer = true:suggestion
dotnet_style_coalesce_expression = true:suggestion
dotnet_style_null_propagation = true:suggestion
dotnet_style_explicit_tuple_names = true:suggestion
# CSharp code style settings:
[*.cs]
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = false:suggestion
csharp_style_var_when_type_is_apparent = false:suggestion
csharp_style_var_elsewhere = false:suggestion
# Prefer method-like constructs to have a block body
csharp_style_expression_bodied_methods = false:none
csharp_style_expression_bodied_constructors = false:none
csharp_style_expression_bodied_operators = false:none
# Prefer property-like constructs to have an expression-body
csharp_style_expression_bodied_properties = true:none
csharp_style_expression_bodied_indexers = true:none
csharp_style_expression_bodied_accessors = true:none
# Suggest more modern language features when available
csharp_style_pattern_matching_over_is_with_cast_check = true:suggestion
csharp_style_pattern_matching_over_as_with_null_check = true:suggestion
csharp_style_inlined_variable_declaration = true:suggestion
csharp_style_throw_expression = true:suggestion
csharp_style_conditional_delegate_call = true:suggestion
# Newline settings
csharp_new_line_before_open_brace = all
csharp_new_line_before_else = true
csharp_new_line_before_catch = true
csharp_new_line_before_finally = true
csharp_new_line_before_members_in_object_initializers = true
csharp_new_line_before_members_in_anonymous_types = true

Просмотреть файл

@ -23,6 +23,11 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "docs", "docs", "{AF9B24D9-4
docs\Terminolgy.md = docs\Terminolgy.md
EndProjectSection
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "scripts", "scripts", "{A574A852-591E-4594-96BB-808122581462}"
ProjectSection(SolutionItems) = preProject
scripts\Create-AzureADApplication.ps1 = scripts\Create-AzureADApplication.ps1
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU

Просмотреть файл

@ -0,0 +1,134 @@
<#
* MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a copy of this
* software and associated documentation files (the "Software"), to deal in the Software
* without restriction, including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
* to whom the Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all copies or
* substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
* PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE
* FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
#>
<#
.SYNOPSIS
This script will apply the supported service policy restriction for the specified Azure subscription.
.EXAMPLE
.\Create-AzureADApplication.ps1 -DisplayName "Partner Center Explorer"
.\Create-AzureADApplication.ps1 -DisplayName "Partner Center Explorer" -TenantId eb210c1e-b697-4c06-b4e3-8b104c226b9a
.\Create-AzureADApplication.ps1 -DisplayName "Partner Center Explorer" -TenantId tenant01.onmicrosoft.com
.PARAMETER DisplayName
Display name for the Azure AD application that will be created.
.PARAMETER TenantId
[OPTIONAL] The domain or tenant identifier for the Azure AD tenant that should be utilized to create the various resources.
#>
Param
(
[Parameter(Mandatory = $true)]
[string]$DisplayName,
[Parameter(Mandatory = $false)]
[string]$TenantId
)
$ErrorActionPreference = "Stop"
# Check if the Azure AD PowerShell module has already been loaded.
if ( ! ( Get-Module AzureAD ) ) {
# Check if the Azure AD PowerShell module is installed.
if ( Get-Module -ListAvailable -Name AzureAD ) {
# The Azure AD PowerShell module is not load and it is installed. This module
# must be loaded for other operations performed by this script.
Write-Host -ForegroundColor Green "Loading the AzureAD PowerShell module..."
Import-Module AzureAD
} else {
Install-Module AzureAD
}
}
$credential = Get-Credential -Message "Please specify credentials that have Global Admin privileges..."
try {
Write-Host -ForegroundColor Green "When prompted please enter the appropriate credentials..."
if([string]::IsNullOrEmpty($TenantId)) {
Connect-AzureAD -Credential $credential
$TenantId = $(Get-AzureADTenantDetail).ObjectId
} else {
Connect-AzureAD -Credential $credential -TenantId $TenantId
}
} catch [Microsoft.Azure.Common.Authentication.AadAuthenticationCanceledException] {
# The authentication attempt was canceled by the end-user. Execution of the script should be halted.
Write-Host -ForegroundColor Yellow "The authentication attempt was canceled. Execution of the script will be halted..."
Exit
} catch {
# An unexpected error has occurred. The end-user should be notified so that the appropriate action can be taken.
Write-Error "An unexpected error has occurred. Please review the following error message and try again." `
"$($Error[0].Exception)"
}
$sessionInfo = Get-AzureADCurrentSessionInfo
$adAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "00000002-0000-0000-c000-000000000000";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "311a71cc-e848-46a1-bdf8-97ff7156d8e6";
Type = "Scope"},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "a42657d6-7f20-40e3-b6f0-cee03008a62a";
Type = "Scope"},
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "5778995a-e1bf-45b8-affa-663a9f3f4d04";
Type = "Role"}
}
$azureAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "797f4846-ba00-4fd7-ba43-dac1f8f63013";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "41094075-9dad-400e-a0bd-54e686782033";
Type = "Scope"}
}
$officeAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "c5393580-f805-4401-95e8-94b7a6ef2fc2";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "e2cea78f-e743-4d8f-a16a-75b629a038ae";
Type = "Role"}
}
$partnerCenterAppAccess = [Microsoft.Open.AzureAD.Model.RequiredResourceAccess]@{
ResourceAppId = "fa3d9a0c-3fb0-42cc-9193-47c7ecd2edbd";
ResourceAccess =
[Microsoft.Open.AzureAD.Model.ResourceAccess]@{
Id = "1cebfa2a-fb4d-419e-b5f9-839b4383e05a";
Type = "Scope"}
}
Write-Host -ForegroundColor Green "Creating the Azure AD application and related resources..."
$app = New-AzureADApplication -AvailableToOtherTenants $true -DisplayName $DisplayName -IdentifierUris "https://$($sessionInfo.TenantDomain)/$((New-Guid).ToString())" -RequiredResourceAccess $adAppAccess, $azureAppAccess, $officeAppAccess, $partnerCenterAppAccess
$spn = New-AzureADServicePrincipal -AppId $app.AppId -DisplayName $DisplayName
$password = New-AzureADApplicationPasswordCredential -ObjectId $app.ObjectId
$adminAgentsGroup = Get-AzureADGroup | Where-Object {$_.DisplayName -eq 'AdminAgents'}
Add-AzureADGroupMember -ObjectId $adminAgentsGroup.ObjectId -RefObjectId $spn.ObjectId
Write-Host "ApplicationId = $($app.AppId)"
Write-Host "ApplicationSecret = $($password.Value)"
Write-Host "ApplicationTenantId = $($sessionInfo.TenantId)"

Просмотреть файл

@ -31,7 +31,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <param name="app">The application to be configured.</param>
public void ConfigureAuth(IAppBuilder app)
{
IExplorerService service = MvcApplication.UnityContainer.Resolve<IExplorerService>();
IExplorerService service = UnityConfig.Container.Resolve<IExplorerService>();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
@ -65,7 +65,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
IGraphClient client = new GraphClient(service, userTenantId);
List<RoleModel> roles = await client.GetDirectoryRolesAsync(signedInUserObjectId);
List<RoleModel> roles = await client.GetDirectoryRolesAsync(signedInUserObjectId).ConfigureAwait(false);
foreach (RoleModel role in roles)
{
@ -81,7 +81,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
{
try
{
Customer c = await service.PartnerOperations.GetCustomerAsync(userTenantId);
Customer c = await service.PartnerOperations.GetCustomerAsync(userTenantId).ConfigureAwait(false);
customerId = c.Id;
}
catch (PartnerException ex)

Просмотреть файл

@ -11,35 +11,34 @@ namespace Microsoft.Store.PartnerCenter.Explorer
using Unity;
/// <summary>
/// Provides configurations for Unity.
/// Specifies the Unity configuration for the main container.
/// </summary>
public static class UnityConfig
{
/// <summary>
/// The Unity container to be utilized for dependency injection.
/// </summary>
private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() =>
{
UnityContainer container = new UnityContainer();
RegisterTypes(container);
return container;
});
#region Unity Container
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
UnityContainer container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Gets the configured Unity container.
/// Configured Unity Container.
/// </summary>
/// <returns>
/// The configured Unity container.</returns>
public static IUnityContainer GetConfiguredContainer()
{
return container.Value;
}
public static IUnityContainer Container => container.Value;
#endregion
/// <summary>Registers the type mappings with the Unity container.</summary>
/// <summary>
/// Registers the type mappings with the Unity container.
/// </summary>
/// <param name="container">The unity container to configure.</param>
/// <remarks>
/// There is no need to register concrete types such as controllers or API controllers (unless you want to
/// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.
/// There is no need to register concrete types such as controllers or
/// API controllers (unless you want to change the defaults), as Unity
/// allows resolving a concrete type even if it was not previously
/// registered.
/// </remarks>
public static void RegisterTypes(IUnityContainer container)
{

Просмотреть файл

@ -1,17 +1,16 @@
// -----------------------------------------------------------------------
// <copyright file="UnityMvcActivator.cs" company="Microsoft">
// <copyright file="UnityConfig.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator), "Start")]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator), "Shutdown")]
[assembly: WebActivatorEx.PreApplicationStartMethod(typeof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator), nameof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator.Start))]
[assembly: WebActivatorEx.ApplicationShutdownMethod(typeof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator), nameof(Microsoft.Store.PartnerCenter.Explorer.UnityMvcActivator.Shutdown))]
namespace Microsoft.Store.PartnerCenter.Explorer
{
using System.Linq;
using System.Web.Mvc;
using Unity;
using Unity.AspNet.Mvc;
/// <summary>
@ -22,14 +21,15 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
public static void Start()
{
IUnityContainer container = UnityConfig.GetConfiguredContainer();
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(container));
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityDependencyResolver(container));
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>
@ -37,8 +37,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// </summary>
public static void Shutdown()
{
IUnityContainer container = UnityConfig.GetConfiguredContainer();
container.Dispose();
UnityConfig.Container.Dispose();
}
}
}

Просмотреть файл

@ -7,11 +7,13 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
using System;
using System.Net;
using System.IO;
using System.IO.Compression;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Logic;
using Newtonsoft.Json;
using Security;
using StackExchange.Redis;
/// <summary>
@ -19,15 +21,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// </summary>
public class CacheService : ICacheService
{
/// <summary>
/// Provides the ability to protect data.
/// </summary>
private readonly IDataProtector protector;
/// <summary>
/// Provides access to core services.
/// </summary>
private readonly IExplorerService service;
private IExplorerService service;
/// <summary>
/// Provides the ability to interact with an instance of Redis Cache.
@ -35,7 +32,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
private IConnectionMultiplexer connection;
/// <summary>
/// Initializes a new instance of the <see cref="CacheService"/> class.
/// Initializes a new instance of the <see cref="RedisCacheProvider"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <exception cref="ArgumentNullException">
@ -44,32 +41,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
public CacheService(IExplorerService service)
{
service.AssertNotNull(nameof(service));
this.protector = new MachineKeyDataProtector(new[] { typeof(CacheService).FullName });
this.service = service;
}
/// <summary>
/// Initializes a new instance of the <see cref="CacheService"/> class.
/// </summary>
/// <param name="service">Provides access to core services.c</param>
/// <param name="connection">Connection to utilized to communicate with the Redis Cache instance.</param>
/// <param name="dataProtector">Provides protection for data being cached.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// or
/// <paramref name="connection"/> is null.
/// or
/// <paramref name="dataProtector"/> is null.
/// </exception>
public CacheService(IExplorerService service, IConnectionMultiplexer connection, IDataProtector dataProtector)
{
service.AssertNotNull(nameof(service));
connection.AssertNotNull(nameof(connection));
dataProtector.AssertNotNull(nameof(dataProtector));
this.connection = connection;
this.protector = dataProtector;
this.service = service;
}
@ -80,30 +51,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
public async Task ClearAsync(CacheDatabaseType database)
{
EndPoint[] endpoints;
IServer server;
try
{
if (this.connection == null)
{
this.connection = await ConnectionMultiplexer.ConnectAsync(
this.service.Configuration.RedisCacheConnectionString.ToUnsecureString());
}
endpoints = this.connection.GetEndPoints(true);
foreach (EndPoint ep in endpoints)
{
server = this.connection.GetServer(ep);
await server.FlushDatabaseAsync((int)database);
}
}
finally
{
endpoints = null;
server = null;
}
await Task.FromResult(0);
}
/// <summary>
@ -111,17 +59,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// </summary>
/// <param name="database">Cache database type where the data is stored.</param>
/// <param name="key">The key of the entity to be deleted.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
/// <returns>An instance of <see cref="Task"/> that represents the asynchronous operation.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is empty or null.
/// </exception>
public async Task DeleteAsync(CacheDatabaseType database, string key = null)
{
key.AssertNotEmpty(nameof(key));
IDatabase cache = this.GetCacheReference(database);
await cache.KeyDeleteAsync(key);
IDatabase cache = await GetCacheReferenceAsync(database);
await cache.KeyDeleteAsync(key).ConfigureAwait(false);
}
/// <summary>
@ -140,11 +85,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
key.AssertNotEmpty(nameof(key));
IDatabase cache = this.GetCacheReference(database);
IDatabase cache = GetCacheReference(database);
RedisValue value = cache.StringGet(key);
return value.HasValue ?
JsonConvert.DeserializeObject<TEntity>(this.protector.Unprotect(value)) : null;
return value.HasValue ? DecompressEntity<TEntity>(value) : null;
}
/// <summary>
@ -163,10 +107,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
key.AssertNotEmpty(nameof(key));
IDatabase cache = this.GetCacheReference(database);
RedisValue value = await cache.StringGetAsync(key);
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
RedisValue value = await cache.StringGetAsync(key).ConfigureAwait(false);
return value.HasValue ? JsonConvert.DeserializeObject<TEntity>(this.protector.Unprotect(value)) : null;
return value.HasValue ? DecompressEntity<TEntity>(value) : null;
}
/// <summary>
@ -190,9 +134,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
key.AssertNotEmpty(nameof(key));
entity.AssertNotNull(nameof(entity));
IDatabase cache = await this.GetCacheReferenceAsync(database);
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
await cache.StringSetAsync(
key, this.protector.Protect(JsonConvert.SerializeObject(entity)), expiration);
key,
CompressEntity(entity),
expiration).ConfigureAwait(false);
}
/// <summary>
@ -201,30 +148,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <param name="database">Cache database type where the data is stored.</param>
public void Clear(CacheDatabaseType database)
{
EndPoint[] endpoints;
IServer server;
try
{
if (this.connection == null)
{
this.connection = ConnectionMultiplexer.Connect(
this.service.Configuration.RedisCacheConnectionString.ToUnsecureString());
}
endpoints = this.connection.GetEndPoints(true);
foreach (EndPoint ep in endpoints)
{
server = this.connection.GetServer(ep);
server.FlushDatabase((int)database);
}
}
finally
{
endpoints = null;
server = null;
}
}
/// <summary>
@ -235,11 +158,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is empty or null.
/// </exception>
public void Delete(CacheDatabaseType database, string key)
public void Delete(CacheDatabaseType database, string key = null)
{
key.AssertNotEmpty(nameof(key));
IDatabase cache = this.GetCacheReference(database);
IDatabase cache = GetCacheReference(database);
cache.KeyDelete(key);
}
@ -247,7 +168,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// Stores the specified entity in the cache.
/// </summary>
/// <typeparam name="TEntity">The type of the entity in cache.</typeparam>
/// <param name="cacheDatabase">Cache database type where the data should be stored.</param>
/// <param name="database">Cache database type where the data should be stored.</param>
/// <param name="key">A unique identifier for the cache entry.</param>
/// <param name="entity">The object to be cached.</param>
/// <param name="expiration">When the entity in the cache should expire.</param>
@ -257,15 +178,89 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <exception cref="ArgumentNullException">
/// entity
/// </exception>
public void Store<TEntity>(CacheDatabaseType cacheDatabase, string key, TEntity entity, TimeSpan? expiration = null)
public void Store<TEntity>(CacheDatabaseType database, string key, TEntity entity, TimeSpan? expiration = null)
where TEntity : class
{
key.AssertNotEmpty(nameof(key));
entity.AssertNotNull(nameof(entity));
IDatabase cache = this.GetCacheReference(cacheDatabase);
IDatabase cache = GetCacheReference(database);
cache.StringSet(
key, this.protector.Protect(JsonConvert.SerializeObject(entity)), expiration);
key, CompressEntity(entity), expiration);
}
/// <summary>
/// Compresses the specified entity.
/// </summary>
/// <typeparam name="TEntity">The type of the entity to be compressed.</typeparam>
/// <param name="entity">The entity to be compressed.</param>
/// <returns>A base 64 string that represents the compressed entity.</returns>
/// <exception cref="ArgumentNullException">
/// <paramref name="entity"/> is null.
/// </exception>
private static string CompressEntity<TEntity>(TEntity entity)
{
MemoryStream memoryStream;
byte[] buffer;
entity.AssertNotNull(nameof(entity));
try
{
buffer = Encoding.UTF8.GetBytes(JsonConvert.SerializeObject(entity));
memoryStream = new MemoryStream();
using (GZipStream stream = new GZipStream(memoryStream, CompressionMode.Compress))
{
stream.Write(buffer, 0, buffer.Length);
}
return Convert.ToBase64String(memoryStream.ToArray());
}
finally
{
buffer = null;
}
}
/// <summary>
/// Decompresses the entity represented by the specified value.
/// </summary>
/// <typeparam name="TEntity">The type of the entity to be decompressed.</typeparam>
/// <param name="value">A base 64 string that represented the compressed entity.</param>
/// <returns>The decompressed and deserialized instance of the entity.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="value"/> is empty or null.
/// </exception>
public static TEntity DecompressEntity<TEntity>(string value)
{
MemoryStream memoryStream;
byte[] buffer;
value.AssertNotEmpty(nameof(value));
try
{
buffer = Convert.FromBase64String(value);
memoryStream = new MemoryStream(buffer, 0, buffer.Length);
using (MemoryStream decompressedStream = new MemoryStream())
{
using (GZipStream stream = new GZipStream(memoryStream, CompressionMode.Decompress))
{
stream.CopyTo(decompressedStream);
}
return JsonConvert.DeserializeObject<TEntity>(Encoding.UTF8.GetString(decompressedStream.ToArray()));
}
}
finally
{
buffer = null;
}
}
/// <summary>
@ -275,22 +270,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <returns>A reference to the appropriate cache database.</returns>
private IDatabase GetCacheReference(CacheDatabaseType database)
{
if (this.connection != null)
if (connection == null)
{
return this.connection.GetDatabase((int)database);
using (SecureString redisCacheConnectionString = SynchronousExecute(() => service.Vault.GetAsync("RedisCacheConnectionString")))
{
connection = ConnectionMultiplexer.Connect(
redisCacheConnectionString.ToUnsecureString());
}
}
try
{
this.connection = ConnectionMultiplexer.Connect(
this.service.Configuration.RedisCacheConnectionString.ToUnsecureString());
return this.connection.GetDatabase((int)database);
}
catch (RedisConnectionException ex)
{
throw new CacheException("Failed to connect to the instance of Redis Cache.", ex);
}
return connection.GetDatabase((int)database);
}
/// <summary>
@ -300,21 +289,39 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <returns>A reference to the appropriate cache database.</returns>
private async Task<IDatabase> GetCacheReferenceAsync(CacheDatabaseType database)
{
if (this.connection != null)
if (connection == null)
{
return this.connection.GetDatabase((int)database);
using (SecureString redisCacheConnectionString = await service.Vault.GetAsync("RedisCacheConnectionString"))
{
connection = await ConnectionMultiplexer.ConnectAsync(
redisCacheConnectionString.ToUnsecureString()).ConfigureAwait(false);
}
}
return connection.GetDatabase((int)database);
}
/// <summary>
/// Executes an asynchronous method synchronously
/// </summary>
/// <typeparam name="T">The type to be returned.</typeparam>
/// <param name="operation">The asynchronous operation to be executed.</param>
/// <returns>The result from the operation.</returns>
private static T SynchronousExecute<T>(Func<Task<T>> operation)
{
try
{
this.connection = await ConnectionMultiplexer.ConnectAsync(
this.service.Configuration.RedisCacheConnectionString.ToUnsecureString());
return this.connection.GetDatabase((int)database);
return Task.Run(async () => await operation?.Invoke()).Result;
}
catch (RedisConnectionException ex)
catch (AggregateException ex)
{
throw new CacheException("Failed to connect to the instance of Redis Cache.", ex);
if (ex.InnerException != null)
{
throw ex.InnerException;
}
throw;
}
}
}

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// Initializes a new instance of the <see cref="Configuration"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// </exception>
public Configuration(IExplorerService service)
@ -39,12 +39,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Gets the Active Directory endpoint address.
/// </summary>
public string ActiveDirectoryEndpoint => ConfigurationManager.AppSettings["ActiveDirectoryEndpoint"];
public string ActiveDirectoryEndpoint { get; private set; }
/// <summary>
/// Gets the application identifier value.
/// </summary>
public string ApplicationId => ConfigurationManager.AppSettings["ApplicationId"];
public string ApplicationId { get; private set; }
/// <summary>
/// Gets the application secret value.
@ -54,27 +54,27 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Gets the application tenant identifier.
/// </summary>
public string ApplicationTenantId => ConfigurationManager.AppSettings["ApplicationTenantId"];
public string ApplicationTenantId { get; private set; }
/// <summary>
/// Gets the Azure Resource Manager endpoint address.
/// </summary>
public string AzureResourceManagerEndpoint => ConfigurationManager.AppSettings["AzureResourceManagerEndpoint"];
public string AzureResourceManagerEndpoint { get; private set; }
/// <summary>
/// Gets the Microsoft Graph endpoint address.
/// </summary>
public string GraphEndpoint => ConfigurationManager.AppSettings["GraphEndpoint"];
public string GraphEndpoint { get; private set; }
/// <summary>
/// Gets the Application Insights instrumentation key.
/// </summary>
public string InstrumentationKey => ConfigurationManager.AppSettings["InstrumentationKey"];
public string InstrumentationKey { get; private set; }
/// <summary>
/// Gets the endpoint address for the instance of Key Vault.
/// </summary>
public string KeyVaultEndpoint => ConfigurationManager.AppSettings["KeyVaultEndpoint"];
public string KeyVaultEndpoint { get; private set; }
/// <summary>
/// Gets a value indicating whether or not the reseller tenant is the TIP tenant.
@ -84,12 +84,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Gets the Office 365 Management endpoint address.
/// </summary>
public string OfficeManagementEndpoint => ConfigurationManager.AppSettings["OfficeManagementEndpoint"];
public string OfficeManagementEndpoint { get; private set; }
/// <summary>
/// Gets the Partner Center application identifier.
/// </summary>
public string PartnerCenterApplicationId => ConfigurationManager.AppSettings["PartnerCenterApplicationId"];
public string PartnerCenterApplicationId { get; private set; }
/// <summary>
/// Gets the Partner Center application secret.
@ -99,12 +99,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Gets the Partner Center application tenant identifier.
/// </summary>
public string PartnerCenterApplicationTenantId => ConfigurationManager.AppSettings["PartnerCenterApplicationTenantId"];
public string PartnerCenterApplicationTenantId { get; private set; }
/// <summary>
/// Gets the Partner Center endpoint address.
/// </summary>
public string PartnerCenterEndpoint => ConfigurationManager.AppSettings["PartnerCenterEndpoint"];
public string PartnerCenterEndpoint { get; private set; }
/// <summary>
/// Gets the Redis Cache connection string.
@ -117,9 +117,22 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <returns>An instance of the <see cref="Task"/> class that represents the asynchronous operation.</returns>
public async Task InitializeAsync()
{
ApplicationSecret = await service.Vault.GetAsync("ApplicationSecret");
PartnerCenterApplicationSecret = await service.Vault.GetAsync("PartnerCenterApplicationSecret");
RedisCacheConnectionString = await service.Vault.GetAsync("RedisCacheConnectionString");
ActiveDirectoryEndpoint = ConfigurationManager.AppSettings["ActiveDirectoryEndpoint"];
ApplicationId = ConfigurationManager.AppSettings["ApplicationId"];
ApplicationTenantId = ConfigurationManager.AppSettings["ApplicationTenantId"];
AzureResourceManagerEndpoint = ConfigurationManager.AppSettings["AzureResourceManagerEndpoint"];
GraphEndpoint = ConfigurationManager.AppSettings["GraphEndpoint"];
InstrumentationKey = ConfigurationManager.AppSettings["InstrumentationKey"];
KeyVaultEndpoint = ConfigurationManager.AppSettings["KeyVaultEndpoint"];
OfficeManagementEndpoint = ConfigurationManager.AppSettings["OfficeManagementEndpoint"];
PartnerCenterApplicationId = ConfigurationManager.AppSettings["PartnerCenterApplicationId"];
PartnerCenterApplicationTenantId = ConfigurationManager.AppSettings["PartnerCenterApplicationTenantId"];
PartnerCenterEndpoint = ConfigurationManager.AppSettings["PartnerCenterEndpoint"];
ApplicationSecret = await service.Vault.GetAsync("ApplicationSecret").ConfigureAwait(false);
PartnerCenterApplicationSecret = await service.Vault.GetAsync("PartnerCenterApplicationSecret").ConfigureAwait(false);
RedisCacheConnectionString = await service.Vault.GetAsync("RedisCacheConnectionString").ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -38,7 +38,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
AuditRecordsModel auditRecordsModel = new AuditRecordsModel()
{
Records = await this.Service.PartnerOperations.GetAuditRecordsAsync(startDate, endDate)
Records = await Service.PartnerOperations.GetAuditRecordsAsync(startDate, endDate).ConfigureAwait(false)
};
return PartialView("Records", auditRecordsModel);
@ -50,7 +50,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <returns>Returns an empty view.</returns>
public ActionResult Search()
{
return this.View();
return View();
}
}
}

Просмотреть файл

@ -6,7 +6,6 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
@ -46,9 +45,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
customerId.AssertNotEmpty(nameof(customerId));
if (this.Service.Configuration.IsIntegrationSandbox)
if (Service.Configuration.IsIntegrationSandbox)
{
await this.Service.PartnerOperations.DeleteCustomerAsync(customerId);
await Service.PartnerOperations.DeleteCustomerAsync(customerId).ConfigureAwait(false);
}
return new HttpResponseMessage(HttpStatusCode.NoContent);
@ -61,7 +60,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
[HttpGet]
public PartialViewResult Create()
{
return this.PartialView();
return PartialView();
}
/// <summary>
@ -107,7 +106,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
}
};
entity = await this.Service.PartnerOperations.CreateCustomerAsync(entity);
entity = await Service.PartnerOperations.CreateCustomerAsync(entity).ConfigureAwait(false);
createdCustomerModel = new CreatedCustomerModel()
{
@ -116,7 +115,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
Username = entity.UserCredentials.UserName
};
return this.PartialView("CreatedSuccessfully", createdCustomerModel);
return PartialView("CreatedSuccessfully", createdCustomerModel);
}
finally
{
@ -132,11 +131,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
CustomersModel customersModel = new CustomersModel()
{
Customers = await this.GetCustomerModelsAsync(),
IsSandboxEnvironment = this.Service.Configuration.IsIntegrationSandbox
Customers = await GetCustomerModelsAsync().ConfigureAwait(false),
IsSandboxEnvironment = Service.Configuration.IsIntegrationSandbox
};
return this.PartialView(customersModel);
return PartialView(customersModel);
}
/// <summary>
@ -145,7 +144,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <returns>The HTML template for the index page.</returns>
public ActionResult Index()
{
return this.View();
return View();
}
/// <summary>
@ -165,7 +164,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await this.Service.PartnerOperations.GetCustomerAsync(customerId);
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
customerModel = new CustomerModel()
{
@ -176,7 +175,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customer.CompanyProfile.TenantId
};
return this.View(customerModel);
return View(customerModel);
}
finally
{
@ -195,7 +194,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customers = await this.Service.PartnerOperations.GetCustomersAsync();
customers = await Service.PartnerOperations.GetCustomersAsync().ConfigureAwait(false);
return customers.Select(item => new CustomerModel
{

Просмотреть файл

@ -43,7 +43,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
return Json(false, JsonRequestBehavior.AllowGet);
}
bool exists = await Service.PartnerOperations.CheckDomainAsync($"{primaryDomain}.onmicrosoft.com");
bool exists = await Service.PartnerOperations.CheckDomainAsync($"{primaryDomain}.onmicrosoft.com").ConfigureAwait(false);
return Json(!exists, JsonRequestBehavior.AllowGet);
}
@ -66,7 +66,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
client = new GraphClient(Service, customerId);
domains = await client.GetDomainsAsync();
domains = await client.GetDomainsAsync().ConfigureAwait(false);
return Json(domains, JsonRequestBehavior.AllowGet);
}

Просмотреть файл

@ -56,8 +56,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId);
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
healthModel = new SubscriptionHealthModel
{
@ -74,7 +74,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
}
else
{
healthModel.HealthEvents = await GetOfficeSubscriptionHealthAsync(customerId);
healthModel.HealthEvents = await GetOfficeSubscriptionHealthAsync(customerId).ConfigureAwait(false);
}
return View(healthModel.ViewModel, healthModel);
@ -115,11 +115,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ApplicationSecret = Service.Configuration.ApplicationSecret,
UseCache = true
},
Service.AccessToken.UserAssertionToken);
Service.AccessToken.UserAssertionToken).ConfigureAwait(false);
using (Insights insights = new Insights(subscriptionId, token.AccessToken))
{
return await insights.GetHealthEventsAsync();
return await insights.GetHealthEventsAsync().ConfigureAwait(false);
}
}
finally
@ -150,10 +150,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ApplicationId = Service.Configuration.ApplicationId,
ApplicationSecret = Service.Configuration.ApplicationSecret,
UseCache = true
});
}).ConfigureAwait(false);
comm = new ServiceCommunications(Service, token);
return await comm.GetCurrentStatusAsync(customerId);
return await comm.GetCurrentStatusAsync(customerId).ConfigureAwait(false);
}
finally
{

Просмотреть файл

@ -30,7 +30,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <returns>The HTML template for the index page.</returns>
public ActionResult Index()
{
return this.View();
return View();
}
/// <summary>
@ -39,7 +39,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <returns>The HTML template for the error page.</returns>
public ActionResult Error()
{
return this.View();
return View();
}
}
}

Просмотреть файл

@ -52,10 +52,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
InvoiceDetailsModel invoiceDetailsModel = new InvoiceDetailsModel()
{
InvoiceLineItems = await this.GetInvoiceLineItemsAsync(invoiceId, customerName, "Azure")
InvoiceLineItems = await GetInvoiceLineItemsAsync(invoiceId, customerName, "Azure").ConfigureAwait(false)
};
return this.PartialView(invoiceDetailsModel);
return PartialView(invoiceDetailsModel);
}
/// <summary>
@ -66,10 +66,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
InvoicesModel invoicesModel = new InvoicesModel()
{
Invoices = await this.Service.PartnerOperations.GetInvoicesAsync()
Invoices = await Service.PartnerOperations.GetInvoicesAsync().ConfigureAwait(false)
};
return this.View(invoicesModel);
return View(invoicesModel);
}
/// <summary>
@ -85,15 +85,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
List<string> customers;
List<InvoiceLineItem> lineItems;
if (string.IsNullOrEmpty(invoiceId))
{
throw new ArgumentNullException(nameof(invoiceId));
}
invoiceId.AssertNotEmpty(nameof(invoiceId));
try
{
customers = new List<string>();
lineItems = await this.GetInvoiceLineItemsAsync(invoiceId);
lineItems = await GetInvoiceLineItemsAsync(invoiceId).ConfigureAwait(false);
customers.AddRange(
lineItems
@ -113,7 +110,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
.Cast<UsageBasedLineItem>()
.Select(x => x.CustomerCompanyName));
return this.Json(customers.Distinct(), JsonRequestBehavior.AllowGet);
return Json(customers.Distinct(), JsonRequestBehavior.AllowGet);
}
finally
{
@ -131,7 +128,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
if (string.IsNullOrEmpty(invoiceId))
{
return this.RedirectToAction("Index", "Invoices");
return RedirectToAction("Index", "Invoices");
}
InvoiceDetailsModel invoiceDetailsModel = new InvoiceDetailsModel()
@ -139,7 +136,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
InvoiceId = invoiceId,
};
return this.View(invoiceDetailsModel);
return View(invoiceDetailsModel);
}
/// <summary>
@ -168,14 +165,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
if (providerType.Equals("Azure", StringComparison.OrdinalIgnoreCase))
{
data = await this.GetUsageRecordsAsync(invoiceId, customerName);
data = await GetUsageRecordsAsync(invoiceId, customerName).ConfigureAwait(false);
}
else
{
data = await this.GetLicensedRecordsAsync(invoiceId, customerName);
data = await GetLicensedRecordsAsync(invoiceId, customerName).ConfigureAwait(false);
}
return this.File(data.ToArray(), "text/csv", $"Invoice-{invoiceId}-{customerName}-{providerType}.csv");
return File(data.ToArray(), "text/csv", $"Invoice-{invoiceId}-{customerName}-{providerType}.csv");
}
finally
{
@ -201,10 +198,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
InvoiceDetailsModel invoiceDetailsModel = new InvoiceDetailsModel()
{
InvoiceLineItems = await this.GetInvoiceLineItemsAsync(invoiceId, customerName, "Office")
InvoiceLineItems = await GetInvoiceLineItemsAsync(invoiceId, customerName, "Office").ConfigureAwait(false)
};
return this.PartialView(invoiceDetailsModel);
return PartialView(invoiceDetailsModel);
}
/// <summary>
@ -234,13 +231,15 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
return lineItems;
}
invoice = await this.Service.PartnerOperations.GetInvoiceAsync(invoiceId);
invoice = await Service.PartnerOperations.GetInvoiceAsync(invoiceId).ConfigureAwait(false);
lineItems = new List<InvoiceLineItem>();
foreach (InvoiceDetail detail in invoice.InvoiceDetails)
{
data = await this.Service.PartnerOperations
.GetInvoiceLineItemsAsync(invoiceId, detail.BillingProvider, detail.InvoiceLineItemType);
data = await Service.PartnerOperations.GetInvoiceLineItemsAsync(
invoiceId,
detail.BillingProvider,
detail.InvoiceLineItemType).ConfigureAwait(false);
lineItems.AddRange(data);
}
@ -281,7 +280,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
if (providerType.Equals("Azure", StringComparison.OrdinalIgnoreCase))
{
items = await this.GetInvoiceLineItemsAsync(invoiceId);
items = await GetInvoiceLineItemsAsync(invoiceId).ConfigureAwait(false);
return items
.Where(x => x is UsageBasedLineItem)
@ -291,7 +290,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
}
else if (providerType.Equals("Office", StringComparison.OrdinalIgnoreCase))
{
items = await this.GetInvoiceLineItemsAsync(invoiceId);
items = await GetInvoiceLineItemsAsync(invoiceId).ConfigureAwait(false);
return items
.Where(x => x is LicenseBasedLineItem)
@ -326,7 +325,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
data = await this.GetInvoiceLineItemsAsync(invoiceId, customerName, "Office");
data = await GetInvoiceLineItemsAsync(invoiceId, customerName, "Office").ConfigureAwait(false);
items = data.Cast<LicenseBasedLineItem>().ToList();
using (MemoryStream stream = new MemoryStream())
@ -365,7 +364,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
data = await this.GetInvoiceLineItemsAsync(invoiceId, customerName, "Azure");
data = await GetInvoiceLineItemsAsync(invoiceId, customerName, "Azure").ConfigureAwait(false);
items = data.Cast<UsageBasedLineItem>().ToList();
using (MemoryStream stream = new MemoryStream())

Просмотреть файл

@ -60,8 +60,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
deployments = await this.GetDeploymentsAsync(customerId, resourceGroupName, subscriptionId);
return this.PartialView("Deployments", deployments);
deployments = await GetDeploymentsAsync(customerId, resourceGroupName, subscriptionId).ConfigureAwait(false);
return PartialView("Deployments", deployments);
}
finally
{
@ -91,8 +91,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId);
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
manageModel = new SubscriptionManageModel
{
@ -164,7 +164,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{model.CustomerId}");
$"{Service.Configuration.ActiveDirectoryEndpoint}/{model.CustomerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
{
@ -174,7 +174,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
model.TemplateUri,
model.ParametersUri);
results = await GetDeploymentsAsync(model.CustomerId, model.ResourceGroupName, model.SubscriptionId);
results = await GetDeploymentsAsync(
model.CustomerId,
model.ResourceGroupName,
model.SubscriptionId).ConfigureAwait(false);
return PartialView("Deployments", results);
}
}
@ -208,7 +212,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}");
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
{
@ -242,7 +246,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}");
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
{
@ -275,7 +279,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ApplicationSecret = Service.Configuration.ApplicationSecret,
UseCache = true
},
Service.AccessToken.UserAssertionToken);
Service.AccessToken.UserAssertionToken).ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -43,7 +43,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
offers = await this.Service.PartnerOperations.GetOffersAsync();
offers = await Service.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
offersModel = new OffersModel
{
@ -64,7 +64,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customerId
};
return this.PartialView("Offers", offersModel);
return PartialView("Offers", offersModel);
}
finally
{
@ -90,8 +90,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
offers = await this.Service.PartnerOperations.GetOffersAsync();
return this.Json(offers.Single(x => x.Id.Equals(offerId, StringComparison.CurrentCultureIgnoreCase)), JsonRequestBehavior.AllowGet);
offers = await Service.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
return Json(
offers.Single(x => x.Id.Equals(offerId, StringComparison.CurrentCultureIgnoreCase)),
JsonRequestBehavior.AllowGet);
}
finally
{

Просмотреть файл

@ -49,7 +49,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
ServiceRequestsModel serviceRequestsModel = new ServiceRequestsModel()
{
ServiceRequests = await GetServiceRequestsAsync()
ServiceRequests = await GetServiceRequestsAsync().ConfigureAwait(false)
};
return PartialView(serviceRequestsModel);
@ -65,7 +65,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
requests = await Service.PartnerOperations.GetServiceRequestsAsync();
requests = await Service.PartnerOperations.GetServiceRequestsAsync().ConfigureAwait(false);
return requests.Items.Select(r => new ServiceRequestModel()
{

Просмотреть файл

@ -52,7 +52,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customerId
};
return this.PartialView(newSubscriptionModel);
return PartialView(newSubscriptionModel);
}
/// <summary>
@ -74,10 +74,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ReferenceCustomerId = model.CustomerId
};
newOrder = await this.Service.PartnerOperations.CreateOrderAsync(model.CustomerId, newOrder);
subscriptionsModel = await this.GetSubscriptionsAsync(model.CustomerId);
newOrder = await Service.PartnerOperations.CreateOrderAsync(model.CustomerId, newOrder).ConfigureAwait(false);
subscriptionsModel = await GetSubscriptionsAsync(model.CustomerId).ConfigureAwait(false);
return this.PartialView("List", subscriptionsModel);
return PartialView("List", subscriptionsModel);
}
finally
{
@ -97,13 +97,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
subscription = await this.Service.PartnerOperations.GetSubscriptionAsync(model.CustomerId, model.Id);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(model.CustomerId, model.Id).ConfigureAwait(false);
subscription.FriendlyName = model.FriendlyName;
subscription.Status = model.Status;
subscription.Quantity = model.Quantity;
await this.Service.PartnerOperations.UpdateSubscriptionAsync(model.CustomerId, subscription);
await Service.PartnerOperations.UpdateSubscriptionAsync(model.CustomerId, subscription).ConfigureAwait(false);
return new HttpResponseMessage(HttpStatusCode.OK);
}
@ -129,8 +129,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
subscriptionsModel = await this.GetSubscriptionsAsync(customerId);
return this.PartialView(subscriptionsModel);
subscriptionsModel = await GetSubscriptionsAsync(customerId).ConfigureAwait(false);
return PartialView(subscriptionsModel);
}
finally
{
@ -160,8 +160,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await this.Service.PartnerOperations.GetCustomerAsync(customerId);
subscription = await this.Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId);
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
model = new SubscriptionModel()
{
@ -185,7 +185,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ViewModel = (subscription.BillingType == BillingType.License) ? "Office" : "Azure"
};
return this.View(model.ViewModel, model);
return View(model.ViewModel, model);
}
finally
{
@ -211,7 +211,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
subscriptions = await this.Service.PartnerOperations.GetSubscriptionsAsync(customerId);
subscriptions = await Service.PartnerOperations.GetSubscriptionsAsync(customerId).ConfigureAwait(false);
subscriptionsModel = new SubscriptionsModel()
{
Subscriptions = new List<SubscriptionModel>()

Просмотреть файл

@ -50,8 +50,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await this.Service.PartnerOperations.GetCustomerAsync(customerId);
subscription = await this.Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId);
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
UsageModel usageModel = new UsageModel()
{
@ -59,11 +59,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customerId,
SubscriptionId = subscriptionId,
SubscriptionFriendlyName = subscription.FriendlyName,
Usage = await this.Service.PartnerOperations
.GetSubscriptionUsageAsync(customerId, subscriptionId, DateTime.Now.AddMonths(-1), DateTime.Now)
Usage = await Service.PartnerOperations
.GetSubscriptionUsageAsync(customerId, subscriptionId, DateTime.Now.AddMonths(-1), DateTime.Now).ConfigureAwait(false)
};
return this.View(usageModel);
return View(usageModel);
}
finally
{

Просмотреть файл

@ -52,7 +52,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customerId
};
return this.PartialView(newUserModel);
return PartialView(newUserModel);
}
/// <summary>
@ -84,12 +84,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
client = new GraphClient(Service, newUserModel.CustomerId);
await Service.PartnerOperations.CreateUserAsync(newUserModel.CustomerId, user);
await Service.PartnerOperations.CreateUserAsync(newUserModel.CustomerId, user).ConfigureAwait(false);
UsersModel usersModel = new UsersModel()
{
CustomerId = newUserModel.CustomerId,
Users = await client.GetUsersAsync()
Users = await client.GetUsersAsync().ConfigureAwait(false)
};
return PartialView("List", usersModel);
@ -118,7 +118,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
customerId.AssertNotEmpty(nameof(customerId));
userId.AssertNotEmpty(nameof(userId));
await Service.PartnerOperations.DeleteUserAsync(customerId, userId);
await Service.PartnerOperations.DeleteUserAsync(customerId, userId).ConfigureAwait(false);
return new HttpResponseMessage(HttpStatusCode.OK);
}
@ -145,7 +145,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customerUser = await Service.PartnerOperations.GetUserAsync(customerId, userId);
customerUser = await Service.PartnerOperations.GetUserAsync(customerId, userId).ConfigureAwait(false);
editUserModel = new EditUserModel()
{
@ -181,7 +181,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
client = new GraphClient(Service, editUserModel.CustomerId);
customerUser = await Service.PartnerOperations.GetUserAsync(editUserModel.CustomerId, editUserModel.UserId);
customerUser = await Service.PartnerOperations.GetUserAsync(
editUserModel.CustomerId,
editUserModel.UserId).ConfigureAwait(false);
customerUser.DisplayName = editUserModel.DisplayName;
customerUser.FirstName = editUserModel.FirstName;
@ -192,14 +194,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
await Service.PartnerOperations.UpdateUserAsync(
editUserModel.CustomerId,
editUserModel.UserId,
customerUser);
customerUser).ConfigureAwait(false);
await ProcessLicenseModifications(editUserModel);
await ProcessLicenseModifications(editUserModel).ConfigureAwait(false);
UsersModel usersModel = new UsersModel()
{
CustomerId = editUserModel.CustomerId,
Users = await client.GetUsersAsync()
Users = await client.GetUsersAsync().ConfigureAwait(false)
};
return PartialView("List", usersModel);
@ -232,7 +234,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
UsersModel usersModel = new UsersModel()
{
CustomerId = customerId,
Users = await client.GetUsersAsync()
Users = await client.GetUsersAsync().ConfigureAwait(false)
};
return PartialView(usersModel);
@ -263,8 +265,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
values = new List<LicenseModel>();
licenses = await Service.PartnerOperations.GetUserLicensesAsync(customerId, userId);
subscribedSkus = await Service.PartnerOperations.GetCustomerSubscribedSkusAsync(customerId);
licenses = await Service.PartnerOperations.GetUserLicensesAsync(customerId, userId).ConfigureAwait(false);
subscribedSkus = await Service.PartnerOperations.GetCustomerSubscribedSkusAsync(customerId).ConfigureAwait(false);
foreach (SubscribedSku sku in subscribedSkus.Items)
{
@ -309,7 +311,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
assignments = new List<LicenseAssignment>();
current = await GetLicenses(model.CustomerId, model.UserId);
current = await GetLicenses(model.CustomerId, model.UserId).ConfigureAwait(false);
licenseUpdate = new LicenseUpdate();
removals = new List<string>();
@ -344,7 +346,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
if (assignments.Count > 0 || removals.Count > 0)
{
await Service.PartnerOperations.UpdateUserLicensesAsync(model.CustomerId, model.UserId, licenseUpdate);
await Service.PartnerOperations.UpdateUserLicensesAsync(
model.CustomerId,
model.UserId,
licenseUpdate).ConfigureAwait(false);
}
}
finally

Просмотреть файл

@ -56,10 +56,10 @@
<HintPath>..\..\packages\Antlr.3.5.0.2\lib\Antlr3.Runtime.dll</HintPath>
</Reference>
<Reference Include="CommonServiceLocator, Version=2.0.1.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\CommonServiceLocator.dll</HintPath>
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\CommonServiceLocator.dll</HintPath>
</Reference>
<Reference Include="CsvHelper, Version=6.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\..\packages\CsvHelper.6.0.3\lib\net45\CsvHelper.dll</HintPath>
<HintPath>..\..\packages\CsvHelper.6.1.0\lib\net45\CsvHelper.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.Agent.Intercept, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Agent.Intercept.2.4.0\lib\net45\Microsoft.AI.Agent.Intercept.dll</HintPath>
@ -258,29 +258,29 @@
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<Reference Include="Unity.Abstractions, Version=2.3.1.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Abstractions.2.3.1\lib\net45\Unity.Abstractions.dll</HintPath>
<Reference Include="Unity.Abstractions, Version=2.4.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Abstractions.2.4.0\lib\net45\Unity.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Unity.Configuration, Version=5.1.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\Unity.Configuration.dll</HintPath>
<Reference Include="Unity.Configuration, Version=5.1.1.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\Unity.Configuration.dll</HintPath>
</Reference>
<Reference Include="Unity.Container, Version=5.3.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Container.5.3.2\lib\net45\Unity.Container.dll</HintPath>
<Reference Include="Unity.Container, Version=5.4.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Container.5.4.0\lib\net45\Unity.Container.dll</HintPath>
</Reference>
<Reference Include="Unity.Interception, Version=5.1.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\Unity.Interception.dll</HintPath>
<Reference Include="Unity.Interception, Version=5.2.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\Unity.Interception.dll</HintPath>
</Reference>
<Reference Include="Unity.Interception.Configuration, Version=5.1.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\Unity.Interception.Configuration.dll</HintPath>
<Reference Include="Unity.Interception.Configuration, Version=5.1.1.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\Unity.Interception.Configuration.dll</HintPath>
</Reference>
<Reference Include="Unity.Mvc, Version=5.0.9.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Mvc.5.0.9\lib\net45\Unity.Mvc.dll</HintPath>
<Reference Include="Unity.Mvc, Version=5.0.10.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Mvc.5.0.10\lib\net45\Unity.Mvc.dll</HintPath>
</Reference>
<Reference Include="Unity.RegistrationByConvention, Version=2.1.1.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\Unity.RegistrationByConvention.dll</HintPath>
<Reference Include="Unity.RegistrationByConvention, Version=2.1.2.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\Unity.RegistrationByConvention.dll</HintPath>
</Reference>
<Reference Include="Unity.ServiceLocation, Version=2.0.8.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.3.2\lib\net45\Unity.ServiceLocation.dll</HintPath>
<Reference Include="Unity.ServiceLocation, Version=2.0.9.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.4.0\lib\net45\Unity.ServiceLocation.dll</HintPath>
</Reference>
<Reference Include="WebActivatorEx, Version=2.0.0.0, Culture=neutral, PublicKeyToken=7b26dc2a43f6a0d4, processorArchitecture=MSIL">
<HintPath>..\..\packages\WebActivatorEx.2.2.0\lib\net40\WebActivatorEx.dll</HintPath>
@ -377,11 +377,8 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\AuthenticationFilter.cs" />
<Compile Include="Security\CustomerPrincipal.cs" />
<Compile Include="Security\DataProtectorException.cs" />
<Compile Include="Security\IAccessTokenProvider.cs" />
<Compile Include="Security\IDataProtector.cs" />
<Compile Include="Security\IVaultService.cs" />
<Compile Include="Security\MachineKeyDataProtector.cs" />
<Compile Include="Security\UserRole.cs" />
<Compile Include="Security\VaultService.cs" />
<Compile Include="Startup.cs" />

Просмотреть файл

@ -20,11 +20,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <seealso cref="System.Web.HttpApplication" />
public class MvcApplication : HttpApplication
{
/// <summary>
/// Gets the unity container for the application.
/// </summary>
internal static IUnityContainer UnityContainer { get; private set; }
/// <summary>
/// Called when the application starts.
/// </summary>
@ -36,9 +31,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
{
AreaRegistration.RegisterAllAreas();
UnityContainer = UnityConfig.GetConfiguredContainer();
service = UnityContainer.Resolve<IExplorerService>();
service = UnityConfig.Container.Resolve<IExplorerService>();
Task.Run(service.InitializeAsync).Wait();

Просмотреть файл

@ -47,7 +47,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
/// </summary>
/// <param name="subscriptionId">The subscription identifier.</param>
/// <param name="token">Valid JSON Web Token (JWT).</param>
/// <exception cref="System.ArgumentNullException">
/// <exception cref="ArgumentNullException">
/// subscriptionId
/// or
/// token
@ -57,7 +57,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
subscriptionId.AssertNotEmpty(nameof(subscriptionId));
token.AssertNotEmpty(nameof(token));
this.client = new InsightsClient(new TokenCredentials(token));
client = new InsightsClient(new TokenCredentials(token));
this.subscriptionId = subscriptionId;
}
@ -66,7 +66,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
/// </summary>
public void Dispose()
{
this.Dispose(true);
Dispose(true);
GC.SuppressFinalize(this);
}
@ -83,7 +83,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
try
{
this.client.SubscriptionId = this.subscriptionId;
client.SubscriptionId = subscriptionId;
queryEndDate = DateTime.UtcNow;
queryStartDate = DateTime.UtcNow.AddMonths(-1);
@ -93,7 +93,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
&& (eventData.EventTimestamp <= queryEndDate)
&& (eventData.ResourceProvider == ResourceProviderName)));
events = await this.client.Events.ListAsync(query);
events = await client.Events.ListAsync(query).ConfigureAwait(false);
return events.Select(x => new AzureHealthEvent
{
@ -119,19 +119,19 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
/// <param name="disposing"><c>true</c> to release both managed and unmanaged resources; <c>false</c> to release only unmanaged resources.</param>
protected virtual void Dispose(bool disposing)
{
if (this.disposed)
if (disposed)
{
return;
}
this.client.Dispose();
client.Dispose();
if (disposing)
{
GC.SuppressFinalize(this);
}
this.disposed = true;
disposed = true;
}
}
}

Просмотреть файл

@ -92,7 +92,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
try
{
this.client.SubscriptionId = subscriptionId;
client.SubscriptionId = subscriptionId;
deployment = new Deployment()
{
@ -110,7 +110,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
deploymentName = Guid.NewGuid().ToString();
result = await client.Deployments.CreateOrUpdateAsync(resourceGroupName, deploymentName, deployment);
result = await client.Deployments.CreateOrUpdateAsync(
resourceGroupName,
deploymentName,
deployment).ConfigureAwait(false);
return result.Properties.ProvisioningState;
}
@ -142,7 +145,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
try
{
client.SubscriptionId = subscriptionId;
deployements = await client.Deployments.ListByResourceGroupAsync(resourceGroupName);
deployements = await client.Deployments.ListByResourceGroupAsync(resourceGroupName).ConfigureAwait(false);
return deployements.ToList();
}
@ -169,7 +172,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
try
{
client.SubscriptionId = subscriptionId;
resourceGroups = await client.ResourceGroups.ListAsync();
resourceGroups = await client.ResourceGroups.ListAsync().ConfigureAwait(false);
return resourceGroups.ToList();
}
finally

Просмотреть файл

@ -50,16 +50,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
response = await client.GetAsync(requestUri);
response = await client.GetAsync(requestUri).ConfigureAwait(false);
if (!response.IsSuccessStatusCode)
{
string result = await response.Content.ReadAsStringAsync();
string result = await response.Content.ReadAsStringAsync().ConfigureAwait(false);
throw new CommunicationException(result, response.StatusCode);
}
return await response.Content.ReadAsAsync<T>();
return await response.Content.ReadAsAsync<T>().ConfigureAwait(false);
}
}
finally

Просмотреть файл

@ -89,7 +89,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
return telemetry;
}
if (string.IsNullOrEmpty(this.Configuration.InstrumentationKey))
if (string.IsNullOrEmpty(Configuration.InstrumentationKey))
{
telemetry = new EmptyTelemetryProvider();
}
@ -113,7 +113,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <returns>An instance of <see cref="Task"/> that represents the asynchronous operation.</returns>
public async Task InitializeAsync()
{
await Configuration.InitializeAsync();
await Configuration.InitializeAsync().ConfigureAwait(false);
}
}
}

Просмотреть файл

@ -55,7 +55,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
this.customerId = customerId;
this.service = service;
this.client = new ActiveDirectoryClient(
client = new ActiveDirectoryClient(
new Uri($"{this.service.Configuration.GraphEndpoint}/{customerId}"),
async () =>
{
@ -67,7 +67,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
ApplicationId = service.Configuration.ApplicationId,
ApplicationSecret = service.Configuration.ApplicationSecret,
UseCache = true
});
}).ConfigureAwait(false);
return token.AccessToken;
});
@ -111,7 +111,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
try
{
memberships = await this.client.Users.GetByObjectId(objectId).MemberOf.ExecuteAsync();
memberships = await client.Users.GetByObjectId(objectId).MemberOf.ExecuteAsync().ConfigureAwait(false);
roles = new List<RoleModel>();
do
@ -141,7 +141,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
}
}
memberships = await memberships.GetNextPageAsync();
memberships = await memberships.GetNextPageAsync().ConfigureAwait(false);
}
while (memberships != null);
@ -165,7 +165,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
try
{
domains = await this.client.Domains.ExecuteAsync();
domains = await client.Domains.ExecuteAsync().ConfigureAwait(false);
models = new List<DomainModel>();
do
@ -184,7 +184,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
SupportedServices = d.SupportedServices
}));
domains = await domains.GetNextPageAsync();
domains = await domains.GetNextPageAsync().ConfigureAwait(false);
}
while (domains != null);
@ -207,14 +207,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
try
{
users = await this.client.Users.ExecuteAsync();
users = await client.Users.ExecuteAsync().ConfigureAwait(false);
value = new List<UserModel>();
do
{
value.AddRange(users.CurrentPage.Select(u => new UserModel()
{
CustomerId = this.customerId,
CustomerId = customerId,
DisplayName = u.DisplayName,
FirstName = u.GivenName,
Id = u.ObjectId,
@ -223,7 +223,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
UserPrincipalName = u.UserPrincipalName
}));
users = await users.GetNextPageAsync();
users = await users.GetNextPageAsync().ConfigureAwait(false);
}
while (users != null);

Просмотреть файл

@ -65,7 +65,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
records = await service.Communication.GetAsync<Result<OfficeHealthEvent>>(
requestUri,
token.AccessToken);
token.AccessToken).ConfigureAwait(false);
return records.Value.ToList<IHealthEvent>();
}

Просмотреть файл

@ -102,11 +102,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
exists = await operations.Domains.ByDomain(domain).ExistsAsync();
exists = await operations.Domains.ByDomain(domain).ExistsAsync().ConfigureAwait(false);
eventMetrics = new Dictionary<string, double>
{
@ -159,16 +159,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
newEntity = await operations.Customers.CreateAsync(customer);
newEntity = await operations.Customers.CreateAsync(customer).ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
@ -220,7 +220,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
@ -230,7 +230,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
}
else
{
newEntity = await operations.Customers.ById(principal.CustomerId).Orders.CreateAsync(newOrder);
newEntity = await operations.Customers.ById(principal.CustomerId).Orders.CreateAsync(newOrder).ConfigureAwait(false);
}
// Track the event measurements for analysis.
@ -292,13 +292,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
user = await operations.Customers.ById(customerId).Users.CreateAsync(newEntity);
user = await operations.Customers.ById(customerId).Users.CreateAsync(newEntity).ConfigureAwait(false);
}
else
{
@ -354,7 +354,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
@ -363,15 +363,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
await operations.Customers.ById(customerId).DeleteAsync();
await operations.Customers.ById(customerId).DeleteAsync().ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -420,7 +418,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
@ -429,7 +427,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
await operations.Customers.ById(customerId).Users.ById(userId).DeleteAsync();
await operations.Customers.ById(customerId).Users.ById(userId).DeleteAsync().ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
@ -445,7 +443,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("DeleteCustomerAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(DeleteUserAsync), eventProperties, eventMetrics);
}
finally
{
@ -476,14 +474,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
records = await operations.AuditRecords.QueryAsync(
startDate,
endDate,
QueryFactory.Instance.BuildSimpleQuery());
QueryFactory.Instance.BuildSimpleQuery()).ConfigureAwait(false);
eventMetrics = new Dictionary<string, double>
{
@ -530,26 +528,24 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
customer = await operations.Customers.ById(customerId).GetAsync();
customer = await operations.Customers.ById(customerId).GetAsync().ConfigureAwait(false);
}
else
{
customer = await operations.Customers.ById(principal.CustomerId).GetAsync();
customer = await operations.Customers.ById(principal.CustomerId).GetAsync().ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -557,7 +553,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetCustomerAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetCustomerAsync), eventProperties, eventMetrics);
return customer;
}
@ -591,37 +587,35 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
customers = new List<Customer>();
if (principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
seekCustomers = await operations.Customers.GetAsync();
seekCustomers = await operations.Customers.GetAsync().ConfigureAwait(false);
customersEnumerator = operations.Enumerators.Customers.Create(seekCustomers);
while (customersEnumerator.HasValue)
{
customers.AddRange(customersEnumerator.Current.Items);
await customersEnumerator.NextAsync();
await customersEnumerator.NextAsync().ConfigureAwait(false);
}
}
else
{
customer = await operations.Customers.ById(principal.CustomerId).GetAsync();
customer = await operations.Customers.ById(principal.CustomerId).GetAsync().ConfigureAwait(false);
customers.Add(customer);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
{ "NumberOfCustomers", customers.Count }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -668,14 +662,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
skus = await operations.Customers.ById(customerId).SubscribedSkus.GetAsync();
skus = await operations.Customers.ById(customerId).SubscribedSkus.GetAsync().ConfigureAwait(false);
}
else
{
@ -732,24 +726,22 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
invoice = await operations.Invoices.ById(invoiceId).GetAsync();
invoice = await operations.Invoices.ById(invoiceId).GetAsync().ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -757,7 +749,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetInvoiceAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetInvoiceAsync), eventProperties, eventMetrics);
return invoice;
}
@ -796,25 +788,23 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
invoiceLineItems = await operations.Invoices.ById(invoiceId).By(billingProvider, invoiceLineItemType).GetAsync();
invoiceLineItems = await operations.Invoices.ById(invoiceId).By(billingProvider, invoiceLineItemType).GetAsync().ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
{ "NumberOfInvoiceLineItems", invoiceLineItems.TotalCount }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -822,7 +812,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetInvoiceLineItemsAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetInvoiceLineItemsAsync), eventProperties, eventMetrics);
return new List<InvoiceLineItem>(invoiceLineItems.Items);
}
@ -854,25 +844,23 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
invoices = await operations.Invoices.GetAsync();
invoices = await operations.Invoices.GetAsync().ConfigureAwait(false);
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
{ "NumberOfInvoices", invoices.TotalCount }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -880,7 +868,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetInvoicesAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent("GetInvoicesAsync", eventProperties, eventMetrics);
return new List<Invoice>(invoices.Items);
}
@ -912,26 +900,24 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
offers = await this.service.Cache.FetchAsync<ResourceCollection<Offer>>(CacheDatabaseType.DataStructures, OffersKey);
offers = await service.Cache.FetchAsync<ResourceCollection<Offer>>(CacheDatabaseType.DataStructures, OffersKey).ConfigureAwait(false);
if (offers == null)
{
offers = await operations.Offers.ByCountry("US").GetAsync();
await this.service.Cache.StoreAsync(CacheDatabaseType.DataStructures, OffersKey, offers, TimeSpan.FromDays(1));
await service.Cache.StoreAsync(CacheDatabaseType.DataStructures, OffersKey, offers, TimeSpan.FromDays(1)).ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
{ "NumberOfInvoices", offers.TotalCount }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -939,7 +925,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetOffersAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetOffersAsync), eventProperties, eventMetrics);
return new List<Offer>(offers.Items);
}
@ -971,13 +957,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
requests = await operations.ServiceRequests.GetAsync();
requests = await operations.ServiceRequests.GetAsync().ConfigureAwait(false);
}
else
{
@ -1038,17 +1024,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
subscription = await operations.Customers.ById(customerId).Subscriptions.ById(subscriptionId).GetAsync();
subscription = await operations.Customers.ById(customerId).Subscriptions.ById(subscriptionId).GetAsync().ConfigureAwait(false);
}
else
{
subscription = await operations.Customers.ById(principal.CustomerId).Subscriptions.ById(subscriptionId).GetAsync();
subscription = await operations.Customers.ById(principal.CustomerId).Subscriptions.ById(subscriptionId).GetAsync().ConfigureAwait(false);
}
eventMetrics = new Dictionary<string, double>
@ -1100,27 +1086,25 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
subscriptions = await operations.Customers.ById(customerId).Subscriptions.GetAsync();
subscriptions = await operations.Customers.ById(customerId).Subscriptions.GetAsync().ConfigureAwait(false);
}
else
{
subscriptions = await operations.Customers.ById(principal.CustomerId).Subscriptions.GetAsync();
subscriptions = await operations.Customers.ById(principal.CustomerId).Subscriptions.GetAsync().ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds },
{ "NumberOfSubscriptions", subscriptions.TotalCount }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -1128,7 +1112,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetSubscriptionsAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetSubscriptionsAsync), eventProperties, eventMetrics);
return new List<Subscription>(subscriptions.Items);
}
@ -1168,45 +1152,43 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
invokeTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await this.GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
usageRecords = new List<AzureUtilizationRecord>();
if (principal.CustomerId.Equals(this.service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
records = await operations.Customers.ById(customerId).Subscriptions.ById(subscriptionId)
.Utilization.Azure.QueryAsync(startTime, endTime);
.Utilization.Azure.QueryAsync(startTime, endTime).ConfigureAwait(false);
usageEnumerator = operations.Enumerators.Utilization.Azure.Create(records);
while (usageEnumerator.HasValue)
{
usageRecords.AddRange(usageEnumerator.Current.Items);
await usageEnumerator.NextAsync();
await usageEnumerator.NextAsync().ConfigureAwait(false);
}
}
else
{
records = await operations.Customers.ById(principal.CustomerId).Subscriptions.ById(subscriptionId)
.Utilization.Azure.QueryAsync(startTime, endTime);
.Utilization.Azure.QueryAsync(startTime, endTime).ConfigureAwait(false);
usageEnumerator = operations.Enumerators.Utilization.Azure.Create(records);
while (usageEnumerator.HasValue)
{
usageRecords.AddRange(usageEnumerator.Current.Items);
await usageEnumerator.NextAsync();
await usageEnumerator.NextAsync().ConfigureAwait(false);
}
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(invokeTime).TotalMilliseconds },
{ "NumberOfUsageRecords", usageRecords.Count }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -1214,7 +1196,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
this.service.Telemetry.TrackEvent("GetSubscriptionUsageAsync", eventProperties, eventMetrics);
service.Telemetry.TrackEvent(nameof(GetSubscriptionUsageAsync), eventProperties, eventMetrics);
return usageRecords;
}
@ -1257,14 +1239,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
user = await operations.Customers.ById(customerId).Users.ById(userId).GetAsync();
user = await operations.Customers.ById(customerId).Users.ById(userId).GetAsync().ConfigureAwait(false);
}
else
{
@ -1325,14 +1307,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
licenses = await operations.Customers.ById(customerId).Users.ById(userId).Licenses.GetAsync();
licenses = await operations.Customers.ById(customerId).Users.ById(userId).Licenses.GetAsync().ConfigureAwait(false);
}
else
{
@ -1394,28 +1376,26 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
startTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetAppOperationsAsync(correlationId);
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
{
updatedSubscription = await operations.Customers.ById(customerId).Subscriptions
.ById(subscription.Id).PatchAsync(subscription);
.ById(subscription.Id).PatchAsync(subscription).ConfigureAwait(false);
}
else
{
updatedSubscription = await operations.Customers.ById(principal.CustomerId).Subscriptions
.ById(subscription.Id).PatchAsync(subscription);
.ById(subscription.Id).PatchAsync(subscription).ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(startTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -1461,27 +1441,25 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
user = await operations.Customers.ById(customerId).Users.ById(userId).PatchAsync(entity);
user = await operations.Customers.ById(customerId).Users.ById(userId).PatchAsync(entity).ConfigureAwait(false);
}
else
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(executionTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", principal.CustomerId },
@ -1534,14 +1512,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
executionTime = DateTime.Now;
correlationId = Guid.NewGuid();
operations = await GetUserOperationsAsync(correlationId);
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
await operations.Customers.ById(customerId).Users.ById(userId).LicenseUpdates.CreateAsync(entity);
await operations.Customers.ById(customerId).Users.ById(userId).LicenseUpdates.CreateAsync(entity).ConfigureAwait(false);
}
else
{
@ -1580,7 +1558,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
if (appOperations == null || appOperations.Credentials.ExpiresAt > DateTime.UtcNow)
{
IPartnerCredentials credentials = await GetPartnerCenterCredentialsAsync();
IPartnerCredentials credentials = await GetPartnerCenterCredentialsAsync().ConfigureAwait(false);
lock (appLock)
{
@ -1610,7 +1588,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
// Attempt to obtain the Partner Center token from the cache.
IPartnerCredentials credentials =
await service.Cache.FetchAsync<Models.PartnerCenterToken>(
CacheDatabaseType.Authentication, PartnerCenterCacheKey);
CacheDatabaseType.Authentication, PartnerCenterCacheKey).ConfigureAwait(false);
if (credentials != null && !credentials.IsExpired())
{
@ -1621,9 +1599,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
credentials = await PartnerCredentials.Instance.GenerateByApplicationCredentialsAsync(
service.Configuration.PartnerCenterApplicationId,
service.Configuration.PartnerCenterApplicationSecret.ToUnsecureString(),
service.Configuration.PartnerCenterApplicationTenantId);
service.Configuration.PartnerCenterApplicationTenantId).ConfigureAwait(false);
await service.Cache.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials);
await service.Cache.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials).ConfigureAwait(false);
return credentials;
}
@ -1644,11 +1622,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
ApplicationSecret = service.Configuration.ApplicationSecret,
UseCache = true
},
service.AccessToken.UserAssertionToken);
service.AccessToken.UserAssertionToken).ConfigureAwait(false);
IPartnerCredentials credentials = await PartnerCredentials.Instance.GenerateByUserCredentialsAsync(
service.Configuration.ApplicationId,
new AuthenticationToken(token.AccessToken, token.ExpiresOn));
new AuthenticationToken(token.AccessToken, token.ExpiresOn)).ConfigureAwait(false);
IAggregatePartner userOperations = PartnerService.Instance.CreatePartnerOperations(credentials);

Просмотреть файл

@ -27,7 +27,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
try
{
service = MvcApplication.UnityContainer.Resolve<IExplorerService>();
service = UnityConfig.Container.Resolve<IExplorerService>();
if (filterContext?.HttpContext != null && filterContext.Exception != null)
{

Просмотреть файл

@ -108,7 +108,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
resource,
new ClientCredential(
credential.ApplicationId,
secret));
secret)).ConfigureAwait(false);
return authResult;
}
@ -170,7 +170,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
new ClientCredential(
credential.ApplicationId,
secret),
new UserAssertion(token, AssertionType));
new UserAssertion(token, AssertionType)).ConfigureAwait(false);
return authResult;
}

Просмотреть файл

@ -26,9 +26,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
/// <param name="principal">A user claims principal created by Azure Active Directory.</param>
public CustomerPrincipal(ClaimsPrincipal principal) : base(principal)
{
this.CustomerId = principal.FindFirst("CustomerId")?.Value;
this.Email = principal.FindFirst(ClaimTypes.Email)?.Value;
this.Name = principal.FindFirst(ClaimTypes.Name)?.Value;
CustomerId = principal.FindFirst("CustomerId")?.Value;
Email = principal.FindFirst(ClaimTypes.Email)?.Value;
Name = principal.FindFirst(ClaimTypes.Name)?.Value;
}
/// <summary>

Просмотреть файл

@ -1,67 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="DataProtectorException.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
using System;
using System.Runtime.Serialization;
using System.Security.Permissions;
/// <summary>
/// The exception that is thrown when an error is encountered when protecting, or unprotecting, data.
/// </summary>
[Serializable]
public class DataProtectorException : Exception
{
/// <summary>
/// Initializes a new instance of the <see cref="DataProtectorException"/> class.
/// </summary>
public DataProtectorException()
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DataProtectorException"/> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
public DataProtectorException(string message) : base(message)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DataProtectorException" /> class.
/// </summary>
/// <param name="message">The message that describes the error.</param>
/// <param name="innerException">The exception that is the cause of the current exception, or a null reference (Nothing in Visual Basic) if no inner exception is specified.</param>
public DataProtectorException(string message, Exception innerException) : base(message, innerException)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="DataProtectorException"/> class.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination.</param>
protected DataProtectorException(SerializationInfo info, StreamingContext context) : base(info, context)
{
}
/// <summary>
/// When overridden in a derived class, sets the <see cref="T:System.Runtime.Serialization.SerializationInfo" /> with information about the exception.
/// </summary>
/// <param name="info">The <see cref="T:System.Runtime.Serialization.SerializationInfo" /> that holds the serialized object data about the exception being thrown.</param>
/// <param name="context">The <see cref="T:System.Runtime.Serialization.StreamingContext" /> that contains contextual information about the source or destination.</param>
/// <PermissionSet>
/// <IPermission class="System.Security.Permissions.FileIOPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Read="*AllFiles*" PathDiscovery="*AllFiles*" />
/// <IPermission class="System.Security.Permissions.SecurityPermission, mscorlib, Version=2.0.3600.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" version="1" Flags="SerializationFormatter" />
/// </PermissionSet>
[SecurityPermission(SecurityAction.Demand, SerializationFormatter = true)]
public override void GetObjectData(SerializationInfo info, StreamingContext context)
{
base.GetObjectData(info, context);
}
}
}

Просмотреть файл

@ -1,34 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="IDataProtector.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
/// <summary>
/// Represents a data protection strategy.
/// </summary>
public interface IDataProtector
{
/// <summary>
/// Protects the specified data by encrypting.
/// </summary>
/// <param name="data">The data to be encrypted.</param>
/// <returns>Base64 encoded string that represented the protected data.</returns>
/// <exception cref="System.ArgumentException">
/// <paramref name="data"/> is empty or null.
/// </exception>
string Protect(string data);
/// <summary>
/// Unprotects the specified data, which was protected by the <see cref="Protect(string)"/> method.
/// </summary>
/// <param name="data">The cipher text data to unprotect.</param>
/// <returns>The decrypted data in plaintext.</returns>
/// <exception cref="System.ArgumentException">
/// <paramref name="data"/> is empty or null.
/// </exception>
string Unprotect(string data);
}
}

Просмотреть файл

@ -1,92 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="MachineKeyDataProtector.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
using System;
using System.Text;
using System.Web.Security;
using Logic;
/// <summary>
/// Provides data protection using the machine encryption.
/// </summary>
internal sealed class MachineKeyDataProtector : IDataProtector
{
/// <summary>
/// The purposes of the data being protected.
/// </summary>
private readonly string[] purposes;
/// <summary>
/// Initializes a new instance of the <see cref="MachineKeyDataProtector"/> class.
/// </summary>
/// <param name="purposes">The purpose of the data being protected.</param>
public MachineKeyDataProtector(string[] purposes)
{
this.purposes = purposes;
}
/// <summary>
/// Protects the specified data by encrypting.
/// </summary>
/// <param name="data">The data to be encrypted.</param>
/// <returns>Base64 encoded string that represented the protected data.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="data"/> is empty or null.
/// </exception>
public string Protect(string data)
{
byte[] buffer;
data.AssertNotEmpty(nameof(data));
try
{
buffer = Encoding.ASCII.GetBytes(data);
return Convert.ToBase64String(MachineKey.Protect(buffer, this.purposes));
}
finally
{
buffer = null;
}
}
/// <summary>
/// Unprotects the specified data, which was protected by the <see cref="Protect(string)"/> method.
/// </summary>
/// <param name="data">The cipher text data to unprotect.</param>
/// <returns>The decrypted data in plaintext.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="data"/> is empty or null.
/// </exception>
public string Unprotect(string data)
{
byte[] buffer;
byte[] decrypt;
data.AssertNotEmpty(nameof(data));
try
{
buffer = Convert.FromBase64String(data);
decrypt = MachineKey.Unprotect(buffer, this.purposes);
if (decrypt == null)
{
throw new DataProtectorException("Unable to unprotect the specified data.");
}
return Encoding.ASCII.GetString(decrypt);
}
finally
{
buffer = null;
decrypt = null;
}
}
}
}

Просмотреть файл

@ -68,7 +68,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
try
{
bundle = await client.GetSecretAsync(service.Configuration.KeyVaultEndpoint, identifier);
bundle = await client.GetSecretAsync(service.Configuration.KeyVaultEndpoint, identifier).ConfigureAwait(false);
}
catch (KeyVaultErrorException ex)
{
@ -83,13 +83,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
}
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(executionTime).TotalMilliseconds }
};
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "Identifier", identifier }
@ -135,10 +133,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
using (IKeyVaultClient client = GetAzureKeyVaultClient())
{
await client.SetSecretAsync(
service.Configuration.KeyVaultEndpoint, identifier, value.ToUnsecureString());
service.Configuration.KeyVaultEndpoint, identifier, value.ToUnsecureString()).ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(executionTime).TotalMilliseconds }

Просмотреть файл

@ -3,7 +3,7 @@
<package id="Antlr" version="3.5.0.2" targetFramework="net461" />
<package id="bootstrap" version="3.3.7" targetFramework="net461" />
<package id="CommonServiceLocator" version="2.0.1" targetFramework="net461" />
<package id="CsvHelper" version="6.0.3" targetFramework="net461" />
<package id="CsvHelper" version="6.1.0" targetFramework="net461" />
<package id="FontAwesome" version="4.7.0" targetFramework="net461" />
<package id="jQuery" version="3.2.1" targetFramework="net461" />
<package id="jQuery.UI.Combined" version="1.12.1" targetFramework="net461" />
@ -68,10 +68,10 @@
<package id="System.Security.Cryptography.Primitives" version="4.3.0" targetFramework="net461" />
<package id="System.Security.Cryptography.X509Certificates" version="4.3.2" targetFramework="net461" />
<package id="System.Spatial" version="5.8.3" targetFramework="net461" />
<package id="Unity" version="5.3.2" targetFramework="net461" />
<package id="Unity.Abstractions" version="2.3.1" targetFramework="net461" />
<package id="Unity.Container" version="5.3.2" targetFramework="net461" />
<package id="Unity.Mvc" version="5.0.9" targetFramework="net461" />
<package id="Unity" version="5.4.0" targetFramework="net461" />
<package id="Unity.Abstractions" version="2.4.0" targetFramework="net461" />
<package id="Unity.Container" version="5.4.0" targetFramework="net461" />
<package id="Unity.Mvc" version="5.0.10" targetFramework="net461" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net461" />
<package id="WebGrease" version="1.6.0" targetFramework="net461" />
</packages>