Merge pull request #7 from isaiahwilliams/dev

Corrected authentication issue with creating and deleting users.
This commit is contained in:
Isaiah Williams 2018-07-07 09:17:02 -05:00 коммит произвёл GitHub
Родитель ce5ab9f60b 6dbaab5598
Коммит 36e54da4a9
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
11 изменённых файлов: 123 добавлений и 86 удалений

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

@ -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">
&nbsp;
<fieldset>
<div class="row">
&nbsp;
</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")