Fixed possible null reference exceptions

This commit is contained in:
Bjarke Berg
2021-01-14 19:41:32 +01:00
parent 680f8c4d96
commit 04bb4e99b6
32 changed files with 411 additions and 284 deletions

View File

@@ -6,7 +6,6 @@ using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Extensions;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@@ -34,7 +33,6 @@ using Umbraco.Web.BackOffice.ModelBinders;
using Umbraco.Web.Common.ActionsResults;
using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Exceptions;
using Umbraco.Web.ContentApps;
using Umbraco.Web.Models.ContentEditing;
using Umbraco.Web.Models.Mapping;
@@ -335,13 +333,12 @@ namespace Umbraco.Web.BackOffice.Controllers
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.ContentPermissionBrowseById)]
[DetermineAmbiguousActionByPassingParameters]
public ContentItemDisplay GetById(int id)
public ActionResult<ContentItemDisplay> GetById(int id)
{
var foundContent = GetObjectFromRequest(() => _contentService.GetById(id));
if (foundContent == null)
{
HandleContentNotFound(id);
return null;//irrelevant since the above throws
return HandleContentNotFound(id);
}
var content = MapToDisplay(foundContent);
return content;
@@ -355,13 +352,12 @@ namespace Umbraco.Web.BackOffice.Controllers
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.ContentPermissionBrowseById)]
[DetermineAmbiguousActionByPassingParameters]
public ContentItemDisplay GetById(Guid id)
public ActionResult<ContentItemDisplay> GetById(Guid id)
{
var foundContent = GetObjectFromRequest(() => _contentService.GetById(id));
if (foundContent == null)
{
HandleContentNotFound(id);
return null;//irrelevant since the above throws
return HandleContentNotFound(id);
}
var content = MapToDisplay(foundContent);
@@ -590,9 +586,14 @@ namespace Umbraco.Web.BackOffice.Controllers
var content = _contentService.GetById(contentId);
if (content == null)
{
return NotFound();
}
EnsureUniqueName(name, content, nameof(name));
if (!EnsureUniqueName(name, content, nameof(name)))
{
return new ValidationErrorResult(ModelState.ToErrorDictionary());
}
var blueprint = _contentService.CreateContentFromBlueprint(content, name, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
@@ -1484,7 +1485,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (foundContent == null)
{
return HandleContentNotFound(id, false);
return HandleContentNotFound(id);
}
var publishResult = _contentService.SaveAndPublish(foundContent, userId: _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
@@ -1507,7 +1508,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (found == null)
{
return HandleContentNotFound(id, false);
return HandleContentNotFound(id);
}
_contentService.DeleteBlueprint(found);
@@ -1533,7 +1534,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (foundContent == null)
{
return HandleContentNotFound(id, false);
return HandleContentNotFound(id);
}
//if the current item is in the recycle bin
@@ -1639,7 +1640,12 @@ namespace Umbraco.Web.BackOffice.Controllers
return Forbid();
}
var toMove = ValidateMoveOrCopy(move).Value;
var toMoveResult = ValidateMoveOrCopy(move);
if (!(toMoveResult is null))
{
return toMoveResult.Result;
}
var toMove = toMoveResult.Value;
_contentService.Move(toMove, move.ParentId, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
@@ -1651,7 +1657,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary>
/// <param name="copy"></param>
/// <returns></returns>
public async Task<IActionResult> PostCopy(MoveOrCopy copy)
public async Task<ActionResult<IContent>> PostCopy(MoveOrCopy copy)
{
// Authorize...
var resource = new ContentPermissionsResource(_contentService.GetById(copy.ParentId), ActionCopy.ActionLetter);
@@ -1661,8 +1667,12 @@ namespace Umbraco.Web.BackOffice.Controllers
return Forbid();
}
var toCopy = ValidateMoveOrCopy(copy).Value;
var toCopyResult = ValidateMoveOrCopy(copy);
if ((toCopyResult.Result is null))
{
return toCopyResult.Result;
}
var toCopy = toCopyResult.Value;
var c = _contentService.Copy(toCopy, copy.ParentId, copy.RelateToOriginal, copy.Recursive, _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
return Content(c.Path, MediaTypeNames.Text.Plain, Encoding.UTF8);
@@ -1680,7 +1690,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (foundContent == null)
{
HandleContentNotFound(model.Id);
return HandleContentNotFound(model.Id);
}
// Authorize...

View File

@@ -11,7 +11,6 @@ using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Web.Common.Exceptions;
using Umbraco.Web.Common.Filters;
using Umbraco.Web.Models.ContentEditing;
@@ -71,14 +70,10 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary>
protected ILocalizedTextService LocalizedTextService { get; }
protected NotFoundObjectResult HandleContentNotFound(object id, bool throwException = true)
protected NotFoundObjectResult HandleContentNotFound(object id)
{
ModelState.AddModelError("id", $"content with id: {id} was not found");
var errorResponse = NotFound(ModelState);
if (throwException)
{
throw new HttpResponseException(errorResponse);
}
return errorResponse;
}

View File

@@ -208,9 +208,18 @@ namespace Umbraco.Web.BackOffice.Controllers
/// </summary>
[HttpPost]
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public IActionResult GetAvailableCompositeContentTypes(GetAvailableCompositionsFilter filter)
public ActionResult GetAvailableCompositeContentTypes(GetAvailableCompositionsFilter filter)
{
var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement).Value
var actionResult = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId,
UmbracoObjectTypes.DocumentType, filter.FilterContentTypes, filter.FilterPropertyTypes,
filter.IsElement);
if (!(actionResult.Result is null))
{
return actionResult.Result;
}
var result = actionResult.Value
.Select(x => new
{
contentType = x.Item1,
@@ -361,7 +370,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
public DocumentTypeDisplay PostSave(DocumentTypeSave contentTypeSave)
public ActionResult<DocumentTypeDisplay> PostSave(DocumentTypeSave contentTypeSave)
{
//Before we send this model into this saving/mapping pipeline, we need to do some cleanup on variations.
//If the doc type does not allow content variations, we need to update all of it's property types to not allow this either
@@ -404,8 +413,14 @@ namespace Umbraco.Web.BackOffice.Controllers
}
});
if (!(savedCt.Result is null))
{
return savedCt.Result;
}
var display = _umbracoMapper.Map<DocumentTypeDisplay>(savedCt.Value);
display.AddSuccessNotification(
_localizedTextService.Localize("speechBubbles/contentTypeSavedHeader"),
string.Empty);

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Reflection;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Umbraco.Core;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
@@ -201,11 +202,16 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="type"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
public IEnumerable<int> GetPath(int id, UmbracoEntityTypes type)
public IConvertToActionResult GetPath(int id, UmbracoEntityTypes type)
{
var foundContent = GetResultForId(id, type).Value;
var foundContentResult = GetResultForId(id, type);
var foundContent = foundContentResult.Value;
if (foundContent is null)
{
return foundContentResult;
}
return foundContent.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse);
return new ActionResult<IEnumerable<int>>(foundContent.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse));
}
/// <summary>
@@ -215,11 +221,16 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="type"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
public IEnumerable<int> GetPath(Guid id, UmbracoEntityTypes type)
public IConvertToActionResult GetPath(Guid id, UmbracoEntityTypes type)
{
var foundContent = GetResultForKey(id, type).Value;
var foundContentResult = GetResultForKey(id, type);
var foundContent = foundContentResult.Value;
if (foundContent is null)
{
return foundContentResult;
}
return foundContent.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse);
return new ActionResult<IEnumerable<int>>(foundContent.Path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).Select(int.Parse));
}
/// <summary>
@@ -229,12 +240,12 @@ namespace Umbraco.Web.BackOffice.Controllers
/// <param name="type"></param>
/// <returns></returns>
[DetermineAmbiguousActionByPassingParameters]
public ActionResult<IEnumerable<int>> GetPath(Udi id, UmbracoEntityTypes type)
public IActionResult GetPath(Udi id, UmbracoEntityTypes type)
{
var guidUdi = id as GuidUdi;
if (guidUdi != null)
{
return new ActionResult<IEnumerable<int>>(GetPath(guidUdi.Guid, type));
return GetPath(guidUdi.Guid, type).Convert();
}
return NotFound();

View File

@@ -8,6 +8,7 @@ using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Core;
@@ -443,7 +444,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (foundMedia == null)
{
return HandleContentNotFound(id, false);
return HandleContentNotFound(id);
}
//if the current item is in the recycle bin
@@ -486,7 +487,13 @@ namespace Umbraco.Web.BackOffice.Controllers
return Forbid();
}
var toMove = ValidateMoveOrCopy(move).Value;
var toMoveResult = ValidateMoveOrCopy(move);
var toMove = toMoveResult.Value;
if (toMove is null && toMoveResult is IConvertToActionResult convertToActionResult)
{
return convertToActionResult.Convert();
}
var destinationParentID = move.ParentId;
var sourceParentID = toMove.ParentId;
@@ -667,7 +674,12 @@ namespace Umbraco.Web.BackOffice.Controllers
public async Task<ActionResult<MediaItemDisplay>> PostAddFolder(PostedFolder folder)
{
var parentId = (await GetParentIdAsIntAsync(folder.ParentId, validatePermissions:true)).Value;
var parentIdResult = await GetParentIdAsIntAsync(folder.ParentId, validatePermissions:true);
if (!(parentIdResult.Result is null))
{
return new ActionResult<MediaItemDisplay>(parentIdResult.Result);
}
var parentId = parentIdResult.Value;
if (!parentId.HasValue)
{
return NotFound("The passed id doesn't exist");
@@ -699,11 +711,18 @@ namespace Umbraco.Web.BackOffice.Controllers
}
//get the string json from the request
var parentId = (await GetParentIdAsIntAsync(currentFolder, validatePermissions: true)).Value;
var parentIdResult = await GetParentIdAsIntAsync(currentFolder, validatePermissions:true);
if (!(parentIdResult.Result is null))
{
return parentIdResult.Result;
}
var parentId = parentIdResult.Value;
if (!parentId.HasValue)
{
return NotFound("The passed id doesn't exist");
}
var tempFiles = new PostedFiles();

View File

@@ -176,9 +176,16 @@ namespace Umbraco.Web.BackOffice.Controllers
[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)]
public IActionResult GetAvailableCompositeMediaTypes(GetAvailableCompositionsFilter filter)
{
var result = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId, UmbracoObjectTypes.MediaType,
filter.FilterContentTypes, filter.FilterPropertyTypes, filter.IsElement).Value
.Select(x => new
var actionResult = PerformGetAvailableCompositeContentTypes(filter.ContentTypeId,
UmbracoObjectTypes.MediaType, filter.FilterContentTypes, filter.FilterPropertyTypes,
filter.IsElement);
if (!(actionResult.Result is null))
{
return actionResult.Result;
}
var result = actionResult.Value.Select(x => new
{
contentType = x.Item1,
allowed = x.Item2
@@ -273,15 +280,21 @@ namespace Umbraco.Web.BackOffice.Controllers
}
[Authorize(Policy = AuthorizationPolicies.TreeAccessMediaTypes)]
public MediaTypeDisplay PostSave(MediaTypeSave contentTypeSave)
public ActionResult<MediaTypeDisplay> PostSave(MediaTypeSave contentTypeSave)
{
var savedCt = PerformPostSave<MediaTypeDisplay, MediaTypeSave, PropertyTypeBasic>(
contentTypeSave,
i => _mediaTypeService.Get(i),
type => _mediaTypeService.Save(type));
if (!(savedCt.Result is null))
{
return savedCt.Result;
}
var display = _umbracoMapper.Map<MediaTypeDisplay>(savedCt.Value);
display.AddSuccessNotification(
_localizedTextService.Localize("speechBubbles/mediaTypeSavedHeader"),
string.Empty);

View File

@@ -33,7 +33,6 @@ using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Filters;
using Umbraco.Web.ContentApps;
using Umbraco.Web.Models.ContentEditing;
using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.BackOffice.Controllers
{
@@ -453,7 +452,7 @@ namespace Umbraco.Web.BackOffice.Controllers
var foundMember = _memberService.GetByKey(key);
if (foundMember == null)
{
return HandleContentNotFound(key, false);
return HandleContentNotFound(key);
}
_memberService.Delete(foundMember);

View File

@@ -1,20 +1,19 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Core;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Security;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Web.Models.ContentEditing;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Mapping;
using Umbraco.Core.Security;
using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Editors;
using Microsoft.AspNetCore.Authorization;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Editors;
using Umbraco.Web.Models.ContentEditing;
namespace Umbraco.Web.BackOffice.Controllers
{
@@ -152,7 +151,16 @@ namespace Umbraco.Web.BackOffice.Controllers
[FromQuery]string[] filterContentTypes,
[FromQuery]string[] filterPropertyTypes)
{
var result = PerformGetAvailableCompositeContentTypes(contentTypeId, UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes, false).Value
var actionResult = PerformGetAvailableCompositeContentTypes(contentTypeId,
UmbracoObjectTypes.MemberType, filterContentTypes, filterPropertyTypes,
false);
if (!(actionResult.Result is null))
{
return actionResult.Result;
}
var result = actionResult.Value
.Select(x => new
{
contentType = x.Item1,
@@ -230,6 +238,11 @@ namespace Umbraco.Web.BackOffice.Controllers
getContentType: i => ct,
saveContentType: type => _memberTypeService.Save(type));
if (!(savedCt.Result is null))
{
return savedCt.Result;
}
var display =_umbracoMapper.Map<MemberTypeDisplay>(savedCt.Value);
display.AddSuccessNotification(

View File

@@ -1,6 +1,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Infrastructure;
using Umbraco.Core;
@@ -48,7 +49,7 @@ namespace Umbraco.Web.BackOffice.Controllers
_actionDescriptorCollectionProvider = actionDescriptorCollectionProvider;
}
public async Task<IEnumerable<Section>> GetSections()
public async Task<ActionResult<IEnumerable<Section>>> GetSections()
{
var sections = _sectionService.GetAllowedSections(_backofficeSecurityAccessor.BackOfficeSecurity.GetUserId().ResultOr(0));
@@ -74,6 +75,11 @@ namespace Umbraco.Web.BackOffice.Controllers
// get the first tree in the section and get its root node route path
var sectionRoot = await appTreeController.GetApplicationTrees(section.Alias, null, null);
if (!(sectionRoot.Result is null))
{
return sectionRoot.Result;
}
section.RoutePath = GetRoutePathForFirstTree(sectionRoot.Value);
}

View File

@@ -427,7 +427,13 @@ namespace Umbraco.Web.BackOffice.Controllers
else
{
//first validate the username if we're showing it
user = CheckUniqueUsername(userSave.Username, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue).Value;
var userResult = CheckUniqueUsername(userSave.Username, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
if (!(userResult.Result is null))
{
return userResult.Result;
}
user = userResult.Value;
}
user = CheckUniqueEmail(userSave.Email, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);