Converted services pattern to provider and switched to Microsoft Graph

This commit is contained in:
Isaiah Williams 2018-02-27 14:07:11 +00:00
Родитель 392aca0105
Коммит 556560a3b7
68 изменённых файлов: 1815 добавлений и 1569 удалений

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

@ -7,7 +7,7 @@
namespace Microsoft.Store.PartnerCenter.Explorer
{
using System.Web.Mvc;
using Logic;
using Logic;
using Security;
/// <summary>

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

@ -8,16 +8,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer
{
using System;
using System.Collections.Generic;
using System.IdentityModel.Tokens;
using System.Threading.Tasks;
using Logic;
using Models;
using global::Owin;
using Logic;
using IdentityModel.Tokens;
using Models;
using Owin.Security;
using Owin.Security.Cookies;
using Owin.Security.OpenIdConnect;
using PartnerCenter.Exceptions;
using PartnerCenter.Models.Customers;
using Providers;
using Unity;
/// <summary>
@ -31,7 +32,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <param name="app">The application to be configured.</param>
public void ConfigureAuth(IAppBuilder app)
{
IExplorerService service = UnityConfig.Container.Resolve<IExplorerService>();
IExplorerProvider provider = UnityConfig.Container.Resolve<IExplorerProvider>();
app.SetDefaultSignInAsAuthenticationType(CookieAuthenticationDefaults.AuthenticationType);
@ -40,15 +41,15 @@ namespace Microsoft.Store.PartnerCenter.Explorer
app.UseOpenIdConnectAuthentication(
new OpenIdConnectAuthenticationOptions
{
ClientId = service.Configuration.ApplicationId,
Authority = $"{service.Configuration.ActiveDirectoryEndpoint}/common",
ClientId = provider.Configuration.ApplicationId,
Authority = $"{provider.Configuration.ActiveDirectoryEndpoint}/common",
Notifications = new OpenIdConnectAuthenticationNotifications
{
AuthenticationFailed = (context) =>
{
// Track the exceptions using the telemetry provider.
service.Telemetry.TrackException(context.Exception);
provider.Telemetry.TrackException(context.Exception);
// Pass in the context back to the app
context.OwinContext.Response.Redirect("/Home/Error");
@ -63,7 +64,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
string userTenantId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/tenantid").Value;
string signedInUserObjectId = context.AuthenticationTicket.Identity.FindFirst("http://schemas.microsoft.com/identity/claims/objectidentifier").Value;
IGraphClient client = new GraphClient(service, userTenantId);
IGraphClient client = new GraphClient(provider, userTenantId);
List<RoleModel> roles = await client.GetDirectoryRolesAsync(signedInUserObjectId).ConfigureAwait(false);
@ -73,7 +74,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
}
bool isPartnerUser = userTenantId.Equals(
service.Configuration.ApplicationTenantId, StringComparison.CurrentCultureIgnoreCase);
provider.Configuration.ApplicationTenantId, StringComparison.CurrentCultureIgnoreCase);
string customerId = string.Empty;
@ -81,7 +82,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
{
try
{
Customer c = await service.PartnerOperations.GetCustomerAsync(userTenantId).ConfigureAwait(false);
Customer c = await provider.PartnerOperations.GetCustomerAsync(userTenantId).ConfigureAwait(false);
customerId = c.Id;
}
catch (PartnerException ex)

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

@ -7,28 +7,27 @@
namespace Microsoft.Store.PartnerCenter.Explorer
{
using System;
using Logic;
using Providers;
using Unity;
using Unity.Lifetime;
/// <summary>
/// Specifies the Unity configuration for the main container.
/// </summary>
public static class UnityConfig
{
#region Unity Container
private static Lazy<IUnityContainer> container =
new Lazy<IUnityContainer>(() =>
{
UnityContainer container = new UnityContainer();
RegisterTypes(container);
return container;
});
new Lazy<IUnityContainer>(() =>
{
UnityContainer container = new UnityContainer();
RegisterTypes(container);
return container;
});
/// <summary>
/// Configured Unity Container.
/// </summary>
public static IUnityContainer Container => container.Value;
#endregion
/// <summary>
/// Registers the type mappings with the Unity container.
@ -42,7 +41,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// </remarks>
public static void RegisterTypes(IUnityContainer container)
{
container.RegisterType<IExplorerService, ExplorerService>();
container.RegisterType<IExplorerProvider, ExplorerProvider>(new ContainerControlledLifetimeManager());
}
}
}

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

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="UnityConfig.cs" company="Microsoft">
// <copyright file="UnityMvcActivator.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
@ -21,15 +21,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <summary>
/// Integrates Unity when the application starts.
/// </summary>
public static void Start()
public static void Start()
{
FilterProviders.Providers.Remove(FilterProviders.Providers.OfType<FilterAttributeFilterProvider>().First());
FilterProviders.Providers.Add(new UnityFilterAttributeFilterProvider(UnityConfig.Container));
DependencyResolver.SetResolver(new UnityDependencyResolver(UnityConfig.Container));
// TODO: Uncomment if you want to use PerRequestLifetimeManager
// Microsoft.Web.Infrastructure.DynamicModuleHelper.DynamicModuleUtility.RegisterModule(typeof(UnityPerRequestHttpModule));
}
/// <summary>

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

@ -23,8 +23,7 @@
<Add Type="Microsoft.ApplicationInsights.DependencyCollector.DependencyTrackingTelemetryModule, Microsoft.AI.DependencyCollector">
<ExcludeComponentCorrelationHttpHeadersOnDomains>
<!--
Requests to the following hostnames will not be modified by adding correlation headers.
This is only applicable if Profiler is installed via either StatusMonitor or Azure Extension.
Requests to the following hostnames will not be modified by adding correlation headers.
Add entries here to exclude additional hostnames.
NOTE: this configuration will be lost upon NuGet upgrade.
-->
@ -35,6 +34,10 @@
<Add>localhost</Add>
<Add>127.0.0.1</Add>
</ExcludeComponentCorrelationHttpHeadersOnDomains>
<IncludeDiagnosticSourceActivities>
<Add>Microsoft.Azure.EventHubs</Add>
<Add>Microsoft.Azure.ServiceBus</Add>
</IncludeDiagnosticSourceActivities>
</Add>
<Add Type="Microsoft.ApplicationInsights.Extensibility.PerfCounterCollector.PerformanceCollectorModule, Microsoft.AI.PerfCounterCollector">
<!--
@ -69,7 +72,6 @@
NOTE: handler configuration will be lost upon NuGet upgrade.
-->
<Add>System.Web.Handlers.TransferRequestHandler</Add>
<Add>Microsoft.VisualStudio.Web.PageInspector.Runtime.Tracing.RequestDataHttpHandler</Add>
<Add>System.Web.StaticFileHandler</Add>
<Add>System.Web.Handlers.AssemblyResourceLoader</Add>

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

@ -11,6 +11,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
using System.Security.Claims;
using IdentityModel.Clients.ActiveDirectory;
using Logic;
using Providers;
/// <summary>
/// Custom implementation of the <see cref="TokenCache"/> class.
@ -34,39 +35,39 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
private readonly string resource;
/// <summary>
/// Provides access to the core services.
/// Provides access to the core explorer providers.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Initializes a new instance of the <see cref="DistributedTokenCache"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to the core explorer providers.</param>
/// <param name="resource">The resource being accessed.</param>
/// <param name="key">The unique identifier for the cache entry.</param>
/// <exception cref="ArgumentException">
/// <paramref name="resource"/> is empty or null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public DistributedTokenCache(IExplorerService service, string resource, string key = null)
public DistributedTokenCache(IExplorerProvider provider, string resource, string key = null)
{
service.AssertNotNull(nameof(service));
provider.AssertNotNull(nameof(provider));
resource.AssertNotEmpty(nameof(resource));
this.service = service;
this.keyValue = key;
this.provider = provider;
keyValue = key;
this.resource = resource;
this.AfterAccess = this.AfterAccessNotification;
this.BeforeAccess = this.BeforeAccessNotification;
AfterAccess = AfterAccessNotification;
BeforeAccess = BeforeAccessNotification;
}
/// <summary>
/// Gets the unique identifier for the cache entry.
/// </summary>
private string Key => string.IsNullOrEmpty(this.keyValue) ? $"Resource::{this.resource}::Identifier::{ClaimsPrincipal.Current.Identities.First().FindFirst(ObjectIdClaimType).Value}" : this.keyValue;
private string Key => string.IsNullOrEmpty(keyValue) ? $"Resource::{resource}::Identifier::{ClaimsPrincipal.Current.Identities.First().FindFirst(ObjectIdClaimType).Value}" : keyValue;
/// <summary>
/// Notification method called after any library method accesses the cache.
@ -74,22 +75,22 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <param name="args">Contains parameters used by the ADAL call accessing the cache.</param>
public void AfterAccessNotification(TokenCacheNotificationArgs args)
{
if (!this.HasStateChanged)
if (!HasStateChanged)
{
return;
}
if (this.Count > 0)
if (Count > 0)
{
this.service.Cache.Store(
CacheDatabaseType.Authentication, this.Key, Convert.ToBase64String(this.Serialize()));
provider.Cache.Store(
CacheDatabaseType.Authentication, Key, Convert.ToBase64String(Serialize()));
}
else
{
this.service.Cache.Delete(CacheDatabaseType.Authentication, this.Key);
provider.Cache.Delete(CacheDatabaseType.Authentication, Key);
}
this.HasStateChanged = false;
HasStateChanged = false;
}
/// <summary>
@ -98,14 +99,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <param name="args">Contains parameters used by the ADAL call accessing the cache.</param>
public void BeforeAccessNotification(TokenCacheNotificationArgs args)
{
string value = this.service.Cache.Fetch<string>(CacheDatabaseType.Authentication, this.Key);
string value = provider.Cache.Fetch<string>(CacheDatabaseType.Authentication, Key);
if (string.IsNullOrEmpty(value))
{
return;
}
this.Deserialize(Convert.FromBase64String(value));
Deserialize(Convert.FromBase64String(value));
}
/// <summary>
@ -115,7 +116,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
public override void Clear()
{
base.Clear();
this.service.Cache.Clear(CacheDatabaseType.Authentication);
provider.Cache.Clear(CacheDatabaseType.Authentication);
}
/// <summary>
@ -125,7 +126,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
public override void DeleteItem(TokenCacheItem item)
{
base.DeleteItem(item);
this.service.Cache.Delete(CacheDatabaseType.Authentication, this.Key);
provider.Cache.Delete(CacheDatabaseType.Authentication, Key);
}
}
}

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

@ -50,12 +50,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <returns>Returns a redirect to the home page.</returns>
public ActionResult SignOutCallback()
{
if (this.Request.IsAuthenticated)
if (Request.IsAuthenticated)
{
return this.RedirectToAction("Index", "Home");
return RedirectToAction("Index", "Home");
}
return this.View();
return View();
}
}
}

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

@ -9,8 +9,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using System;
using System.Threading.Tasks;
using System.Web.Mvc;
using Logic;
using Models;
using Providers;
using Security;
/// <summary>
@ -24,7 +24,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="AuditController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public AuditController(IExplorerService service) : base(service)
public AuditController(IExplorerProvider provider) : base(provider)
{
}
@ -38,7 +38,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
AuditRecordsModel auditRecordsModel = new AuditRecordsModel()
{
Records = await Service.PartnerOperations.GetAuditRecordsAsync(startDate, endDate).ConfigureAwait(false)
Records = await Provider.PartnerOperations.GetAuditRecordsAsync(startDate, endDate).ConfigureAwait(false)
};
return PartialView("Records", auditRecordsModel);

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

@ -7,7 +7,7 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
using System.Web.Mvc;
using Logic;
using Providers;
/// <summary>
/// Base controller for controllers.
@ -17,22 +17,19 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <summary>
/// Provides access to the core application services.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Initializes a new instance of the <see cref="BaseController"/> class.
/// </summary>
/// <param name="service">Provides access to the core application services.</param>
protected BaseController(IExplorerService service)
protected BaseController(IExplorerProvider provider)
{
service.AssertNotNull(nameof(service));
this.service = service;
this.provider = provider;
}
/// <summary>
/// Provides access to the core application services.
/// </summary>
protected IExplorerService Service => this.service;
protected IExplorerProvider Provider => provider;
}
}

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

@ -16,6 +16,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using Models;
using PartnerCenter.Models;
using PartnerCenter.Models.Customers;
using Providers;
using Security;
/// <summary>
@ -28,7 +29,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="CustomersController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public CustomersController(IExplorerService service) : base(service)
public CustomersController(IExplorerProvider provider) : base(provider)
{
}
@ -45,9 +46,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
customerId.AssertNotEmpty(nameof(customerId));
if (Service.Configuration.IsIntegrationSandbox)
if (Provider.Configuration.IsIntegrationSandbox)
{
await Service.PartnerOperations.DeleteCustomerAsync(customerId).ConfigureAwait(false);
await Provider.PartnerOperations.DeleteCustomerAsync(customerId).ConfigureAwait(false);
}
return new HttpResponseMessage(HttpStatusCode.NoContent);
@ -106,7 +107,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
}
};
entity = await Service.PartnerOperations.CreateCustomerAsync(entity).ConfigureAwait(false);
entity = await Provider.PartnerOperations.CreateCustomerAsync(entity).ConfigureAwait(false);
createdCustomerModel = new CreatedCustomerModel()
{
@ -132,7 +133,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomersModel customersModel = new CustomersModel()
{
Customers = await GetCustomerModelsAsync().ConfigureAwait(false),
IsSandboxEnvironment = Service.Configuration.IsIntegrationSandbox
IsSandboxEnvironment = Provider.Configuration.IsIntegrationSandbox
};
return PartialView(customersModel);
@ -164,7 +165,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
customer = await Provider.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
customerModel = new CustomerModel()
{
@ -194,7 +195,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customers = await Service.PartnerOperations.GetCustomersAsync().ConfigureAwait(false);
customers = await Provider.PartnerOperations.GetCustomersAsync().ConfigureAwait(false);
return customers.Select(item => new CustomerModel
{

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

@ -10,7 +10,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using System.Threading.Tasks;
using System.Web.Mvc;
using Logic;
using Microsoft.Graph;
using Models;
using Providers;
using Security;
/// <summary>
@ -23,10 +25,34 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="DomainsController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public DomainsController(IExplorerService service) : base(service)
public DomainsController(IExplorerProvider provider) : base(provider)
{
}
/// <summary>
/// Obtains the service configuration records for the specified domain.
/// </summary>
/// <param name="domain">Name of the domain</param>
/// <returns>A collection of service configuration records for the specified domain in JSON.</returns>
public async Task<PartialViewResult> ConfigurationRecords(string customerId, string domain)
{
GraphClient client;
List<DomainDnsRecord> records;
try
{
client = new GraphClient(Provider, customerId);
records = await client.GetDomainConfigurationRecordsAsync(domain).ConfigureAwait(false);
return PartialView(new ConfigurationRecordsModel { ServiceConfigurationRecords = records });
}
finally
{
client = null;
records = null;
}
}
/// <summary>
/// Determines whether the specified domain is available or not.
/// </summary>
@ -43,7 +69,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
return Json(false, JsonRequestBehavior.AllowGet);
}
bool exists = await Service.PartnerOperations.CheckDomainAsync($"{primaryDomain}.onmicrosoft.com").ConfigureAwait(false);
bool exists = await Provider.PartnerOperations.CheckDomainAsync($"{primaryDomain}.onmicrosoft.com").ConfigureAwait(false);
return Json(!exists, JsonRequestBehavior.AllowGet);
}
@ -65,7 +91,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
client = new GraphClient(Service, customerId);
client = new GraphClient(Provider, customerId);
domains = await client.GetDomainsAsync().ConfigureAwait(false);
return Json(domains, JsonRequestBehavior.AllowGet);

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

@ -6,18 +6,17 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using System.Web.Mvc;
using Logic;
using Logic.Azure;
using Logic.Office;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Models;
using PartnerCenter.Models.Customers;
using PartnerCenter.Models.Invoices;
using PartnerCenter.Models.Subscriptions;
using Providers;
using Security;
/// <summary>
@ -30,7 +29,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="HealthController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public HealthController(IExplorerService service) : base(service)
public HealthController(IExplorerProvider provider) : base(provider)
{
}
@ -56,8 +55,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
customer = await Provider.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Provider.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
healthModel = new SubscriptionHealthModel
{
@ -106,21 +105,25 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await Service.AccessToken.GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}",
Service.Configuration.AzureResourceManagerEndpoint,
token = await Provider.AccessToken.GetAccessTokenAsync(
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}",
Provider.Configuration.AzureResourceManagerEndpoint,
new ApplicationCredential
{
ApplicationId = Service.Configuration.ApplicationId,
ApplicationSecret = Service.Configuration.ApplicationSecret,
ApplicationId = Provider.Configuration.ApplicationId,
ApplicationSecret = Provider.Configuration.ApplicationSecret,
UseCache = true
},
Service.AccessToken.UserAssertionToken).ConfigureAwait(false);
Provider.AccessToken.UserAssertionToken).ConfigureAwait(false);
using (Insights insights = new Insights(subscriptionId, token.AccessToken))
{
return await insights.GetHealthEventsAsync().ConfigureAwait(false);
}
// TODO -- Create a custom HttpService to query Azure health events.
//using (Insights insights = new Insights(subscriptionId, token.AccessToken))
//{
// return await insights.GetHealthEventsAsync().ConfigureAwait(false);
//}
return null;
}
finally
{
@ -142,17 +145,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await Service.AccessToken.GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}",
Service.Configuration.OfficeManagementEndpoint,
token = await Provider.AccessToken.GetAccessTokenAsync(
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}",
Provider.Configuration.OfficeManagementEndpoint,
new ApplicationCredential
{
ApplicationId = Service.Configuration.ApplicationId,
ApplicationSecret = Service.Configuration.ApplicationSecret,
ApplicationId = Provider.Configuration.ApplicationId,
ApplicationSecret = Provider.Configuration.ApplicationSecret,
UseCache = true
}).ConfigureAwait(false);
comm = new ServiceCommunications(Service, token);
comm = new ServiceCommunications(Provider, token);
return await comm.GetCurrentStatusAsync(customerId).ConfigureAwait(false);
}
finally

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

