-
Notifications
You must be signed in to change notification settings - Fork 644
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
9ea3066
commit a1bc005
Showing
30 changed files
with
1,662 additions
and
95 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
src/NuGetGallery/Areas/Admin/Controllers/SecurityPolicyController.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,122 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using System.Web.Mvc; | ||
using Newtonsoft.Json; | ||
using Newtonsoft.Json.Linq; | ||
using NuGetGallery.Areas.Admin.ViewModels; | ||
using NuGetGallery.Security; | ||
|
||
namespace NuGetGallery.Areas.Admin.Controllers | ||
{ | ||
/// <summary> | ||
/// Controller for the security policy management Admin view. | ||
/// </summary> | ||
public class SecurityPolicyController : AdminControllerBase | ||
{ | ||
protected IEntitiesContext EntitiesContext { get; set; } | ||
|
||
protected ISecurityPolicyService PolicyService { get; set; } | ||
|
||
protected SecurityPolicyController() | ||
{ | ||
} | ||
|
||
public SecurityPolicyController(IEntitiesContext entitiesContext, ISecurityPolicyService policyService) | ||
{ | ||
EntitiesContext = entitiesContext ?? throw new ArgumentNullException(nameof(entitiesContext)); | ||
PolicyService = policyService ?? throw new ArgumentNullException(nameof(policyService)); | ||
} | ||
|
||
[HttpGet] | ||
public virtual ActionResult Index() | ||
{ | ||
var model = new SecurityPolicyViewModel() | ||
{ | ||
SubscriptionNames = PolicyService.UserSubscriptions.Select(s => s.SubscriptionName) | ||
}; | ||
|
||
return View(model); | ||
} | ||
|
||
[HttpGet] | ||
public virtual JsonResult Search(string query) | ||
{ | ||
// Parse query and look for users in the DB. | ||
var usernames = GetUsernamesFromQuery(query ?? ""); | ||
var users = FindUsers(usernames); | ||
var usersNotFound = usernames.Except(users.Select(u => u.Username)); | ||
|
||
var results = new UserSecurityPolicySearchResult() | ||
{ | ||
// Found users and subscribed status for each policy subscription. | ||
Users = users.Select(u => new UserSecurityPolicySubscriptions() | ||
{ | ||
Username = u.Username, | ||
Subscriptions = PolicyService.UserSubscriptions.ToDictionary( | ||
s => s.SubscriptionName, | ||
s => PolicyService.IsSubscribed(u, s)) | ||
}), | ||
// Usernames that weren't found in the DB. | ||
UsersNotFound = usersNotFound | ||
}; | ||
|
||
return Json(results, JsonRequestBehavior.AllowGet); | ||
} | ||
|
||
[HttpPost] | ||
[ValidateAntiForgeryToken] | ||
public async Task<ActionResult> Update(SecurityPolicyViewModel viewModel) | ||
{ | ||
// Policy subscription requests by user. | ||
var subscriptions = viewModel.UserSubscriptions? | ||
.Select(json => JsonConvert.DeserializeObject<JObject>(json)) | ||
.GroupBy(obj => obj["u"].ToString()) | ||
.ToDictionary( | ||
g => g.Key, | ||
g => g.Select(obj => obj["g"].ToString()) | ||
); | ||
|
||
// Iterate all users and groups to handle both subscribe and unsubscribe. | ||
var usernames = GetUsernamesFromQuery(viewModel.UsersQuery); | ||
var users = FindUsers(usernames); | ||
foreach (var user in users) | ||
{ | ||
foreach (var subscription in PolicyService.UserSubscriptions) | ||
{ | ||
var userKeyExists = subscriptions?.ContainsKey(user.Username) ?? false; | ||
if (userKeyExists && subscriptions[user.Username].Contains(subscription.SubscriptionName)) | ||
{ | ||
await PolicyService.SubscribeAsync(user, subscription); | ||
} | ||
else | ||
{ | ||
await PolicyService.UnsubscribeAsync(user, subscription); | ||
} | ||
} | ||
} | ||
|
||
TempData["Message"] = $"Updated policies for {users.Count()} users."; | ||
|
||
return RedirectToAction("Index"); | ||
} | ||
|
||
private static string[] GetUsernamesFromQuery(string query) | ||
{ | ||
return query.Split(',', '\r', '\n') | ||
.Select(username => username.Trim()) | ||
.Where(username => !string.IsNullOrEmpty(username)).ToArray(); | ||
} | ||
|
||
private IEnumerable<User> FindUsers(string[] usernames) | ||
{ | ||
return EntitiesContext.Users | ||
.Where(u => usernames.Any(name => u.Username.Equals(name, StringComparison.OrdinalIgnoreCase))) | ||
.ToList(); | ||
} | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
src/NuGetGallery/Areas/Admin/ViewModels/SecurityPolicyViewModel.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace NuGetGallery.Areas.Admin.ViewModels | ||
{ | ||
/// <summary> | ||
/// View model for the security policies admin view. | ||
/// </summary> | ||
public class SecurityPolicyViewModel | ||
{ | ||
/// <summary> | ||
/// Users search query. | ||
/// </summary> | ||
public string UsersQuery { get; set; } | ||
|
||
/// <summary> | ||
/// Available security policy groups. | ||
/// </summary> | ||
public IEnumerable<string> SubscriptionNames { get; set; } | ||
|
||
/// <summary> | ||
/// User subscription requests, in JSON format. | ||
/// </summary> | ||
public IEnumerable<string> UserSubscriptions { get; set; } | ||
} | ||
} |
23 changes: 23 additions & 0 deletions
23
src/NuGetGallery/Areas/Admin/ViewModels/UserSecurityPolicySearchResult.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace NuGetGallery.Areas.Admin.ViewModels | ||
{ | ||
/// <summary> | ||
/// User search results for the security policies admin view. | ||
/// </summary> | ||
public class UserSecurityPolicySearchResult | ||
{ | ||
/// <summary> | ||
/// Found users, with security policy subscriptions they are subscribed to. | ||
/// </summary> | ||
public IEnumerable<UserSecurityPolicySubscriptions> Users { get; set; } | ||
|
||
/// <summary> | ||
/// Usernames not found in the database. | ||
/// </summary> | ||
public IEnumerable<string> UsersNotFound { get; set; } | ||
} | ||
} |
22 changes: 22 additions & 0 deletions
22
src/NuGetGallery/Areas/Admin/ViewModels/UserSecurityPolicySubscriptions.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// Copyright (c) .NET Foundation. All rights reserved. | ||
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. | ||
|
||
using System.Collections.Generic; | ||
|
||
namespace NuGetGallery.Areas.Admin.ViewModels | ||
{ | ||
/// <summary> | ||
/// Security policy group subscriptions for a user. | ||
/// </summary> | ||
public class UserSecurityPolicySubscriptions | ||
{ | ||
public int UserId { get; set; } | ||
|
||
public string Username { get; set; } | ||
|
||
/// <summary> | ||
/// Dictionary of security policy subscriptions, and whether user is subscribed. | ||
/// </summary> | ||
public IDictionary<string, bool> Subscriptions { get; set; } | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.