Merge remote-tracking branch 'origin/v8/dev' into netcore/feature/merge-v8-05032021

# Conflicts:
#	src/SolutionInfo.cs
#	src/Umbraco.Web/Editors/Filters/UserGroupValidateAttribute.cs
#	src/Umbraco.Web/Editors/PasswordChanger.cs
#	src/Umbraco.Web/Editors/UserGroupsController.cs
This commit is contained in:
Bjarke Berg
2021-03-09 10:08:53 +01:00
12 changed files with 188 additions and 47 deletions

View File

@@ -78,18 +78,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// <summary>
/// Authorize that the user is not adding a section to the group that they don't have access to
/// </summary>
/// <param name="currentUser"></param>
/// <param name="currentAllowedSections"></param>
/// <param name="proposedAllowedSections"></param>
/// <returns></returns>
public Attempt<string> AuthorizeSectionChanges(IUser currentUser,
IEnumerable<string> currentAllowedSections,
public Attempt<string> AuthorizeSectionChanges(
IUser currentUser,
IEnumerable<string> existingSections,
IEnumerable<string> proposedAllowedSections)
{
if (currentUser.IsAdmin())
return Attempt<string>.Succeed();
var sectionsAdded = currentAllowedSections.Except(proposedAllowedSections).ToArray();
var sectionsAdded = proposedAllowedSections.Except(existingSections).ToArray();
var sectionAccessMissing = sectionsAdded.Except(currentUser.AllowedSections).ToArray();
return sectionAccessMissing.Length > 0
? Attempt.Fail("Current user doesn't have access to add these sections " + string.Join(", ", sectionAccessMissing))

View File

@@ -34,9 +34,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
private readonly IShortStringHelper _shortStringHelper;
private readonly AppCaches _appCaches;
public UserGroupsController(IUserService userService, IContentService contentService,
IEntityService entityService, IMediaService mediaService, IBackOfficeSecurityAccessor backofficeSecurityAccessor,
UmbracoMapper umbracoMapper, ILocalizedTextService localizedTextService,
public UserGroupsController(
IUserService userService,
IContentService contentService,
IEntityService entityService,
IMediaService mediaService,
IBackOfficeSecurityAccessor backofficeSecurityAccessor,
UmbracoMapper umbracoMapper,
ILocalizedTextService localizedTextService,
IShortStringHelper shortStringHelper,
AppCaches appCaches)
{
@@ -66,7 +71,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return Unauthorized(isAuthorized.Result);
//if sections were added we need to check that the current user has access to that section
isAuthorized = authHelper.AuthorizeSectionChanges(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser,
isAuthorized = authHelper.AuthorizeSectionChanges(
_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser,
userGroupSave.PersistedUserGroup.AllowedSections,
userGroupSave.Sections);
if (isAuthorized == false)
@@ -82,7 +88,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return Unauthorized(isAuthorized.Result);
//need to ensure current user is in a group if not an admin to avoid a 401
EnsureNonAdminUserIsInSavedUserGroup(userGroupSave);
EnsureNonAdminUserIsInSavedUserGroup(userGroupSave);
//map the model to the persisted instance
_umbracoMapper.Map(userGroupSave, userGroupSave.PersistedUserGroup);
//save the group
_userService.Save(userGroupSave.PersistedUserGroup, userGroupSave.Users.ToArray());

View File

@@ -6,6 +6,7 @@ using Umbraco.Cms.Core.Mapping;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Membership;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Web.BackOffice.ActionResults;
using Umbraco.Cms.Web.Common.ActionsResults;
using Umbraco.Extensions;
@@ -20,15 +21,15 @@ namespace Umbraco.Cms.Web.BackOffice.Filters
private class UserGroupValidateFilter : IActionFilter
{
private readonly UmbracoMapper _umbracoMapper;
private readonly IShortStringHelper _shortStringHelper;
private readonly IUserService _userService;
public UserGroupValidateFilter(
IUserService userService,
UmbracoMapper umbracoMapper)
IShortStringHelper shortStringHelper)
{
_userService = userService ?? throw new ArgumentNullException(nameof(userService));
_umbracoMapper = umbracoMapper ?? throw new ArgumentNullException(nameof(umbracoMapper));
_shortStringHelper = shortStringHelper ?? throw new ArgumentNullException(nameof(shortStringHelper));
}
public void OnActionExecuting(ActionExecutingContext context)
@@ -58,13 +59,9 @@ namespace Umbraco.Cms.Web.BackOffice.Filters
return;
}
//map the model to the persisted instance
_umbracoMapper.Map(userGroupSave, persisted);
break;
case ContentSaveAction.SaveNew:
//create the persisted model from mapping the saved model
persisted = _umbracoMapper.Map<IUserGroup>(userGroupSave);
((UserGroup) persisted).ResetIdentity();
persisted = new UserGroup(_shortStringHelper);
break;
default:
context.Result =

View File

@@ -64,6 +64,11 @@ namespace Umbraco.Cms.Web.BackOffice.Security
return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("The current user is not authorized", new[] { "value" }) });
}
if (!currentUser.IsAdmin() && savingUser.IsAdmin())
{
return Attempt.Fail(new PasswordChangedModel { ChangeError = new ValidationResult("The current user cannot change the password for the specified user", new[] { "resetPassword" }) });
}
//ok, we should be able to reset it
var resetToken = await userMgr.GeneratePasswordResetTokenAsync(backOfficeIdentityUser);