diff --git a/src/Umbraco.Core/Editors/UserEditorAuthorizationHelper.cs b/src/Umbraco.Core/Editors/UserEditorAuthorizationHelper.cs
index eeb3982118..b2cd34875c 100644
--- a/src/Umbraco.Core/Editors/UserEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Core/Editors/UserEditorAuthorizationHelper.cs
@@ -37,7 +37,7 @@ namespace Umbraco.Cms.Core.Editors
/// The user aliases of the user being saved (can be null or empty)
///
public Attempt IsAuthorized(IUser? currentUser,
- IUser savingUser,
+ IUser? savingUser,
IEnumerable? startContentIds, IEnumerable? startMediaIds,
IEnumerable? userGroupAliases)
{
diff --git a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs
index 280f25ad23..27f092b6ac 100644
--- a/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs
+++ b/src/Umbraco.Core/Extensions/PublishedContentExtensions.cs
@@ -963,7 +963,7 @@ namespace Umbraco.Extensions
/// The specific culture to filter for. If null is used the current culture is used. (Default is null)
/// The content type alias.
/// The children of the content, of any of the specified types.
- public static IEnumerable? ChildrenOfType(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string contentTypeAlias, string? culture = null)
+ public static IEnumerable? ChildrenOfType(this IPublishedContent content, IVariationContextAccessor variationContextAccessor, string? contentTypeAlias, string? culture = null)
{
return content.Children(variationContextAccessor, x => x.ContentType.Alias.InvariantEquals(contentTypeAlias), culture);
}
diff --git a/src/Umbraco.Core/Models/BackOfficeTour.cs b/src/Umbraco.Core/Models/BackOfficeTour.cs
index a8e6c535e1..d6a5d8971e 100644
--- a/src/Umbraco.Core/Models/BackOfficeTour.cs
+++ b/src/Umbraco.Core/Models/BackOfficeTour.cs
@@ -18,7 +18,7 @@ namespace Umbraco.Cms.Core.Models
public string? Name { get; set; }
[DataMember(Name = "alias")]
- public string? Alias { get; set; }
+ public string Alias { get; set; } = null!;
[DataMember(Name = "group")]
public string? Group { get; set; }
diff --git a/src/Umbraco.Core/Models/ITemplate.cs b/src/Umbraco.Core/Models/ITemplate.cs
index 3f82957eb5..e20dcc55fa 100644
--- a/src/Umbraco.Core/Models/ITemplate.cs
+++ b/src/Umbraco.Core/Models/ITemplate.cs
@@ -31,6 +31,6 @@ namespace Umbraco.Cms.Core.Models
/// Set the mastertemplate
///
///
- void SetMasterTemplate(ITemplate masterTemplate);
+ void SetMasterTemplate(ITemplate? masterTemplate);
}
}
diff --git a/src/Umbraco.Core/Models/Template.cs b/src/Umbraco.Core/Models/Template.cs
index 67fdecadfd..1ba6b4a5ff 100644
--- a/src/Umbraco.Core/Models/Template.cs
+++ b/src/Umbraco.Core/Models/Template.cs
@@ -63,7 +63,7 @@ namespace Umbraco.Cms.Core.Models
///
public bool IsMasterTemplate { get; set; }
- public void SetMasterTemplate(ITemplate masterTemplate)
+ public void SetMasterTemplate(ITemplate? masterTemplate)
{
if (masterTemplate == null)
{
diff --git a/src/Umbraco.Core/Persistence/Repositories/IMemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/IMemberRepository.cs
index 42a4dfc788..a868eefe9f 100644
--- a/src/Umbraco.Core/Persistence/Repositories/IMemberRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/IMemberRepository.cs
@@ -9,7 +9,7 @@ namespace Umbraco.Cms.Core.Persistence.Repositories
{
int[] GetMemberIds(string[] names);
- IMember? GetByUsername(string username);
+ IMember? GetByUsername(string? username);
///
/// Finds members in a given role
diff --git a/src/Umbraco.Core/Services/FileService.cs b/src/Umbraco.Core/Services/FileService.cs
index 0d65ac1c2a..c6a5e5f8e4 100644
--- a/src/Umbraco.Core/Services/FileService.cs
+++ b/src/Umbraco.Core/Services/FileService.cs
@@ -368,7 +368,7 @@ namespace Umbraco.Cms.Core.Services
///
///
///
- public ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate? masterTemplate = null, int userId = Constants.Security.SuperUserId)
+ public ITemplate CreateTemplateWithIdentity(string? name, string? alias, string? content, ITemplate? masterTemplate = null, int userId = Constants.Security.SuperUserId)
{
if (name == null)
{
diff --git a/src/Umbraco.Core/Services/IFileService.cs b/src/Umbraco.Core/Services/IFileService.cs
index b6b4772d0d..9df9a671c3 100644
--- a/src/Umbraco.Core/Services/IFileService.cs
+++ b/src/Umbraco.Core/Services/IFileService.cs
@@ -253,7 +253,7 @@ namespace Umbraco.Cms.Core.Services
///
Attempt?> CreateTemplateForContentType(string contentTypeAlias, string contentTypeName, int userId = Constants.Security.SuperUserId);
- ITemplate CreateTemplateWithIdentity(string name, string alias, string content, ITemplate? masterTemplate = null, int userId = Constants.Security.SuperUserId);
+ ITemplate CreateTemplateWithIdentity(string? name, string? alias, string? content, ITemplate? masterTemplate = null, int userId = Constants.Security.SuperUserId);
///
/// Deletes a template by its alias
diff --git a/src/Umbraco.Core/Services/IMembershipMemberService.cs b/src/Umbraco.Core/Services/IMembershipMemberService.cs
index f183882b55..94dbbf3da9 100644
--- a/src/Umbraco.Core/Services/IMembershipMemberService.cs
+++ b/src/Umbraco.Core/Services/IMembershipMemberService.cs
@@ -99,7 +99,7 @@ namespace Umbraco.Cms.Core.Services
/// An can be of type or
/// Username to use for retrieval
///
- T? GetByUsername(string username);
+ T? GetByUsername(string? username);
///
/// Deletes an
diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs
index 5478a924e3..0842d47b36 100644
--- a/src/Umbraco.Core/Services/IUserService.cs
+++ b/src/Umbraco.Core/Services/IUserService.cs
@@ -243,7 +243,7 @@ namespace Umbraco.Cms.Core.Services
/// If null than no changes are made to the users who are assigned to this group, however if a value is passed in
/// than all users will be removed from this group and only these users will be added
///
- void Save(IUserGroup userGroup, int[]? userIds = null);
+ void Save(IUserGroup? userGroup, int[]? userIds = null);
///
/// Deletes a UserGroup
diff --git a/src/Umbraco.Core/Services/MemberService.cs b/src/Umbraco.Core/Services/MemberService.cs
index 7f7eac952a..77c6476ec9 100644
--- a/src/Umbraco.Core/Services/MemberService.cs
+++ b/src/Umbraco.Core/Services/MemberService.cs
@@ -392,7 +392,7 @@ namespace Umbraco.Cms.Core.Services
///
/// Username to use for retrieval
///
- public IMember? GetByUsername(string username)
+ public IMember? GetByUsername(string? username)
{
using (var scope = ScopeProvider.CreateScope(autoComplete: true))
{
diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs
index 680882a990..1cf1f9ede2 100644
--- a/src/Umbraco.Core/Services/UserService.cs
+++ b/src/Umbraco.Core/Services/UserService.cs
@@ -813,7 +813,7 @@ namespace Umbraco.Cms.Core.Services
/// than all users will be removed from this group and only these users will be added
///
/// Default is True otherwise set to False to not raise events
- public void Save(IUserGroup userGroup, int[]? userIds = null)
+ public void Save(IUserGroup? userGroup, int[]? userIds = null)
{
var evtMsgs = EventMessagesFactory.Get();
@@ -826,7 +826,7 @@ namespace Umbraco.Cms.Core.Services
if (userIds != null)
{
- var groupUsers = userGroup.HasIdentity ? _userRepository.GetAllInGroup(userGroup.Id).ToArray() : empty;
+ var groupUsers = userGroup?.HasIdentity ?? false ? _userRepository.GetAllInGroup(userGroup.Id).ToArray() : empty;
var xGroupUsers = groupUsers.ToDictionary(x => x.Id, x => x);
var groupIds = groupUsers.Select(x => x.Id).ToArray();
var addedUserIds = userIds.Except(groupIds);
diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs
index 2f0d8eac12..227550e0d9 100644
--- a/src/Umbraco.Core/Services/UserServiceExtensions.cs
+++ b/src/Umbraco.Core/Services/UserServiceExtensions.cs
@@ -32,7 +32,7 @@ namespace Umbraco.Extensions
///
/// Specifying nothing will return all permissions for all nodes
/// An enumerable list of
- public static EntityPermissionCollection GetPermissions(this IUserService service, IUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
+ public static EntityPermissionCollection GetPermissions(this IUserService service, IUserGroup? group, bool fallbackToDefaultPermissions, params int[] nodeIds)
{
return service.GetPermissions(new[] {group}, fallbackToDefaultPermissions, nodeIds);
}
diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs
index 867c90be40..17f7c0a67d 100644
--- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs
+++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberRepository.cs
@@ -290,7 +290,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement
ordering);
}
- public IMember? GetByUsername(string username) =>
+ public IMember? GetByUsername(string? username) =>
_memberByUsernameCachePolicy.Get(username, PerformGetByUsername, PerformGetAllByUsername);
public int[] GetMemberIds(string[] usernames)
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs b/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
index 9f948716c6..64e04f7810 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeIdentityUser.cs
@@ -29,7 +29,7 @@ namespace Umbraco.Cms.Core.Security
/// Used to construct a new instance without an identity
///
/// This is allowed to be null (but would need to be filled in if trying to persist this instance)
- public static BackOfficeIdentityUser CreateNew(GlobalSettings globalSettings, string username, string email, string culture, string? name = null)
+ public static BackOfficeIdentityUser CreateNew(GlobalSettings globalSettings, string? username, string email, string culture, string? name = null)
{
if (string.IsNullOrWhiteSpace(username))
{
diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
index 2d1e9198a2..74c14ddd62 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
@@ -190,7 +190,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
else
{
- BackOfficeExternaLoginProviderScheme opt = await _externalAuthenticationOptions.GetAsync(authType.Name);
+ BackOfficeExternaLoginProviderScheme? opt = await _externalAuthenticationOptions.GetAsync(authType.Name);
if (opt == null)
{
return BadRequest($"Could not find external authentication options registered for provider {unlinkLoginModel.LoginProvider}");
diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
index e01759791d..9dce470b3e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
@@ -391,7 +391,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return RedirectToLocal(Url.Action(nameof(Default), this.GetControllerName()));
}
- ExternalLoginInfo info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
+ ExternalLoginInfo? info = await _signInManager.GetExternalLoginInfoAsync(await _userManager.GetUserIdAsync(user));
if (info == null)
{
@@ -448,7 +448,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var oauthRedirectAuthProvider = _externalLogins.GetAutoLoginProvider();
if (!oauthRedirectAuthProvider.IsNullOrWhiteSpace())
{
- return ExternalLogin(oauthRedirectAuthProvider);
+ return ExternalLogin(oauthRedirectAuthProvider!);
}
}
diff --git a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs
index 23c955219a..65052df636 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/TemplateController.cs
@@ -14,6 +14,7 @@ using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.Authorization;
using Umbraco.Cms.Web.Common.DependencyInjection;
+using Umbraco.Extensions;
using Constants = Umbraco.Cms.Core.Constants;
namespace Umbraco.Cms.Web.BackOffice.Controllers
@@ -55,7 +56,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public TemplateDisplay GetByAlias(string alias)
+ public TemplateDisplay? GetByAlias(string alias)
{
var template = _fileService.GetTemplate(alias);
return template == null ? null : _umbracoMapper.Map(template);
@@ -65,9 +66,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Get all templates
///
///
- public IEnumerable GetAll()
+ public IEnumerable? GetAll()
{
- return _fileService.GetTemplates().Select(_umbracoMapper.Map);
+ return _fileService.GetTemplates()?.Select(_umbracoMapper.Map).WhereNotNull();
}
///
@@ -75,7 +76,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public ActionResult GetById(int id)
+ public ActionResult GetById(int id)
{
var template = _fileService.GetTemplate(id);
if (template == null)
@@ -90,7 +91,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public ActionResult GetById(Guid id)
+ public ActionResult GetById(Guid id)
{
var template = _fileService.GetTemplate(id);
if (template == null)
@@ -104,7 +105,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public ActionResult GetById(Udi id)
+ public ActionResult GetById(Udi id)
{
var guidUdi = id as GuidUdi;
if (guidUdi == null)
@@ -136,7 +137,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return Ok();
}
- public TemplateDisplay GetScaffold(int id)
+ public TemplateDisplay? GetScaffold(int id)
{
//empty default
var dt = new Template(_shortStringHelper, string.Empty, string.Empty);
@@ -154,7 +155,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var content = _defaultViewContentProvider.GetDefaultFileContent( layoutPageAlias: dt.MasterTemplateAlias );
var scaffold = _umbracoMapper.Map(dt);
- scaffold.Content = content;
+ if (scaffold is not null)
+ {
+ scaffold.Content = content;
+ }
+
return scaffold;
}
@@ -244,7 +249,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
else
{
//create
- ITemplate master = null;
+ ITemplate? master = null;
if (string.IsNullOrEmpty(display.MasterTemplateAlias) == false)
{
master = _fileService.GetTemplate(display.MasterTemplateAlias);
diff --git a/src/Umbraco.Web.BackOffice/Controllers/TemplateQueryController.cs b/src/Umbraco.Web.BackOffice/Controllers/TemplateQueryController.cs
index d0aadac744..86a65ac977 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/TemplateQueryController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/TemplateQueryController.cs
@@ -75,11 +75,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
public QueryResultModel PostTemplateQuery(QueryModel model)
{
var queryExpression = new StringBuilder();
- IEnumerable contents;
+ IEnumerable? contents;
if (model == null)
{
- contents = _publishedContentQuery.ContentAtRoot().FirstOrDefault().Children(_variationContextAccessor);
+ contents = _publishedContentQuery.ContentAtRoot().FirstOrDefault()?.Children(_variationContextAccessor);
queryExpression.Append("Umbraco.ContentAtRoot().FirstOrDefault().Children()");
}
else
@@ -90,7 +90,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// timing should be fairly correct, due to the fact that all the linq statements are yield returned.
var timer = new Stopwatch();
timer.Start();
- var results = contents.ToList();
+ var results = contents?.ToList() ?? new List();
timer.Stop();
return new QueryResultModel
@@ -106,12 +106,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
};
}
- private IEnumerable PostTemplateValue(QueryModel model, StringBuilder queryExpression)
+ private IEnumerable? PostTemplateValue(QueryModel model, StringBuilder queryExpression)
{
var indent = Environment.NewLine + " ";
// set the source
- IPublishedContent sourceDocument;
+ IPublishedContent? sourceDocument;
if (model.Source != null && model.Source.Id > 0)
{
sourceDocument = _publishedContentQuery.Content(model.Source.Id);
@@ -128,7 +128,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
// get children, optionally filtered by type
- IEnumerable contents;
+ IEnumerable? contents;
queryExpression.Append(indent);
if (model.ContentType != null && !model.ContentType.Alias.IsNullOrWhiteSpace())
{
@@ -145,25 +145,28 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
queryExpression.Append(".Children()");
}
- // apply filters
- foreach (var condition in model.Filters.Where(x => !x.ConstraintValue.IsNullOrWhiteSpace()))
+ if (model.Filters is not null)
{
- //x is passed in as the parameter alias for the linq where statement clause
- var operation = condition.BuildCondition("x");
+ // apply filters
+ foreach (var condition in model.Filters.Where(x => !x.ConstraintValue.IsNullOrWhiteSpace()))
+ {
+ //x is passed in as the parameter alias for the linq where statement clause
+ var operation = condition.BuildCondition("x");
//for review - this uses a tonized query rather then the normal linq query.
- contents = contents.Where(operation.Compile());
- queryExpression.Append(indent);
- queryExpression.AppendFormat(".Where({0})", operation);
+ contents = contents?.Where(operation.Compile());
+ queryExpression.Append(indent);
+ queryExpression.AppendFormat(".Where({0})", operation);
+ }
}
// always add IsVisible() to the query
- contents = contents.Where(x => x.IsVisible(_publishedValueFallback));
+ contents = contents?.Where(x => x.IsVisible(_publishedValueFallback));
queryExpression.Append(indent);
queryExpression.Append(".Where(x => x.IsVisible())");
// apply sort
- if (model.Sort != null && !model.Sort.Property.Alias.IsNullOrWhiteSpace())
+ if (model.Sort != null && (!model.Sort.Property?.Alias.IsNullOrWhiteSpace() ?? false))
{
contents = SortByDefaultPropertyValue(contents, model.Sort);
@@ -177,7 +180,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// take
if (model.Take > 0)
{
- contents = contents.Take(model.Take);
+ contents = contents?.Take(model.Take);
queryExpression.Append(indent);
queryExpression.AppendFormat(".Take({0})", model.Take);
}
@@ -199,30 +202,30 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
}
- private IEnumerable SortByDefaultPropertyValue(IEnumerable contents, SortExpression sortExpression)
+ private IEnumerable? SortByDefaultPropertyValue(IEnumerable? contents, SortExpression sortExpression)
{
- switch (sortExpression.Property.Alias)
+ switch (sortExpression.Property?.Alias)
{
case "id":
return sortExpression.Direction == "ascending"
- ? contents.OrderBy(x => x.Id)
- : contents.OrderByDescending(x => x.Id);
+ ? contents?.OrderBy(x => x.Id)
+ : contents?.OrderByDescending(x => x.Id);
case "createDate":
return sortExpression.Direction == "ascending"
- ? contents.OrderBy(x => x.CreateDate)
- : contents.OrderByDescending(x => x.CreateDate);
+ ? contents?.OrderBy(x => x.CreateDate)
+ : contents?.OrderByDescending(x => x.CreateDate);
case "publishDate":
return sortExpression.Direction == "ascending"
- ? contents.OrderBy(x => x.UpdateDate)
- : contents.OrderByDescending(x => x.UpdateDate);
+ ? contents?.OrderBy(x => x.UpdateDate)
+ : contents?.OrderByDescending(x => x.UpdateDate);
case "name":
return sortExpression.Direction == "ascending"
- ? contents.OrderBy(x => x.Name)
- : contents.OrderByDescending(x => x.Name);
+ ? contents?.OrderBy(x => x.Name)
+ : contents?.OrderByDescending(x => x.Name);
default:
return sortExpression.Direction == "ascending"
- ? contents.OrderBy(x => x.Name)
- : contents.OrderByDescending(x => x.Name);
+ ? contents?.OrderBy(x => x.Name)
+ : contents?.OrderByDescending(x => x.Name);
}
}
@@ -233,7 +236,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
public IEnumerable GetContentTypes()
{
var contentTypes = _contentTypeService.GetAll()
- .Select(x => new ContentTypeModel { Alias = x.Alias, Name = _localizedTextService.Localize("template", "contentOfType", tokens: new string[] { x.Name }) })
+ .Select(x => new ContentTypeModel { Alias = x.Alias, Name = _localizedTextService.Localize("template", "contentOfType", tokens: new string[] { x.Name ?? string.Empty }) })
.OrderBy(x => x.Name).ToList();
contentTypes.Insert(0, new ContentTypeModel { Alias = string.Empty, Name = _localizedTextService.Localize("template", "allContent") });
diff --git a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs
index 63696a8dea..d11334f98e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/TourController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/TourController.cs
@@ -14,6 +14,7 @@ using Umbraco.Cms.Core.Security;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Tour;
using Umbraco.Cms.Web.Common.Attributes;
+using Umbraco.Extensions;
namespace Umbraco.Cms.Web.BackOffice.Controllers
{
@@ -48,7 +49,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (_tourSettings.EnableTours == false)
return result;
- var user = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ var user = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
if (user == null)
return result;
@@ -134,6 +135,10 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
var resourceStream = GetType().Assembly.GetManifestResourceStream(fileName);
+ if (resourceStream is null)
+ {
+ return string.Empty;
+ }
using var reader = new StreamReader(resourceStream, Encoding.UTF8);
return await reader.ReadToEndAsync();
}
@@ -176,7 +181,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
List filters,
List aliasOnlyFilters,
Func> fileNameToFileContent,
- string pluginName = null)
+ string? pluginName = null)
{
var fileName = Path.GetFileNameWithoutExtension(tourFile);
if (fileName == null) return;
@@ -198,20 +203,20 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var contents = await fileNameToFileContent(tourFile);
var tours = JsonConvert.DeserializeObject(contents);
- var backOfficeTours = tours.Where(x =>
- aliasFilters.Count == 0 || aliasFilters.All(filter => filter.IsMatch(x.Alias)) == false);
+ var backOfficeTours = tours?.Where(x =>
+ aliasFilters.Count == 0 || aliasFilters.WhereNotNull().All(filter => filter.IsMatch(x.Alias)) == false);
- var user = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ var user = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
- var localizedTours = backOfficeTours.Where(x =>
- string.IsNullOrWhiteSpace(x.Culture) || x.Culture.Equals(user.Language,
+ var localizedTours = backOfficeTours?.Where(x =>
+ string.IsNullOrWhiteSpace(x.Culture) || x.Culture.Equals(user?.Language,
StringComparison.InvariantCultureIgnoreCase)).ToList();
var tour = new BackOfficeTourFile
{
FileName = Path.GetFileNameWithoutExtension(tourFile),
PluginName = pluginName,
- Tours = localizedTours
+ Tours = localizedTours ?? new List(),
};
//don't add if all of the tours are filtered
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs b/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs
index 5b548a146a..9e81cb196e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UmbracoAuthorizedApiController.cs
@@ -63,17 +63,17 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// creates validation problem details instance.
// borrowed from netcore: https://github.com/dotnet/aspnetcore/blob/main/src/Mvc/Mvc.Core/src/ControllerBase.cs#L1970
- protected ValidationProblemDetails GetValidationProblemDetails(
- string detail = null,
- string instance = null,
+ protected ValidationProblemDetails? GetValidationProblemDetails(
+ string? detail = null,
+ string? instance = null,
int? statusCode = null,
- string title = null,
- string type = null,
- [ActionResultObjectValue] ModelStateDictionary modelStateDictionary = null)
+ string? title = null,
+ string? type = null,
+ [ActionResultObjectValue] ModelStateDictionary? modelStateDictionary = null)
{
modelStateDictionary ??= ModelState;
- ValidationProblemDetails validationProblem;
+ ValidationProblemDetails? validationProblem;
if (ProblemDetailsFactory == null)
{
// ProblemDetailsFactory may be null in unit testing scenarios. Improvise to make this more testable.
@@ -108,7 +108,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
protected virtual ActionResult ValidationProblem(string errorMessage)
{
- ValidationProblemDetails problemDetails = GetValidationProblemDetails(errorMessage);
+ ValidationProblemDetails? problemDetails = GetValidationProblemDetails(errorMessage);
return new ValidationErrorResult(problemDetails);
}
@@ -118,7 +118,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- protected virtual ActionResult ValidationProblem(object value, int statusCode)
+ protected virtual ActionResult ValidationProblem(object? value, int statusCode)
=> new ValidationErrorResult(value, statusCode);
///
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs b/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs
index dad9c1d4ef..9620848666 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UpdateCheckController.cs
@@ -41,11 +41,11 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
[UpdateCheckResponseFilter]
- public async Task GetCheck()
+ public async Task GetCheck()
{
var updChkCookie = _cookieManager.GetCookieValue("UMB_UPDCHK");
var updateCheckCookie = updChkCookie ?? string.Empty;
- if (_globalSettings.VersionCheckPeriod > 0 && string.IsNullOrEmpty(updateCheckCookie) && _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsAdmin())
+ if (_globalSettings.VersionCheckPeriod > 0 && string.IsNullOrEmpty(updateCheckCookie) && (_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.IsAdmin() ?? false))
{
try
{
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UserGroupEditorAuthorizationHelper.cs b/src/Umbraco.Web.BackOffice/Controllers/UserGroupEditorAuthorizationHelper.cs
index 35eab84432..e71018c460 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UserGroupEditorAuthorizationHelper.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UserGroupEditorAuthorizationHelper.cs
@@ -56,9 +56,9 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public Attempt AuthorizeGroupAccess(IUser currentUser, params string[] groupAliases)
+ public Attempt AuthorizeGroupAccess(IUser? currentUser, params string[] groupAliases)
{
- if (currentUser.IsAdmin())
+ if (currentUser?.IsAdmin() ?? false)
return Attempt.Succeed();
var existingGroups = _userService.GetUserGroupsByAlias(groupAliases);
@@ -67,12 +67,12 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
{
// We're dealing with new groups,
// so authorization should be given to any user with access to Users section
- if (currentUser.AllowedSections.Contains(Constants.Applications.Users))
+ if (currentUser?.AllowedSections.Contains(Constants.Applications.Users) ?? false)
return Attempt.Succeed();
}
- var userGroups = currentUser.Groups.Select(x => x.Alias).ToArray();
- var missingAccess = groupAliases.Except(userGroups).ToArray();
+ var userGroups = currentUser?.Groups.Select(x => x.Alias).ToArray();
+ var missingAccess = groupAliases.Except(userGroups ?? Array.Empty()).ToArray();
return missingAccess.Length == 0
? Attempt.Succeed()
: Attempt.Fail("User is not a member of " + string.Join(", ", missingAccess));
@@ -82,16 +82,16 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Authorize that the user is not adding a section to the group that they don't have access to
///
public Attempt AuthorizeSectionChanges(
- IUser currentUser,
- IEnumerable existingSections,
- IEnumerable proposedAllowedSections)
+ IUser? currentUser,
+ IEnumerable? existingSections,
+ IEnumerable? proposedAllowedSections)
{
- if (currentUser.IsAdmin())
+ if (currentUser?.IsAdmin() ?? false)
return Attempt.Succeed();
- var sectionsAdded = proposedAllowedSections.Except(existingSections).ToArray();
- var sectionAccessMissing = sectionsAdded.Except(currentUser.AllowedSections).ToArray();
- return sectionAccessMissing.Length > 0
+ var sectionsAdded = proposedAllowedSections?.Except(existingSections ?? Enumerable.Empty()).ToArray();
+ var sectionAccessMissing = sectionsAdded?.Except(currentUser?.AllowedSections ?? Enumerable.Empty()).ToArray();
+ return sectionAccessMissing?.Length > 0
? Attempt.Fail("Current user doesn't have access to add these sections " + string.Join(", ", sectionAccessMissing))
: Attempt.Succeed();
}
@@ -105,7 +105,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public Attempt AuthorizeStartNodeChanges(IUser currentUser,
+ public Attempt AuthorizeStartNodeChanges(IUser? currentUser,
int? currentContentStartId,
int? proposedContentStartId,
int? currentMediaStartId,
@@ -116,7 +116,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var content = _contentService.GetById(proposedContentStartId.Value);
if (content != null)
{
- if (currentUser.HasPathAccess(content, _entityService, _appCaches) == false)
+ if (currentUser?.HasPathAccess(content, _entityService, _appCaches) == false)
return Attempt.Fail("Current user doesn't have access to the content path " + content.Path);
}
}
@@ -126,7 +126,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var media = _mediaService.GetById(proposedMediaStartId.Value);
if (media != null)
{
- if (currentUser.HasPathAccess(media, _entityService, _appCaches) == false)
+ if (currentUser?.HasPathAccess(media, _entityService, _appCaches) == false)
return Attempt.Fail("Current user doesn't have access to the media path " + media.Path);
}
}
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs
index ad8d11f95a..a6b9772d43 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UserGroupsController.cs
@@ -57,7 +57,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
[UserGroupValidate]
- public ActionResult PostSaveUserGroup(UserGroupSave userGroupSave)
+ public ActionResult PostSaveUserGroup(UserGroupSave userGroupSave)
{
if (userGroupSave == null) throw new ArgumentNullException(nameof(userGroupSave));
@@ -65,23 +65,23 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var authHelper = new UserGroupEditorAuthorizationHelper(
_userService, _contentService, _mediaService, _entityService, _appCaches);
- var isAuthorized = authHelper.AuthorizeGroupAccess(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, userGroupSave.Alias);
+ var isAuthorized = authHelper.AuthorizeGroupAccess(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, userGroupSave.Alias);
if (isAuthorized == false)
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,
- userGroupSave.PersistedUserGroup.AllowedSections,
+ _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser,
+ userGroupSave.PersistedUserGroup?.AllowedSections,
userGroupSave.Sections);
if (isAuthorized == false)
return Unauthorized(isAuthorized.Result);
//if start nodes were changed we need to check that the current user has access to them
- isAuthorized = authHelper.AuthorizeStartNodeChanges(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser,
- userGroupSave.PersistedUserGroup.StartContentId,
+ isAuthorized = authHelper.AuthorizeStartNodeChanges(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser,
+ userGroupSave.PersistedUserGroup?.StartContentId,
userGroupSave.StartContentId,
- userGroupSave.PersistedUserGroup.StartMediaId,
+ userGroupSave.PersistedUserGroup?.StartMediaId,
userGroupSave.StartMediaId);
if (isAuthorized == false)
return Unauthorized(isAuthorized.Result);
@@ -93,43 +93,48 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
_umbracoMapper.Map(userGroupSave, userGroupSave.PersistedUserGroup);
//save the group
- _userService.Save(userGroupSave.PersistedUserGroup, userGroupSave.Users.ToArray());
+ _userService.Save(userGroupSave.PersistedUserGroup, userGroupSave.Users?.ToArray());
//deal with permissions
//remove ones that have been removed
var existing = _userService.GetPermissions(userGroupSave.PersistedUserGroup, true)
.ToDictionary(x => x.EntityId, x => x);
- var toRemove = existing.Keys.Except(userGroupSave.AssignedPermissions.Select(x => x.Key));
- foreach (var contentId in toRemove)
+ if (userGroupSave.AssignedPermissions is not null)
{
- _userService.RemoveUserGroupPermissions(userGroupSave.PersistedUserGroup.Id, contentId);
- }
+ var toRemove = existing.Keys.Except(userGroupSave.AssignedPermissions.Select(x => x.Key));
+ foreach (var contentId in toRemove)
+ {
+ _userService.RemoveUserGroupPermissions(userGroupSave.PersistedUserGroup?.Id ?? default, contentId);
+ }
- //update existing
- foreach (var assignedPermission in userGroupSave.AssignedPermissions)
- {
- _userService.ReplaceUserGroupPermissions(
- userGroupSave.PersistedUserGroup.Id,
- assignedPermission.Value.Select(x => x[0]),
- assignedPermission.Key);
+ //update existing
+ foreach (var assignedPermission in userGroupSave.AssignedPermissions)
+ {
+ _userService.ReplaceUserGroupPermissions(
+ userGroupSave.PersistedUserGroup?.Id ?? default,
+ assignedPermission.Value.Select(x => x[0]),
+ assignedPermission.Key);
+ }
}
var display = _umbracoMapper.Map(userGroupSave.PersistedUserGroup);
- display.AddSuccessNotification(_localizedTextService.Localize("speechBubbles","operationSavedHeader"), _localizedTextService.Localize("speechBubbles","editUserGroupSaved"));
+ display?.AddSuccessNotification(_localizedTextService.Localize("speechBubbles","operationSavedHeader"), _localizedTextService.Localize("speechBubbles","editUserGroupSaved"));
return display;
}
private void EnsureNonAdminUserIsInSavedUserGroup(UserGroupSave userGroupSave)
{
- if (_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsAdmin())
+ if (_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.IsAdmin() ?? false)
{
return;
}
- var userIds = userGroupSave.Users.ToList();
- if (userIds.Contains(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id))
+ var userIds = userGroupSave.Users?.ToList();
+ if (_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser is null ||
+ userIds is null ||
+ userIds.Contains(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Id))
{
return;
}
@@ -142,7 +147,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Returns the scaffold for creating a new user group
///
///
- public UserGroupDisplay GetEmptyUserGroup()
+ public UserGroupDisplay? GetEmptyUserGroup()
{
return _umbracoMapper.Map(new UserGroup(_shortStringHelper));
}
@@ -151,24 +156,24 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
/// Returns all user groups
///
///
- public IEnumerable GetUserGroups(bool onlyCurrentUserGroups = true)
+ public IEnumerable GetUserGroups(bool onlyCurrentUserGroups = true)
{
var allGroups = _umbracoMapper.MapEnumerable(_userService.GetAllUserGroups())
.ToList();
- var isAdmin = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsAdmin();
+ var isAdmin = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.IsAdmin() ?? false;
if (isAdmin) return allGroups;
if (onlyCurrentUserGroups == false)
{
//this user is not an admin so in that case we need to exclude all admin users
- allGroups.RemoveAt(allGroups.IndexOf(allGroups.Find(basic => basic.Alias == Constants.Security.AdminGroupAlias)));
+ allGroups.RemoveAt(allGroups.IndexOf(allGroups.Find(basic => basic?.Alias == Constants.Security.AdminGroupAlias)));
return allGroups;
}
//we cannot return user groups that this user does not have access to
- var currentUserGroups = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Groups.Select(x => x.Alias).ToArray();
- return allGroups.Where(x => currentUserGroups.Contains(x.Alias)).ToArray();
+ var currentUserGroups = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Groups.Select(x => x.Alias).ToArray();
+ return allGroups.WhereNotNull().Where(x => currentUserGroups?.Contains(x.Alias) ?? false).ToArray();
}
///
@@ -176,7 +181,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
[Authorize(Policy = AuthorizationPolicies.UserBelongsToUserGroupInRequest)]
- public ActionResult GetUserGroup(int id)
+ public ActionResult GetUserGroup(int id)
{
var found = _userService.GetUserGroupById(id);
if (found == null)
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
index ad766e034c..ae07b7f4d0 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
@@ -136,7 +136,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
public ActionResult GetCurrentUserAvatarUrls()
{
- var urls = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator);
+ var urls = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator);
if (urls == null)
return ValidationProblem("Could not access Gravatar endpoint");
@@ -223,8 +223,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (filePath.IsNullOrWhiteSpace() == false)
{
- if (_mediaFileManager.FileSystem.FileExists(filePath))
- _mediaFileManager.FileSystem.DeleteFile(filePath);
+ if (_mediaFileManager.FileSystem.FileExists(filePath!))
+ _mediaFileManager.FileSystem.DeleteFile(filePath!);
}
return found.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator);
@@ -237,7 +237,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
- public ActionResult GetById(int id)
+ public ActionResult GetById(int id)
{
var user = _userService.GetUserById(id);
if (user == null)
@@ -255,7 +255,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
[OutgoingEditorModelEvent]
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
- public ActionResult> GetByIds([FromJsonPath]int[] ids)
+ public ActionResult> GetByIds([FromJsonPath]int[] ids)
{
if (ids == null)
{
@@ -291,8 +291,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
int pageSize = 10,
string orderBy = "username",
Direction orderDirection = Direction.Ascending,
- [FromQuery]string[] userGroups = null,
- [FromQuery]UserState[] userStates = null,
+ [FromQuery]string[]? userGroups = null,
+ [FromQuery]UserState[]? userStates = null,
string filter = "")
{
//following the same principle we had in previous versions, we would only show admins to admins, see
@@ -302,7 +302,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var hideDisabledUsers = _securitySettings.HideDisabledUsersInBackOffice;
var excludeUserGroups = new string[0];
- var isAdmin = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsAdmin();
+ var isAdmin = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.IsAdmin();
if (isAdmin == false)
{
//this user is not an admin so in that case we need to exclude all admin users
@@ -311,7 +311,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var filterQuery = _sqlContext.Query();
- if (!_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.IsSuper())
+ if (!_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.IsSuper() ?? false)
{
// only super can see super - but don't use IsSuper, cannot be mapped to SQL
//filterQuery.Where(x => !x.IsSuper());
@@ -320,7 +320,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
if (filter.IsNullOrWhiteSpace() == false)
{
- filterQuery.Where(x => x.Name.Contains(filter) || x.Username.Contains(filter));
+ filterQuery.Where(x => x.Name!.Contains(filter) || x.Username.Contains(filter));
}
if (hideDisabledUsers)
@@ -337,7 +337,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var paged = new PagedUserResult(total, pageNumber, pageSize)
{
- Items = _umbracoMapper.MapEnumerable(result),
+ Items = _umbracoMapper.MapEnumerable(result).WhereNotNull(),
UserStates = _userService.GetUserStates()
};
@@ -349,7 +349,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public async Task> PostCreateUser(UserInvite userSave)
+ public async Task> PostCreateUser(UserInvite userSave)
{
if (userSave == null) throw new ArgumentNullException("userSave");
@@ -376,7 +376,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
//Perform authorization here to see if the current user can actually save this user with the info being requested
- var canSaveUser = _userEditorAuthorizationHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, null, null, null, userSave.UserGroups);
+ var canSaveUser = _userEditorAuthorizationHelper.IsAuthorized(_backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser, null, null, null, userSave.UserGroups);
if (canSaveUser == false)
{
return Unauthorized(canSaveUser.Result);
@@ -410,13 +410,21 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
//map the save info over onto the user
user = _umbracoMapper.Map(userSave, user);
- //since the back office user is creating this user, they will be set to approved
- user.IsApproved = true;
+ if (user is not null)
+ {
+ // Since the back office user is creating this user, they will be set to approved
+ user.IsApproved = true;
- _userService.Save(user);
+ _userService.Save(user);
+ }
var display = _umbracoMapper.Map(user);
- display.ResetPasswordValue = resetPassword;
+
+ if (display is not null)
+ {
+ display.ResetPasswordValue = resetPassword;
+ }
+
return display;
}
@@ -428,7 +436,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
/// This will email the user an invite and generate a token that will be validated in the email
///
- public async Task> PostInviteUser(UserInvite userSave)
+ public async Task> PostInviteUser(UserInvite userSave)
{
if (userSave == null)
{
@@ -448,14 +456,14 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
else
{
// first validate the username if we're showing it
- ActionResult userResult = CheckUniqueUsername(userSave.Username, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
+ ActionResult userResult = CheckUniqueUsername(userSave.Username, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
if (userResult.Result is not null)
{
return userResult.Result;
}
}
- IUser user = CheckUniqueEmail(userSave.Email, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
+ IUser? user = CheckUniqueEmail(userSave.Email, u => u.LastLoginDate != default || u.EmailConfirmedDate.HasValue);
if (ModelState.IsValid == false)
{
@@ -468,7 +476,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
}
// Perform authorization here to see if the current user can actually save this user with the info being requested
- var canSaveUser = _userEditorAuthorizationHelper.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 ValidationProblem(canSaveUser.Result, StatusCodes.Status401Unauthorized);
@@ -494,21 +502,25 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
// map the save info over onto the user
user = _umbracoMapper.Map(userSave, user);
- // ensure the invited date is set
- user.InvitedDate = DateTime.Now;
+ if (user is not null)
+ {
+ // ensure the invited date is set
+ user.InvitedDate = DateTime.Now;
+
+ // Save the updated user (which will process the user groups too)
+ _userService.Save(user);
+ }
- // Save the updated user (which will process the user groups too)
- _userService.Save(user);
var display = _umbracoMapper.Map(user);
// send the email
- await SendUserInviteEmailAsync(display, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Name, _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser.Email, user, userSave.Message);
+ await SendUserInviteEmailAsync(display, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Name, _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser?.Email, user, userSave.Message);
- display.AddSuccessNotification(_localizedTextService.Localize("speechBubbles","resendInviteHeader"), _localizedTextService.Localize("speechBubbles","resendInviteSuccess", new[] { user.Name }));
+ display?.AddSuccessNotification(_localizedTextService.Localize("speechBubbles","resendInviteHeader"), _localizedTextService.Localize("speechBubbles","resendInviteSuccess", new[] { user?.Name }));
return display;
}
- private IUser CheckUniqueEmail(string email, Func extraCheck)
+ private IUser? CheckUniqueEmail(string email, Func? extraCheck)
{
var user = _userService.GetByEmail(email);
if (user != null && (extraCheck == null || extraCheck(user)))
@@ -518,7 +530,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return user;
}
- private ActionResult CheckUniqueUsername(string username, Func extraCheck)
+ private ActionResult CheckUniqueUsername(string? username, Func? extraCheck)
{
var user = _userService.GetByUsername(username);
if (user != null && (extraCheck == null || extraCheck(user)))
@@ -529,19 +541,19 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return ValidationProblem(ModelState);
}
- return new ActionResult(user);
+ return new ActionResult(user);
}
- private async Task SendUserInviteEmailAsync(UserBasic userDisplay, string from, string fromEmail, IUser to, string message)
+ private async Task SendUserInviteEmailAsync(UserBasic? userDisplay, string? from, string? fromEmail, IUser? to, string? message)
{
- var user = await _userManager.FindByIdAsync(((int) userDisplay.Id).ToString());
+ var user = await _userManager.FindByIdAsync(((int?) userDisplay?.Id).ToString());
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
// Use info from SMTP Settings if configured, otherwise set fromEmail as fallback
var senderEmail = !string.IsNullOrEmpty(_globalSettings.Smtp?.From) ? _globalSettings.Smtp.From : fromEmail;
var inviteToken = string.Format("{0}{1}{2}",
- (int)userDisplay.Id,
+ (int?)userDisplay?.Id,
WebUtility.UrlEncode("|"),
token.ToUrlBase64());
@@ -561,16 +573,16 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var emailSubject = _localizedTextService.Localize("user","inviteEmailCopySubject",
// Ensure the culture of the found user is used for the email!
- UmbracoUserExtensions.GetUserCulture(to.Language, _localizedTextService, _globalSettings));
+ UmbracoUserExtensions.GetUserCulture(to?.Language, _localizedTextService, _globalSettings));
var emailBody = _localizedTextService.Localize("user","inviteEmailCopyFormat",
// Ensure the culture of the found user is used for the email!
- UmbracoUserExtensions.GetUserCulture(to.Language, _localizedTextService, _globalSettings),
- new[] { userDisplay.Name, from, message, inviteUri.ToString(), senderEmail });
+ UmbracoUserExtensions.GetUserCulture(to?.Language, _localizedTextService, _globalSettings),
+ new[] { userDisplay?.Name, from, message, inviteUri.ToString(), senderEmail });
// This needs to be in the correct mailto format including the name, else
// the name cannot be captured in the email sending notification.
// i.e. "Some Person"
- var toMailBoxAddress = new MailboxAddress(to.Name, to.Email);
+ var toMailBoxAddress = new MailboxAddress(to?.Name, to?.Email);
var mailMessage = new EmailMessage(senderEmail, toMailBoxAddress.ToString(), emailSubject, emailBody, true);
@@ -583,7 +595,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
[OutgoingEditorModelEvent]
- public ActionResult PostSaveUser(UserSave userSave)
+ public ActionResult PostSaveUser(UserSave userSave)
{
if (userSave == null) throw new ArgumentNullException(nameof(userSave));
@@ -597,7 +609,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return NotFound();
//Perform authorization here to see if the current user can actually save this user with the info being requested
- var canSaveUser = _userEditorAuthorizationHelper.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)
{
return Unauthorized(canSaveUser.Result);
@@ -657,15 +669,15 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
var display = _umbracoMapper.Map(user);
// determine if the user has changed their own language;
- var currentUser = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ var currentUser = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
var userHasChangedOwnLanguage =
- user.Id == currentUser.Id && currentUser.Language != user.Language;
+ user.Id == currentUser?.Id && currentUser.Language != user.Language;
var textToLocalise = userHasChangedOwnLanguage ? "operationSavedHeaderReloadUser" : "operationSavedHeader";
var culture = userHasChangedOwnLanguage
- ? CultureInfo.GetCultureInfo(user.Language)
+ ? CultureInfo.GetCultureInfo(user.Language!)
: Thread.CurrentThread.CurrentUICulture;
- display.AddSuccessNotification(_localizedTextService.Localize("speechBubbles", textToLocalise, culture), _localizedTextService.Localize("speechBubbles","editUserSaved", culture));
+ display?.AddSuccessNotification(_localizedTextService.Localize("speechBubbles", textToLocalise, culture), _localizedTextService.Localize("speechBubbles","editUserSaved", culture));
return display;
}
@@ -674,7 +686,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
///
///
///
- public async Task>> PostChangePassword(ChangingPasswordModel changingPasswordModel)
+ public async Task>> PostChangePassword(ChangingPasswordModel changingPasswordModel)
{
changingPasswordModel = changingPasswordModel ?? throw new ArgumentNullException(nameof(changingPasswordModel));
@@ -683,37 +695,40 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
return ValidationProblem(ModelState);
}
- IUser found = _userService.GetUserById(changingPasswordModel.Id);
+ IUser? found = _userService.GetUserById(changingPasswordModel.Id);
if (found == null)
{
return NotFound();
}
- IUser currentUser = _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser;
+ IUser? currentUser = _backofficeSecurityAccessor.BackOfficeSecurity?.CurrentUser;
// if it's the current user, the current user cannot reset their own password without providing their old password
- if (currentUser.Username == found.Username && string.IsNullOrEmpty(changingPasswordModel.OldPassword))
+ if (currentUser?.Username == found.Username && string.IsNullOrEmpty(changingPasswordModel.OldPassword))
{
return ValidationProblem("Password reset is not allowed without providing old password");
}
- if (!currentUser.IsAdmin() && found.IsAdmin())
+ if ((!currentUser?.IsAdmin() ?? false) && found.IsAdmin())
{
return ValidationProblem("The current user cannot change the password for the specified user");
}
- Attempt passwordChangeResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _userManager);
+ Attempt passwordChangeResult = await _passwordChanger.ChangePasswordWithIdentityAsync(changingPasswordModel, _userManager);
if (passwordChangeResult.Success)
{
- var result = new ModelWithNotifications(passwordChangeResult.Result.ResetPassword);
+ var result = new ModelWithNotifications(passwordChangeResult.Result?.ResetPassword);
result.AddSuccessNotification(_localizedTextService.Localize("general","success"), _localizedTextService.Localize("user","passwordChangedGeneric"));
return result;
}
- foreach (string memberName in passwordChangeResult.Result.ChangeError.MemberNames)
+ if (passwordChangeResult.Result?.ChangeError is not null)
{
- ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage);
+ foreach (string memberName in passwordChangeResult.Result.ChangeError.MemberNames)
+ {
+ ModelState.AddModelError(memberName, passwordChangeResult.Result.ChangeError.ErrorMessage ?? string.Empty);
+ }
}
return ValidationProblem(ModelState);
@@ -727,8 +742,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
[Authorize(Policy = AuthorizationPolicies.AdminUserEditsRequireAdmin)]
public IActionResult PostDisableUsers([FromQuery]int[] userIds)
{
- var tryGetCurrentUserId = _backofficeSecurityAccessor.BackOfficeSecurity.GetUserId();
- if (tryGetCurrentUserId.Success && userIds.Contains(tryGetCurrentUserId.Result.Value))
+ var tryGetCurrentUserId = _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId() ?? Attempt.Fail();
+ if (tryGetCurrentUserId.Success && userIds.Contains(tryGetCurrentUserId.Result!.Value))
{
return ValidationProblem("The current user cannot disable itself");
}
diff --git a/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs b/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
index 378be18440..3207272b66 100644
--- a/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
+++ b/src/Umbraco.Web.Common/ActionsResults/ValidationErrorResult.cs
@@ -40,12 +40,12 @@ namespace Umbraco.Cms.Web.Common.ActionsResults
public ValidationErrorResult(ModelStateDictionary modelState)
: this(new SimpleValidationModel(modelState.ToErrorDictionary())) { }
- public ValidationErrorResult(object value, int statusCode) : base(value)
+ public ValidationErrorResult(object? value, int statusCode) : base(value)
{
StatusCode = statusCode;
}
- public ValidationErrorResult(object value) : this(value, StatusCodes.Status400BadRequest)
+ public ValidationErrorResult(object? value) : this(value, StatusCodes.Status400BadRequest)
{
}