@ -7,7 +7,7 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
using System.Web.Mvc;
using Logic;
using Providers;
using Security;
/// <summary>
@ -19,8 +19,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// <summary>
/// Initializes a new instance of the <see cref="HomeController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public HomeController(IExplorerService service) : base(service)
public HomeController(IExplorerProvider provider) : base(provider)
{
}

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

@ -16,8 +16,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using CsvHelper;
using Logic;
using Models;
using PartnerCenter.Models;
using PartnerCenter.Models.Invoices;
using Providers;
using Security;
/// <summary>
@ -30,7 +30,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="InvoicesController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public InvoicesController(IExplorerService service) : base(service)
public InvoicesController(IExplorerProvider provider) : base(provider)
{
}
@ -66,7 +66,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
InvoicesModel invoicesModel = new InvoicesModel()
{
Invoices = await Service.PartnerOperations.GetInvoicesAsync().ConfigureAwait(false)
Invoices = await Provider.PartnerOperations.GetInvoicesAsync().ConfigureAwait(false)
};
return View(invoicesModel);
@ -231,12 +231,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
return lineItems;
}
invoice = await Service.PartnerOperations.GetInvoiceAsync(invoiceId).ConfigureAwait(false);
invoice = await Provider.PartnerOperations.GetInvoiceAsync(invoiceId).ConfigureAwait(false);
lineItems = new List<InvoiceLineItem>();
foreach (InvoiceDetail detail in invoice.InvoiceDetails)
{
data = await Service.PartnerOperations.GetInvoiceLineItemsAsync(
data = await Provider.PartnerOperations.GetInvoiceLineItemsAsync(
invoiceId,
detail.BillingProvider,
detail.InvoiceLineItemType).ConfigureAwait(false);

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

@ -18,6 +18,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using Models;
using PartnerCenter.Models.Customers;
using PartnerCenter.Models.Invoices;
using Providers;
using Security;
using Subscriptions;
@ -31,7 +32,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="ManageController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public ManageController(IExplorerService service) : base(service)
public ManageController(IExplorerProvider provider) : base(provider)
{
}
@ -91,8 +92,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
customer = await Provider.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Provider.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
manageModel = new SubscriptionManageModel
{
@ -164,15 +165,15 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{model.CustomerId}").ConfigureAwait(false);
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{model.CustomerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
{
await manager.ApplyTemplateAsync(
model.SubscriptionId,
model.ResourceGroupName,
model.TemplateUri,
model.ParametersUri);
model.ParametersUri).ConfigureAwait(false);
results = await GetDeploymentsAsync(
model.CustomerId,
@ -212,11 +213,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
{
groups = await manager.GetResourceGroupsAsync(subscriptionId);
groups = await manager.GetResourceGroupsAsync(subscriptionId).ConfigureAwait(false);
return Json(groups, JsonRequestBehavior.AllowGet);
}
}
@ -246,11 +247,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
token = await GetAccessTokenAsync(
$"{Service.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
using (ResourceManager manager = new ResourceManager(Service, token.AccessToken))
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
{
deployments = await manager.GetDeploymentsAsync(subscriptionId, resourceGroupName);
deployments = await manager.GetDeploymentsAsync(subscriptionId, resourceGroupName).ConfigureAwait(false);
return deployments.Select(d => new DeploymentModel()
{
@ -270,16 +271,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
private async Task<AuthenticationResult> GetAccessTokenAsync(string authority)
{
return await Service.AccessToken.GetAccessTokenAsync(
return await Provider.AccessToken.GetAccessTokenAsync(
authority,
Service.Configuration.AzureResourceManagerEndpoint,
Provider.Configuration.AzureResourceManagerEndpoint,
new ApplicationCredential
{
ApplicationId = Service.Configuration.ApplicationId,
ApplicationSecret = Service.Configuration.ApplicationSecret,
ApplicationId = Provider.Configuration.ApplicationId,
ApplicationSecret = Provider.Configuration.ApplicationSecret,
UseCache = true
},
Service.AccessToken.UserAssertionToken).ConfigureAwait(false);
Provider.AccessToken.UserAssertionToken).ConfigureAwait(false);
}
}
}

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

@ -14,6 +14,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using Logic;
using Models;
using PartnerCenter.Models.Offers;
using Providers;
/// <summary>
/// Processes offer related operations.
@ -25,7 +26,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="OfferController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public OfferController(IExplorerService service) : base(service)
public OfferController(IExplorerProvider provider) : base(provider)
{
}
@ -43,7 +44,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
offers = await Service.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
offers = await Provider.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
offersModel = new OffersModel
{
@ -90,7 +91,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
offers = await Service.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
offers = await Provider.PartnerOperations.GetOffersAsync().ConfigureAwait(false);
return Json(
offers.Single(x => x.Id.Equals(offerId, StringComparison.CurrentCultureIgnoreCase)),

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

@ -10,10 +10,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using System.Linq;
using System.Threading.Tasks;
using System.Web.Mvc;
using Logic;
using Models;
using PartnerCenter.Models;
using PartnerCenter.Models.ServiceRequests;
using Providers;
using Security;
/// <summary>
@ -26,7 +26,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="ServiceRequestsController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public ServiceRequestsController(IExplorerService service) : base(service)
public ServiceRequestsController(IExplorerProvider provider) : base(provider)
{
}
@ -65,7 +65,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
requests = await Service.PartnerOperations.GetServiceRequestsAsync().ConfigureAwait(false);
requests = await Provider.PartnerOperations.GetServiceRequestsAsync().ConfigureAwait(false);
return requests.Items.Select(r => new ServiceRequestModel()
{

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

@ -18,6 +18,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using PartnerCenter.Models.Invoices;
using PartnerCenter.Models.Orders;
using PartnerCenter.Models.Subscriptions;
using Providers;
using Security;
/// <summary>
@ -30,7 +31,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="SubscriptionsController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public SubscriptionsController(IExplorerService service) : base(service)
public SubscriptionsController(IExplorerProvider provider) : base(provider)
{
}
@ -74,7 +75,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
ReferenceCustomerId = model.CustomerId
};
newOrder = await Service.PartnerOperations.CreateOrderAsync(model.CustomerId, newOrder).ConfigureAwait(false);
newOrder = await Provider.PartnerOperations.CreateOrderAsync(model.CustomerId, newOrder).ConfigureAwait(false);
subscriptionsModel = await GetSubscriptionsAsync(model.CustomerId).ConfigureAwait(false);
return PartialView("List", subscriptionsModel);
@ -97,13 +98,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
subscription = await Service.PartnerOperations.GetSubscriptionAsync(model.CustomerId, model.Id).ConfigureAwait(false);
subscription = await Provider.PartnerOperations.GetSubscriptionAsync(model.CustomerId, model.Id).ConfigureAwait(false);
subscription.FriendlyName = model.FriendlyName;
subscription.Status = model.Status;
subscription.Quantity = model.Quantity;
await Service.PartnerOperations.UpdateSubscriptionAsync(model.CustomerId, subscription).ConfigureAwait(false);
await Provider.PartnerOperations.UpdateSubscriptionAsync(model.CustomerId, subscription).ConfigureAwait(false);
return new HttpResponseMessage(HttpStatusCode.OK);
}
@ -160,8 +161,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
customer = await Provider.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Provider.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
model = new SubscriptionModel()
{
@ -211,7 +212,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
subscriptions = await Service.PartnerOperations.GetSubscriptionsAsync(customerId).ConfigureAwait(false);
subscriptions = await Provider.PartnerOperations.GetSubscriptionsAsync(customerId).ConfigureAwait(false);
subscriptionsModel = new SubscriptionsModel()
{
Subscriptions = new List<SubscriptionModel>()

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

@ -13,6 +13,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using Models;
using PartnerCenter.Models.Customers;
using PartnerCenter.Models.Subscriptions;
using Providers;
using Security;
/// <summary>
@ -25,7 +26,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="UsageController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public UsageController(IExplorerService service) : base(service)
public UsageController(IExplorerProvider provider) : base(provider)
{
}
@ -50,8 +51,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customer = await Service.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Service.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
customer = await Provider.PartnerOperations.GetCustomerAsync(customerId).ConfigureAwait(false);
subscription = await Provider.PartnerOperations.GetSubscriptionAsync(customerId, subscriptionId).ConfigureAwait(false);
UsageModel usageModel = new UsageModel()
{
@ -59,7 +60,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
CustomerId = customerId,
SubscriptionId = subscriptionId,
SubscriptionFriendlyName = subscription.FriendlyName,
Usage = await Service.PartnerOperations
Usage = await Provider.PartnerOperations
.GetSubscriptionUsageAsync(customerId, subscriptionId, DateTime.Now.AddMonths(-1), DateTime.Now).ConfigureAwait(false)
};

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

@ -18,6 +18,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
using PartnerCenter.Models;
using PartnerCenter.Models.Licenses;
using PartnerCenter.Models.Users;
using Providers;
using Security;
/// <summary>
@ -30,7 +31,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
/// Initializes a new instance of the <see cref="UsersController"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
public UsersController(IExplorerService service) : base(service)
public UsersController(IExplorerProvider provider) : base(provider)
{
}
@ -82,9 +83,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
UserPrincipalName = newUserModel.UserPrincipalName
};
client = new GraphClient(Service, newUserModel.CustomerId);
client = new GraphClient(Provider, newUserModel.CustomerId);
await Service.PartnerOperations.CreateUserAsync(newUserModel.CustomerId, user).ConfigureAwait(false);
await Provider.PartnerOperations.CreateUserAsync(newUserModel.CustomerId, user).ConfigureAwait(false);
UsersModel usersModel = new UsersModel()
{
@ -118,7 +119,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
customerId.AssertNotEmpty(nameof(customerId));
userId.AssertNotEmpty(nameof(userId));
await Service.PartnerOperations.DeleteUserAsync(customerId, userId).ConfigureAwait(false);
await Provider.PartnerOperations.DeleteUserAsync(customerId, userId).ConfigureAwait(false);
return new HttpResponseMessage(HttpStatusCode.OK);
}
@ -145,7 +146,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
customerUser = await Service.PartnerOperations.GetUserAsync(customerId, userId).ConfigureAwait(false);
customerUser = await Provider.PartnerOperations.GetUserAsync(customerId, userId).ConfigureAwait(false);
editUserModel = new EditUserModel()
{
@ -180,8 +181,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
client = new GraphClient(Service, editUserModel.CustomerId);
customerUser = await Service.PartnerOperations.GetUserAsync(
client = new GraphClient(Provider, editUserModel.CustomerId);
customerUser = await Provider.PartnerOperations.GetUserAsync(
editUserModel.CustomerId,
editUserModel.UserId).ConfigureAwait(false);
@ -191,7 +192,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
customerUser.UserPrincipalName = editUserModel.UserPrincipalName;
customerUser.UsageLocation = editUserModel.UsageLocation;
await Service.PartnerOperations.UpdateUserAsync(
await Provider.PartnerOperations.UpdateUserAsync(
editUserModel.CustomerId,
editUserModel.UserId,
customerUser).ConfigureAwait(false);
@ -229,7 +230,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
try
{
client = new GraphClient(Service, customerId);
client = new GraphClient(Provider, customerId);
UsersModel usersModel = new UsersModel()
{
@ -265,8 +266,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
{
values = new List<LicenseModel>();
licenses = await Service.PartnerOperations.GetUserLicensesAsync(customerId, userId).ConfigureAwait(false);
subscribedSkus = await Service.PartnerOperations.GetCustomerSubscribedSkusAsync(customerId).ConfigureAwait(false);
licenses = await Provider.PartnerOperations.GetUserLicensesAsync(customerId, userId).ConfigureAwait(false);
subscribedSkus = await Provider.PartnerOperations.GetCustomerSubscribedSkusAsync(customerId).ConfigureAwait(false);
foreach (SubscribedSku sku in subscribedSkus.Items)
{
@ -346,7 +347,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
if (assignments.Count > 0 || removals.Count > 0)
{
await Service.PartnerOperations.UpdateUserLicensesAsync(
await Provider.PartnerOperations.UpdateUserLicensesAsync(
model.CustomerId,
model.UserId,
licenseUpdate).ConfigureAwait(false);

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

@ -55,45 +55,36 @@
<Reference Include="Antlr3.Runtime, Version=3.5.0.2, Culture=neutral, PublicKeyToken=eb42632606e9261f, processorArchitecture=MSIL">
<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.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.1.0\lib\net45\CsvHelper.dll</HintPath>
<Reference Include="CsvHelper, Version=7.0.0.0, Culture=neutral, PublicKeyToken=8c4959082be5c823, processorArchitecture=MSIL">
<HintPath>..\..\packages\CsvHelper.7.0.1\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>
</Reference>
<Reference Include="Microsoft.AI.DependencyCollector, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.4.1\lib\net45\Microsoft.AI.DependencyCollector.dll</HintPath>
<Reference Include="Microsoft.AI.DependencyCollector, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.DependencyCollector.2.5.1\lib\net45\Microsoft.AI.DependencyCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.4.1\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
<Reference Include="Microsoft.AI.PerfCounterCollector, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.PerfCounterCollector.2.5.1\lib\net45\Microsoft.AI.PerfCounterCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.ServerTelemetryChannel, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.4.0\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll</HintPath>
<Reference Include="Microsoft.AI.ServerTelemetryChannel, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel.2.5.1\lib\net45\Microsoft.AI.ServerTelemetryChannel.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.Web, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Web.2.4.1\lib\net45\Microsoft.AI.Web.dll</HintPath>
<Reference Include="Microsoft.AI.Web, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.Web.2.5.1\lib\net45\Microsoft.AI.Web.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AI.WindowsServer, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.2.4.1\lib\net45\Microsoft.AI.WindowsServer.dll</HintPath>
<Reference Include="Microsoft.AI.WindowsServer, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.WindowsServer.2.5.1\lib\net45\Microsoft.AI.WindowsServer.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ApplicationInsights, Version=2.4.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.2.4.0\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
<Reference Include="Microsoft.ApplicationInsights, Version=2.5.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.2.5.1\lib\net46\Microsoft.ApplicationInsights.dll</HintPath>
</Reference>
<Reference Include="Microsoft.ApplicationInsights.SnapshotCollector, Version=1.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.0\lib\net45\Microsoft.ApplicationInsights.SnapshotCollector.dll</HintPath>
<Reference Include="Microsoft.ApplicationInsights.SnapshotCollector, Version=1.1.2.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.2\lib\net45\Microsoft.ApplicationInsights.SnapshotCollector.dll</HintPath>
</Reference>
<Reference Include="Microsoft.AspNet.TelemetryCorrelation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.TelemetryCorrelation.1.0.0\lib\net45\Microsoft.AspNet.TelemetryCorrelation.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.ActiveDirectory.GraphClient, Version=2.1.10.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.ActiveDirectory.GraphClient.2.1.1\lib\portable-net4+sl5+win+wpa+wp8\Microsoft.Azure.ActiveDirectory.GraphClient.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Insights, Version=0.15.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Insights.0.15.0-preview\lib\net45\Microsoft.Azure.Insights.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.2.3.2\lib\net452\Microsoft.Azure.KeyVault.dll</HintPath>
</Reference>
@ -119,29 +110,47 @@
<Reference Include="Microsoft.Data.Services.Client, Version=5.8.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.8.3\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.17.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
<Reference Include="Microsoft.Graph, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Graph.1.7.0\lib\net45\Microsoft.Graph.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.17.2.31801, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.17.2\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
<Reference Include="Microsoft.Graph.Core, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Graph.Core.1.7.0\lib\net45\Microsoft.Graph.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory, Version=3.19.1.3001, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform, Version=3.19.1.3001, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Clients.ActiveDirectory.3.19.1\lib\net45\Microsoft.IdentityModel.Clients.ActiveDirectory.Platform.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Logging, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Logging.5.2.1\lib\net451\Microsoft.IdentityModel.Logging.dll</HintPath>
</Reference>
<Reference Include="Microsoft.IdentityModel.Protocol.Extensions, Version=1.0.40306.1554, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Protocol.Extensions.1.0.4.403061554\lib\net45\Microsoft.IdentityModel.Protocol.Extensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.3.1.0\lib\net45\Microsoft.Owin.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Protocols, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Protocols.5.2.1\lib\net451\Microsoft.IdentityModel.Protocols.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Host.SystemWeb.3.1.0\lib\net45\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Protocols.OpenIdConnect, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Protocols.OpenIdConnect.5.2.1\lib\net451\Microsoft.IdentityModel.Protocols.OpenIdConnect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.3.1.0\lib\net45\Microsoft.Owin.Security.dll</HintPath>
<Reference Include="Microsoft.IdentityModel.Tokens, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.IdentityModel.Tokens.5.2.1\lib\net451\Microsoft.IdentityModel.Tokens.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.Cookies.3.1.0\lib\net45\Microsoft.Owin.Security.Cookies.dll</HintPath>
<Reference Include="Microsoft.Owin, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.4.0.0\lib\net451\Microsoft.Owin.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OpenIdConnect, Version=3.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.OpenIdConnect.3.1.0\lib\net45\Microsoft.Owin.Security.OpenIdConnect.dll</HintPath>
<Reference Include="Microsoft.Owin.Host.SystemWeb, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Host.SystemWeb.4.0.0\lib\net451\Microsoft.Owin.Host.SystemWeb.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.4.0.0\lib\net451\Microsoft.Owin.Security.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.Cookies, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.Cookies.4.0.0\lib\net451\Microsoft.Owin.Security.Cookies.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Owin.Security.OpenIdConnect, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Owin.Security.OpenIdConnect.4.0.0\lib\net451\Microsoft.Owin.Security.OpenIdConnect.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Rest.ClientRuntime, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.2.3.10\lib\net452\Microsoft.Rest.ClientRuntime.dll</HintPath>
@ -149,14 +158,14 @@
<Reference Include="Microsoft.Rest.ClientRuntime.Azure, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Rest.ClientRuntime.Azure.3.3.10\lib\net452\Microsoft.Rest.ClientRuntime.Azure.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Store.PartnerCenter, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.6.0\lib\Net45\Microsoft.Store.PartnerCenter.dll</HintPath>
<Reference Include="Microsoft.Store.PartnerCenter, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.7.0\lib\Net45\Microsoft.Store.PartnerCenter.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Store.PartnerCenter.Extensions, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.6.0\lib\Net45\Microsoft.Store.PartnerCenter.Extensions.dll</HintPath>
<Reference Include="Microsoft.Store.PartnerCenter.Extensions, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.7.0\lib\Net45\Microsoft.Store.PartnerCenter.Extensions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Store.PartnerCenter.Models, Version=1.6.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.6.0\lib\Net45\Microsoft.Store.PartnerCenter.Models.dll</HintPath>
<Reference Include="Microsoft.Store.PartnerCenter.Models, Version=1.7.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Store.PartnerCenter.1.7.0\lib\Net45\Microsoft.Store.PartnerCenter.Models.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Threading.Tasks, Version=1.0.12.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Bcl.Async.1.0.168\lib\net40\Microsoft.Threading.Tasks.dll</HintPath>
@ -170,9 +179,8 @@
<Reference Include="Microsoft.Web.Infrastructure, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Web.Infrastructure.1.0.0.0\lib\net40\Microsoft.Web.Infrastructure.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=6.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.6.0.8\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.10.0.3\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="Owin, Version=1.0.0.0, Culture=neutral, PublicKeyToken=f0ebd12fd5e55cc5, processorArchitecture=MSIL">
<HintPath>..\..\packages\Owin.1.0\lib\net40\Owin.dll</HintPath>
@ -187,8 +195,8 @@
</Reference>
<Reference Include="System.Drawing" />
<Reference Include="System.IdentityModel" />
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=4.0.40306.1554, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IdentityModel.Tokens.Jwt.4.0.4.403061554\lib\net45\System.IdentityModel.Tokens.Jwt.dll</HintPath>
<Reference Include="System.IdentityModel.Tokens.Jwt, Version=5.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IdentityModel.Tokens.Jwt.5.2.1\lib\net451\System.IdentityModel.Tokens.Jwt.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression, Version=4.1.2.0, Culture=neutral, PublicKeyToken=b77a5c561934e089, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.IO.Compression.4.3.0\lib\net46\System.IO.Compression.dll</HintPath>
@ -232,55 +240,56 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Web" />
<Reference Include="System.Web.Abstractions" />
<Reference Include="System.Web.Extensions" />
<Reference Include="System.Web.Helpers, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.Helpers.dll</HintPath>
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.Helpers.dll</HintPath>
</Reference>
<Reference Include="System.Web.Mvc, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.2.3\lib\net45\System.Web.Mvc.dll</HintPath>
<Reference Include="System.Web.Mvc, Version=5.2.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.Mvc.5.2.4\lib\net45\System.Web.Mvc.dll</HintPath>
</Reference>
<Reference Include="System.Web.Optimization, Version=1.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.Web.Optimization.1.1.3\lib\net40\System.Web.Optimization.dll</HintPath>
</Reference>
<Reference Include="System.Web.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.Razor.3.2.3\lib\net45\System.Web.Razor.dll</HintPath>
<HintPath>..\..\packages\Microsoft.AspNet.Razor.3.2.4\lib\net45\System.Web.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Web.Routing" />
<Reference Include="System.Web.WebPages, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.dll</HintPath>
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Deployment, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.Deployment.dll</HintPath>
</Reference>
<Reference Include="System.Web.WebPages.Razor, Version=3.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.3\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
<HintPath>..\..\packages\Microsoft.AspNet.WebPages.3.2.4\lib\net45\System.Web.WebPages.Razor.dll</HintPath>
</Reference>
<Reference Include="System.Xml" />
<Reference Include="System.Configuration" />
<Reference Include="System.Web.Services" />
<Reference Include="System.EnterpriseServices" />
<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 Include="Unity.Abstractions, Version=3.2.0.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Abstractions.3.2.0\lib\net45\Unity.Abstractions.dll</HintPath>
</Reference>
<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 Include="Unity.Configuration, Version=5.1.3.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.6.1\lib\net45\Unity.Configuration.dll</HintPath>
</Reference>
<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 Include="Unity.Container, Version=5.6.1.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Container.5.6.1\lib\net45\Unity.Container.dll</HintPath>
</Reference>
<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 Include="Unity.Interception, Version=5.4.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.6.1\lib\net45\Unity.Interception.dll</HintPath>
</Reference>
<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 Include="Unity.Interception.Configuration, Version=5.1.3.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.6.1\lib\net45\Unity.Interception.Configuration.dll</HintPath>
</Reference>
<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 Include="Unity.Mvc, Version=5.0.12.0, Culture=neutral, PublicKeyToken=6d32ff45e0ccc69f, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.Mvc.5.0.12\lib\net45\Unity.Mvc.dll</HintPath>
</Reference>
<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 Include="Unity.RegistrationByConvention, Version=2.1.4.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.6.1\lib\net45\Unity.RegistrationByConvention.dll</HintPath>
</Reference>
<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 Include="Unity.ServiceLocation, Version=2.1.0.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\..\packages\Unity.5.6.1\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>
@ -290,6 +299,8 @@
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="App_Start\UnityConfig.cs" />
<Compile Include="App_Start\UnityMvcActivator.cs" />
<Compile Include="Controllers\OfferController.cs" />
<Compile Include="Logic\IPartnerOperations.cs" />
<Compile Include="Logic\PartnerOperations.cs" />
@ -298,18 +309,22 @@
<Compile Include="App_Start\FilterConfig.cs" />
<Compile Include="App_Start\RouteConfig.cs" />
<Compile Include="App_Start\Startup.Auth.cs" />
<Compile Include="App_Start\UnityConfig.cs" />
<Compile Include="App_Start\UnityMvcActivator.cs" />
<Compile Include="Models\ApplicationCredential.cs" />
<Compile Include="Security\AccessTokenProvider.cs" />
<Compile Include="Providers\AccessTokenProvider.cs" />
<Compile Include="Providers\ConfigurationProvider.cs" />
<Compile Include="Providers\ExplorerProvider.cs" />
<Compile Include="Providers\IAccessTokenProvider.cs" />
<Compile Include="Providers\ICacheProvider.cs" />
<Compile Include="Providers\IConfigurationProvider.cs" />
<Compile Include="Providers\IExplorerProvider.cs" />
<Compile Include="Providers\IVaultProvider.cs" />
<Compile Include="Providers\KeyVaultProvider.cs" />
<Compile Include="Providers\RedisCacheProvider.cs" />
<Compile Include="Security\AuthenticationProvider.cs" />
<Compile Include="Security\AuthorizationFilterAttribute.cs" />
<Compile Include="Cache\CacheDatabaseType.cs" />
<Compile Include="Cache\CacheException.cs" />
<Compile Include="Cache\CacheService.cs" />
<Compile Include="Cache\DistributedTokenCache.cs" />
<Compile Include="Cache\ICacheService.cs" />
<Compile Include="Configuration\Configuration.cs" />
<Compile Include="Configuration\IConfiguration.cs" />
<Compile Include="Controllers\AccountController.cs" />
<Compile Include="Controllers\AuditController.cs" />
<Compile Include="Controllers\BaseController.cs" />
@ -328,15 +343,12 @@
</Compile>
<Compile Include="Logic\Azure\AzureHealthEvent.cs" />
<Compile Include="Logic\Azure\IncidentEvent.cs" />
<Compile Include="Logic\Azure\Insights.cs" />
<Compile Include="Logic\Azure\ResourceManager.cs" />
<Compile Include="Logic\Communication.cs" />
<Compile Include="Logic\HttpService.cs" />
<Compile Include="Logic\CommunicationException.cs" />
<Compile Include="Logic\ExplorerService.cs" />
<Compile Include="Logic\Extensions.cs" />
<Compile Include="Logic\HealthEventType.cs" />
<Compile Include="Logic\ICommunication.cs" />
<Compile Include="Logic\IExplorerService.cs" />
<Compile Include="Logic\IHttpService.cs" />
<Compile Include="Logic\IGraphClient.cs" />
<Compile Include="Logic\IHealthEvent.cs" />
<Compile Include="Logic\Office\OfficeHealthEvent.cs" />
@ -363,7 +375,6 @@
<Compile Include="Models\OffersModel.cs" />
<Compile Include="Models\PartnerCenterToken.cs" />
<Compile Include="Models\RoleModel.cs" />
<Compile Include="Models\ServiceConfigurationRecordModel.cs" />
<Compile Include="Models\ServiceRequestModel.cs" />
<Compile Include="Models\ServiceRequestsModel.cs" />
<Compile Include="Models\SubscriptionHealthModel.cs" />
@ -377,10 +388,7 @@
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Security\AuthenticationFilter.cs" />
<Compile Include="Security\CustomerPrincipal.cs" />
<Compile Include="Security\IAccessTokenProvider.cs" />
<Compile Include="Security\IVaultService.cs" />
<Compile Include="Security\UserRole.cs" />
<Compile Include="Security\VaultService.cs" />
<Compile Include="Startup.cs" />
<Compile Include="Subscriptions\AzureSubscriptionDetails.cs" />
<Compile Include="Subscriptions\ISubscriptionDetails.cs" />
@ -459,6 +467,7 @@
<Content Include="Content\bootstrap-theme.min.css.map" />
<Content Include="Content\bootstrap-theme.css.map" />
<None Include="packages.config" />
<None Include="Properties\PublishProfiles\partnercenterexplorer - Web Deploy.pubxml" />
<None Include="Scripts\jquery-2.2.3.intellisense.js" />
<Content Include="Scripts\ai.0.22.9-build00167.js" />
<Content Include="Scripts\ai.0.22.9-build00167.min.js" />
@ -467,16 +476,16 @@
<Content Include="Scripts\bootstrap.min.js" />
<Content Include="Scripts\jquery-2.2.3.js" />
<Content Include="Scripts\jquery-2.2.3.min.js" />
<None Include="Scripts\jquery-3.2.1.intellisense.js" />
<Content Include="Scripts\jquery-3.2.1.js" />
<Content Include="Scripts\jquery-3.2.1.min.js" />
<Content Include="Scripts\jquery-3.2.1.slim.js" />
<Content Include="Scripts\jquery-3.2.1.slim.min.js" />
<None Include="Scripts\jquery-3.3.1.intellisense.js" />
<Content Include="Scripts\jquery-3.3.1.js" />
<Content Include="Scripts\jquery-3.3.1.min.js" />
<Content Include="Scripts\jquery-3.3.1.slim.js" />
<Content Include="Scripts\jquery-3.3.1.slim.min.js" />
<Content Include="Scripts\jquery-ui-1.12.1.js" />
<Content Include="Scripts\jquery-ui-1.12.1.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery.unobtrusive-ajax.js" />
<Content Include="Scripts\jquery.unobtrusive-ajax.min.js" />
<None Include="Scripts\jquery.validate-vsdoc.js" />
<Content Include="Scripts\jquery.validate.js" />
<Content Include="Scripts\jquery.validate.min.js" />
<Content Include="Scripts\jquery.validate.unobtrusive.js" />
@ -543,8 +552,8 @@
<Content Include="Views\ServiceRequests\List.cshtml" />
<Content Include="Views\Shared\EditorTemplates\ServiceRequestModel.cshtml" />
<Content Include="Views\Home\Error.cshtml" />
<Content Include="Scripts\jquery-3.2.1.slim.min.map" />
<Content Include="Scripts\jquery-3.2.1.min.map" />
<Content Include="Scripts\jquery-3.3.1.slim.min.map" />
<Content Include="Scripts\jquery-3.3.1.min.map" />
</ItemGroup>
<ItemGroup>
<Folder Include="App_Data\" />
@ -587,10 +596,10 @@
<Error Condition="!Exists('..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.Net.Compilers.2.6.1\build\Microsoft.Net.Compilers.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.Net.Compilers.2.6.1\build\Microsoft.Net.Compilers.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.1.0.8\build\net45\Microsoft.CodeDom.Providers.DotNetCompilerPlatform.props'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.0\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.0\build\Microsoft.ApplicationInsights.SnapshotCollector.targets'))" />
<Error Condition="!Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.2\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.2\build\Microsoft.ApplicationInsights.SnapshotCollector.targets'))" />
</Target>
<Import Project="..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets" Condition="Exists('..\..\packages\Microsoft.Azure.Services.AppAuthentication.1.1.0-preview\build\Microsoft.Azure.Services.AppAuthentication.targets')" />
<Import Project="..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.0\build\Microsoft.ApplicationInsights.SnapshotCollector.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.0\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" />
<Import Project="..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.2\build\Microsoft.ApplicationInsights.SnapshotCollector.targets" Condition="Exists('..\..\packages\Microsoft.ApplicationInsights.SnapshotCollector.1.1.2\build\Microsoft.ApplicationInsights.SnapshotCollector.targets')" />
<!-- To modify your build process, add your task inside one of the targets below and uncomment it.
Other similar extension points exist, see Microsoft.Common.targets.
<Target Name="BeforeBuild">

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

@ -11,13 +11,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer
using System.Web.Mvc;
using System.Web.Optimization;
using System.Web.Routing;
using Logic;
using Providers;
using Unity;
/// <summary>
/// Defines the methods and properties that are common to application objects.
/// </summary>
/// <seealso cref="System.Web.HttpApplication" />
/// <seealso cref="HttpApplication" />
public class MvcApplication : HttpApplication
{
/// <summary>
@ -25,18 +25,18 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// </summary>
protected void Application_Start()
{
IExplorerService service;
IExplorerProvider provider;
try
{
AreaRegistration.RegisterAllAreas();
service = UnityConfig.Container.Resolve<IExplorerService>();
provider = UnityConfig.Container.Resolve<IExplorerProvider>();
Task.Run(service.InitializeAsync).Wait();
Task.Run(provider.InitializeAsync).Wait();
ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey =
service.Configuration.InstrumentationKey;
provider.Configuration.InstrumentationKey;
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
@ -44,7 +44,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
}
finally
{
service = null;
provider = null;
}
}
}

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

@ -1,137 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="Insights.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.Insights;
using Microsoft.Azure.Insights.Models;
using Rest;
using Rest.Azure;
using Rest.Azure.OData;
/// <summary>
/// Facilitates interactions with the Azure Insights in order to expose Azure health information.
/// </summary>
/// <seealso cref="System.IDisposable" />
public class Insights : IDisposable
{
/// <summary>
/// Name of the resource provider to be queried.
/// </summary>
private const string ResourceProviderName = "Azure.Health";
/// <summary>
/// Provides the ability to interact with the Azure Monitor API.
/// </summary>
private readonly IInsightsClient client;
/// <summary>
/// The subscription identifier that should be utilized in querying the health.
/// </summary>
private readonly string subscriptionId;
/// <summary>
/// A flag indicating whether or not this object has been disposed.
/// </summary>
private bool disposed;
/// <summary>
/// Initializes a new instance of the <see cref="Insights"/> class.
/// </summary>
/// <param name="subscriptionId">The subscription identifier.</param>
/// <param name="token">Valid JSON Web Token (JWT).</param>
/// <exception cref="ArgumentNullException">
/// subscriptionId
/// or
/// token
/// </exception>
public Insights(string subscriptionId, string token)
{
subscriptionId.AssertNotEmpty(nameof(subscriptionId));
token.AssertNotEmpty(nameof(token));
client = new InsightsClient(new TokenCredentials(token));
this.subscriptionId = subscriptionId;
}
/// <summary>
/// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
/// </summary>
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
/// <summary>
/// Gets a list of health events for subscription.
/// </summary>
/// <returns>A list of health events for the given subscription.</returns>
public async Task<List<IHealthEvent>> GetHealthEventsAsync()
{
DateTime queryEndDate;
DateTime queryStartDate;
IPage<EventData> events;
ODataQuery<EventData> query;
try
{
client.SubscriptionId = subscriptionId;
queryEndDate = DateTime.UtcNow;
queryStartDate = DateTime.UtcNow.AddMonths(-1);
query = new ODataQuery<EventData>(FilterString.Generate<IncidentEvent>(
eventData => (eventData.EventTimestamp >= queryStartDate)
&& (eventData.EventTimestamp <= queryEndDate)
&& (eventData.ResourceProvider == ResourceProviderName)));
events = await client.Events.ListAsync(query).ConfigureAwait(false);
return events.Select(x => new AzureHealthEvent
{
Description = x.Description,
EventTimestamp = x.EventTimestamp,
ResourceGroupName = x.ResourceGroupName,
ResourceId = x.ResourceId,
ResourceProviderName = x.ResourceProviderName.Value,
ResourceType = x.ResourceType.Value,
Status = x.Status.LocalizedValue
}).ToList<IHealthEvent>();
}
finally
{
events = null;
query = null;
}
}
/// <summary>
/// Releases unmanaged and - optionally - managed resources.
/// </summary>
/// <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 (disposed)
{
return;
}
client.Dispose();
if (disposing)
{
GC.SuppressFinalize(this);
}
disposed = true;
}
}
}

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

@ -12,8 +12,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
using System.Threading.Tasks;
using Microsoft.Azure.Management.ResourceManager;
using Microsoft.Azure.Management.ResourceManager.Models;
using Microsoft.Rest;
using Microsoft.Rest.Azure;
using Providers;
using Rest;
using Rest.Azure;
/// <summary>
/// Facilitates interactions with the Azure Resource Manager API.
@ -24,7 +25,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
/// <summary>
/// Provides access to core services.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Provides the ability to interact with the Azure Resource Manager API.
@ -39,21 +40,21 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
/// <summary>
/// Initializes a new instance of the <see cref="ResourceManager"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to core services.</param>
/// <param name="token">A valid JSON Web Token (JWT).</param>
/// <exception cref="ArgumentException">
/// <paramref name="token"/> is empty or null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public ResourceManager(IExplorerService service, string token)
public ResourceManager(IExplorerProvider provider, string token)
{
service.AssertNotNull(nameof(service));
provider.AssertNotNull(nameof(provider));
token.AssertNotEmpty(nameof(token));
client = new ResourceManagementClient(new TokenCredentials(token));
this.service = service;
this.provider = provider;
}
/// <summary>

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

@ -10,10 +10,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.Azure.ActiveDirectory.GraphClient;
using Microsoft.Azure.ActiveDirectory.GraphClient.Extensions;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Graph;
using Models;
using Providers;
using Security;
/// <summary>
/// Provides the ability to interact with the Microsoft Graph.
@ -24,12 +24,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Provides access to core services.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Provides access to the Microsoft Azure AD Graph API.
/// Provides access to the Microsoft Graph.
/// </summary>
private readonly IActiveDirectoryClient client;
private readonly IGraphServiceClient client;
/// <summary>
/// Identifier of the customer.
@ -39,56 +39,41 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Initializes a new instance of the <see cref="GraphClient"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to core services.</param>
/// <param name="customerId">Identifier for customer whose resources are being accessed.</param>
/// <exception cref="ArgumentException">
/// <paramref name="customerId"/> is empty or null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public GraphClient(IExplorerService service, string customerId)
public GraphClient(IExplorerProvider provider, string customerId)
{
service.AssertNotNull(nameof(service));
provider.AssertNotNull(nameof(provider));
customerId.AssertNotEmpty(nameof(customerId));
this.customerId = customerId;
this.service = service;
this.provider = provider;
client = new ActiveDirectoryClient(
new Uri($"{this.service.Configuration.GraphEndpoint}/{customerId}"),
async () =>
{
AuthenticationResult token = await service.AccessToken.GetAccessTokenAsync(
$"{this.service.Configuration.ActiveDirectoryEndpoint}/{customerId}",
service.Configuration.GraphEndpoint,
new ApplicationCredential
{
ApplicationId = service.Configuration.ApplicationId,
ApplicationSecret = service.Configuration.ApplicationSecret,
UseCache = true
}).ConfigureAwait(false);
return token.AccessToken;
});
client = new GraphServiceClient(new AuthenticationProvider(this.provider, customerId));
}
/// <summary>
/// Initializes a new instance of the <see cref="GraphClient"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="client">Provides the ability to interact with the Microsoft AD Graph API.</param>
/// <param name="provider">Provides access to core services.</param>
/// <param name="client">Provides the ability to interact with the Microsoft Graph.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// or
/// <paramref name="client"/> is null.
/// </exception>
public GraphClient(IExplorerService service, IActiveDirectoryClient client)
public GraphClient(IExplorerProvider provider, IGraphServiceClient client)
{
service.AssertNotNull(nameof(service));
provider.AssertNotNull(nameof(provider));
client.AssertNotNull(nameof(client));
this.service = service;
this.provider = provider;
this.client = client;
}
@ -102,21 +87,27 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// </exception>
public async Task<List<RoleModel>> GetDirectoryRolesAsync(string objectId)
{
IPagedCollection<IDirectoryObject> memberships;
List<Group> groups;
List<DirectoryRole> directoryRoles;
DateTime executionTime;
Dictionary<string, double> eventMeasurements;
Dictionary<string, string> eventProperties;
IUserMemberOfCollectionWithReferencesPage directoryGroups;
List<RoleModel> roles;
List<DirectoryRole> directoryRoles;
List<Group> groups;
bool morePages;
objectId.AssertNotEmpty(nameof(objectId));
try
{
memberships = await client.Users.GetByObjectId(objectId).MemberOf.ExecuteAsync().ConfigureAwait(false);
executionTime = DateTime.Now;
directoryGroups = await client.Users[objectId].MemberOf.Request().GetAsync().ConfigureAwait(false);
roles = new List<RoleModel>();
do
{
directoryRoles = memberships.CurrentPage.OfType<DirectoryRole>().ToList();
directoryRoles = directoryGroups.CurrentPage.OfType<DirectoryRole>().ToList();
if (directoryRoles.Count > 0)
{
@ -127,30 +118,80 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
}));
}
if (customerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (customerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
groups = memberships.CurrentPage.OfType<Group>().Where(
g => g.DisplayName.Equals("AdminAgents") || g.DisplayName.Equals("HelpdeskAgents")).ToList();
groups = directoryGroups.CurrentPage.OfType<Group>().Where(
g => g.DisplayName.Equals("AdminAgents") || g.DisplayName.Equals("HelpdeskAgents") || g.DisplayName.Equals("SalesAgent")).ToList();
if (groups.Count > 0)
{
roles.AddRange(groups.Select(g => new RoleModel
{
Description = g.Description,
DisplayName = g.DisplayName
}));
}
}
memberships = await memberships.GetNextPageAsync().ConfigureAwait(false);
morePages = directoryGroups.NextPageRequest != null;
if (morePages)
{
directoryGroups = await directoryGroups.NextPageRequest.GetAsync().ConfigureAwait(false);
}
}
while (memberships != null);
while (morePages);
// Capture the request for the customer summary for analysis.
eventProperties = new Dictionary<string, string>
{
{ "CustomerId", customerId },
{ "ObjectId", objectId }
};
// Track the event measurements for analysis.
eventMeasurements = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(executionTime).TotalMilliseconds },
{ "NumberOfRoles", roles.Count }
};
provider.Telemetry.TrackEvent(nameof(GetDirectoryRolesAsync), eventProperties, eventMeasurements);
return roles;
}
catch (Exception ex)
{
provider.Telemetry.TrackException(ex);
return null;
}
finally
{
directoryGroups = null;
directoryRoles = null;
memberships = null;
eventMeasurements = null;
eventProperties = null;
groups = null;
}
}
/// <summary>
/// Gets the service configuration records for the specified domain.
/// </summary>
/// <param name="domain">Name of the domain</param>
/// <returns>A list of service configuration records for the specified domain.</returns>
public async Task<List<DomainDnsRecord>> GetDomainConfigurationRecordsAsync(string domain)
{
IDomainServiceConfigurationRecordsCollectionPage records;
try
{
records = await client.Domains[domain].ServiceConfigurationRecords.Request().GetAsync().ConfigureAwait(false);
return records.CurrentPage.ToList();
}
finally
{
records = null;
}
}
@ -160,33 +201,38 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <returns>A list of domains configured for the customer.</returns>
public async Task<List<DomainModel>> GetDomainsAsync()
{
IPagedCollection<IDomain> domains;
IGraphServiceDomainsCollectionPage domains;
List<DomainModel> models;
bool morePages;
try
{
domains = await client.Domains.ExecuteAsync().ConfigureAwait(false);
domains = await client.Domains.Request().GetAsync().ConfigureAwait(false);
models = new List<DomainModel>();
do
{
models.AddRange(domains.CurrentPage.Select(d => new DomainModel
{
AdminManaged = d.IsAdminManaged,
AdminManaged = d.IsAdminManaged.Value,
AuthenticationType = d.AuthenticationType,
AvailabilityStatus = d.AvailabilityStatus,
IsDefault = d.IsDefault,
IsInitial = d.IsInitial,
IsRoot = d.IsRoot,
IsVerified = d.IsVerified,
Name = d.Name,
ServiceConfigurationRecords = d.ServiceConfigurationRecords.CurrentPage.ToList(),
IsDefault = d.IsDefault.Value,
IsInitial = d.IsInitial.Value,
IsRoot = d.IsRoot.Value,
IsVerified = d.IsVerified.Value,
Name = d.Id,
SupportedServices = d.SupportedServices
}));
domains = await domains.GetNextPageAsync().ConfigureAwait(false);
morePages = domains.NextPageRequest != null;
if (morePages)
{
domains = await domains.NextPageRequest.GetAsync().ConfigureAwait(false);
}
}
while (domains != null);
while (morePages);
return models;
}
@ -202,12 +248,13 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <returns>A list of users that belong to the customer.</returns>
public async Task<List<UserModel>> GetUsersAsync()
{
IPagedCollection<IUser> users;
IGraphServiceUsersCollectionPage users;
List<UserModel> value;
bool morePages;
try
{
users = await client.Users.ExecuteAsync().ConfigureAwait(false);
users = await client.Users.Request().GetAsync().ConfigureAwait(false);
value = new List<UserModel>();
do
@ -217,15 +264,20 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
CustomerId = customerId,
DisplayName = u.DisplayName,
FirstName = u.GivenName,
Id = u.ObjectId,
Id = u.Id,
LastName = u.Surname,
UsageLocation = u.UsageLocation,
UserPrincipalName = u.UserPrincipalName
}));
users = await users.GetNextPageAsync().ConfigureAwait(false);
morePages = users.NextPageRequest != null;
if (morePages)
{
users = await users.NextPageRequest.GetAsync().ConfigureAwait(false);
}
}
while (users != null);
while (morePages);
return value;
}

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

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="Communication.cs" company="Microsoft">
// <copyright file="HttpService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
@ -9,19 +9,21 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;
using Rest;
/// <summary>
/// Provides the ability to perform HTTP operations.
/// </summary>
public class Communication : ICommunication
public class HttpService : IHttpService
{
/// <summary>
/// Initializes a new instance of the <see cref="Communication"/> class.
/// Static instance of the <see cref="HttpClient" /> class.
/// </summary>
/// <param name="service">Provides access to the core services.</param>
public Communication(IExplorerService service)
{
}
private static HttpClient client = new HttpClient(
new RetryDelegatingHandler
{
InnerHandler = new HttpClientHandler()
});
/// <summary>
/// Sends a GET request to the specified Uri as an asynchronous operation.

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

@ -8,6 +8,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.Graph;
using Models;
/// <summary>
@ -20,11 +21,15 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// </summary>
/// <param name="objectId">Object identifier for the object to be checked.</param>
/// <returns>A list of roles that that are associated with the specified object identifier.</returns>
/// <exception cref="System.ArgumentException">
/// <paramref name="objectId"/> is empty or null.
/// </exception>
Task<List<RoleModel>> GetDirectoryRolesAsync(string objectId);
/// <summary>
/// Gets the service configuration records for the specified domain.
/// </summary>
/// <param name="domain">Name of the domain</param>
/// <returns>A list of service configuration records for the specified domain.</returns>
Task<List<DomainDnsRecord>> GetDomainConfigurationRecordsAsync(string domain);
/// <summary>
/// Gets a list of domains configured for the customer.
/// </summary>

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

@ -1,5 +1,5 @@
// -----------------------------------------------------------------------
// <copyright file="ICommunication.cs" company="Microsoft">
// <copyright file="IHttpService.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
@ -11,7 +11,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Represent the ability to perform HTTP operations.
/// </summary>
public interface ICommunication
public interface IHttpService
{
/// <summary>
/// Sends a GET request to the specified Uri as an asynchronous operation.
@ -20,12 +20,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <param name="requestUri">The Uri where the request should be sent.</param>
/// <param name="token">The access token value used to authorize the request.</param>
/// <returns>The task object representing the asynchronous operation.</returns>
/// <exception cref="System.ArgumentException">
/// <paramref name="requestUri"/> is empty or null.
/// or
/// <paramref name="token"/> is empty or null.
/// </exception>
/// <exception cref="CommunicationException"></exception>
Task<T> GetAsync<T>(string requestUri, string token);
}
}

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

@ -9,7 +9,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using IdentityModel.Clients.ActiveDirectory;
using Providers;
/// <summary>
/// Facilities interactions with the Office 365 Service Communications API.
@ -24,23 +25,23 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
/// <summary>
/// Provides access to core services.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Initializes a new instance of the <see cref="ServiceCommunications" /> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to core services.</param>
/// <param name="token">Access token to be used for the requests.</param>
/// <exception cref="System.ArgumentException">
/// <paramref name="token"/> is null.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public ServiceCommunications(IExplorerService service, AuthenticationResult token)
public ServiceCommunications(IExplorerProvider provider, AuthenticationResult token)
{
service.AssertNotNull(nameof(service));
this.service = service;
provider.AssertNotNull(nameof(provider));
this.provider = provider;
this.token = token;
}
@ -61,9 +62,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
try
{
requestUri = $"{service.Configuration.OfficeManagementEndpoint}/api/v1.0/{customerId}/ServiceComms/CurrentStatus";
requestUri = $"{provider.Configuration.OfficeManagementEndpoint}/api/v1.0/{customerId}/ServiceComms/CurrentStatus";
records = await service.Communication.GetAsync<Result<OfficeHealthEvent>>(
records = await provider.Communication.GetAsync<Result<OfficeHealthEvent>>(
requestUri,
token.AccessToken).ConfigureAwait(false);

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

@ -11,21 +11,22 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
using System.Security.Claims;
using System.Threading.Tasks;
using Cache;
using Microsoft.IdentityModel.Clients.ActiveDirectory;
using Microsoft.Store.PartnerCenter.Extensions;
using Microsoft.Store.PartnerCenter.Models.Auditing;
using Microsoft.Store.PartnerCenter.Models.Licenses;
using Microsoft.Store.PartnerCenter.Models.Query;
using Microsoft.Store.PartnerCenter.Models.ServiceRequests;
using Microsoft.Store.PartnerCenter.Models.Users;
using IdentityModel.Clients.ActiveDirectory;
using PartnerCenter.Enumerators;
using PartnerCenter.Extensions;
using PartnerCenter.Models;
using PartnerCenter.Models.Auditing;
using PartnerCenter.Models.Customers;
using PartnerCenter.Models.Invoices;
using PartnerCenter.Models.Licenses;
using PartnerCenter.Models.Offers;
using PartnerCenter.Models.Orders;
using PartnerCenter.Models.Query;
using PartnerCenter.Models.ServiceRequests;
using PartnerCenter.Models.Subscriptions;
using PartnerCenter.Models.Users;
using PartnerCenter.Models.Utilizations;
using Providers;
using RequestContext;
using Security;
@ -57,7 +58,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Provides access to core services.
/// </summary>
private IExplorerService service;
private IExplorerProvider provider;
/// <summary>
/// Provides a way to ensure that <see cref="appOperations"/> is only being modified
@ -68,14 +69,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Initializes a new instance of the <see cref="PartnerOperations"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to core services.</param>
/// <exception cref="ArgumentException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public PartnerOperations(IExplorerService service)
public PartnerOperations(IExplorerProvider provider)
{
service.AssertNotNull(nameof(service));
this.service = service;
provider.AssertNotNull(nameof(provider));
this.provider = provider;
}
/// <summary>
@ -122,7 +123,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(CheckDomainAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(CheckDomainAsync), eventProperties, eventMetrics);
return exists;
}
@ -163,7 +164,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -184,7 +185,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(CreateCustomerAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(CreateCustomerAsync), eventProperties, eventMetrics);
return newEntity;
}
@ -224,7 +225,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
newEntity = await operations.Customers.ById(customerId).Orders.CreateAsync(newOrder);
}
@ -247,7 +248,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(CreateOrderAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(CreateOrderAsync), eventProperties, eventMetrics);
return newEntity;
}
@ -296,7 +297,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
user = await operations.Customers.ById(customerId).Users.CreateAsync(newEntity).ConfigureAwait(false);
}
@ -317,7 +318,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(CreateUserAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(CreateUserAsync), eventProperties, eventMetrics);
return user;
}
@ -358,7 +359,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -377,7 +378,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(DeleteCustomerAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(DeleteCustomerAsync), eventProperties, eventMetrics);
}
finally
{
@ -422,7 +423,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -443,7 +444,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(DeleteUserAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(DeleteUserAsync), eventProperties, eventMetrics);
}
finally
{
@ -496,7 +497,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetAuditRecordsAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetAuditRecordsAsync), eventProperties, eventMetrics);
return records;
}
@ -532,7 +533,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
customer = await operations.Customers.ById(customerId).GetAsync().ConfigureAwait(false);
}
@ -553,7 +554,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetCustomerAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetCustomerAsync), eventProperties, eventMetrics);
return customer;
}
@ -593,7 +594,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
customers = new List<Customer>();
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
seekCustomers = await operations.Customers.GetAsync().ConfigureAwait(false);
customersEnumerator = operations.Enumerators.Customers.Create(seekCustomers);
@ -623,7 +624,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetCustomersAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetCustomersAsync), eventProperties, eventMetrics);
return customers;
}
@ -666,7 +667,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
skus = await operations.Customers.ById(customerId).SubscribedSkus.GetAsync().ConfigureAwait(false);
@ -688,7 +689,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetCustomerSubscribedSkusAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetCustomerSubscribedSkusAsync), eventProperties, eventMetrics);
return skus;
}
@ -730,7 +731,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -749,7 +750,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetInvoiceAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetInvoiceAsync), eventProperties, eventMetrics);
return invoice;
}
@ -792,7 +793,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -812,7 +813,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetInvoiceLineItemsAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetInvoiceLineItemsAsync), eventProperties, eventMetrics);
return new List<InvoiceLineItem>(invoiceLineItems.Items);
}
@ -848,7 +849,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (!principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (!principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
throw new UnauthorizedAccessException("You are not authorized to perform this operation.");
}
@ -868,7 +869,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent("GetInvoicesAsync", eventProperties, eventMetrics);
provider.Telemetry.TrackEvent("GetInvoicesAsync", eventProperties, eventMetrics);
return new List<Invoice>(invoices.Items);
}
@ -904,12 +905,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
offers = await service.Cache.FetchAsync<ResourceCollection<Offer>>(CacheDatabaseType.DataStructures, OffersKey).ConfigureAwait(false);
offers = await provider.Cache.FetchAsync<ResourceCollection<Offer>>(CacheDatabaseType.DataStructures, OffersKey).ConfigureAwait(false);
if (offers == null)
{
offers = await operations.Offers.ByCountry("US").GetAsync();
await service.Cache.StoreAsync(CacheDatabaseType.DataStructures, OffersKey, offers, TimeSpan.FromDays(1)).ConfigureAwait(false);
await provider.Cache.StoreAsync(CacheDatabaseType.DataStructures, OffersKey, offers, TimeSpan.FromDays(1)).ConfigureAwait(false);
}
eventMetrics = new Dictionary<string, double>
@ -925,7 +926,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetOffersAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetOffersAsync), eventProperties, eventMetrics);
return new List<Offer>(offers.Items);
}
@ -961,7 +962,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
requests = await operations.ServiceRequests.GetAsync().ConfigureAwait(false);
}
@ -983,7 +984,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetServiceRequestsAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetServiceRequestsAsync), eventProperties, eventMetrics);
return requests;
}
@ -1028,7 +1029,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
subscription = await operations.Customers.ById(customerId).Subscriptions.ById(subscriptionId).GetAsync().ConfigureAwait(false);
}
@ -1049,7 +1050,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetSubscriptionAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetSubscriptionAsync), eventProperties, eventMetrics);
return subscription;
}
@ -1090,7 +1091,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
subscriptions = await operations.Customers.ById(customerId).Subscriptions.GetAsync().ConfigureAwait(false);
}
@ -1112,7 +1113,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetSubscriptionsAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetSubscriptionsAsync), eventProperties, eventMetrics);
return new List<Subscription>(subscriptions.Items);
}
@ -1158,7 +1159,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
usageRecords = new List<AzureUtilizationRecord>();
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
records = await operations.Customers.ById(customerId).Subscriptions.ById(subscriptionId)
.Utilization.Azure.QueryAsync(startTime, endTime).ConfigureAwait(false);
@ -1196,7 +1197,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetSubscriptionUsageAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetSubscriptionUsageAsync), eventProperties, eventMetrics);
return usageRecords;
}
@ -1243,7 +1244,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
user = await operations.Customers.ById(customerId).Users.ById(userId).GetAsync().ConfigureAwait(false);
@ -1266,7 +1267,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetUserAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetUserAsync), eventProperties, eventMetrics);
return user;
}
@ -1311,7 +1312,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
licenses = await operations.Customers.ById(customerId).Users.ById(userId).Licenses.GetAsync().ConfigureAwait(false);
@ -1334,7 +1335,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(GetUserLicensesAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(GetUserLicensesAsync), eventProperties, eventMetrics);
return licenses;
}
@ -1380,7 +1381,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId))
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId))
{
updatedSubscription = await operations.Customers.ById(customerId).Subscriptions
.ById(subscription.Id).PatchAsync(subscription).ConfigureAwait(false);
@ -1403,7 +1404,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(UpdateSubscriptionAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(UpdateSubscriptionAsync), eventProperties, eventMetrics);
return updatedSubscription;
}
@ -1445,7 +1446,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
user = await operations.Customers.ById(customerId).Users.ById(userId).PatchAsync(entity).ConfigureAwait(false);
@ -1467,7 +1468,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(UpdateUserAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(UpdateUserAsync), eventProperties, eventMetrics);
return user;
}
@ -1516,7 +1517,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
if (principal.CustomerId.Equals(service.Configuration.PartnerCenterApplicationTenantId) ||
if (principal.CustomerId.Equals(provider.Configuration.PartnerCenterApplicationTenantId) ||
principal.CustomerId.Equals(customerId))
{
await operations.Customers.ById(customerId).Users.ById(userId).LicenseUpdates.CreateAsync(entity).ConfigureAwait(false);
@ -1538,7 +1539,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{ "ParternCenterCorrelationId", correlationId.ToString() }
};
service.Telemetry.TrackEvent(nameof(UpdateUserLicensesAsync), eventProperties, eventMetrics);
provider.Telemetry.TrackEvent(nameof(UpdateUserLicensesAsync), eventProperties, eventMetrics);
}
finally
{
@ -1587,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>(
await provider.Cache.FetchAsync<Models.PartnerCenterToken>(
CacheDatabaseType.Authentication, PartnerCenterCacheKey).ConfigureAwait(false);
if (credentials != null && !credentials.IsExpired())
@ -1597,11 +1598,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
// The access token has expired, so a new one must be requested.
credentials = await PartnerCredentials.Instance.GenerateByApplicationCredentialsAsync(
service.Configuration.PartnerCenterApplicationId,
service.Configuration.PartnerCenterApplicationSecret.ToUnsecureString(),
service.Configuration.PartnerCenterApplicationTenantId).ConfigureAwait(false);
provider.Configuration.PartnerCenterApplicationId,
provider.Configuration.PartnerCenterApplicationSecret.ToUnsecureString(),
provider.Configuration.PartnerCenterApplicationTenantId).ConfigureAwait(false);
await service.Cache.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials).ConfigureAwait(false);
await provider.Cache.StoreAsync(CacheDatabaseType.Authentication, PartnerCenterCacheKey, credentials).ConfigureAwait(false);
return credentials;
}
@ -1613,19 +1614,19 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <returns>An instance of the partner service.</returns>
private async Task<IPartner> GetUserOperationsAsync(Guid correlationId)
{
AuthenticationResult token = await service.AccessToken.GetAccessTokenAsync(
$"{service.Configuration.ActiveDirectoryEndpoint}/{service.Configuration.PartnerCenterApplicationTenantId}",
service.Configuration.PartnerCenterEndpoint,
AuthenticationResult token = await provider.AccessToken.GetAccessTokenAsync(
$"{provider.Configuration.ActiveDirectoryEndpoint}/{provider.Configuration.PartnerCenterApplicationTenantId}",
provider.Configuration.PartnerCenterEndpoint,
new Models.ApplicationCredential
{
ApplicationId = service.Configuration.ApplicationId,
ApplicationSecret = service.Configuration.ApplicationSecret,
ApplicationId = provider.Configuration.ApplicationId,
ApplicationSecret = provider.Configuration.ApplicationSecret,
UseCache = true
},
service.AccessToken.UserAssertionToken).ConfigureAwait(false);
provider.AccessToken.UserAssertionToken).ConfigureAwait(false);
IPartnerCredentials credentials = await PartnerCredentials.Instance.GenerateByUserCredentialsAsync(
service.Configuration.ApplicationId,
provider.Configuration.ApplicationId,
new AuthenticationToken(token.AccessToken, token.ExpiresOn)).ConfigureAwait(false);
IAggregatePartner userOperations = PartnerService.Instance.CreatePartnerOperations(credentials);

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

@ -8,6 +8,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
{
using System;
using System.Web.Mvc;
using Providers;
using Unity;
/// <summary>
@ -23,17 +24,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <param name="filterContext">The action-filter context.</param>
public override void OnException(ExceptionContext filterContext)
{
IExplorerService service;
IExplorerProvider provider;
try
{
service = UnityConfig.Container.Resolve<IExplorerService>();
provider = UnityConfig.Container.Resolve<IExplorerProvider>();
if (filterContext?.HttpContext != null && filterContext.Exception != null)
{
if (filterContext.HttpContext.IsCustomErrorEnabled)
{
service.Telemetry.TrackException(filterContext.Exception);
provider.Telemetry.TrackException(filterContext.Exception);
}
}
@ -41,7 +42,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
}
finally
{
service = null;
provider = null;
}
}
}

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

@ -7,6 +7,7 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Models
{
using System.Collections.Generic;
using Microsoft.Graph;
/// <summary>
/// Model for domain configuration records obtain from Azure AD Graph API.
@ -16,6 +17,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Models
/// <summary>
/// Gets or sets the service configuration records.
/// </summary>
public List<ServiceConfigurationRecordModel> ServiceConfigurationRecords { get; set; }
public List<DomainDnsRecord> ServiceConfigurationRecords { get; set; }
}
}

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

