Merge remote-tracking branch 'origin/netcore/netcore' into netcore/feature/2FAuth

# Conflicts:
#	src/Umbraco.Tests.Integration/TestServerTest/TestAuthHandler.cs
#	src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
#	src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
#	src/Umbraco.Web.BackOffice/Controllers/ContentController.cs
#	src/Umbraco.Web.BackOffice/Controllers/ContentTypeController.cs
#	src/Umbraco.Web.BackOffice/Controllers/MediaTypeController.cs
#	src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
#	src/Umbraco.Web.BackOffice/Filters/DenyLocalLoginAuthorizationAttribute.cs
#	src/Umbraco.Web.BackOffice/Filters/OverrideAuthorizationFilterProvider.cs
#	src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeAttribute.cs
#	src/Umbraco.Web.Common/Filters/UmbracoBackOfficeAuthorizeFilter.cs
This commit is contained in:
Shannon
2020-12-02 13:14:47 +11:00
512 changed files with 27283 additions and 4558 deletions

View File

@@ -41,11 +41,13 @@ using IUser = Umbraco.Core.Models.Membership.IUser;
using Task = System.Threading.Tasks.Task;
using Umbraco.Net;
using Umbraco.Web.Common.ActionsResults;
using Microsoft.AspNetCore.Authorization;
using Umbraco.Web.Common.Authorization;
namespace Umbraco.Web.BackOffice.Controllers
{
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
[UmbracoApplicationAuthorize(Constants.Applications.Users)]
[Authorize(Policy = AuthorizationPolicies.SectionAccessUsers)]
[PrefixlessBodyModelValidator]
[IsCurrentUserModelFilter]
public class UsersController : UmbracoAuthorizedJsonController
@@ -64,14 +66,12 @@ namespace Umbraco.Web.BackOffice.Controllers
private readonly IUserService _userService;
private readonly ILocalizedTextService _localizedTextService;
private readonly UmbracoMapper _umbracoMapper;
private readonly IEntityService _entityService;
private readonly IMediaService _mediaService;
private readonly IContentService _contentService;
private readonly GlobalSettings _globalSettings;
private readonly IBackOfficeUserManager _userManager;
private readonly ILoggerFactory _loggerFactory;
private readonly LinkGenerator _linkGenerator;
private readonly IBackOfficeExternalLoginProviders _externalLogins;
private readonly UserEditorAuthorizationHelper _userEditorAuthorizationHelper;
private readonly ILogger<UsersController> _logger;
public UsersController(
@@ -89,14 +89,12 @@ namespace Umbraco.Web.BackOffice.Controllers
IUserService userService,
ILocalizedTextService localizedTextService,
UmbracoMapper umbracoMapper,
IEntityService entityService,
IMediaService mediaService,
IContentService contentService,
IOptions<GlobalSettings> globalSettings,
IBackOfficeUserManager backOfficeUserManager,
ILoggerFactory loggerFactory,
LinkGenerator linkGenerator,
IBackOfficeExternalLoginProviders externalLogins)
IBackOfficeExternalLoginProviders externalLogins,
UserEditorAuthorizationHelper userEditorAuthorizationHelper)
{
_mediaFileSystem = mediaFileSystem;
_contentSettings = contentSettings.Value;
@@ -112,19 +110,17 @@ namespace Umbraco.Web.BackOffice.Controllers
_userService = userService;
_localizedTextService = localizedTextService;
_umbracoMapper = umbracoMapper;
_entityService = entityService;
_mediaService = mediaService;
_contentService = contentService;
_globalSettings = globalSettings.Value;
_userManager = backOfficeUserManager;
_loggerFactory = loggerFactory;
_linkGenerator = linkGenerator;
_externalLogins = externalLogins;
_userEditorAuthorizationHelper = userEditorAuthorizationHelper;
_logger = _loggerFactory.CreateLogger<UsersController>();
}
/// <summary>
/// Returns a list of the sizes of gravatar urls for the user or null if the gravatar server cannot be reached
/// Returns a list of the sizes of gravatar URLs for the user or null if the gravatar server cannot be reached
/// </summary>
/// <returns></returns>
public string[] GetCurrentUserAvatarUrls()
@@ -137,7 +133,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
[AppendUserModifiedHeader("id")]
[AdminUsersAuthorize]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostSetAvatar(int id, IList<IFormFile> files)
{
return PostSetAvatarInternal(files, _userService, _appCaches.RuntimeCache, _mediaFileSystem, _shortStringHelper, _contentSettings, _hostingEnvironment, _imageUrlGenerator, id);
@@ -190,7 +186,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
[AppendUserModifiedHeader("id")]
[AdminUsersAuthorize]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public ActionResult<string[]> PostClearAvatar(int id)
{
var found = _userService.GetUserById(id);
@@ -229,7 +225,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="id"></param>
/// <returns></returns>
[TypeFilter(typeof(OutgoingEditorModelEventAttribute))]
[AdminUsersAuthorize]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public UserDisplay GetById(int id)
{
var user = _userService.GetUserById(id);
@@ -247,7 +243,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="ids"></param>
/// <returns></returns>
[TypeFilter(typeof(OutgoingEditorModelEventAttribute))]
[AdminUsersAuthorize]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IEnumerable<UserDisplay> GetByIds([FromJsonPath]int[] ids)
{
if (ids == null)
@@ -364,8 +360,7 @@ namespace Umbraco.Web.BackOffice.Controllers
CheckUniqueEmail(userSave.Email, null);
//Perform authorization here to see if the current user can actually save this user with the info being requested
var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService);
var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, null, null, null, userSave.UserGroups);
var canSaveUser = _userEditorAuthorizationHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, null, null, null, userSave.UserGroups);
if (canSaveUser == false)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized, canSaveUser.Result);
@@ -448,8 +443,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
//Perform authorization here to see if the current user can actually save this user with the info being requested
var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService);
var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, user, null, null, userSave.UserGroups);
var canSaveUser = _userEditorAuthorizationHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, user, null, null, userSave.UserGroups);
if (canSaveUser == false)
{
return new ValidationErrorResult(canSaveUser.Result, StatusCodes.Status401Unauthorized);
@@ -490,8 +484,8 @@ namespace Umbraco.Web.BackOffice.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "An error occured in a custom event handler while inviting the user");
return ValidationErrorResult.CreateNotificationValidationErrorResult($"An error occured inviting the user (check logs for more info): {ex.Message}");
_logger.LogError(ex, "An error occurred in a custom event handler while inviting the user");
return ValidationErrorResult.CreateNotificationValidationErrorResult($"An error occurred inviting the user (check logs for more info): {ex.Message}");
}
// If the event is handled then no need to send the email
@@ -554,7 +548,7 @@ namespace Umbraco.Web.BackOffice.Controllers
WebUtility.UrlEncode("|"),
token.ToUrlBase64());
// Get an mvc helper to get the url
// Get an mvc helper to get the URL
var action = _linkGenerator.GetPathByAction("VerifyInvite", "BackOffice", new
{
area = _globalSettings.GetUmbracoMvcArea(_hostingEnvironment),
@@ -602,8 +596,7 @@ namespace Umbraco.Web.BackOffice.Controllers
throw new HttpResponseException(HttpStatusCode.NotFound);
//Perform authorization here to see if the current user can actually save this user with the info being requested
var authHelper = new UserEditorAuthorizationHelper(_contentService,_mediaService, _userService, _entityService);
var canSaveUser = authHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, found, userSave.StartContentIds, userSave.StartMediaIds, userSave.UserGroups);
var canSaveUser = _userEditorAuthorizationHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, found, userSave.StartContentIds, userSave.StartMediaIds, userSave.UserGroups);
if (canSaveUser == false)
{
throw new HttpResponseException(HttpStatusCode.Unauthorized, canSaveUser.Result);
@@ -716,7 +709,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Disables the users with the given user ids
/// </summary>
/// <param name="userIds"></param>
[AdminUsersAuthorize("userIds")]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostDisableUsers([FromQuery]int[] userIds)
{
var tryGetCurrentUserId = _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId();
@@ -747,7 +740,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Enables the users with the given user ids
/// </summary>
/// <param name="userIds"></param>
[AdminUsersAuthorize("userIds")]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostEnableUsers([FromQuery]int[] userIds)
{
var users = _userService.GetUsersById(userIds).ToArray();
@@ -771,7 +764,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Unlocks the users with the given user ids
/// </summary>
/// <param name="userIds"></param>
[AdminUsersAuthorize("userIds")]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public async Task<IActionResult> PostUnlockUsers([FromQuery]int[] userIds)
{
if (userIds.Length <= 0) return Ok();
@@ -804,7 +797,7 @@ namespace Umbraco.Web.BackOffice.Controllers
_localizedTextService.Localize("speechBubbles/unlockUsersSuccess", new[] {(userIds.Length - notFound.Count).ToString()}));
}
[AdminUsersAuthorize("userIds")]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostSetUserGroupsOnUsers([FromQuery]string[] userGroupAliases, [FromQuery]int[] userIds)
{
var users = _userService.GetUsersById(userIds).ToArray();
@@ -830,7 +823,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Limited to users that haven't logged in to avoid issues with related records constrained
/// with a foreign key on the user Id
/// </remarks>
[AdminUsersAuthorize]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostDeleteNonLoggedInUser(int id)
{
var user = _userService.GetUserById(id);