Merge pull request #7 from isaiahwilliams/dev
Corrected authentication issue with creating and deleting users.
This commit is contained in:
Коммит
36e54da4a9
|
@ -167,7 +167,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
|
|||
token = await GetAccessTokenAsync(
|
||||
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{model.CustomerId}").ConfigureAwait(false);
|
||||
|
||||
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
|
||||
using (AzureManagement manager = new AzureManagement(Provider, token.AccessToken))
|
||||
{
|
||||
await manager.ApplyTemplateAsync(
|
||||
model.SubscriptionId,
|
||||
|
@ -215,7 +215,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
|
|||
token = await GetAccessTokenAsync(
|
||||
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
|
||||
|
||||
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
|
||||
using (AzureManagement manager = new AzureManagement(Provider, token.AccessToken))
|
||||
{
|
||||
groups = await manager.GetResourceGroupsAsync(subscriptionId).ConfigureAwait(false);
|
||||
return Json(groups, JsonRequestBehavior.AllowGet);
|
||||
|
@ -249,7 +249,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Controllers
|
|||
token = await GetAccessTokenAsync(
|
||||
$"{Provider.Configuration.ActiveDirectoryEndpoint}/{customerId}").ConfigureAwait(false);
|
||||
|
||||
using (ResourceManager manager = new ResourceManager(Provider, token.AccessToken))
|
||||
using (AzureManagement manager = new AzureManagement(Provider, token.AccessToken))
|
||||
{
|
||||
deployments = await manager.GetDeploymentsAsync(subscriptionId, resourceGroupName).ConfigureAwait(false);
|
||||
|
||||
|
|
|
@ -312,6 +312,7 @@
|
|||
<Compile Include="App_Start\UnityConfig.cs" />
|
||||
<Compile Include="App_Start\UnityMvcActivator.cs" />
|
||||
<Compile Include="Controllers\OfferController.cs" />
|
||||
<Compile Include="GlobalSuppressions.cs" />
|
||||
<Compile Include="Logic\IPartnerOperations.cs" />
|
||||
<Compile Include="Logic\PartnerOperations.cs" />
|
||||
<Compile Include="Logic\TelemetryHandleErrorAttribute.cs" />
|
||||
|
@ -382,7 +383,7 @@
|
|||
</Compile>
|
||||
<Compile Include="Logic\Azure\AzureHealthEvent.cs" />
|
||||
<Compile Include="Logic\Azure\IncidentEvent.cs" />
|
||||
<Compile Include="Logic\Azure\ResourceManager.cs" />
|
||||
<Compile Include="Logic\Azure\AzureManagement.cs" />
|
||||
<Compile Include="Logic\HttpService.cs" />
|
||||
<Compile Include="Logic\CommunicationException.cs" />
|
||||
<Compile Include="Logic\Extensions.cs" />
|
||||
|
@ -477,6 +478,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" />
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
|
||||
// This file is used by Code Analysis to maintain SuppressMessage
|
||||
// attributes that are applied to this project.
|
||||
// Project-level suppressions either have no target or are given
|
||||
// a specific target and scoped to a namespace, type, member, etc.
|
||||
|
||||
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Naming", "CA1707:Identifiers should not contain underscores", Justification = "This is requred function name.", Scope = "member", Target = "~M:Microsoft.Store.PartnerCenter.Explorer.MvcApplication.Application_Start")]
|
||||
[assembly: System.Diagnostics.CodeAnalysis.SuppressMessage("Performance", "CA1822:Mark members as static", Justification = "This function is called externally.", Scope = "member", Target = "~M:Microsoft.Store.PartnerCenter.Explorer.MvcApplication.Application_Start")]
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
// -----------------------------------------------------------------------
|
||||
// <copyright file="ResourceManager.cs" company="Microsoft">
|
||||
// <copyright file="AzureManagement.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
// -----------------------------------------------------------------------
|
||||
|
@ -20,7 +20,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
|
|||
/// Facilitates interactions with the Azure Resource Manager API.
|
||||
/// </summary>
|
||||
/// <seealso cref="System.IDisposable" />
|
||||
public class ResourceManager : IDisposable
|
||||
public class AzureManagement : IDisposable
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides access to core services.
|
||||
|
@ -38,7 +38,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
|
|||
private bool disposed;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ResourceManager"/> class.
|
||||
/// Initializes a new instance of the <see cref="AzureManagement"/> class.
|
||||
/// </summary>
|
||||
/// <param name="provider">Provides access to core services.</param>
|
||||
/// <param name="token">A valid JSON Web Token (JWT).</param>
|
||||
|
@ -48,7 +48,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Azure
|
|||
/// <exception cref="ArgumentNullException">
|
||||
/// <paramref name="provider"/> is null.
|
||||
/// </exception>
|
||||
public ResourceManager(IExplorerProvider provider, string token)
|
||||
public AzureManagement(IExplorerProvider provider, string token)
|
||||
{
|
||||
provider.AssertNotNull(nameof(provider));
|
||||
token.AssertNotEmpty(nameof(token));
|
|
@ -9,6 +9,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net.Http;
|
||||
using System.Threading.Tasks;
|
||||
using Graph;
|
||||
using Models;
|
||||
|
@ -21,6 +22,11 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
/// <seealso cref="IGraphClient" />
|
||||
public class GraphClient : IGraphClient
|
||||
{
|
||||
/// <summary>
|
||||
/// Static instance of the <see cref="HttpProvider" /> class.
|
||||
/// </summary>
|
||||
private static HttpProvider httpProvider = new HttpProvider(new HttpClientHandler(), false);
|
||||
|
||||
/// <summary>
|
||||
/// Provides access to core services.
|
||||
/// </summary>
|
||||
|
@ -55,7 +61,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
this.customerId = customerId;
|
||||
this.provider = provider;
|
||||
|
||||
client = new GraphServiceClient(new AuthenticationProvider(this.provider, customerId));
|
||||
client = new GraphServiceClient(new AuthenticationProvider(this.provider, customerId), httpProvider);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -121,8 +127,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
if (customerId.Equals(provider.Configuration.PartnerCenterAccountId, StringComparison.InvariantCultureIgnoreCase))
|
||||
{
|
||||
groups = directoryGroups.CurrentPage.OfType<Group>().Where(
|
||||
g => g.DisplayName.Equals("AdminAgents", StringComparison.InvariantCultureIgnoreCase)
|
||||
|| g.DisplayName.Equals("HelpdeskAgents", StringComparison.InvariantCultureIgnoreCase)
|
||||
g => g.DisplayName.Equals("AdminAgents", StringComparison.InvariantCultureIgnoreCase)
|
||||
|| g.DisplayName.Equals("HelpdeskAgents", StringComparison.InvariantCultureIgnoreCase)
|
||||
|| g.DisplayName.Equals("SalesAgent", StringComparison.InvariantCultureIgnoreCase)).ToList();
|
||||
|
||||
if (groups.Count > 0)
|
||||
|
|
|
@ -48,12 +48,12 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
|
||||
try
|
||||
{
|
||||
using (HttpClient client = new HttpClient())
|
||||
using (HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, requestUri))
|
||||
{
|
||||
client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
|
||||
request.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
|
||||
|
||||
response = await client.GetAsync(requestUri).ConfigureAwait(false);
|
||||
response = await client.SendAsync(request).ConfigureAwait(false);
|
||||
|
||||
if (!response.IsSuccessStatusCode)
|
||||
{
|
||||
|
|
|
@ -13,8 +13,16 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
|
|||
/// Represents a result from the Service Communication API.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">Type return from the Service Communication API.</typeparam>
|
||||
internal class Result<T>
|
||||
public class Result<T>
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="Result{T}" /> class.
|
||||
/// </summary>
|
||||
public Result()
|
||||
{
|
||||
Value = new List<T>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the OData context.
|
||||
/// </summary>
|
||||
|
@ -24,6 +32,6 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic.Office
|
|||
/// <summary>
|
||||
/// Gets or sets the value returned from the API.
|
||||
/// </summary>
|
||||
public List<T> Value { get; set; }
|
||||
public List<T> Value { get; }
|
||||
}
|
||||
}
|
|
@ -294,7 +294,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
{
|
||||
executionTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
|
||||
|
||||
|
@ -420,7 +420,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Logic
|
|||
{
|
||||
startTime = DateTime.Now;
|
||||
correlationId = Guid.NewGuid();
|
||||
operations = await GetAppOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
operations = await GetUserOperationsAsync(correlationId).ConfigureAwait(false);
|
||||
|
||||
principal = new CustomerPrincipal(ClaimsPrincipal.Current);
|
||||
|
||||
|
|
|
@ -48,7 +48,8 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Models
|
|||
/// <summary>
|
||||
/// Gets the usage location.
|
||||
/// </summary>
|
||||
public string UsageLocation => "US";
|
||||
[Required]
|
||||
public string UsageLocation { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the name of the user principal.
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace Microsoft.Store.PartnerCenter.Explorer.Models
|
|||
/// Represents an access token used to access Partner Center.
|
||||
/// </summary>
|
||||
/// <seealso cref="IPartnerCredentials" />
|
||||
internal sealed class PartnerCenterToken : IPartnerCredentials
|
||||
public sealed class PartnerCenterToken : IPartnerCredentials
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the expiry time in UTC for the token.
|
||||
|
|
|
@ -10,78 +10,89 @@
|
|||
</div>
|
||||
@using (Ajax.BeginForm("Create", "Users", new AjaxOptions { HttpMethod = "POST", InsertionMode = InsertionMode.Replace, OnSuccess = "OnUserSuccessCallback", UpdateTargetId = "users" }))
|
||||
{
|
||||
<fieldset>
|
||||
<div class="row">
|
||||
|
||||
<fieldset>
|
||||
<div class="row">
|
||||
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => Model.DisplayName)
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => Model.DisplayName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => Model.DisplayName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => Model.DisplayName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => Model.DisplayName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => Model.FirstName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => Model.FirstName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.FirstName)
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => Model.DisplayName)
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.LastName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => item.LastName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.LastName)
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => Model.FirstName)
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.UserPrincipalName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => item.UserPrincipalName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.UserPrincipalName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => Model.FirstName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.Password)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.PasswordFor(item => item.Password, new { @class = "form-control", placeholder = "Password" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.Password)
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.FirstName)
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-offset-1">
|
||||
<button type="button" class="btn btn-default"
|
||||
data-dismiss="modal">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" id="approve-btn"
|
||||
class="btn btn-danger">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.LastName)
|
||||
</div>
|
||||
</fieldset>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => item.LastName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.LastName)
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.UserPrincipalName)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => item.UserPrincipalName, new { @class = "form-control" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.UserPrincipalName)
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.Password)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.PasswordFor(item => item.Password, new { @class = "form-control", placeholder = "Password" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.Password)
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-3 col-xs-offset-1">
|
||||
@Html.LabelFor(item => item.UsageLocation)
|
||||
</div>
|
||||
<div class="col-xs-5">
|
||||
@Html.TextBoxFor(item => item.UsageLocation, new { @class = "form-control", placeholder = "US" })
|
||||
</div>
|
||||
<div class="col-xs-3">
|
||||
@Html.ValidationMessageFor(item => item.UsageLocation)
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-offset-1">
|
||||
<button type="button" class="btn btn-default"
|
||||
data-dismiss="modal">
|
||||
Cancel
|
||||
</button>
|
||||
<button type="submit" id="approve-btn"
|
||||
class="btn btn-danger">
|
||||
Create
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
}
|
||||
|
||||
@Scripts.Render("~/bundles/jqueryval")
|
Загрузка…
Ссылка в новой задаче