@ -7,10 +7,9 @@
namespace Microsoft.Store.PartnerCenter.Explorer.Models
{
using System.Collections.Generic;
using Azure.ActiveDirectory.GraphClient;
/// <summary>
/// Represents a domain obtained from Azure AD Graph API.
/// Represents a domain obtained from Microsoft Graph.
/// </summary>
public class DomainModel
{
@ -54,14 +53,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Models
/// </summary>
public string Name { get; set; }
/// <summary>
/// Gets or sets the service configuration records.
/// </summary>
public IList<IDomainDnsRecord> ServiceConfigurationRecords { get; set; }
/// <summary>
/// Gets or sets the supported services.
/// </summary>
public IList<string> SupportedServices { get; set; }
public IEnumerable<string> SupportedServices { get; set; }
}
}

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

@ -1,15 +0,0 @@
// -----------------------------------------------------------------------
// <copyright file="ServiceConfigurationRecordModel.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Models
{
/// <summary>
/// Represents a service configuration record obtained from Azure AD Graph API.
/// </summary>
public class ServiceConfigurationRecordModel
{
}
}

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

@ -4,7 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Linq;
using System.Security.Claims;
@ -20,9 +20,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
internal sealed class AccessTokenProvider : IAccessTokenProvider
{
/// <summary>
/// Provides access to the application core services.
/// Provides access to the core explorer providers.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Type of the assertion representing the user when performing app + user authentication.
@ -32,37 +32,20 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
/// <summary>
/// Initializes a new instance of <see cref="AccessTokenProvider"/> class.
/// </summary>
/// <param name="service">Provides access to the application core services.</param>
/// <param name="provider">Provides access to core explorer providers.</param>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public AccessTokenProvider(IExplorerService service)
public AccessTokenProvider(IExplorerProvider provider)
{
service.AssertNotNull(nameof(service));
this.service = service;
provider.AssertNotNull(nameof(provider));
this.provider = provider;
}
/// <summary>
/// Get the user assertion token for the authenticated user.
/// </summary>
public string UserAssertionToken
{
get
{
System.IdentityModel.Tokens.BootstrapContext bootstrapContext;
try
{
bootstrapContext = ClaimsPrincipal.Current.Identities.First().BootstrapContext as System.IdentityModel.Tokens.BootstrapContext;
return bootstrapContext?.Token;
}
finally
{
bootstrapContext = null;
}
}
}
public string UserAssertionToken => ClaimsPrincipal.Current.Identities.First().BootstrapContext.ToString();
/// <summary>
/// Gets an access token from the authority.
@ -94,7 +77,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
if (credential.UseCache)
{
tokenCache = new DistributedTokenCache(service, resource, $"AppOnly::{authority}::{resource}");
tokenCache = new DistributedTokenCache(provider, resource, $"AppOnly::{authority}::{resource}");
authContext = new AuthenticationContext(authority, tokenCache);
}
else
@ -155,7 +138,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
if (credential.UseCache)
{
tokenCache = new DistributedTokenCache(service, resource);
tokenCache = new DistributedTokenCache(provider, resource);
authContext = new AuthenticationContext(authority, tokenCache);
}
else

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

@ -1,10 +1,10 @@
// -----------------------------------------------------------------------
// <copyright file="Configuration.cs" company="Microsoft">
// <copyright file="ConfigurationProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System;
using System.Configuration;
@ -15,22 +15,22 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Provides easy access to various configurations stored in sources like app.config and web.config
/// </summary>
/// <seealso cref="IConfiguration" />
public class Configuration : IConfiguration
/// <seealso cref="IConfigurationProvider" />
public class ConfigurationProvider : IConfigurationProvider
{
/// <summary>
/// Provides access to core services.
/// Provides access to core explorer providers.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider service;
/// <summary>
/// Initializes a new instance of the <see cref="Configuration"/> class.
/// Initializes a new instance of the <see cref="ConfigurationProvider"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="service">Provides access to core explorer providers.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// </exception>
public Configuration(IExplorerService service)
public ConfigurationProvider(IExplorerProvider service)
{
service.AssertNotNull(nameof(service));
this.service = service;

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

@ -1,21 +1,19 @@
// -----------------------------------------------------------------------
// <copyright file="ExplorerService.cs" company="Microsoft">
// <copyright file="ExplorerProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Logic
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Threading.Tasks;
using Cache;
using Configuration;
using Security;
using Logic;
using Telemetry;
/// <summary>
/// Provides access to the core services.
/// </summary>
public class ExplorerService : IExplorerService
public class ExplorerProvider : IExplorerProvider
{
/// <summary>
/// Provides the ability to manage access tokens.
@ -25,17 +23,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Provides the ability to cache often used objects.
/// </summary>
private static ICacheService cache;
private static ICacheProvider cache;
/// <summary>
/// Provides the ability to access various configurations.
/// </summary>
private static IConfiguration configuration;
private static IConfigurationProvider configuration;
/// <summary>
/// Provides the ability to perform HTTP operations.
/// </summary>
private static ICommunication communication;
private static IHttpService communication;
/// <summary>
/// Provides the ability to perform various partner operations.
@ -50,7 +48,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Provides the ability to securely access and store resources.
/// </summary>
private static IVaultService vault;
private static IVaultProvider vault;
/// <summary>
/// Gets the a reference to the token management service.
@ -60,17 +58,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Gets the service that provides caching functionality.
/// </summary>
public ICacheService Cache => cache ?? (cache = new CacheService(this));
public ICacheProvider Cache => cache ?? (cache = new RedisCacheProvider(this));
/// <summary>
/// Gets a reference to the available configurations.
/// </summary>
public IConfiguration Configuration => configuration ?? (configuration = new Configuration(this));
public IConfigurationProvider Configuration => configuration ?? (configuration = new ConfigurationProvider(this));
/// <summary>
/// Gets a reference to the communication.
/// </summary>
public ICommunication Communication => communication ?? (communication = new Communication(this));
public IHttpService Communication => communication ?? (communication = new HttpService());
/// <summary>
/// Gets a reference to the partner operations.
@ -105,7 +103,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Gets a reference to the vault service.
/// </summary>
public IVaultService Vault => vault ?? (vault = new VaultService(this));
public IVaultProvider Vault => vault ?? (vault = new KeyVaultProvider(this));
/// <summary>
/// Initializes this instance of the <see cref="ReportProvider"/> class.

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

@ -4,7 +4,7 @@
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Threading.Tasks;
using IdentityModel.Clients.ActiveDirectory;

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

@ -1,18 +1,19 @@
// -----------------------------------------------------------------------
// <copyright file="ICacheService.cs" company="Microsoft">
// <copyright file="ICacheProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Cache
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System;
using System.Threading.Tasks;
using Cache;
/// <summary>
/// Provides quick access to frequently utilized resources.
/// Represents a way to cache data structures.
/// </summary>
public interface ICacheService
public interface ICacheProvider
{
/// <summary>
/// Removes all entities from the specified cache database.
@ -27,9 +28,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <param name="database">Cache database type where the data is stored.</param>
/// <param name="key">A unique identifier for the cache entry.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
Task DeleteAsync(CacheDatabaseType database, string key = null);
/// <summary>
@ -41,9 +39,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <returns>
/// The entity associated with the specified key.
/// </returns>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
TEntity Fetch<TEntity>(CacheDatabaseType database, string key) where TEntity : class;
/// <summary>
@ -55,9 +50,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <returns>
/// The entity associated with the specified key.
/// </returns>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
Task<TEntity> FetchAsync<TEntity>(CacheDatabaseType database, string key) where TEntity : class;
/// <summary>
@ -69,12 +61,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <param name="entity">The object to be cached.</param>
/// <param name="expiration">When the cached object expires.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// entity
/// </exception>
Task StoreAsync<TEntity>(CacheDatabaseType database, string key, TEntity entity, TimeSpan? expiration = null)
where TEntity : class;
@ -89,10 +75,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// </summary>
/// <param name="database">Cache database type where the data is stored.</param>
/// <param name="key">A unique identifier for the cache entry.</param>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
void Delete(CacheDatabaseType database, string key);
void Delete(CacheDatabaseType database, string key = null);
/// <summary>
/// Stores the specified entity in the cache.
@ -102,12 +85,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <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 cached object expires.</param>
/// <exception cref="ArgumentException">
/// <paramref name="key"/> is null.
/// </exception>
/// <exception cref="ArgumentNullException">
/// entity
/// </exception>
void Store<TEntity>(CacheDatabaseType database, string key, TEntity entity, TimeSpan? expiration = null)
where TEntity : class;
}

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

@ -1,10 +1,10 @@
// -----------------------------------------------------------------------
// <copyright file="IConfiguration.cs" company="Microsoft">
// <copyright file="IConfigurationProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Security;
using System.Threading.Tasks;
@ -12,7 +12,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Configuration
/// <summary>
/// Represents the ability to reference various configurations.
/// </summary>
public interface IConfiguration
public interface IConfigurationProvider
{
/// <summary>
/// Gets the Active Directory endpoint address.

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

@ -1,21 +1,19 @@
// -----------------------------------------------------------------------
// <copyright file="IExplorerService.cs" company="Microsoft">
// <copyright file="IExplorerProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Logic
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Threading.Tasks;
using Cache;
using Configuration;
using Security;
using Logic;
using Telemetry;
/// <summary>
/// Represents the core service that powers this application.
/// Represents the core application provider.
/// </summary>
public interface IExplorerService
public interface IExplorerProvider
{
/// <summary>
/// Gets a reference to the token management service.
@ -25,17 +23,17 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
/// <summary>
/// Gets the service that provides caching functionality.
/// </summary>
ICacheService Cache { get; }
ICacheProvider Cache { get; }
/// <summary>
/// Gets a reference to the available configurations.
/// </summary>
IConfiguration Configuration { get; }
IConfigurationProvider Configuration { get; }
/// <summary>
/// Gets a reference to the communication service.
/// </summary>
ICommunication Communication { get; }
IHttpService Communication { get; }
/// <summary>
/// Gets a reference to the partner operations.
@ -48,9 +46,9 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
ITelemetryProvider Telemetry { get; }
/// <summary>
/// Gets a reference to the vault service.
/// Gets a reference to the vault provider.
/// </summary>
IVaultService Vault { get; }
IVaultProvider Vault { get; }
/// <summary>
/// Initializes this instance of the <see cref="ReportProvider"/> class.

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

@ -1,10 +1,10 @@
// -----------------------------------------------------------------------
// <copyright file="IVaultService.cs" company="Microsoft">
// <copyright file="IVaultProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System.Security;
using System.Threading.Tasks;
@ -12,7 +12,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
/// <summary>
/// Represents a secure mechanism for retrieving and store information.
/// </summary>
public interface IVaultService
public interface IVaultProvider
{
/// <summary>
/// Gets the specified entity from the vault.

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

@ -1,10 +1,10 @@
// -----------------------------------------------------------------------
// <copyright file="VaultService.cs" company="Microsoft">
// <copyright file="KeyVaultProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System;
using System.Collections.Generic;
@ -18,12 +18,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
/// <summary>
/// Provides a secure mechanism for retrieving and store information.
/// </summary>
internal sealed class VaultService : IVaultService
internal sealed class KeyVaultProvider : IVaultProvider
{
/// <summary>
/// Provides access to the application core services.
/// Provides access to core explorer providers.
/// </summary>
private readonly IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Error code returned when a secret is not found in the vault.
@ -31,16 +31,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
private const string NotFoundErrorCode = "SecretNotFound";
/// <summary>
/// Initializes a new instance of the <see cref="VaultService"/> class.
/// Initializes a new instance of the <see cref="KeyVaultProvider"/> class.
/// </summary>
/// <param name="provider">Provides access to the application core services.</param>
/// <param name="provider">Provides access to core explorer providers.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="provider"/> is null.
/// </exception>
public VaultService(IExplorerService service)
public KeyVaultProvider(IExplorerProvider provider)
{
service.AssertNotNull(nameof(service));
this.service = service;
provider.AssertNotNull(nameof(provider));
this.provider = provider;
}
/// <summary>
@ -68,7 +68,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
try
{
bundle = await client.GetSecretAsync(service.Configuration.KeyVaultEndpoint, identifier).ConfigureAwait(false);
bundle = await client.GetSecretAsync(provider.Configuration.KeyVaultEndpoint, identifier).ConfigureAwait(false);
}
catch (KeyVaultErrorException ex)
{
@ -83,17 +83,19 @@ 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 }
};
service.Telemetry.TrackEvent("KeyVault/GetAsync", eventProperties, eventMetrics);
provider.Telemetry.TrackEvent("KeyVault/GetAsync", eventProperties, eventMetrics);
return bundle?.Value.ToSecureString();
}
@ -133,9 +135,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
using (IKeyVaultClient client = GetAzureKeyVaultClient())
{
await client.SetSecretAsync(
service.Configuration.KeyVaultEndpoint, identifier, value.ToUnsecureString()).ConfigureAwait(false);
provider.Configuration.KeyVaultEndpoint, identifier, value.ToUnsecureString()).ConfigureAwait(false);
}
// Track the event measurements for analysis.
eventMetrics = new Dictionary<string, double>
{
{ "ElapsedMilliseconds", DateTime.Now.Subtract(executionTime).TotalMilliseconds }
@ -147,7 +150,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Security
{ "Identifier", identifier }
};
service.Telemetry.TrackEvent("KeyVault/StoreAsync", eventProperties, eventMetrics);
provider.Telemetry.TrackEvent("KeyVault/StoreAsync", eventProperties, eventMetrics);
}
finally
{

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

@ -1,30 +1,30 @@
// -----------------------------------------------------------------------
// <copyright file="CacheService.cs" company="Microsoft">
// <copyright file="RedisCacheProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Cache
namespace Microsoft.Store.PartnerCenter.Explorer.Providers
{
using System;
using System.IO;
using System.IO.Compression;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using Cache;
using Logic;
using Newtonsoft.Json;
using StackExchange.Redis;
/// <summary>
/// Provides quick access to frequently utilized resources.
/// Provides the ability to cache resources using an instance of Redis Cache.
/// </summary>
public class CacheService : ICacheService
internal sealed class RedisCacheProvider : ICacheProvider
{
/// <summary>
/// Provides access to core services.
/// Provides access to core report providers.
/// </summary>
private IExplorerService service;
private readonly IExplorerProvider provider;
/// <summary>
/// Provides the ability to interact with an instance of Redis Cache.
@ -34,14 +34,14 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
/// <summary>
/// Initializes a new instance of the <see cref="RedisCacheProvider"/> class.
/// </summary>
/// <param name="service">Provides access to core services.</param>
/// <param name="provider">Provides access to core report providers.</param>
/// <exception cref="ArgumentNullException">
/// <paramref name="service"/> is null.
/// <paramref name="provider"/> is null.
/// </exception>
public CacheService(IExplorerService service)
public RedisCacheProvider(IExplorerProvider provider)
{
service.AssertNotNull(nameof(service));
this.service = service;
provider.AssertNotNull(nameof(provider));
this.provider = provider;
}
/// <summary>
@ -66,7 +66,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
public async Task DeleteAsync(CacheDatabaseType database, string key = null)
{
IDatabase cache = await GetCacheReferenceAsync(database);
await cache.KeyDeleteAsync(key).ConfigureAwait(false);
await cache.KeyDeleteAsync(key);
}
/// <summary>
@ -107,8 +107,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
key.AssertNotEmpty(nameof(key));
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
RedisValue value = await cache.StringGetAsync(key).ConfigureAwait(false);
IDatabase cache = await GetCacheReferenceAsync(database);
RedisValue value = await cache.StringGetAsync(key);
return value.HasValue ? DecompressEntity<TEntity>(value) : null;
}
@ -134,12 +134,10 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
key.AssertNotEmpty(nameof(key));
entity.AssertNotNull(nameof(entity));
IDatabase cache = await GetCacheReferenceAsync(database).ConfigureAwait(false);
IDatabase cache = await GetCacheReferenceAsync(database);
await cache.StringSetAsync(
key,
CompressEntity(entity),
expiration).ConfigureAwait(false);
key, CompressEntity(entity), expiration);
}
/// <summary>
@ -272,11 +270,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
if (connection == null)
{
using (SecureString redisCacheConnectionString = SynchronousExecute(() => service.Vault.GetAsync("RedisCacheConnectionString")))
{
connection = ConnectionMultiplexer.Connect(
redisCacheConnectionString.ToUnsecureString());
}
connection = ConnectionMultiplexer.Connect(
provider.Configuration.RedisCacheConnectionString.ToUnsecureString());
}
return connection.GetDatabase((int)database);
@ -291,11 +286,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Cache
{
if (connection == null)
{
using (SecureString redisCacheConnectionString = await service.Vault.GetAsync("RedisCacheConnectionString"))
{
connection = await ConnectionMultiplexer.ConnectAsync(
redisCacheConnectionString.ToUnsecureString()).ConfigureAwait(false);
}
connection = await ConnectionMultiplexer.ConnectAsync(
provider.Configuration.RedisCacheConnectionString.ToUnsecureString());
}
return connection.GetDatabase((int)database);

4
src/Explorer/Scripts/jquery-3.2.1.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

Разница между файлами не показана из-за своего большого размера Загрузить разницу

2
src/Explorer/Scripts/jquery-3.3.1.min.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Разница между файлами не показана из-за своего большого размера Загрузить разницу

2
src/Explorer/Scripts/jquery-3.3.1.slim.min.js поставляемый Normal file

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -56,19 +56,12 @@
mode = (element.getAttribute("data-ajax-mode") || "").toUpperCase();
$(element.getAttribute("data-ajax-update")).each(function (i, update) {
var top;
switch (mode) {
case "BEFORE":
top = update.firstChild;
$("<div />").html(data).contents().each(function () {
update.insertBefore(this, top);
});
$(update).prepend(data);
break;
case "AFTER":
$("<div />").html(data).contents().each(function () {
update.appendChild(this);
});
$(update).append(data);
break;
case "REPLACE-WITH":
$(update).replaceWith(data);

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

@ -1,3 +1,17 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
@ -16,4 +30,4 @@
** Unobtrusive Ajax support library for jQuery
** Copyright (C) Microsoft Corporation. All rights reserved.
*/
(function(a){var b="unobtrusiveAjaxClick",d="unobtrusiveAjaxClickTarget",h="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function e(a){return a==="GET"||a==="POST"}function g(b,a){!e(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function i(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(f,c){var e;switch(d){case"BEFORE":e=c.firstChild;a("<div />").html(b).contents().each(function(){c.insertBefore(this,e)});break;case"AFTER":a("<div />").html(b).contents().each(function(){c.appendChild(this)});break;case"REPLACE-WITH":a(c).replaceWith(b);break;default:a(c).html(b)}})}function f(b,d){var j,k,f,h;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));h=parseInt(b.getAttribute("data-ajax-loading-duration"),10)||0;a.extend(d,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,cache:!!b.getAttribute("data-ajax-cache"),beforeSend:function(d){var a;g(d,f);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(b,arguments);a!==false&&k.show(h);return a},complete:function(){k.hide(h);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(b,arguments)},success:function(a,e,d){i(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(b,arguments)},error:function(){c(b.getAttribute("data-ajax-failure"),["xhr","status","error"]).apply(b,arguments)}});d.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});f=d.type.toUpperCase();if(!e(f)){d.type="POST";d.data.push({name:"X-HTTP-Method-Override",value:f})}a.ajax(d)}function j(c){var b=a(c).data(h);return!b||!b.validate||b.validate()}a(document).on("click","a[data-ajax=true]",function(a){a.preventDefault();f(this,{url:this.href,type:"GET",data:[]})});a(document).on("click","form[data-ajax=true] input[type=image]",function(c){var g=c.target.name,e=a(c.target),f=a(e.parents("form")[0]),d=e.offset();f.data(b,[{name:g+".x",value:Math.round(c.pageX-d.left)},{name:g+".y",value:Math.round(c.pageY-d.top)}]);setTimeout(function(){f.removeData(b)},0)});a(document).on("click","form[data-ajax=true] :submit",function(e){var g=e.currentTarget.name,f=a(e.target),c=a(f.parents("form")[0]);c.data(b,g?[{name:g,value:e.currentTarget.value}]:[]);c.data(d,f);setTimeout(function(){c.removeData(b);c.removeData(d)},0)});a(document).on("submit","form[data-ajax=true]",function(h){var e=a(this).data(b)||[],c=a(this).data(d),g=c&&c.hasClass("cancel");h.preventDefault();if(!g&&!j(this))return;f(this,{url:this.action,type:this.method||"GET",data:e.concat(a(this).serializeArray())})})})(jQuery);
(function(a){var b="unobtrusiveAjaxClick",d="unobtrusiveAjaxClickTarget",h="unobtrusiveValidation";function c(d,b){var a=window,c=(d||"").split(".");while(a&&c.length)a=a[c.shift()];if(typeof a==="function")return a;b.push(d);return Function.constructor.apply(null,b)}function e(a){return a==="GET"||a==="POST"}function g(b,a){!e(a)&&b.setRequestHeader("X-HTTP-Method-Override",a)}function i(c,b,e){var d;if(e.indexOf("application/x-javascript")!==-1)return;d=(c.getAttribute("data-ajax-mode")||"").toUpperCase();a(c.getAttribute("data-ajax-update")).each(function(e,c){switch(d){case"BEFORE":a(c).prepend(b);break;case"AFTER":a(c).append(b);break;case"REPLACE-WITH":a(c).replaceWith(b);break;default:a(c).html(b)}})}function f(b,d){var j,k,f,h;j=b.getAttribute("data-ajax-confirm");if(j&&!window.confirm(j))return;k=a(b.getAttribute("data-ajax-loading"));h=parseInt(b.getAttribute("data-ajax-loading-duration"),10)||0;a.extend(d,{type:b.getAttribute("data-ajax-method")||undefined,url:b.getAttribute("data-ajax-url")||undefined,cache:!!b.getAttribute("data-ajax-cache"),beforeSend:function(d){var a;g(d,f);a=c(b.getAttribute("data-ajax-begin"),["xhr"]).apply(b,arguments);a!==false&&k.show(h);return a},complete:function(){k.hide(h);c(b.getAttribute("data-ajax-complete"),["xhr","status"]).apply(b,arguments)},success:function(a,e,d){i(b,a,d.getResponseHeader("Content-Type")||"text/html");c(b.getAttribute("data-ajax-success"),["data","status","xhr"]).apply(b,arguments)},error:function(){c(b.getAttribute("data-ajax-failure"),["xhr","status","error"]).apply(b,arguments)}});d.data.push({name:"X-Requested-With",value:"XMLHttpRequest"});f=d.type.toUpperCase();if(!e(f)){d.type="POST";d.data.push({name:"X-HTTP-Method-Override",value:f})}a.ajax(d)}function j(c){var b=a(c).data(h);return!b||!b.validate||b.validate()}a(document).on("click","a[data-ajax=true]",function(a){a.preventDefault();f(this,{url:this.href,type:"GET",data:[]})});a(document).on("click","form[data-ajax=true] input[type=image]",function(c){var g=c.target.name,e=a(c.target),f=a(e.parents("form")[0]),d=e.offset();f.data(b,[{name:g+".x",value:Math.round(c.pageX-d.left)},{name:g+".y",value:Math.round(c.pageY-d.top)}]);setTimeout(function(){f.removeData(b)},0)});a(document).on("click","form[data-ajax=true] :submit",function(e){var g=e.currentTarget.name,f=a(e.target),c=a(f.parents("form")[0]);c.data(b,g?[{name:g,value:e.currentTarget.value}]:[]);c.data(d,f);setTimeout(function(){c.removeData(b);c.removeData(d)},0)});a(document).on("submit","form[data-ajax=true]",function(h){var e=a(this).data(b)||[],c=a(this).data(d),g=c&&c.hasClass("cancel");h.preventDefault();if(!g&&!j(this))return;f(this,{url:this.action,type:this.method||"GET",data:e.concat(a(this).serializeArray())})})})(jQuery);

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

@ -4,7 +4,7 @@
* intended to be used only for design-time IntelliSense. Please use the
* standard jQuery library for all production use.
*
* Comment version: 1.16.0
* Comment version: 1.17.0
*/
/*
@ -15,7 +15,7 @@
* for informational purposes only and are not the license terms under
* which Microsoft distributed this file.
*
* jQuery Validation Plugin - v1.16.0 - 12/5/2016
* jQuery Validation Plugin - v1.17.0 - 12/5/2016
* https://github.com/jzaefferer/jquery-validation
* Copyright (c) 2013 Jörn Zaefferer; Licensed MIT
*

151
src/Explorer/Scripts/jquery.validate.js поставляемый
Просмотреть файл

@ -1,9 +1,9 @@
/*!
* jQuery Validation Plugin v1.16.0
* jQuery Validation Plugin v1.17.0
*
* http://jqueryvalidation.org/
* https://jqueryvalidation.org/
*
* Copyright (c) 2016 Jörn Zaefferer
* Copyright (c) 2017 Jörn Zaefferer
* Released under the MIT license
*/
(function( factory ) {
@ -18,7 +18,7 @@
$.extend( $.fn, {
// http://jqueryvalidation.org/validate/
// https://jqueryvalidation.org/validate/
validate: function( options ) {
// If nothing is selected, return nothing; can't chain anyway
@ -44,9 +44,10 @@ $.extend( $.fn, {
if ( validator.settings.onsubmit ) {
this.on( "click.validate", ":submit", function( event ) {
if ( validator.settings.submitHandler ) {
validator.submitButton = event.target;
}
// Track the used submit button to properly handle scripted
// submits later.
validator.submitButton = event.currentTarget;
// Allow suppressing validation by adding a cancel class to the submit button
if ( $( this ).hasClass( "cancel" ) ) {
@ -68,17 +69,22 @@ $.extend( $.fn, {
}
function handle() {
var hidden, result;
if ( validator.settings.submitHandler ) {
if ( validator.submitButton ) {
// Insert a hidden input as a replacement for the missing submit button
hidden = $( "<input type='hidden'/>" )
.attr( "name", validator.submitButton.name )
.val( $( validator.submitButton ).val() )
.appendTo( validator.currentForm );
}
// Insert a hidden input as a replacement for the missing submit button
// The hidden input is inserted in two cases:
// - A user defined a `submitHandler`
// - There was a pending request due to `remote` method and `stopRequest()`
// was called to submit the form in case it's valid
if ( validator.submitButton && ( validator.settings.submitHandler || validator.formSubmitted ) ) {
hidden = $( "<input type='hidden'/>" )
.attr( "name", validator.submitButton.name )
.val( $( validator.submitButton ).val() )
.appendTo( validator.currentForm );
}
if ( validator.settings.submitHandler ) {
result = validator.settings.submitHandler.call( validator, validator.currentForm, event );
if ( validator.submitButton ) {
if ( hidden ) {
// And clean up afterwards; thanks to no-block-scope, hidden can be referenced
hidden.remove();
@ -112,7 +118,7 @@ $.extend( $.fn, {
return validator;
},
// http://jqueryvalidation.org/valid/
// https://jqueryvalidation.org/valid/
valid: function() {
var valid, validator, errorList;
@ -133,13 +139,22 @@ $.extend( $.fn, {
return valid;
},
// http://jqueryvalidation.org/rules/
// https://jqueryvalidation.org/rules/
rules: function( command, argument ) {
var element = this[ 0 ],
settings, staticRules, existingRules, data, param, filtered;
// If nothing is selected, return empty object; can't chain anyway
if ( element == null || element.form == null ) {
if ( element == null ) {
return;
}
if ( !element.form && element.hasAttribute( "contenteditable" ) ) {
element.form = this.closest( "form" )[ 0 ];
element.name = this.attr( "name" );
}
if ( element.form == null ) {
return;
}
@ -167,9 +182,6 @@ $.extend( $.fn, {
$.each( argument.split( /\s/ ), function( index, method ) {
filtered[ method ] = existingRules[ method ];
delete existingRules[ method ];
if ( method === "required" ) {
$( element ).removeAttr( "aria-required" );
}
} );
return filtered;
}
@ -189,7 +201,6 @@ $.extend( $.fn, {
param = data.required;
delete data.required;
data = $.extend( { required: param }, data );
$( element ).attr( "aria-required", "true" );
}
// Make sure remote is at back
@ -206,18 +217,18 @@ $.extend( $.fn, {
// Custom selectors
$.extend( $.expr.pseudos || $.expr[ ":" ], { // '|| $.expr[ ":" ]' here enables backwards compatibility to jQuery 1.7. Can be removed when dropping jQ 1.7.x support
// http://jqueryvalidation.org/blank-selector/
// https://jqueryvalidation.org/blank-selector/
blank: function( a ) {
return !$.trim( "" + $( a ).val() );
},
// http://jqueryvalidation.org/filled-selector/
// https://jqueryvalidation.org/filled-selector/
filled: function( a ) {
var val = $( a ).val();
return val !== null && !!$.trim( "" + val );
},
// http://jqueryvalidation.org/unchecked-selector/
// https://jqueryvalidation.org/unchecked-selector/
unchecked: function( a ) {
return !$( a ).prop( "checked" );
}
@ -230,7 +241,7 @@ $.validator = function( options, form ) {
this.init();
};
// http://jqueryvalidation.org/jQuery.validator.format/
// https://jqueryvalidation.org/jQuery.validator.format/
$.validator.format = function( source, params ) {
if ( arguments.length === 1 ) {
return function() {
@ -343,7 +354,7 @@ $.extend( $.validator, {
}
},
// http://jqueryvalidation.org/jQuery.validator.setDefaults/
// https://jqueryvalidation.org/jQuery.validator.setDefaults/
setDefaults: function( settings ) {
$.extend( $.validator.defaults, settings );
},
@ -402,6 +413,7 @@ $.extend( $.validator, {
// Set form expando on contenteditable
if ( !this.form && this.hasAttribute( "contenteditable" ) ) {
this.form = $( this ).closest( "form" )[ 0 ];
this.name = $( this ).attr( "name" );
}
var validator = $.data( this.form, "validator" ),
@ -426,13 +438,9 @@ $.extend( $.validator, {
if ( this.settings.invalidHandler ) {
$( this.currentForm ).on( "invalid-form.validate", this.settings.invalidHandler );
}
// Add aria-required to any Static/Data/Class required fields before first validation
// Screen readers require this attribute to be present before the initial submission http://www.w3.org/TR/WCAG-TECHS/ARIA2.html
$( this.currentForm ).find( "[required], [data-rule-required], .required" ).attr( "aria-required", "true" );
},
// http://jqueryvalidation.org/Validator.form/
// https://jqueryvalidation.org/Validator.form/
form: function() {
this.checkForm();
$.extend( this.submitted, this.errorMap );
@ -452,7 +460,7 @@ $.extend( $.validator, {
return this.valid();
},
// http://jqueryvalidation.org/Validator.element/
// https://jqueryvalidation.org/Validator.element/
element: function( element ) {
var cleanElement = this.clean( element ),
checkElement = this.validationTargetFor( cleanElement ),
@ -503,7 +511,7 @@ $.extend( $.validator, {
return result;
},
// http://jqueryvalidation.org/Validator.showErrors/
// https://jqueryvalidation.org/Validator.showErrors/
showErrors: function( errors ) {
if ( errors ) {
var validator = this;
@ -529,7 +537,7 @@ $.extend( $.validator, {
}
},
// http://jqueryvalidation.org/Validator.resetForm/
// https://jqueryvalidation.org/Validator.resetForm/
resetForm: function() {
if ( $.fn.resetForm ) {
$( this.currentForm ).resetForm();
@ -570,7 +578,10 @@ $.extend( $.validator, {
var count = 0,
i;
for ( i in obj ) {
if ( obj[ i ] ) {
// This check allows counting elements with empty error
// message as invalid elements
if ( obj[ i ] !== undefined && obj[ i ] !== null && obj[ i ] !== false ) {
count++;
}
}
@ -635,6 +646,7 @@ $.extend( $.validator, {
// Set form expando on contenteditable
if ( this.hasAttribute( "contenteditable" ) ) {
this.form = $( this ).closest( "form" )[ 0 ];
this.name = name;
}
// Select only the first element for each name, and only those with rules specified
@ -735,21 +747,27 @@ $.extend( $.validator, {
} ).length,
dependencyMismatch = false,
val = this.elementValue( element ),
result, method, rule;
result, method, rule, normalizer;
// If a normalizer is defined for this element, then
// call it to retreive the changed value instead
// Prioritize the local normalizer defined for this element over the global one
// if the former exists, otherwise user the global one in case it exists.
if ( typeof rules.normalizer === "function" ) {
normalizer = rules.normalizer;
} else if ( typeof this.settings.normalizer === "function" ) {
normalizer = this.settings.normalizer;
}
// If normalizer is defined, then call it to retreive the changed value instead
// of using the real one.
// Note that `this` in the normalizer is `element`.
if ( typeof rules.normalizer === "function" ) {
val = rules.normalizer.call( element, val );
if ( normalizer ) {
val = normalizer.call( element, val );
if ( typeof val !== "string" ) {
throw new TypeError( "The normalizer should return a string value." );
}
// Delete the normalizer from rules to avoid treating
// it as a pre-defined method.
// Delete the normalizer from rules to avoid treating it as a pre-defined method.
delete rules.normalizer;
}
@ -1089,6 +1107,15 @@ $.extend( $.validator, {
$( element ).removeClass( this.settings.pendingClass );
if ( valid && this.pendingRequest === 0 && this.formSubmitted && this.form() ) {
$( this.currentForm ).submit();
// Remove the hidden input that was used as a replacement for the
// missing submit button. The hidden input is added by `handle()`
// to ensure that the value of the used submit button is passed on
// for scripted submits triggered by this method
if ( this.submitButton ) {
$( "input:hidden[name='" + this.submitButton.name + "']", this.currentForm ).remove();
}
this.formSubmitted = false;
} else if ( !valid && this.pendingRequest === 0 && this.formSubmitted ) {
$( this.currentForm ).triggerHandler( "invalid-form", [ this ] );
@ -1316,7 +1343,7 @@ $.extend( $.validator, {
return data;
},
// http://jqueryvalidation.org/jQuery.validator.addMethod/
// https://jqueryvalidation.org/jQuery.validator.addMethod/
addMethod: function( name, method, message ) {
$.validator.methods[ name ] = method;
$.validator.messages[ name ] = message !== undefined ? message : $.validator.messages[ name ];
@ -1325,10 +1352,10 @@ $.extend( $.validator, {
}
},
// http://jqueryvalidation.org/jQuery.validator.methods/
// https://jqueryvalidation.org/jQuery.validator.methods/
methods: {
// http://jqueryvalidation.org/required-method/
// https://jqueryvalidation.org/required-method/
required: function( value, element, param ) {
// Check if dependency is met
@ -1347,7 +1374,7 @@ $.extend( $.validator, {
return value.length > 0;
},
// http://jqueryvalidation.org/email-method/
// https://jqueryvalidation.org/email-method/
email: function( value, element ) {
// From https://html.spec.whatwg.org/multipage/forms.html#valid-e-mail-address
@ -1357,7 +1384,7 @@ $.extend( $.validator, {
return this.optional( element ) || /^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/.test( value );
},
// http://jqueryvalidation.org/url-method/
// https://jqueryvalidation.org/url-method/
url: function( value, element ) {
// Copyright (c) 2010-2013 Diego Perini, MIT licensed
@ -1367,60 +1394,60 @@ $.extend( $.validator, {
return this.optional( element ) || /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test( value );
},
// http://jqueryvalidation.org/date-method/
// https://jqueryvalidation.org/date-method/
date: function( value, element ) {
return this.optional( element ) || !/Invalid|NaN/.test( new Date( value ).toString() );
},
// http://jqueryvalidation.org/dateISO-method/
// https://jqueryvalidation.org/dateISO-method/
dateISO: function( value, element ) {
return this.optional( element ) || /^\d{4}[\/\-](0?[1-9]|1[012])[\/\-](0?[1-9]|[12][0-9]|3[01])$/.test( value );
},
// http://jqueryvalidation.org/number-method/
// https://jqueryvalidation.org/number-method/
number: function( value, element ) {
return this.optional( element ) || /^(?:-?\d+|-?\d{1,3}(?:,\d{3})+)?(?:\.\d+)?$/.test( value );
},
// http://jqueryvalidation.org/digits-method/
// https://jqueryvalidation.org/digits-method/
digits: function( value, element ) {
return this.optional( element ) || /^\d+$/.test( value );
},
// http://jqueryvalidation.org/minlength-method/
// https://jqueryvalidation.org/minlength-method/
minlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || length >= param;
},
// http://jqueryvalidation.org/maxlength-method/
// https://jqueryvalidation.org/maxlength-method/
maxlength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || length <= param;
},
// http://jqueryvalidation.org/rangelength-method/
// https://jqueryvalidation.org/rangelength-method/
rangelength: function( value, element, param ) {
var length = $.isArray( value ) ? value.length : this.getLength( value, element );
return this.optional( element ) || ( length >= param[ 0 ] && length <= param[ 1 ] );
},
// http://jqueryvalidation.org/min-method/
// https://jqueryvalidation.org/min-method/
min: function( value, element, param ) {
return this.optional( element ) || value >= param;
},
// http://jqueryvalidation.org/max-method/
// https://jqueryvalidation.org/max-method/
max: function( value, element, param ) {
return this.optional( element ) || value <= param;
},
// http://jqueryvalidation.org/range-method/
// https://jqueryvalidation.org/range-method/
range: function( value, element, param ) {
return this.optional( element ) || ( value >= param[ 0 ] && value <= param[ 1 ] );
},
// http://jqueryvalidation.org/step-method/
// https://jqueryvalidation.org/step-method/
step: function( value, element, param ) {
var type = $( element ).attr( "type" ),
errorMessage = "Step attribute on input type " + type + " is not supported.",
@ -1458,7 +1485,7 @@ $.extend( $.validator, {
return this.optional( element ) || valid;
},
// http://jqueryvalidation.org/equalTo-method/
// https://jqueryvalidation.org/equalTo-method/
equalTo: function( value, element, param ) {
// Bind to the blur event of the target in order to revalidate whenever the target field is updated
@ -1471,7 +1498,7 @@ $.extend( $.validator, {
return value === target.val();
},
// http://jqueryvalidation.org/remote-method/
// https://jqueryvalidation.org/remote-method/
remote: function( value, element, param, method ) {
if ( this.optional( element ) ) {
return "dependency-mismatch";

8
src/Explorer/Scripts/jquery.validate.min.js поставляемый

Различия файлов скрыты, потому что одна или несколько строк слишком длинны

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

@ -1,3 +1,17 @@
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole
* purpose of either: (i) interacting through your browser with the Microsoft
* website or online service, subject to the applicable licensing or use
* terms; or (ii) using the files as included with a Microsoft product subject
* to that product's license terms. Microsoft reserves all other rights to the
* files not expressly granted by Microsoft, whether by implication, estoppel
* or otherwise. Insofar as a script file is dual licensed under GPL,
* Microsoft neither took the code under GPL nor distributes it thereunder but
* under the terms set out in this paragraph. All notices and licenses
* below are for informational purposes only.
*
* NUGET: END LICENSE TEXT */
/* NUGET: BEGIN LICENSE TEXT
*
* Microsoft grants you the right to use these script files for the sole

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

@ -0,0 +1,83 @@
// -----------------------------------------------------------------------
// <copyright file="AuthenticationProvider.cs" company="Microsoft">
// Copyright (c) Microsoft Corporation. All rights reserved.
// </copyright>
// -----------------------------------------------------------------------
namespace Microsoft.Store.PartnerCenter.Explorer.Security
{
using System.Net.Http;
using System.Threading.Tasks;
using Graph;
using IdentityModel.Clients.ActiveDirectory;
using Logic;
using Models;
using Providers;
/// <summary>
/// Authentication provider for the Microsoft Graph service client.
/// </summary>
/// <seealso cref="IAuthenticationProvider" />
public class AuthenticationProvider : IAuthenticationProvider
{
/// <summary>
/// Name of the authentication header to be utilized.
/// </summary>
private const string AuthHeaderName = "Authorization";
/// <summary>
/// The type of token being utilized for the authentication request.
/// </summary>
private const string TokenType = "Bearer";
/// <summary>
/// Provides access to core services.
/// </summary>
private readonly IExplorerProvider provider;
/// <summary>
/// The customer identifier utilized to scope the Microsoft Graph requests.
/// </summary>
private readonly string customerId;
/// <summary>
/// Initializes a new instance of the <see cref="AuthenticationProvider"/> class.
/// </summary>
/// <param name="provider">Provides access to core services.</param>
/// <param name="customerId">Identifier for customer whose resources are being accessed.</param>
/// <exception cref="System.ArgumentException">
/// <paramref name="customerId"/> is empty or null.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="provider"/> is null.
/// </exception>
public AuthenticationProvider(IExplorerProvider provider, string customerId)
{
provider.AssertNotNull(nameof(provider));
customerId.AssertNotEmpty(nameof(customerId));
this.customerId = customerId;
this.provider = provider;
}
/// <summary>
/// Performs the necessary authentication and injects the required header.
/// </summary>
/// <param name="request">The request being made to the Microsoft Graph API.</param>
/// <returns>A <see cref="Task"/> that represents the asynchronous operation.</returns>
public async Task AuthenticateRequestAsync(HttpRequestMessage request)
{
AuthenticationResult token = await provider.AccessToken.GetAccessTokenAsync(
$"{provider.Configuration.ActiveDirectoryEndpoint}/{customerId}",
provider.Configuration.GraphEndpoint,
new ApplicationCredential
{
ApplicationId = provider.Configuration.ApplicationId,
ApplicationSecret = provider.Configuration.ApplicationSecret,
UseCache = true
}).ConfigureAwait(false);
request.Headers.Add(AuthHeaderName, $"{TokenType} {token.AccessToken}");
}
}
}

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

@ -19,7 +19,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer
/// <param name="app">The application.</param>
public void Configuration(IAppBuilder app)
{
this.ConfigureAuth(app);
ConfigureAuth(app);
}
}
}

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

@ -1,5 +1,5 @@
@model Microsoft.Store.PartnerCenter.Explorer.Models.ConfigurationRecordsModel
@using Microsoft.Samples.AzureAD.Graph.API.Models;
@using Microsoft.Graph
<table class="table table-striped">
<thead>
@ -11,7 +11,7 @@
<th>Service</th>
</tr>
</thead>
@foreach (ServiceConfigurationRecord record in Model.ServiceConfigurationRecords)
@foreach (DomainDnsRecord record in Model.ServiceConfigurationRecords)
{
<tr>
<td>

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

@ -26,6 +26,9 @@
</select>
</div>
</div>
<div class="row">
<div id="records" style="display: none;"></div>
</div>
<h4>Users</h4>
<hr />
<div class="row">
@ -53,6 +56,11 @@
});
var domain = $('#ddlDomains').find(":selected").text();
$.get('/Customers/@Model.CustomerId/Domains/' + domain + '/ConfigurationRecords', function (data) {
$('#records').html(data);
$('#records').fadeIn('fast');
});
}
});

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

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0">
@ -47,7 +47,7 @@
<span class="icon fa fa-unlock-alt"></span><span class="title">Audit Log</span>
</a>
</li>
@if (controller == "Customers" || controller == "Manage" || controller == "Subscriptions" || controller == "Usage")
@if (controller == "Customers" || controller == "Health" || controller == "Manage" || controller == "Subscriptions" || controller == "Usage")
{
className = "active";
}
@ -88,34 +88,13 @@
@RenderSection("scripts", required: false)
<script type="text/javascript" src="~/Scripts/application.js"></script>
<script type="text/javascript">
var appInsights = window.appInsights ||
function (config) {
function r(config) {
t[config] = function () {
var i = arguments;
t.queue.push(function () { t[config].apply(t, i) })
}
}
var appInsights = window.appInsights || function (a) {
function b(a) { c[a] = function () { var b = arguments; c.queue.push(function () { c[a].apply(c, b) }) } } var c = { config: a }, d = document, e = window; setTimeout(function () { var b = d.createElement("script"); b.src = a.url || "https://az416426.vo.msecnd.net/scripts/a/ai.0.js", d.getElementsByTagName("script")[0].parentNode.appendChild(b) }); try { c.cookie = d.cookie } catch (a) { } c.queue = []; for (var f = ["Event", "Exception", "Metric", "PageView", "Trace", "Dependency"]; f.length;)b("track" + f.pop()); if (b("setAuthenticatedUserContext"), b("clearAuthenticatedUserContext"), b("startTrackEvent"), b("stopTrackEvent"), b("startTrackPage"), b("stopTrackPage"), b("flush"), !a.disableExceptionTracking) { f = "onerror", b("_" + f); var g = e[f]; e[f] = function (a, b, d, e, h) { var i = g && g(a, b, d, e, h); return !0 !== i && c["_" + f](a, b, d, e, h), i } } return c
}({
instrumentationKey: "@Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey"
});
var t = { config: config }, u = document, e = window, o = "script", s = u.createElement(o), i, f;
for (s.src = config.url || "//az416426.vo.msecnd.net/scripts/a/ai.0.js", u.getElementsByTagName(o)[0]
.parentNode.appendChild(s), t.cookie = u
.cookie, t.queue = [], i = ["Event", "Exception", "Metric", "PageView", "Trace"];
i.length;
) r("track" + i.pop());
return r("setAuthenticatedUserContext"), r("clearAuthenticatedUserContext"),
config.disableExceptionTracking ||
(i = "onerror", r("_" + i), f = e[i], e[i] = function (config, r, u, e, o) {
var s = f && f(config, r, u, e, o);
return s !== !0 && t["_" + i](config, r, u, e, o), s
}), t
}({
instrumentationKey:
"@Microsoft.ApplicationInsights.Extensibility.TelemetryConfiguration.Active.InstrumentationKey"
});
window.appInsights = appInsights;
appInsights.trackPageView();
window.appInsights = appInsights, appInsights.queue && 0 === appInsights.queue.length && appInsights.trackPageView();
</script>
</body>
</html>

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

@ -8,17 +8,22 @@
<!-- AAD endpoint used during authentication requests -->
<add key="ActiveDirectoryEndpoint" value="https://login.microsoftonline.com" />
<!-- ARM API endpoint address utilized by the application -->
<add key="AzureResourceManagerEndpoint" value="https://management.azure.com/" />
<!-- Azure Active Directory Graph endpoint address utilized by the application -->
<add key="GraphEndpoint" value="https://graph.windows.net/" />
<add key="GraphEndpoint" value="https://graph.microsoft.com/" />
<!-- Office 365 Management API endpoint address utilized by the application -->
<add key="OfficeManagementEndpoint" value="https://manage.office.com" />
<!-- Partner Center API endpoint address utilized by the application -->
<add key="PartnerCenterEndpoint" value="https://api.partnercenter.microsoft.com" />
<!-- Specify the Explorer AAD application ID here -->
<add key="ApplicationId" value="" />
<!-- Specify the Explorer AAD application tenant here -->
<add key="ApplicationTenantId" value="" />
@ -30,6 +35,7 @@
<!-- Specify the Partner Center AAD application ID here -->
<add key="PartnerCenterApplicationId" value="" />
<!-- Specify the partner AAD tenant identifier here -->
<add key="PartnerCenterApplicationTenantId" value="" />
@ -68,6 +74,12 @@
<mimeMap fileExtension="woff2" mimeType="application/font-woff" />
</staticContent>
</system.webServer>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
@ -78,21 +90,21 @@
<assemblyIdentity name="System.Web.WebPages" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-3.0.0.0" newVersion="3.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="1.0.0.0-5.2.3.0" newVersion="5.2.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.2" newVersion="4.1.1.2" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.17.2.31801" newVersion="3.17.2.31801" />
<bindingRedirect oldVersion="0.0.0.0-3.19.1.3001" newVersion="3.19.1.3001" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Clients.ActiveDirectory.Platform" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.17.2.31801" newVersion="3.17.2.31801" />
<bindingRedirect oldVersion="0.0.0.0-3.19.1.3001" newVersion="3.19.1.3001" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IO.Compression" publicKeyToken="b77a5c561934e089" culture="neutral" />
@ -104,27 +116,23 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.ApplicationInsights" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-2.4.0.0" newVersion="2.4.0.0" />
<bindingRedirect oldVersion="0.0.0.0-2.5.1.0" newVersion="2.5.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Owin.Security" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.IdentityModel.Tokens.Jwt" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.40306.1554" newVersion="4.0.40306.1554" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocol.Extensions" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.0.40306.1554" newVersion="1.0.40306.1554" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Services.Client" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.Edm" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.Data.OData" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.8.3.0" newVersion="5.8.3.0" />
<assemblyIdentity name="Unity.Abstractions" publicKeyToken="6d32ff45e0ccc69f" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.2.0.0" newVersion="3.2.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Antlr3.Runtime" publicKeyToken="eb42632606e9261f" culture="neutral" />
@ -132,18 +140,28 @@
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-6.0.0.0" newVersion="6.0.0.0" />
<bindingRedirect oldVersion="0.0.0.0-10.0.0.0" newVersion="10.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="WebGrease" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-1.6.5135.21930" newVersion="1.6.5135.21930" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols.OpenIdConnect" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Tokens" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Microsoft.IdentityModel.Protocols" publicKeyToken="31bf3856ad364e35" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.2.1.0" newVersion="5.2.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Web.Mvc" publicKeyToken="31bf3856ad364e35" />
<bindingRedirect oldVersion="0.0.0.0-5.2.4.0" newVersion="5.2.4.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
<system.codedom>
<compilers>
<compiler language="c#;cs;csharp" extension=".cs" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:1659;1699;1701" />
<compiler language="vb;vbs;visualbasic;vbscript" extension=".vb" type="Microsoft.CodeDom.Providers.DotNetCompilerPlatform.VBCodeProvider, Microsoft.CodeDom.Providers.DotNetCompilerPlatform, Version=1.0.8.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" warningLevel="4" compilerOptions="/langversion:default /nowarn:41008 /define:_MYTYPE=\&quot;Web\&quot; /optionInfer+" />
</compilers>
</system.codedom>
</configuration>

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

@ -2,28 +2,25 @@
<packages>
<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.1.0" targetFramework="net461" />
<package id="CsvHelper" version="7.0.1" targetFramework="net461" />
<package id="FontAwesome" version="4.7.0" targetFramework="net461" />
<package id="jQuery" version="3.2.1" targetFramework="net461" />
<package id="jQuery" version="3.3.1" targetFramework="net461" />
<package id="jQuery.UI.Combined" version="1.12.1" targetFramework="net461" />
<package id="jQuery.Validation" version="1.16.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights" version="2.4.0" targetFramework="net461" />
<package id="jQuery.Validation" version="1.17.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.Agent.Intercept" version="2.4.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.4.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.DependencyCollector" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.JavaScript" version="0.22.9-build00167" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.4.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.SnapshotCollector" version="1.1.0" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.Web" version="2.4.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.4.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.4.0" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="5.2.3" targetFramework="net461" />
<package id="Microsoft.AspNet.Razor" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.PerfCounterCollector" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.SnapshotCollector" version="1.1.2" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.Web" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.ApplicationInsights.WindowsServer.TelemetryChannel" version="2.5.1" targetFramework="net461" />
<package id="Microsoft.AspNet.Mvc" version="5.2.4" targetFramework="net461" />
<package id="Microsoft.AspNet.Razor" version="3.2.4" targetFramework="net461" />
<package id="Microsoft.AspNet.TelemetryCorrelation" version="1.0.0" targetFramework="net461" />
<package id="Microsoft.AspNet.Web.Optimization" version="1.1.3" targetFramework="net461" />
<package id="Microsoft.AspNet.WebPages" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.Azure.ActiveDirectory.GraphClient" version="2.1.1" targetFramework="net461" />
<package id="Microsoft.Azure.Insights" version="0.15.0-preview" targetFramework="net461" />
<package id="Microsoft.AspNet.WebPages" version="3.2.4" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault" version="2.3.2" targetFramework="net461" />
<package id="Microsoft.Azure.KeyVault.WebKey" version="2.0.7" targetFramework="net461" />
<package id="Microsoft.Azure.Management.ResourceManager" version="1.6.0-preview" targetFramework="net461" />
@ -35,29 +32,35 @@
<package id="Microsoft.Data.Edm" version="5.8.3" targetFramework="net461" />
<package id="Microsoft.Data.OData" version="5.8.3" targetFramework="net461" />
<package id="Microsoft.Data.Services.Client" version="5.8.3" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.17.2" targetFramework="net461" />
<package id="Microsoft.Graph" version="1.7.0" targetFramework="net461" />
<package id="Microsoft.Graph.Core" version="1.7.0" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Clients.ActiveDirectory" version="3.19.1" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Logging" version="5.2.1" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Protocol.Extensions" version="1.0.4.403061554" targetFramework="net461" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.3" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Protocols" version="5.2.1" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Protocols.OpenIdConnect" version="5.2.1" targetFramework="net461" />
<package id="Microsoft.IdentityModel.Tokens" version="5.2.1" targetFramework="net461" />
<package id="Microsoft.jQuery.Unobtrusive.Ajax" version="3.2.4" targetFramework="net461" />
<package id="Microsoft.jQuery.Unobtrusive.Validation" version="3.2.4" targetFramework="net461" />
<package id="Microsoft.Net.Compilers" version="2.6.1" targetFramework="net461" developmentDependency="true" />
<package id="Microsoft.Net.Http" version="2.2.29" targetFramework="net461" />
<package id="Microsoft.Owin" version="3.1.0" targetFramework="net461" />
<package id="Microsoft.Owin.Host.SystemWeb" version="3.1.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security" version="3.1.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.Cookies" version="3.1.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="3.1.0" targetFramework="net461" />
<package id="Microsoft.Owin" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Host.SystemWeb" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.Cookies" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Owin.Security.OpenIdConnect" version="4.0.0" targetFramework="net461" />
<package id="Microsoft.Rest.ClientRuntime" version="2.3.10" targetFramework="net461" />
<package id="Microsoft.Rest.ClientRuntime.Azure" version="3.3.10" targetFramework="net461" />
<package id="Microsoft.Store.PartnerCenter" version="1.6.0" targetFramework="net461" />
<package id="Microsoft.Store.PartnerCenter" version="1.7.0" targetFramework="net461" />
<package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net461" />
<package id="Newtonsoft.Json" version="6.0.8" targetFramework="net461" />
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net461" />
<package id="Owin" version="1.0" targetFramework="net461" />
<package id="Respond" version="1.4.2" targetFramework="net461" />
<package id="StackExchange.Redis.StrongName" version="1.2.6" targetFramework="net461" />
<package id="System.ComponentModel.EventBasedAsync" version="4.3.0" targetFramework="net461" />
<package id="System.Diagnostics.DiagnosticSource" version="4.4.1" targetFramework="net461" />
<package id="System.Dynamic.Runtime" version="4.3.0" targetFramework="net461" />
<package id="System.IdentityModel.Tokens.Jwt" version="4.0.4.403061554" targetFramework="net461" />
<package id="System.IdentityModel.Tokens.Jwt" version="5.2.1" targetFramework="net461" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net461" />
<package id="System.Linq.Queryable" version="4.3.0" targetFramework="net461" />
<package id="System.Net.Http" version="4.3.3" targetFramework="net461" />
@ -68,10 +71,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.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="Unity" version="5.6.1" targetFramework="net461" />
<package id="Unity.Abstractions" version="3.2.0" targetFramework="net461" />
<package id="Unity.Container" version="5.6.1" targetFramework="net461" />
<package id="Unity.Mvc" version="5.0.12" targetFramework="net461" />
<package id="WebActivatorEx" version="2.2.0" targetFramework="net461" />
<package id="WebGrease" version="1.6.0" targetFramework="net461" />
</packages>