diff --git a/build/azure-pipelines.yml b/build/azure-pipelines.yml
index ae8ca25f52..328c8dfef5 100644
--- a/build/azure-pipelines.yml
+++ b/build/azure-pipelines.yml
@@ -64,6 +64,11 @@ stages:
gulpFile: src/Umbraco.Web.UI.Client/gulpfile.js
targets: coreBuild
workingDirectory: src/Umbraco.Web.UI.Client
+ - task: UseDotNet@2
+ displayName: Use .Net 7.x
+ inputs:
+ version: 7.x
+ includePreviewVersions: true
- task: DotNetCoreCLI@2
displayName: Run dotnet build
inputs:
@@ -130,41 +135,41 @@ stages:
- task: PowerShell@2
displayName: Install DocFX
inputs:
- targetType: inline
- script: |
- choco install docfx --version=2.59.2 -y
- if ($lastexitcode -ne 0){
- throw ("Error installing DocFX")
- }
+ targetType: inline
+ script: |
+ choco install docfx --version=2.59.2 -y
+ if ($lastexitcode -ne 0){
+ throw ("Error installing DocFX")
+ }
- task: PowerShell@2
displayName: Generate metadata
inputs:
- targetType: inline
- script: |
- docfx metadata "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
- if ($lastexitcode -ne 0){
- throw ("Error generating metadata.")
- }
+ targetType: inline
+ script: |
+ docfx metadata "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
+ if ($lastexitcode -ne 0){
+ throw ("Error generating metadata.")
+ }
- task: PowerShell@2
displayName: Generate documentation
inputs:
- targetType: inline
- script: |
- docfx build "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
- if ($lastexitcode -ne 0){
- throw ("Error generating documentation.")
- }
+ targetType: inline
+ script: |
+ docfx build "$(Build.SourcesDirectory)/build/csharp-docs/docfx.json"
+ if ($lastexitcode -ne 0){
+ throw ("Error generating documentation.")
+ }
- task: ArchiveFiles@2
displayName: Archive C# Docs
inputs:
- rootFolderOrFile: $(Build.SourcesDirectory)/build/csharp-docs/_site
- includeRootFolder: false
- archiveFile: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
+ rootFolderOrFile: $(Build.SourcesDirectory)/build/csharp-docs/_site
+ includeRootFolder: false
+ archiveFile: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
- task: PublishPipelineArtifact@1
displayName: Publish C# Docs
inputs:
- targetPath: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
- artifact: csharp-docs
+ targetPath: $(Build.ArtifactStagingDirectory)/csharp-docs.zip
+ artifact: csharp-docs
# js API Reference
- job:
@@ -192,14 +197,14 @@ stages:
- task: ArchiveFiles@2
displayName: Archive js Docs
inputs:
- rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
- includeRootFolder: false
- archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
+ rootFolderOrFile: $(Build.SourcesDirectory)/src/Umbraco.Web.UI.Docs/api
+ includeRootFolder: false
+ archiveFile: $(Build.ArtifactStagingDirectory)/ui-docs.zip
- task: PublishPipelineArtifact@1
displayName: Publish js Docs
inputs:
- targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
- artifact: ui-docs
+ targetPath: $(Build.ArtifactStagingDirectory)/ui-docs.zip
+ artifact: ui-docs
###############################################
## Test
@@ -228,10 +233,10 @@ stages:
artifact: build_output
path: $(Build.SourcesDirectory)
- task: UseDotNet@2
- condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) # net6 already on the other images
- displayName: Use net6
+ displayName: Use net7
inputs:
- version: 6.x
+ version: 7.x
+ includePreviewVersions: true
- task: DotNetCoreCLI@2
displayName: Run dotnet test
inputs:
@@ -264,10 +269,10 @@ stages:
artifact: build_output
path: $(Build.SourcesDirectory)
- task: UseDotNet@2
- displayName: Use net6
- condition: and(succeeded(), eq(variables['Agent.OS'], 'Darwin')) # net6 already on the other images
+ displayName: Use net7
inputs:
- version: 6.x
+ version: 7.x
+ includePreviewVersions: true
- task: DotNetCoreCLI@2
displayName: Run dotnet test
inputs:
@@ -305,7 +310,7 @@ stages:
- powershell: sqllocaldb start mssqllocaldb
displayName: Start localdb (Windows only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- - powershell: docker run --name mssql -d -p 1433:1433 -e ACCEPT_EULA=Y -e SA_PASSWORD=$(SA_PASSWORD) -e MSSQL_PID=Developer mcr.microsoft.com/mssql/server:2019-latest
+ - powershell: docker run --name mssql -d -p 1433:1433 -e ACCEPT_EULA=Y -e SA_PASSWORD=$(SA_PASSWORD) -e MSSQL_PID=Developer mcr.microsoft.com/mssql/server:2019-latest
displayName: Start SQL Server (Linux only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
- task: DotNetCoreCLI@2
@@ -327,7 +332,7 @@ stages:
displayName: E2E Tests
dependsOn: Build
jobs:
- # E2E Tests
+ # E2E Tests
- job:
displayName: E2E Tests
variables:
@@ -358,7 +363,7 @@ stages:
Windows:
vmImage: 'windows-latest'
pool:
- vmImage: $(vmImage)
+ vmImage: $(vmImage)
steps:
- task: DownloadPipelineArtifact@2
displayName: Download nupkg
@@ -397,7 +402,12 @@ stages:
- powershell: Invoke-Sqlcmd -Query "CREATE DATABASE $env:UmbracoDatabaseName" -ServerInstance $env:UmbracoDatabaseServer
displayName: Create database (Windows only)
condition: and(succeeded(), eq(variables['Agent.OS'], 'Windows_NT'))
- # Linux containers smooth
+ - task: UseDotNet@2
+ displayName: Use .Net 7.x
+ inputs:
+ version: 7.x
+ includePreviewVersions: true
+ # Linux containers smooth
- task: PowerShell@2
condition: and(succeeded(), eq(variables['Agent.OS'], 'Linux'))
displayName: Build & run container (Linux only)
@@ -482,14 +492,17 @@ stages:
inputs:
artifact: nupkg
path: $(Build.ArtifactStagingDirectory)/nupkg
- - task: NuGetCommand@2
- displayName: Nuget push
+ - task: DotNetCoreCLI@2
+ displayName: dotnet restore
inputs:
- command: 'push'
- packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
- nuGetFeedType: 'external'
- publishFeedCredentials: 'MyGet - Pre-releases'
-
+ command: restore
+ projects: '**/umbraco.sln'
+ # TODO: Use NuGetCommand instead of DotNetCoreCLI
+ # - task: NuGetCommand@2
+ # displayName: Restore NuGet Packages
+ # inputs:
+ # restoreSolution: 'umbraco.sln'
+ # feedsToUse: config
- stage: Deploy_NuGet
displayName: NuGet release
dependsOn:
@@ -506,13 +519,11 @@ stages:
inputs:
artifact: nupkg
path: $(Build.ArtifactStagingDirectory)/nupkg
- - task: NuGetCommand@2
- displayName: Nuget push
+ - task: DotNetCoreCLI@2
+ displayName: dotnet restore
inputs:
- command: 'push'
- packagesToPush: $(Build.ArtifactStagingDirectory)/**/*.nupkg
- nuGetFeedType: 'external'
- publishFeedCredentials: 'NuGet - Umbraco.*'
+ command: restore
+ projects: '**/umbraco.sln'
- stage: Upload_API_Docs
pool:
diff --git a/src/Directory.Build.props b/src/Directory.Build.props
index 3505baf38e..657774fcc0 100644
--- a/src/Directory.Build.props
+++ b/src/Directory.Build.props
@@ -7,7 +7,7 @@
10.0.0
10.0.0-rc1
10.0.0
- 10.0
+ preview
en-US
Umbraco CMS
Copyright © Umbraco 2021
diff --git a/src/JsonSchema/JsonSchema.csproj b/src/JsonSchema/JsonSchema.csproj
index ea0ce9b7c3..bd4f04071b 100644
--- a/src/JsonSchema/JsonSchema.csproj
+++ b/src/JsonSchema/JsonSchema.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0
+ net7.0
true
false
false
diff --git a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
index e206cd8653..e78c210ae2 100644
--- a/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
+++ b/src/Umbraco.Cms.Persistence.SqlServer/Umbraco.Cms.Persistence.SqlServer.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Persistence.SqlServer
Umbraco.Cms.Persistence.SqlServer
Adds support for SQL Server to Umbraco CMS.
diff --git a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
index 5aa062df17..943757b353 100644
--- a/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
+++ b/src/Umbraco.Cms.Persistence.Sqlite/Umbraco.Cms.Persistence.Sqlite.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Persistence.Sqlite
Umbraco.Cms.Persistence.Sqlite
Adds support for SQLite to Umbraco CMS.
@@ -12,6 +12,7 @@
+
diff --git a/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj b/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
index 1fbbd8c42f..89cb8a44aa 100644
--- a/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
+++ b/src/Umbraco.Cms.StaticAssets/Umbraco.Cms.StaticAssets.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
true
Umbraco.Cms.StaticAssets
Contains the static assets that is required to run Umbraco CMS.
diff --git a/src/Umbraco.Cms/Umbraco.Cms.csproj b/src/Umbraco.Cms/Umbraco.Cms.csproj
index 23e8febd18..815be058eb 100644
--- a/src/Umbraco.Cms/Umbraco.Cms.csproj
+++ b/src/Umbraco.Cms/Umbraco.Cms.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net7.0
false
Umbraco.Cms
Umbraco.Cms
diff --git a/src/Umbraco.Core/Configuration/ConfigureConnectionStrings.cs b/src/Umbraco.Core/Configuration/ConfigureConnectionStrings.cs
index cd256e1b45..69ef69239e 100644
--- a/src/Umbraco.Core/Configuration/ConfigureConnectionStrings.cs
+++ b/src/Umbraco.Core/Configuration/ConfigureConnectionStrings.cs
@@ -23,8 +23,13 @@ public class ConfigureConnectionStrings : IConfigureNamedOptions Configure(Options.DefaultName, options);
///
- public void Configure(string name, ConnectionStrings options)
+ public void Configure(string? name, ConnectionStrings options)
{
+ if (name is null)
+ {
+ throw new InvalidOperationException("The name of the option instance is required.");
+ }
+
// Default to using UmbracoConnectionName
if (name == Options.DefaultName)
{
diff --git a/src/Umbraco.Core/Configuration/Models/Validation/ContentSettingsValidator.cs b/src/Umbraco.Core/Configuration/Models/Validation/ContentSettingsValidator.cs
index 0798014600..5062dc87e4 100644
--- a/src/Umbraco.Core/Configuration/Models/Validation/ContentSettingsValidator.cs
+++ b/src/Umbraco.Core/Configuration/Models/Validation/ContentSettingsValidator.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Configuration.Models.Validation;
public class ContentSettingsValidator : ConfigurationValidatorBase, IValidateOptions
{
///
- public ValidateOptionsResult Validate(string name, ContentSettings options)
+ public ValidateOptionsResult Validate(string? name, ContentSettings options)
{
if (!ValidateError404Collection(options.Error404Collection, out var message))
{
diff --git a/src/Umbraco.Core/Configuration/Models/Validation/GlobalSettingsValidator.cs b/src/Umbraco.Core/Configuration/Models/Validation/GlobalSettingsValidator.cs
index 32ad130c33..f78ce306dd 100644
--- a/src/Umbraco.Core/Configuration/Models/Validation/GlobalSettingsValidator.cs
+++ b/src/Umbraco.Core/Configuration/Models/Validation/GlobalSettingsValidator.cs
@@ -12,7 +12,7 @@ public class GlobalSettingsValidator
: ConfigurationValidatorBase, IValidateOptions
{
///
- public ValidateOptionsResult Validate(string name, GlobalSettings options)
+ public ValidateOptionsResult Validate(string? name, GlobalSettings options)
{
if (!ValidateSmtpSetting(options.Smtp, out var message))
{
diff --git a/src/Umbraco.Core/Configuration/Models/Validation/HealthChecksSettingsValidator.cs b/src/Umbraco.Core/Configuration/Models/Validation/HealthChecksSettingsValidator.cs
index ac0e1651ea..2b55afdcb0 100644
--- a/src/Umbraco.Core/Configuration/Models/Validation/HealthChecksSettingsValidator.cs
+++ b/src/Umbraco.Core/Configuration/Models/Validation/HealthChecksSettingsValidator.cs
@@ -19,7 +19,7 @@ public class HealthChecksSettingsValidator : ConfigurationValidatorBase, IValida
public HealthChecksSettingsValidator(ICronTabParser cronTabParser) => _cronTabParser = cronTabParser;
///
- public ValidateOptionsResult Validate(string name, HealthChecksSettings options)
+ public ValidateOptionsResult Validate(string? name, HealthChecksSettings options)
{
if (!ValidateNotificationFirstRunTime(options.Notification.FirstRunTime, out var message))
{
diff --git a/src/Umbraco.Core/Configuration/Models/Validation/RequestHandlerSettingsValidator.cs b/src/Umbraco.Core/Configuration/Models/Validation/RequestHandlerSettingsValidator.cs
index 4a1872cf30..8515fc3cc4 100644
--- a/src/Umbraco.Core/Configuration/Models/Validation/RequestHandlerSettingsValidator.cs
+++ b/src/Umbraco.Core/Configuration/Models/Validation/RequestHandlerSettingsValidator.cs
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Configuration.Models.Validation;
public class RequestHandlerSettingsValidator : ConfigurationValidatorBase, IValidateOptions
{
///
- public ValidateOptionsResult Validate(string name, RequestHandlerSettings options)
+ public ValidateOptionsResult Validate(string? name, RequestHandlerSettings options)
{
if (!ValidateConvertUrlsToAscii(options.ConvertUrlsToAscii, out var message))
{
diff --git a/src/Umbraco.Core/Configuration/Models/Validation/UnattendedSettingsValidator.cs b/src/Umbraco.Core/Configuration/Models/Validation/UnattendedSettingsValidator.cs
index e262de76e7..473224553a 100644
--- a/src/Umbraco.Core/Configuration/Models/Validation/UnattendedSettingsValidator.cs
+++ b/src/Umbraco.Core/Configuration/Models/Validation/UnattendedSettingsValidator.cs
@@ -1,4 +1,4 @@
-// Copyright (c) Umbraco.
+// Copyright (c) Umbraco.
// See LICENSE for more details.
using Microsoft.Extensions.Options;
@@ -12,7 +12,7 @@ public class UnattendedSettingsValidator
: IValidateOptions
{
///
- public ValidateOptionsResult Validate(string name, UnattendedSettings options)
+ public ValidateOptionsResult Validate(string? name, UnattendedSettings options)
{
if (options.InstallUnattended)
{
diff --git a/src/Umbraco.Core/Extensions/RequestHandlerSettingsExtension.cs b/src/Umbraco.Core/Extensions/RequestHandlerSettingsExtension.cs
index a083f89cc6..3452059e9b 100644
--- a/src/Umbraco.Core/Extensions/RequestHandlerSettingsExtension.cs
+++ b/src/Umbraco.Core/Extensions/RequestHandlerSettingsExtension.cs
@@ -28,9 +28,28 @@ public static class RequestHandlerSettingsExtension
return RequestHandlerSettings.DefaultCharCollection;
}
- return MergeUnique(
- requestHandlerSettings.UserDefinedCharCollection,
- RequestHandlerSettings.DefaultCharCollection);
+ return MergeUnique(requestHandlerSettings.UserDefinedCharCollection, RequestHandlerSettings.DefaultCharCollection);
+ }
+
+ private static IEnumerable GetReplacements(IConfiguration configuration, string key)
+ {
+ var replacements = new List();
+ IEnumerable config = configuration.GetSection(key).GetChildren();
+
+ foreach (IConfigurationSection section in config)
+ {
+ var @char = section.GetValue(nameof(CharItem.Char));
+ var replacement = section.GetValue(nameof(CharItem.Replacement));
+
+ if (@char is null || replacement is null)
+ {
+ continue;
+ }
+
+ replacements.Add(new CharItem { Char = @char, Replacement = replacement });
+ }
+
+ return replacements;
}
///
diff --git a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
index b8960048f6..1dfa72039c 100644
--- a/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
+++ b/src/Umbraco.Core/Hosting/IHostingEnvironment.cs
@@ -2,7 +2,7 @@ namespace Umbraco.Cms.Core.Hosting;
public interface IHostingEnvironment
{
- string SiteName { get; }
+ string? SiteName { get; }
///
/// The unique application ID for this Umbraco website.
diff --git a/src/Umbraco.Core/Models/ChangingPasswordModel.cs b/src/Umbraco.Core/Models/ChangingPasswordModel.cs
index 946bcde9ab..ecba35f137 100644
--- a/src/Umbraco.Core/Models/ChangingPasswordModel.cs
+++ b/src/Umbraco.Core/Models/ChangingPasswordModel.cs
@@ -11,7 +11,7 @@ public class ChangingPasswordModel
/// The password value
///
[DataMember(Name = "newPassword")]
- public string? NewPassword { get; set; }
+ public required string NewPassword { get; set; }
///
/// The old password - used to change a password when: EnablePasswordRetrieval = false
diff --git a/src/Umbraco.Core/Models/SendCodeViewModel.cs b/src/Umbraco.Core/Models/SendCodeViewModel.cs
index c73fd73eb3..29d318f8ff 100644
--- a/src/Umbraco.Core/Models/SendCodeViewModel.cs
+++ b/src/Umbraco.Core/Models/SendCodeViewModel.cs
@@ -1,4 +1,4 @@
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Cms.Core.Models;
@@ -11,11 +11,11 @@ public class Verify2FACodeModel
{
[Required]
[DataMember(Name = "code", IsRequired = true)]
- public string? Code { get; set; }
+ public required string Code { get; set; }
[Required]
[DataMember(Name = "provider", IsRequired = true)]
- public string? Provider { get; set; }
+ public required string Provider { get; set; }
///
/// Flag indicating whether the sign-in cookie should persist after the browser is closed.
diff --git a/src/Umbraco.Core/Models/SetPasswordModel.cs b/src/Umbraco.Core/Models/SetPasswordModel.cs
index 57d1abc38f..58803c101d 100644
--- a/src/Umbraco.Core/Models/SetPasswordModel.cs
+++ b/src/Umbraco.Core/Models/SetPasswordModel.cs
@@ -1,4 +1,4 @@
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Cms.Core.Models;
@@ -12,9 +12,9 @@ public class SetPasswordModel
[Required]
[DataMember(Name = "password", IsRequired = true)]
- public string? Password { get; set; }
+ public required string Password { get; set; }
[Required]
[DataMember(Name = "resetCode", IsRequired = true)]
- public string? ResetCode { get; set; }
+ public required string ResetCode { get; set; }
}
diff --git a/src/Umbraco.Core/Models/UnLinkLoginModel.cs b/src/Umbraco.Core/Models/UnLinkLoginModel.cs
index c121230810..ba4d881b73 100644
--- a/src/Umbraco.Core/Models/UnLinkLoginModel.cs
+++ b/src/Umbraco.Core/Models/UnLinkLoginModel.cs
@@ -1,4 +1,4 @@
-using System.ComponentModel.DataAnnotations;
+using System.ComponentModel.DataAnnotations;
using System.Runtime.Serialization;
namespace Umbraco.Cms.Core.Models;
@@ -7,9 +7,9 @@ public class UnLinkLoginModel
{
[Required]
[DataMember(Name = "loginProvider", IsRequired = true)]
- public string? LoginProvider { get; set; }
+ public required string LoginProvider { get; set; }
[Required]
[DataMember(Name = "providerKey", IsRequired = true)]
- public string? ProviderKey { get; set; }
+ public required string ProviderKey { get; set; }
}
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 01183739d5..8ee0b780b0 100644
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Core
Umbraco CMS
Umbraco.Cms.Core
@@ -15,6 +15,15 @@
+
+
+
+
+
+
+
+
+
@@ -30,7 +39,7 @@
-
+
all
diff --git a/src/Umbraco.Core/Web/IRequestAccessor.cs b/src/Umbraco.Core/Web/IRequestAccessor.cs
index a72ec5bc72..57940b3c1b 100644
--- a/src/Umbraco.Core/Web/IRequestAccessor.cs
+++ b/src/Umbraco.Core/Web/IRequestAccessor.cs
@@ -5,12 +5,12 @@ public interface IRequestAccessor
///
/// Returns the request/form/querystring value for the given name
///
- string GetRequestValue(string name);
+ string? GetRequestValue(string name);
///
/// Returns the query string value for the given name
///
- string GetQueryStringValue(string name);
+ string? GetQueryStringValue(string name);
///
/// Returns the current request uri
diff --git a/src/Umbraco.Examine.Lucene/DependencyInjection/ConfigureIndexOptions.cs b/src/Umbraco.Examine.Lucene/DependencyInjection/ConfigureIndexOptions.cs
index e6306ab444..f7c3cf9a3e 100644
--- a/src/Umbraco.Examine.Lucene/DependencyInjection/ConfigureIndexOptions.cs
+++ b/src/Umbraco.Examine.Lucene/DependencyInjection/ConfigureIndexOptions.cs
@@ -25,7 +25,7 @@ public sealed class ConfigureIndexOptions : IConfigureNamedOptions
- net6.0
+ net7.0
Umbraco.Cms.Infrastructure.Examine
Umbraco CMS
Umbraco.Examine.Lucene
diff --git a/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs
index 9481eb9958..1e17b959b6 100644
--- a/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs
+++ b/src/Umbraco.Infrastructure/Configuration/JsonConfigManipulator.cs
@@ -229,7 +229,7 @@ namespace Umbraco.Cms.Core.Configuration
{
if (provider.Source.FileProvider is PhysicalFileProvider physicalFileProvider)
{
- var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path);
+ var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path!);
try
{
@@ -264,7 +264,7 @@ namespace Umbraco.Cms.Core.Configuration
return null;
}
- var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path);
+ var jsonFilePath = Path.Combine(physicalFileProvider.Root, provider.Source.Path!);
try
{
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs b/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
index 9555482bbf..a6589166b2 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeClaimsPrincipalFactory.cs
@@ -46,12 +46,12 @@ public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory x.RoleId).ToArray());
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeErrorDescriber.cs b/src/Umbraco.Infrastructure/Security/BackOfficeErrorDescriber.cs
index 2b9daab29f..b99eddba5d 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeErrorDescriber.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeErrorDescriber.cs
@@ -20,7 +20,7 @@ public class BackOfficeErrorDescriber : UmbracoErrorDescriberBase
Description = _textService.Localize("validation", "duplicateUserGroupName", new[] { role }),
};
- public override IdentityError InvalidRoleName(string role) => new()
+ public override IdentityError InvalidRoleName(string? role) => new()
{
Code = nameof(InvalidRoleName),
Description = _textService.Localize("validation", "invalidUserGroupName"),
@@ -70,7 +70,7 @@ public class MembersErrorDescriber : UmbracoErrorDescriberBase
Description = _textService.Localize("validation", "duplicateMemberGroupName", new[] { role }),
};
- public override IdentityError InvalidRoleName(string role) => new()
+ public override IdentityError InvalidRoleName(string? role) => new()
{
Code = nameof(InvalidRoleName),
Description = _textService.Localize("validation", "invalidMemberGroupName"),
diff --git a/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs b/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs
index 729373faba..1908a3fbfc 100644
--- a/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs
+++ b/src/Umbraco.Infrastructure/Security/BackOfficeUserStore.cs
@@ -117,12 +117,17 @@ public class BackOfficeUserStore : UmbracoUserStore();
- var emptyPasswordValue = Constants.Security.EmptyPasswordPrefix +
+ if (user.Email is null || user.UserName is null)
+ {
+ throw new InvalidOperationException("Email and UserName is required.");
+ }
+
+ // the password must be 'something' it could be empty if authenticating
+ // with an external provider so we'll just generate one and prefix it, the
+ // prefix will help us determine if the password hasn't actually been specified yet.
+ // this will hash the guid with a salt so should be nicely random
+ var aspHasher = new PasswordHasher();
+ var emptyPasswordValue = Constants.Security.EmptyPasswordPrefix +
aspHasher.HashPassword(user, Guid.NewGuid().ToString("N"));
var userEntity = new User(_globalSettings, user.Name, user.Email, user.UserName, emptyPasswordValue)
@@ -255,16 +260,14 @@ public class BackOfficeUserStore : UmbracoUserStore
- public override Task FindByNameAsync(
- string userName,
- CancellationToken cancellationToken = default)
+ public override Task FindByNameAsync(string userName, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
IUser? user = _userService.GetByUsername(userName);
if (user == null)
{
- return Task.FromResult((BackOfficeIdentityUser)null!);
+ return Task.FromResult(null);
}
BackOfficeIdentityUser? result = AssignLoginsCallback(_mapper.Map(user));
@@ -273,7 +276,7 @@ public class BackOfficeUserStore : UmbracoUserStore
- protected override Task FindUserAsync(string userId, CancellationToken cancellationToken)
+ protected override Task FindUserAsync(string userId, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -288,7 +291,7 @@ public class BackOfficeUserStore : UmbracoUserStore
- public override Task FindByEmailAsync(
+ public override Task FindByEmailAsync(
string email,
CancellationToken cancellationToken = default)
{
@@ -299,11 +302,11 @@ public class BackOfficeUserStore : UmbracoUserStore(user);
- return Task.FromResult(AssignLoginsCallback(result))!;
+ return Task.FromResult(AssignLoginsCallback(result));
}
///
- public override async Task SetPasswordHashAsync(BackOfficeIdentityUser user, string passwordHash, CancellationToken cancellationToken = default)
+ public override async Task SetPasswordHashAsync(BackOfficeIdentityUser user, string? passwordHash, CancellationToken cancellationToken = default)
{
await base.SetPasswordHashAsync(user, passwordHash, cancellationToken);
@@ -405,7 +408,7 @@ public class BackOfficeUserStore : UmbracoUserStore
///
- public override Task SetTokenAsync(BackOfficeIdentityUser user, string loginProvider, string name, string value, CancellationToken cancellationToken)
+ public override Task SetTokenAsync(BackOfficeIdentityUser user, string loginProvider, string name, string? value, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -437,15 +440,15 @@ public class BackOfficeUserStore : UmbracoUserStore
- protected override async Task> FindUserLoginAsync(string userId, string loginProvider, string providerKey, CancellationToken cancellationToken)
+ protected override async Task?> FindUserLoginAsync(string userId, string loginProvider, string providerKey, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
- BackOfficeIdentityUser user = await FindUserAsync(userId, cancellationToken);
- if (user is null || user.Id is null)
+ BackOfficeIdentityUser? user = await FindUserAsync(userId, cancellationToken);
+ if (user?.Id is null)
{
- return null!;
+ return null;
}
IList logins = await GetLoginsAsync(user, cancellationToken);
@@ -453,7 +456,7 @@ public class BackOfficeUserStore : UmbracoUserStore x.ProviderKey == providerKey && x.LoginProvider == loginProvider);
if (found == null)
{
- return null!;
+ return null;
}
return new IdentityUserLogin
@@ -466,7 +469,7 @@ public class BackOfficeUserStore : UmbracoUserStore
- protected override Task> FindUserLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
+ protected override Task?> FindUserLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -474,11 +477,11 @@ public class BackOfficeUserStore : UmbracoUserStore)null!);
+ return Task.FromResult?>(null);
}
IIdentityUserLogin found = logins[0];
- return Task.FromResult(new IdentityUserLogin
+ return Task.FromResult?>(new IdentityUserLogin
{
LoginProvider = found.LoginProvider,
ProviderKey = found.ProviderKey,
@@ -488,30 +491,33 @@ public class BackOfficeUserStore : UmbracoUserStore
- protected override Task> FindRoleAsync(
+ protected override Task?> FindRoleAsync(
string normalizedRoleName,
CancellationToken cancellationToken)
{
IUserGroup? group = _userService.GetUserGroupByAlias(normalizedRoleName);
- if (group == null)
+ if (group?.Name is null)
{
- return Task.FromResult((IdentityRole)null!);
+ return Task.FromResult?>(null);
}
- return Task.FromResult(new IdentityRole(group.Name) { Id = group.Alias });
+ return Task.FromResult?>(new IdentityRole(group.Name)
+ {
+ Id = group.Alias,
+ });
}
///
- protected override async Task> FindUserRoleAsync(string userId, string roleId, CancellationToken cancellationToken)
+ protected override async Task?> FindUserRoleAsync(string userId, string roleId, CancellationToken cancellationToken)
{
- BackOfficeIdentityUser user = await FindUserAsync(userId, cancellationToken);
+ BackOfficeIdentityUser? user = await FindUserAsync(userId, cancellationToken);
if (user == null)
{
return null!;
}
IdentityUserRole? found = user.Roles.FirstOrDefault(x => x.RoleId.InvariantEquals(roleId));
- return found!;
+ return found;
}
private BackOfficeIdentityUser? AssignLoginsCallback(BackOfficeIdentityUser? user)
@@ -583,7 +589,7 @@ public class BackOfficeUserStore : UmbracoUserStore
- /// Overridden to support Umbraco's own data storage requirements
+ /// Overridden to support Umbraco's own data storage requirements
///
///
- /// The base class's implementation of this calls into FindTokenAsync, RemoveUserTokenAsync and AddUserTokenAsync, both
- /// methods will only work with ORMs that are change
- /// tracking ORMs like EFCore.
+ /// The base class's implementation of this calls into FindTokenAsync, RemoveUserTokenAsync and AddUserTokenAsync, both methods will only work with ORMs that are change
+ /// tracking ORMs like EFCore.
///
///
public override Task RemoveTokenAsync(BackOfficeIdentityUser user, string loginProvider, string name, CancellationToken cancellationToken)
diff --git a/src/Umbraco.Infrastructure/Security/ClaimsIdentityExtensions.cs b/src/Umbraco.Infrastructure/Security/ClaimsIdentityExtensions.cs
index 05ab03b784..c914930e9e 100644
--- a/src/Umbraco.Infrastructure/Security/ClaimsIdentityExtensions.cs
+++ b/src/Umbraco.Infrastructure/Security/ClaimsIdentityExtensions.cs
@@ -38,9 +38,9 @@ public static class MergeClaimsIdentityExtensions
{
foreach (IdentityUserClaim claim in source.Claims
.Where(claim => !_ignoredClaims.Contains(claim.ClaimType))
- .Where(claim => !destination.HasClaim(claim.ClaimType, claim.ClaimValue)))
+ .Where(claim => !destination.HasClaim(claim.ClaimType!, claim.ClaimValue!)))
{
- destination.AddClaim(new Claim(claim.ClaimType, claim.ClaimValue));
+ destination.AddClaim(new Claim(claim.ClaimType!, claim.ClaimValue!));
}
}
}
diff --git a/src/Umbraco.Infrastructure/Security/IUmbracoUserManager.cs b/src/Umbraco.Infrastructure/Security/IUmbracoUserManager.cs
index fe34812334..714db070bb 100644
--- a/src/Umbraco.Infrastructure/Security/IUmbracoUserManager.cs
+++ b/src/Umbraco.Infrastructure/Security/IUmbracoUserManager.cs
@@ -22,14 +22,14 @@ public interface IUmbracoUserManager : IDisposable
///
/// The
/// A representing the result of the asynchronous operation.
- Task GetUserAsync(ClaimsPrincipal principal);
+ Task GetUserAsync(ClaimsPrincipal principal);
///
/// Get the user id from the
///
/// the
/// Returns the user id from the
- string GetUserId(ClaimsPrincipal principal);
+ string? GetUserId(ClaimsPrincipal principal);
///
/// Gets the external logins for the user
@@ -47,7 +47,7 @@ public interface IUmbracoUserManager : IDisposable
/// Finds a user by the external login provider
///
/// A representing the result of the asynchronous operation.
- Task FindByLoginAsync(string loginProvider, string providerKey);
+ Task FindByLoginAsync(string loginProvider, string providerKey);
///
/// Finds and returns a user, if any, who has the specified .
@@ -57,7 +57,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the user matching the specified
/// if it exists.
///
- Task FindByIdAsync(string? userId);
+ Task FindByIdAsync(string userId);
///
/// Generates a password reset token for the specified , using
@@ -80,7 +80,7 @@ public interface IUmbracoUserManager : IDisposable
/// is to generate a token and reset it, however, when we do this we want to track a password change, not a password
/// reset
///
- Task ChangePasswordWithResetAsync(string userId, string token, string? newPassword);
+ Task ChangePasswordWithResetAsync(string userId, string token, string newPassword);
///
/// Validates that an email confirmation token matches the specified .
@@ -91,7 +91,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
- Task ConfirmEmailAsync(TUser user, string? token);
+ Task ConfirmEmailAsync(TUser user, string token);
///
/// Gets the user, if any, associated with the normalized value of the specified email address.
@@ -103,7 +103,7 @@ public interface IUmbracoUserManager : IDisposable
/// The task object containing the results of the asynchronous lookup operation, the user, if any, associated with a
/// normalized value of the specified email address.
///
- Task FindByEmailAsync(string email);
+ Task FindByEmailAsync(string email);
///
/// Resets the 's password to the specified after
@@ -116,7 +116,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
- Task ResetPasswordAsync(TUser user, string? token, string? newPassword);
+ Task ResetPasswordAsync(TUser user, string token, string newPassword);
///
/// Override to check the user approval value as well as the user lock out date, by default this only checks the user's
@@ -216,7 +216,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
- Task ChangePasswordAsync(TUser user, string? currentPassword, string? newPassword);
+ Task ChangePasswordAsync(TUser user, string currentPassword, string newPassword);
///
/// Used to validate a user's session
@@ -268,7 +268,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the
/// of the operation.
///
- Task CreateAsync(TUser user, string? password);
+ Task CreateAsync(TUser user, string password);
///
/// Generate a password for a user based on the current password validator
@@ -302,7 +302,7 @@ public interface IUmbracoUserManager : IDisposable
/// The that represents the asynchronous operation, containing the user matching the specified
/// if it exists.
///
- Task FindByNameAsync(string userName);
+ Task FindByNameAsync(string userName);
///
/// Increments the access failed count for the user as an asynchronous operation.
@@ -373,7 +373,7 @@ public interface IUmbracoUserManager : IDisposable
/// The System.Threading.Tasks.Task that represents the asynchronous operation, containing the
/// Microsoft.AspNetCore.Identity.IdentityResult of the operation.
///
- Task RemoveLoginAsync(TUser user, string? loginProvider, string? providerKey);
+ Task RemoveLoginAsync(TUser user, string loginProvider, string providerKey);
///
/// Resets the access failed count for the user
@@ -395,7 +395,7 @@ public interface IUmbracoUserManager : IDisposable
/// The task object containing the results of the asynchronous operation, the email address for the specified
/// user.
///
- Task GetEmailAsync(TUser user);
+ Task GetEmailAsync(TUser user);
///
/// Gets the telephone number, if any, for the specified user.
@@ -409,7 +409,7 @@ public interface IUmbracoUserManager : IDisposable
/// A user can only support a phone number if the BackOfficeUserStore is replaced with another that implements
/// IUserPhoneNumberStore
///
- Task GetPhoneNumberAsync(TUser user);
+ Task GetPhoneNumberAsync(TUser user);
///
/// Validates that a user's credentials are correct without actually logging them in.
diff --git a/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs b/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs
index eeeed4e4ec..b355bbcb18 100644
--- a/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs
+++ b/src/Umbraco.Infrastructure/Security/MemberRoleStore.cs
@@ -131,7 +131,7 @@ public class MemberRoleStore : IQueryableRoleStore
}
///
- public Task GetRoleNameAsync(UmbracoIdentityRole role, CancellationToken cancellationToken = default)
+ public Task GetRoleNameAsync(UmbracoIdentityRole role, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -141,11 +141,11 @@ public class MemberRoleStore : IQueryableRoleStore
throw new ArgumentNullException(nameof(role));
}
- return Task.FromResult(role.Name)!;
+ return Task.FromResult(role.Name);
}
///
- public Task SetRoleNameAsync(UmbracoIdentityRole role, string roleName,
+ public Task SetRoleNameAsync(UmbracoIdentityRole role, string? roleName,
CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -155,23 +155,24 @@ public class MemberRoleStore : IQueryableRoleStore
throw new ArgumentNullException(nameof(role));
}
- role.Name = roleName;
- return Task.CompletedTask;
- }
+
+ role.Name = roleName;
+ return Task.CompletedTask;
+ }
///
- public Task GetNormalizedRoleNameAsync(
+ public Task GetNormalizedRoleNameAsync(
UmbracoIdentityRole role,
CancellationToken cancellationToken = default)
=> GetRoleNameAsync(role, cancellationToken);
///
- public Task SetNormalizedRoleNameAsync(UmbracoIdentityRole role, string normalizedName,
+ public Task SetNormalizedRoleNameAsync(UmbracoIdentityRole role, string? normalizedName,
CancellationToken cancellationToken = default)
=> SetRoleNameAsync(role, normalizedName, cancellationToken);
///
- public Task FindByIdAsync(string roleId, CancellationToken cancellationToken = default)
+ public Task FindByIdAsync(string roleId, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -185,36 +186,36 @@ public class MemberRoleStore : IQueryableRoleStore
// member group can be found by int or Guid, so try both
if (!int.TryParse(roleId, NumberStyles.Integer, CultureInfo.InvariantCulture, out var id))
- {
- if (!Guid.TryParse(roleId, out Guid guid))
{
- throw new ArgumentOutOfRangeException(nameof(roleId), $"{nameof(roleId)} is not a valid Guid");
- }
+ if (!Guid.TryParse(roleId, out Guid guid))
+ {
+ throw new ArgumentOutOfRangeException(nameof(roleId), $"{nameof(roleId)} is not a valid Guid");
+ }
- memberGroup = _memberGroupService.GetById(guid);
+ memberGroup = _memberGroupService.GetById(guid);
}
else
{
memberGroup = _memberGroupService.GetById(id);
}
- return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup))!;
+ return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup));
}
///
- public Task FindByNameAsync(string name, CancellationToken cancellationToken = default)
+ public Task FindByNameAsync(string name, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
- if (string.IsNullOrWhiteSpace(name))
- {
- throw new ArgumentNullException(nameof(name));
- }
+ if (string.IsNullOrWhiteSpace(name))
+ {
+ throw new ArgumentNullException(nameof(name));
+ }
- IMemberGroup? memberGroup = _memberGroupService.GetByName(name);
- return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup))!;
- }
+ IMemberGroup? memberGroup = _memberGroupService.GetByName(name);
+ return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup))!;
+ }
///
/// Dispose the store
diff --git a/src/Umbraco.Infrastructure/Security/MemberUserStore.cs b/src/Umbraco.Infrastructure/Security/MemberUserStore.cs
index c81b1ed36a..cd684c047a 100644
--- a/src/Umbraco.Infrastructure/Security/MemberUserStore.cs
+++ b/src/Umbraco.Infrastructure/Security/MemberUserStore.cs
@@ -91,7 +91,7 @@ public class MemberUserStore : UmbracoUserStore
- public override Task FindByNameAsync(
- string userName,
- CancellationToken cancellationToken = default)
+ public override Task FindByNameAsync(string userName, CancellationToken cancellationToken = default)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
IMember? user = _memberService.GetByUsername(userName);
if (user == null)
{
- return Task.FromResult((MemberIdentityUser)null!);
+ return Task.FromResult(null);
}
- MemberIdentityUser result = AssignLoginsCallback(_mapper.Map(user))!;
+ MemberIdentityUser? result = AssignLoginsCallback(_mapper.Map(user))!;
- return Task.FromResult(result);
+ return Task.FromResult(result);
}
public IPublishedContent? GetPublishedMember(MemberIdentityUser? user)
@@ -290,7 +288,7 @@ public class MemberUserStore : UmbracoUserStore
- public override Task FindByEmailAsync(
+ public override Task FindByEmailAsync(
string email,
CancellationToken cancellationToken = default)
{
@@ -301,11 +299,11 @@ public class MemberUserStore : UmbracoUserStore(member);
- return Task.FromResult(AssignLoginsCallback(result))!;
+ return Task.FromResult(AssignLoginsCallback(result));
}
///
- protected override Task FindUserAsync(string userId, CancellationToken cancellationToken)
+ protected override Task FindUserAsync(string userId, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -320,7 +318,7 @@ public class MemberUserStore : UmbracoUserStore(user)))!;
@@ -440,7 +438,7 @@ public class MemberUserStore : UmbracoUserStore
- protected override async Task> FindUserLoginAsync(string userId, string loginProvider,
+ protected override async Task?> FindUserLoginAsync(string userId, string loginProvider,
string providerKey, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -456,38 +454,32 @@ public class MemberUserStore : UmbracoUserStore)null!);
+ return await Task.FromResult?>(null);
}
IList logins = await GetLoginsAsync(user, cancellationToken);
UserLoginInfo? found =
logins.FirstOrDefault(x => x.ProviderKey == providerKey && x.LoginProvider == loginProvider);
- if (found == null)
+ if (found is null)
{
- return await Task.FromResult((IdentityUserLogin)null!);
+ return await Task.FromResult?>(null);
}
- if (user.Id is not null)
+ return new IdentityUserLogin
{
- return new IdentityUserLogin
- {
- LoginProvider = found.LoginProvider,
- ProviderKey = found.ProviderKey,
-
- // TODO: We don't store this value so it will be null
- ProviderDisplayName = found.ProviderDisplayName,
- UserId = user.Id,
- };
- }
-
- return null!;
+ LoginProvider = found.LoginProvider,
+ ProviderKey = found.ProviderKey,
+ // TODO: We don't store this value so it will be null
+ ProviderDisplayName = found.ProviderDisplayName,
+ UserId = user.Id
+ };
}
///
- protected override Task> FindUserLoginAsync(string loginProvider, string providerKey,
+ protected override Task?> FindUserLoginAsync(string loginProvider, string providerKey,
CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
@@ -506,11 +498,11 @@ public class MemberUserStore : UmbracoUserStore)null!);
+ return Task.FromResult?>(null);
}
IIdentityUserLogin found = logins[0];
- return Task.FromResult(new IdentityUserLogin
+ return Task.FromResult?>(new IdentityUserLogin
{
LoginProvider = found.LoginProvider,
ProviderKey = found.ProviderKey,
@@ -527,7 +519,7 @@ public class MemberUserStore : UmbracoUserStore currentRoles = _memberService.GetAllRoles(user.UserName);
+ IEnumerable currentRoles = _memberService.GetAllRoles(user.UserName!);
ICollection> roles = currentRoles
.Select(role => new IdentityUserRole { RoleId = role, UserId = user.Id }).ToList();
@@ -538,7 +530,7 @@ public class MemberUserStore : UmbracoUserStore
/// Lists all users of a given role.
///
- public override Task?> GetUsersInRoleAsync(
+ public override Task> GetUsersInRoleAsync(
string roleName,
CancellationToken cancellationToken = default)
{
@@ -550,10 +542,10 @@ public class MemberUserStore : UmbracoUserStore? members = _memberService.GetMembersByMemberType(roleName);
+ IEnumerable members = _memberService.GetMembersByMemberType(roleName);
- IList? membersIdentityUsers =
- members?.Select(x => _mapper.Map(x)!).ToList();
+ IList membersIdentityUsers =
+ members.Select(x => _mapper.Map(x)!).ToList();
return Task.FromResult(membersIdentityUsers);
}
@@ -567,8 +559,7 @@ public class MemberUserStore : UmbracoUserStore
///
- public override Task SetTokenAsync(MemberIdentityUser user, string loginProvider, string name, string value,
- CancellationToken cancellationToken)
+ public override Task SetTokenAsync(MemberIdentityUser user, string loginProvider, string name, string? value, CancellationToken cancellationToken)
{
cancellationToken.ThrowIfCancellationRequested();
ThrowIfDisposed();
@@ -626,7 +617,7 @@ public class MemberUserStore : UmbracoUserStore
- protected override Task FindRoleAsync(string roleName, CancellationToken cancellationToken)
+ protected override Task FindRoleAsync(string roleName, CancellationToken cancellationToken)
{
if (string.IsNullOrWhiteSpace(roleName))
{
@@ -634,12 +625,12 @@ public class MemberUserStore : UmbracoUserStore x.Name == roleName);
- if (group == null)
+ if (group?.Name is null)
{
- return Task.FromResult((UmbracoIdentityRole)null!);
+ return Task.FromResult(null);
}
- return Task.FromResult(new UmbracoIdentityRole(group.Name)
+ return Task.FromResult(new UmbracoIdentityRole(group.Name)
{
// TODO: what should the alias be?
Id = group.Id.ToString(),
@@ -647,27 +638,25 @@ public class MemberUserStore : UmbracoUserStore
- protected override async Task> FindUserRoleAsync(string userId, string roleId,
+ protected override async Task?> FindUserRoleAsync(string userId, string roleId,
CancellationToken cancellationToken)
{
- MemberIdentityUser user = await FindUserAsync(userId, cancellationToken);
- if (user == null)
+ MemberIdentityUser? user = await FindUserAsync(userId, cancellationToken);
+ if (user is null)
{
- return null!;
+ return null;
}
IdentityUserRole? found = user.Roles.FirstOrDefault(x => x.RoleId.InvariantEquals(roleId));
- return found!;
+ return found;
}
private MemberIdentityUser? AssignLoginsCallback(MemberIdentityUser? user)
{
- if (user != null)
+ if (user is not null)
{
- user.SetLoginsCallback(
- new Lazy?>(() => _externalLoginService.GetExternalLogins(user.Key)));
- user.SetTokensCallback(new Lazy?>(() =>
- _externalLoginService.GetExternalLoginTokens(user.Key)));
+ user.SetLoginsCallback(new Lazy?>(() => _externalLoginService.GetExternalLogins(user.Key)));
+ user.SetTokensCallback(new Lazy?>(() => _externalLoginService.GetExternalLoginTokens(user.Key)));
}
return user;
@@ -729,7 +718,7 @@ public class MemberUserStore : UmbracoUserStore
public class NoopLookupNormalizer : ILookupNormalizer
{
- public string NormalizeName(string name) => name;
+ public string? NormalizeName(string? name) => name;
- public string NormalizeEmail(string email) => email;
+ public string? NormalizeEmail(string? email) => email;
}
diff --git a/src/Umbraco.Infrastructure/Security/UmbracoErrorDescriberBase.cs b/src/Umbraco.Infrastructure/Security/UmbracoErrorDescriberBase.cs
index 671483fe7b..ade4fd1515 100644
--- a/src/Umbraco.Infrastructure/Security/UmbracoErrorDescriberBase.cs
+++ b/src/Umbraco.Infrastructure/Security/UmbracoErrorDescriberBase.cs
@@ -34,7 +34,7 @@ public abstract class UmbracoErrorDescriberBase : IdentityErrorDescriber
Description = _textService.Localize("validation", "duplicateUsername", new[] { userName }),
};
- public override IdentityError InvalidEmail(string email) => new()
+ public override IdentityError InvalidEmail(string? email) => new()
{
Code = nameof(InvalidEmail),
Description = _textService.Localize("validation", "invalidEmail"),
@@ -46,7 +46,7 @@ public abstract class UmbracoErrorDescriberBase : IdentityErrorDescriber
Description = _textService.Localize("validation", "invalidToken"),
};
- public override IdentityError InvalidUserName(string userName) => new()
+ public override IdentityError InvalidUserName(string? userName) => new()
{
Code = nameof(InvalidUserName),
Description = _textService.Localize("validation", "invalidUsername"),
diff --git a/src/Umbraco.Infrastructure/Security/UmbracoIdentityRole.cs b/src/Umbraco.Infrastructure/Security/UmbracoIdentityRole.cs
index e38a0b89ab..af6e745f46 100644
--- a/src/Umbraco.Infrastructure/Security/UmbracoIdentityRole.cs
+++ b/src/Umbraco.Infrastructure/Security/UmbracoIdentityRole.cs
@@ -6,10 +6,10 @@ namespace Umbraco.Cms.Core.Security;
public class UmbracoIdentityRole : IdentityRole, IRememberBeingDirty
{
- private string? _id;
- private string? _name;
+ private string _id = string.Empty;
+ private string _name = string.Empty;
- public UmbracoIdentityRole(string? roleName)
+ public UmbracoIdentityRole(string roleName)
: base(roleName)
{
}
@@ -26,7 +26,7 @@ public class UmbracoIdentityRole : IdentityRole, IRememberBeingDirty
}
///
- public override string? Id
+ public override string Id
{
get => _id;
set
@@ -40,11 +40,11 @@ public class UmbracoIdentityRole : IdentityRole, IRememberBeingDirty
public override string? Name
{
get => _name;
- set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _name, nameof(Name));
+ set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _name!, nameof(Name));
}
///
- public override string NormalizedName { get => base.Name; set => base.Name = value; }
+ public override string? NormalizedName { get => base.Name ?? string.Empty; set => base.Name = value; }
///
/// Gets or sets a value indicating whether returns an Id has been set on this object this will be false if the object
@@ -58,7 +58,7 @@ public class UmbracoIdentityRole : IdentityRole, IRememberBeingDirty
// model. A good writeup of that is here:
// https://stackoverflow.com/a/37362173
// For our purposes currently we won't worry about this.
- public override string ConcurrencyStamp { get => base.ConcurrencyStamp; set => base.ConcurrencyStamp = value; }
+ public override string? ConcurrencyStamp { get => base.ConcurrencyStamp; set => base.ConcurrencyStamp = value; }
///
/// Gets the for change tracking
diff --git a/src/Umbraco.Infrastructure/Security/UmbracoIdentityUser.cs b/src/Umbraco.Infrastructure/Security/UmbracoIdentityUser.cs
index bf79ab602d..7a44933e46 100644
--- a/src/Umbraco.Infrastructure/Security/UmbracoIdentityUser.cs
+++ b/src/Umbraco.Infrastructure/Security/UmbracoIdentityUser.cs
@@ -71,7 +71,7 @@ public abstract class UmbracoIdentityUser : IdentityUser, IRememberBeingDirty
// model. A good writeup of that is here:
// https://stackoverflow.com/a/37362173
// For our purposes currently we won't worry about this.
- public override string ConcurrencyStamp { get => base.ConcurrencyStamp; set => base.ConcurrencyStamp = value; }
+ public override string? ConcurrencyStamp { get => base.ConcurrencyStamp; set => base.ConcurrencyStamp = value; }
///
/// Gets or sets last login date
@@ -85,7 +85,7 @@ public abstract class UmbracoIdentityUser : IdentityUser, IRememberBeingDirty
///
/// Gets or sets email
///
- public override string Email
+ public override string? Email
{
get => _email;
set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _email!, nameof(Email));
@@ -247,7 +247,7 @@ public abstract class UmbracoIdentityUser : IdentityUser, IRememberBeingDirty
///
/// Gets or sets user name
///
- public override string UserName
+ public override string? UserName
{
get => _userName;
set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _userName!, nameof(UserName));
diff --git a/src/Umbraco.Infrastructure/Security/UmbracoUserManager.cs b/src/Umbraco.Infrastructure/Security/UmbracoUserManager.cs
index bc8b8078ca..dd3572c928 100644
--- a/src/Umbraco.Infrastructure/Security/UmbracoUserManager.cs
+++ b/src/Umbraco.Infrastructure/Security/UmbracoUserManager.cs
@@ -134,8 +134,8 @@ public abstract class UmbracoUserManager : UserManager
public override async Task CheckPasswordAsync(TUser user, string? password)
{
- // we cannot proceed if the user passed in does not have an identity
- if (user.HasIdentity == false)
+ // we cannot proceed if the user passed in does not have an identity, or if no password is provided.
+ if (user.HasIdentity == false || password is null)
{
return false;
}
@@ -158,10 +158,10 @@ public abstract class UmbracoUserManager : UserManager
- public virtual async Task ChangePasswordWithResetAsync(string userId, string token, string? newPassword)
+ public virtual async Task ChangePasswordWithResetAsync(string userId, string token, string newPassword)
{
- TUser user = await FindByIdAsync(userId);
- if (user == null)
+ TUser? user = await FindByIdAsync(userId);
+ if (user is null)
{
throw new InvalidOperationException("Could not find user");
}
@@ -251,8 +251,8 @@ public abstract class UmbracoUserManager : UserManager ValidateCredentialsAsync(string username, string password)
{
- TUser user = await FindByNameAsync(username);
- if (user == null)
+ TUser? user = await FindByNameAsync(username);
+ if (user is null)
{
return false;
}
diff --git a/src/Umbraco.Infrastructure/Security/UmbracoUserStore.cs b/src/Umbraco.Infrastructure/Security/UmbracoUserStore.cs
index 7a6c9d793a..35a8f2eea9 100644
--- a/src/Umbraco.Infrastructure/Security/UmbracoUserStore.cs
+++ b/src/Umbraco.Infrastructure/Security/UmbracoUserStore.cs
@@ -84,7 +84,7 @@ public abstract class UmbracoUserStore
}
///
- public override Task FindByIdAsync(string userId, CancellationToken cancellationToken = default) =>
+ public override Task FindByIdAsync(string userId, CancellationToken cancellationToken = default) =>
FindUserAsync(userId, cancellationToken);
///
@@ -96,11 +96,11 @@ public abstract class UmbracoUserStore
throw new NotImplementedException();
///
- public override Task GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken)
+ public override Task GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken)
=> GetEmailAsync(user, cancellationToken);
///
- public override Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default)
+ public override Task GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default)
=> GetUserNameAsync(user, cancellationToken);
///
@@ -221,15 +221,15 @@ public abstract class UmbracoUserStore
public override Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default) => throw new NotImplementedException();
///
- public override Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken)
+ public override Task SetNormalizedEmailAsync(TUser user, string? normalizedEmail, CancellationToken cancellationToken)
=> SetEmailAsync(user, normalizedEmail, cancellationToken);
///
- public override Task SetNormalizedUserNameAsync(TUser user, string normalizedName, CancellationToken cancellationToken = default)
+ public override Task SetNormalizedUserNameAsync(TUser user, string? normalizedName, CancellationToken cancellationToken = default)
=> SetUserNameAsync(user, normalizedName, cancellationToken);
///
- public override async Task SetPasswordHashAsync(TUser user, string passwordHash, CancellationToken cancellationToken = default)
+ public override async Task SetPasswordHashAsync(TUser user, string? passwordHash, CancellationToken cancellationToken = default)
{
await base.SetPasswordHashAsync(user, passwordHash, cancellationToken);
user.LastPasswordChangeDateUtc = DateTime.UtcNow;
@@ -247,7 +247,7 @@ public abstract class UmbracoUserStore
///
///
[EditorBrowsable(EditorBrowsableState.Never)]
- protected override Task> FindTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) => throw new NotImplementedException();
+ protected override Task?> FindTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) => throw new NotImplementedException();
///
/// Not supported in Umbraco, see comments above on GetTokenAsync, RemoveTokenAsync, SetTokenAsync
diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
index 7d48468a96..7e038b17cf 100644
--- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
+++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Infrastructure
Umbraco.Cms.Infrastructure
Umbraco CMS Infrastructure
@@ -24,6 +24,11 @@
+
+
+
+
+
@@ -50,6 +55,9 @@
+
+
+
diff --git a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
index 0eb68b99fe..2d82addc84 100644
--- a/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
+++ b/src/Umbraco.PublishedCache.NuCache/Umbraco.PublishedCache.NuCache.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Infrastructure.PublishedCache
Umbraco.Cms.PublishedCache.NuCache
Umbraco CMS Published Cache
diff --git a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
index 390482276e..7704344d4e 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/AuthenticationController.cs
@@ -186,11 +186,13 @@ public class AuthenticationController : UmbracoApiControllerBase
[ValidateAngularAntiForgeryToken]
public async Task PostUnLinkLogin(UnLinkLoginModel unlinkLoginModel)
{
- BackOfficeIdentityUser? user = await _userManager.FindByIdAsync(User.Identity?.GetUserId());
- if (user == null)
+ var userId = User.Identity?.GetUserId();
+ if (userId is null)
{
- throw new InvalidOperationException("Could not find user");
+ throw new InvalidOperationException("Could not find userId");
}
+ var user = await _userManager.FindByIdAsync(userId);
+ if (user == null) throw new InvalidOperationException("Could not find user");
AuthenticationScheme? authType = (await _signInManager.GetExternalAuthenticationSchemesAsync())
.FirstOrDefault(x => x.Name == unlinkLoginModel.LoginProvider);
@@ -484,16 +486,19 @@ public class AuthenticationController : UmbracoApiControllerBase
UmbracoUserExtensions.GetUserCulture(user.Culture, _textService, _globalSettings),
new[] { code });
- if (provider == "Email")
- {
- var mailMessage = new EmailMessage(from, user.Email, subject, message, true);
-
- await _emailSender.SendAsync(mailMessage, Constants.Web.EmailTypes.TwoFactorAuth);
- }
- else if (provider == "Phone")
- {
- await _smsSender.SendSmsAsync(await _userManager.GetPhoneNumberAsync(user), message);
- }
+ if (provider == "Email")
+ {
+ var mailMessage = new EmailMessage(from, user.Email, subject, message, true);
+ await _emailSender.SendAsync(mailMessage, Constants.Web.EmailTypes.TwoFactorAuth);
+ }
+ else if (provider == "Phone")
+ {
+ var phoneNumber = await _userManager.GetPhoneNumberAsync(user);
+ if (phoneNumber is not null)
+ {
+ await _smsSender.SendSmsAsync(phoneNumber, message);
+ }
+ }
return Ok();
}
@@ -544,6 +549,10 @@ public class AuthenticationController : UmbracoApiControllerBase
{
BackOfficeIdentityUser? identityUser =
await _userManager.FindByIdAsync(model.UserId.ToString(CultureInfo.InvariantCulture));
+ if (identityUser is null)
+ {
+ return new ValidationErrorResult("Could not find user");
+ }
IdentityResult result = await _userManager.ResetPasswordAsync(identityUser, model.ResetCode, model.Password);
if (result.Succeeded)
diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
index beee83cbb4..640a03f447 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeController.cs
@@ -379,7 +379,7 @@ public class BackOfficeController : UmbracoController
[HttpGet]
public async Task ExternalLinkLoginCallback()
{
- BackOfficeIdentityUser user = await _userManager.GetUserAsync(User);
+ BackOfficeIdentityUser? user = await _userManager.GetUserAsync(User);
if (user == null)
{
// ... this should really not happen
@@ -497,9 +497,8 @@ public class BackOfficeController : UmbracoController
}
else if (result == SignInResult.TwoFactorRequired)
{
- BackOfficeIdentityUser? attemptedUser =
- await _userManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
- if (attemptedUser == null)
+ BackOfficeIdentityUser? attemptedUser = await _userManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
+ if (attemptedUser?.UserName is null)
{
return new ValidationErrorResult(
$"No local user found for the login provider {loginInfo.LoginProvider} - {loginInfo.ProviderKey}");
diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
index b220b0fcd1..c24bbc8a20 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs
@@ -376,7 +376,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
},
{
"currentUserApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl(
- controller => controller.PostChangePassword(new ChangingPasswordModel()))
+ controller => controller.PostSetAvatar(new List()))
},
{
"entityApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl(
diff --git a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs
index 0c155f5209..87f881ff69 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/CurrentUserController.cs
@@ -198,12 +198,13 @@ public class CurrentUserController : UmbracoAuthorizedJsonController
[AllowAnonymous]
public async Task> PostSetInvitedUserPassword([FromBody] string newPassword)
{
- BackOfficeIdentityUser? user = await _backOfficeUserManager.FindByIdAsync(_backofficeSecurityAccessor
- .BackOfficeSecurity?.GetUserId().ResultOr(0).ToString());
- if (user == null)
+ var userId = _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().ResultOr(0).ToString();
+ if (userId is null)
{
- throw new InvalidOperationException("Could not find user");
+ throw new InvalidOperationException("Could not find user Id");
}
+ var user = await _backOfficeUserManager.FindByIdAsync(userId);
+ if (user == null) throw new InvalidOperationException("Could not find user");
IdentityResult result = await _backOfficeUserManager.AddPasswordAsync(user, newPassword);
@@ -303,8 +304,18 @@ public class CurrentUserController : UmbracoAuthorizedJsonController
[ValidateAngularAntiForgeryToken]
public async Task> GetCurrentUserLinkedLogins()
{
- BackOfficeIdentityUser identityUser = await _backOfficeUserManager.FindByIdAsync(_backofficeSecurityAccessor
- .BackOfficeSecurity?.GetUserId().ResultOr(0).ToString(CultureInfo.InvariantCulture));
+ var userId = _backofficeSecurityAccessor.BackOfficeSecurity?.GetUserId().ResultOr(0).ToString(CultureInfo.InvariantCulture);
+ if (userId is null)
+ {
+ throw new InvalidOperationException("Could not find user Id");
+ }
+
+ BackOfficeIdentityUser? identityUser = await _backOfficeUserManager.FindByIdAsync(userId);
+
+ if (identityUser is null)
+ {
+ throw new InvalidOperationException("Could not find user");
+ }
// deduplicate in case there are duplicates (there shouldn't be now since we have a unique constraint on the external logins
// but there didn't used to be)
diff --git a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs
index 70f337f44f..b7220a3941 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/MemberController.cs
@@ -367,7 +367,7 @@ public class MemberController : ContentControllerBase
contentItem.IsApproved,
contentItem.Name);
- IdentityResult created = await _memberManager.CreateAsync(identityMember, contentItem.Password?.NewPassword);
+ IdentityResult created = await _memberManager.CreateAsync(identityMember, contentItem.Password?.NewPassword!);
if (created.Succeeded == false)
{
@@ -513,8 +513,12 @@ public class MemberController : ContentControllerBase
}
var needsResync = false;
-
- MemberIdentityUser identityMember = await _memberManager.FindByIdAsync(contentItem.Id?.ToString());
+ var memberId = contentItem.Id?.ToString();
+ if (memberId is null)
+ {
+ return ValidationProblem("Member was not found");
+ }
+ MemberIdentityUser? identityMember = await _memberManager.FindByIdAsync(memberId);
if (identityMember == null)
{
return ValidationProblem("Member was not found");
diff --git a/src/Umbraco.Web.BackOffice/Controllers/TwoFactorLoginController.cs b/src/Umbraco.Web.BackOffice/Controllers/TwoFactorLoginController.cs
index 79e5f32707..68a8773362 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/TwoFactorLoginController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/TwoFactorLoginController.cs
@@ -65,7 +65,11 @@ public class TwoFactorLoginController : UmbracoAuthorizedJsonController
[HttpGet]
public async Task>> Get2FAProvidersForUser(int userId)
{
- BackOfficeIdentityUser user = await _backOfficeUserManager.FindByIdAsync(userId.ToString(CultureInfo.InvariantCulture));
+ BackOfficeIdentityUser? user = await _backOfficeUserManager.FindByIdAsync(userId.ToString(CultureInfo.InvariantCulture));
+ if (user is null)
+ {
+ throw new InvalidOperationException("Could not find user");
+ }
var enabledProviderNameHashSet =
new HashSet(await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(user.Key));
diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
index f734d8626b..916ff3d495 100644
--- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
+++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs
@@ -565,10 +565,20 @@ public class UsersController : BackOfficeNotificationsController
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)
{
- BackOfficeIdentityUser user = await _userManager.FindByIdAsync(((int?)userDisplay?.Id).ToString());
+ var userId = userDisplay?.Id?.ToString();
+ if (userId is null)
+ {
+ throw new InvalidOperationException("Could not find user Id");
+ }
+ var user = await _userManager.FindByIdAsync(userId);
+
+ if (user is null)
+ {
+ throw new InvalidOperationException("Could not find user");
+ }
+
var token = await _userManager.GenerateEmailConfirmationTokenAsync(user);
// Use info from SMTP Settings if configured, otherwise set fromEmail as fallback
diff --git a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs
index 54e25240e0..9d677bce66 100644
--- a/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs
+++ b/src/Umbraco.Web.BackOffice/DependencyInjection/UmbracoBuilder.LocalizedText.cs
@@ -48,7 +48,7 @@ namespace Umbraco.Extensions
IEnumerable userLangFileSources = contentFileProvider.GetDirectoryContents(userConfigLangFolder)
.Where(x => x.IsDirectory && x.Name.InvariantEquals("lang"))
- .Select(x => new DirectoryInfo(x.PhysicalPath))
+ .Select(x => new DirectoryInfo(x.PhysicalPath!))
.SelectMany(x => x.GetFiles("*.user.xml", SearchOption.TopDirectoryOnly))
.Select(x => new LocalizedTextServiceSupplementaryFileSource(x, true));
@@ -87,7 +87,7 @@ namespace Umbraco.Extensions
.GetDirectoryContents(langFolder)
.Where(x => !string.IsNullOrEmpty(x.PhysicalPath))
.Where(x => x.Name.InvariantEndsWith(".xml"))
- .Select(x => new FileInfo(x.PhysicalPath));
+ .Select(x => new FileInfo(x.PhysicalPath!));
foreach (FileInfo file in localizationFiles)
{
diff --git a/src/Umbraco.Web.BackOffice/Install/CreateUnattendedUserNotificationHandler.cs b/src/Umbraco.Web.BackOffice/Install/CreateUnattendedUserNotificationHandler.cs
index 13896c8912..1ac7f20819 100644
--- a/src/Umbraco.Web.BackOffice/Install/CreateUnattendedUserNotificationHandler.cs
+++ b/src/Umbraco.Web.BackOffice/Install/CreateUnattendedUserNotificationHandler.cs
@@ -75,7 +75,7 @@ public class CreateUnattendedUserNotificationHandler : INotificationAsyncHandler
using IServiceScope scope = _serviceScopeFactory.CreateScope();
IBackOfficeUserManager backOfficeUserManager =
scope.ServiceProvider.GetRequiredService();
- BackOfficeIdentityUser membershipUser =
+ BackOfficeIdentityUser? membershipUser =
await backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
if (membershipUser == null)
{
diff --git a/src/Umbraco.Web.BackOffice/Install/InstallApiController.cs b/src/Umbraco.Web.BackOffice/Install/InstallApiController.cs
index 3dfc9f51b1..ab1b19dde8 100644
--- a/src/Umbraco.Web.BackOffice/Install/InstallApiController.cs
+++ b/src/Umbraco.Web.BackOffice/Install/InstallApiController.cs
@@ -88,9 +88,11 @@ public class InstallApiController : ControllerBase
{
await _runtime.RestartAsync();
- BackOfficeIdentityUser identityUser =
- await _backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
- _backOfficeSignInManager.SignInAsync(identityUser, false);
+ BackOfficeIdentityUser? identityUser = await _backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
+ if (identityUser is not null)
+ {
+ _backOfficeSignInManager.SignInAsync(identityUser, false);
+ }
return NoContent();
}
diff --git a/src/Umbraco.Web.BackOffice/Middleware/ConfigureGlobalOptionsForKeepAliveMiddlware.cs b/src/Umbraco.Web.BackOffice/Middleware/ConfigureGlobalOptionsForKeepAliveMiddlware.cs
index 15366ec113..5156ad3af5 100644
--- a/src/Umbraco.Web.BackOffice/Middleware/ConfigureGlobalOptionsForKeepAliveMiddlware.cs
+++ b/src/Umbraco.Web.BackOffice/Middleware/ConfigureGlobalOptionsForKeepAliveMiddlware.cs
@@ -1,4 +1,4 @@
-using Microsoft.Extensions.Options;
+using Microsoft.Extensions.Options;
using Umbraco.Cms.Core.Configuration.Models;
namespace Umbraco.Cms.Web.BackOffice.Middleware;
@@ -18,6 +18,6 @@ public sealed class ConfigureGlobalOptionsForKeepAliveMiddlware : IPostConfigure
///
///
///
- public void PostConfigure(string name, GlobalSettings options) =>
+ public void PostConfigure(string? name, GlobalSettings options) =>
options.ReservedUrls += _keepAliveSettings.Value.KeepAlivePingUrl;
}
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
index 24217d331b..f4aed22fbe 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeAuthenticationBuilder.cs
@@ -62,10 +62,10 @@ public class BackOfficeAuthenticationBuilder : AuthenticationBuilder
internal class EnsureBackOfficeScheme : IPostConfigureOptions
where TOptions : RemoteAuthenticationOptions
{
- public void PostConfigure(string name, TOptions options)
+ public void PostConfigure(string? name, TOptions options)
{
// ensure logic only applies to backoffice authentication schemes
- if (name.StartsWith(Constants.Security.BackOfficeExternalAuthenticationTypePrefix))
+ if (name is not null && name.StartsWith(Constants.Security.BackOfficeExternalAuthenticationTypePrefix))
{
options.SignInScheme = Constants.Security.BackOfficeExternalAuthenticationType;
}
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs
index 15413db2a7..f0cb1beee5 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeSessionIdValidator.cs
@@ -126,7 +126,12 @@ public class BackOfficeSessionIdValidator
}
var userId = currentIdentity.GetUserId();
- BackOfficeIdentityUser? user = await _userManager.FindByIdAsync(userId);
+ if (userId is null)
+ {
+ return false;
+ }
+
+ var user = await _userManager.FindByIdAsync(userId);
if (user == null)
{
return false;
diff --git a/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs b/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
index 74f5fb5eb8..19a231cf52 100644
--- a/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
+++ b/src/Umbraco.Web.BackOffice/Security/BackOfficeSignInManager.cs
@@ -117,7 +117,7 @@ public class BackOfficeSignInManager : UmbracoSignInManagerThe external login URL users should be redirected to during the login flow.
/// The current user's identifier, which will be used to provide CSRF protection.
/// A configured .
- public override AuthenticationProperties ConfigureExternalAuthenticationProperties(string provider, string? redirectUrl, string? userId = null)
+ public override AuthenticationProperties ConfigureExternalAuthenticationProperties(string? provider, string? redirectUrl, string? userId = null)
{
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
// to be able to use our own XsrfKey/LoginProviderKey because the default is private :/
@@ -197,7 +197,7 @@ public class BackOfficeSignInManager : UmbracoSignInManager
- public void Configure(string name, CookieAuthenticationOptions options)
+ public void Configure(string? name, CookieAuthenticationOptions options)
{
if (name != Constants.Security.BackOfficeAuthenticationType)
{
diff --git a/src/Umbraco.Web.BackOffice/Security/PasswordChanger.cs b/src/Umbraco.Web.BackOffice/Security/PasswordChanger.cs
index 59ea9a7b81..25f0548386 100644
--- a/src/Umbraco.Web.BackOffice/Security/PasswordChanger.cs
+++ b/src/Umbraco.Web.BackOffice/Security/PasswordChanger.cs
@@ -52,7 +52,7 @@ internal class PasswordChanger : IPasswordChanger where TUser : Um
}
var userId = changingPasswordModel.Id.ToString();
- TUser identityUser = await userMgr.FindByIdAsync(userId);
+ TUser? identityUser = await userMgr.FindByIdAsync(userId);
if (identityUser == null)
{
// this really shouldn't ever happen... but just in case
@@ -96,7 +96,7 @@ internal class PasswordChanger : IPasswordChanger where TUser : Um
}
// can we change to the new password?
- IdentityResult changeResult = await userMgr.ChangePasswordAsync(identityUser, changingPasswordModel.OldPassword, changingPasswordModel.NewPassword);
+ IdentityResult changeResult = await userMgr.ChangePasswordAsync(identityUser, changingPasswordModel.OldPassword!, changingPasswordModel.NewPassword);
if (changeResult.Succeeded == false)
{
// no, fail with error messages for "password"
diff --git a/src/Umbraco.Web.BackOffice/Services/IconService.cs b/src/Umbraco.Web.BackOffice/Services/IconService.cs
index 7f060dc756..fa6bf3eb4c 100644
--- a/src/Umbraco.Web.BackOffice/Services/IconService.cs
+++ b/src/Umbraco.Web.BackOffice/Services/IconService.cs
@@ -141,7 +141,7 @@ public class IconService : IIconService
IEnumerable coreIcons = iconFolder
.Where(x => !x.IsDirectory && x.Name.EndsWith(".svg"))
- .Select(x => new FileInfo(x.PhysicalPath));
+ .Select(x => new FileInfo(x.PhysicalPath!));
icons.UnionWith(coreIcons);
diff --git a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
index 3f24e2717e..6d8cc02c1a 100644
--- a/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
+++ b/src/Umbraco.Web.BackOffice/Umbraco.Web.BackOffice.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Library
Umbraco.Cms.Web.BackOffice
Umbraco.Cms.Web.BackOffice
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
index 57f1e288b7..af8fec7f69 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreHostingEnvironment.cs
@@ -82,7 +82,7 @@ public class AspNetCoreHostingEnvironment : IHostingEnvironment
public Uri ApplicationMainUrl { get; private set; } = null!;
///
- public string SiteName { get; private set; } = null!;
+ public string? SiteName { get; private set; }
///
public string ApplicationId
diff --git a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs
index 38d67ff2f0..abb2b71a4e 100644
--- a/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/AspNetCoreRequestAccessor.cs
@@ -44,10 +44,10 @@ public class AspNetCoreRequestAccessor : IRequestAccessor, INotificationHandler<
});
///
- public string GetRequestValue(string name) => GetFormValue(name) ?? GetQueryStringValue(name);
+ public string? GetRequestValue(string name) => GetFormValue(name) ?? GetQueryStringValue(name);
///
- public string GetQueryStringValue(string name) => _httpContextAccessor.GetRequiredHttpContext().Request.Query[name];
+ public string? GetQueryStringValue(string name) => _httpContextAccessor.GetRequiredHttpContext().Request.Query[name];
///
public Uri? GetRequestUrl() => _httpContextAccessor.HttpContext != null
diff --git a/src/Umbraco.Web.Common/AspNetCore/OptionsMonitorAdapter.cs b/src/Umbraco.Web.Common/AspNetCore/OptionsMonitorAdapter.cs
index 112841a722..fd3d3516af 100644
--- a/src/Umbraco.Web.Common/AspNetCore/OptionsMonitorAdapter.cs
+++ b/src/Umbraco.Web.Common/AspNetCore/OptionsMonitorAdapter.cs
@@ -15,7 +15,7 @@ internal class OptionsMonitorAdapter : IOptionsMonitor
public T CurrentValue { get; }
- public T Get(string name) => CurrentValue;
+ public T Get(string? name) => CurrentValue;
public IDisposable OnChange(Action listener) => throw new NotImplementedException();
}
diff --git a/src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs b/src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs
index c91d0fb6c2..e8961dba0a 100644
--- a/src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs
+++ b/src/Umbraco.Web.Common/Extensions/FormCollectionExtensions.cs
@@ -49,7 +49,7 @@ public static class FormCollectionExtensions
///
///
///
- public static string GetRequiredString(this FormCollection items, string key)
+ public static string? GetRequiredString(this FormCollection items, string key)
{
if (items.HasKey(key) == false)
{
diff --git a/src/Umbraco.Web.Common/Extensions/HttpContextExtensions.cs b/src/Umbraco.Web.Common/Extensions/HttpContextExtensions.cs
index 226755039e..0f2da0ac4e 100644
--- a/src/Umbraco.Web.Common/Extensions/HttpContextExtensions.cs
+++ b/src/Umbraco.Web.Common/Extensions/HttpContextExtensions.cs
@@ -65,7 +65,7 @@ public static class HttpContextExtensions
///
/// Get the value in the request form or query string for the key
///
- public static string GetRequestValue(this HttpContext context, string key)
+ public static string? GetRequestValue(this HttpContext context, string key)
{
HttpRequest request = context.Request;
if (!request.HasFormContentType)
@@ -73,7 +73,7 @@ public static class HttpContextExtensions
return request.Query[key];
}
- string value = request.Form[key];
+ string? value = request.Form[key];
return value ?? request.Query[key];
}
diff --git a/src/Umbraco.Web.Common/Routing/RoutableDocumentFilter.cs b/src/Umbraco.Web.Common/Routing/RoutableDocumentFilter.cs
index 44fa64b274..4abbb21cb3 100644
--- a/src/Umbraco.Web.Common/Routing/RoutableDocumentFilter.cs
+++ b/src/Umbraco.Web.Common/Routing/RoutableDocumentFilter.cs
@@ -70,7 +70,7 @@ public sealed class RoutableDocumentFilter : IRoutableDocumentFilter
return maybeDoc;
}
- private void EndpointsChanged(object value)
+ private void EndpointsChanged(object? value)
{
lock (_routeLocker)
{
diff --git a/src/Umbraco.Web.Common/Security/BackOfficeUserManager.cs b/src/Umbraco.Web.Common/Security/BackOfficeUserManager.cs
index 09793081cf..352136504e 100644
--- a/src/Umbraco.Web.Common/Security/BackOfficeUserManager.cs
+++ b/src/Umbraco.Web.Common/Security/BackOfficeUserManager.cs
@@ -90,7 +90,7 @@ public class BackOfficeUserManager : UmbracoUserManager ChangePasswordWithResetAsync(string userId, string token, string? newPassword)
+ public override async Task ChangePasswordWithResetAsync(string userId, string token, string newPassword)
{
IdentityResult result = await base.ChangePasswordWithResetAsync(userId, token, newPassword);
if (result.Succeeded)
@@ -101,7 +101,7 @@ public class BackOfficeUserManager : UmbracoUserManager ChangePasswordAsync(BackOfficeIdentityUser user, string? currentPassword, string? newPassword)
+ public override async Task ChangePasswordAsync(BackOfficeIdentityUser user, string currentPassword, string newPassword)
{
IdentityResult result = await base.ChangePasswordAsync(user, currentPassword, newPassword);
if (result.Succeeded)
diff --git a/src/Umbraco.Web.Common/Security/ConfigureMemberCookieOptions.cs b/src/Umbraco.Web.Common/Security/ConfigureMemberCookieOptions.cs
index 1e0960fbc7..5bf7a98749 100644
--- a/src/Umbraco.Web.Common/Security/ConfigureMemberCookieOptions.cs
+++ b/src/Umbraco.Web.Common/Security/ConfigureMemberCookieOptions.cs
@@ -18,7 +18,7 @@ public sealed class ConfigureMemberCookieOptions : IConfigureNamedOptions
{
- ClaimsIdentity newIdentity = refreshingPrincipal.NewPrincipal.Identities.First();
- ClaimsIdentity currentIdentity = refreshingPrincipal.CurrentPrincipal.Identities.First();
+ ClaimsIdentity? newIdentity = refreshingPrincipal.NewPrincipal?.Identities.First();
+ ClaimsIdentity? currentIdentity = refreshingPrincipal.CurrentPrincipal?.Identities.First();
- // Since this is refreshing an existing principal, we want to merge all claims.
- newIdentity.MergeAllClaims(currentIdentity);
+ if (currentIdentity is not null)
+ {
+ // Since this is refreshing an existing principal, we want to merge all claims.
+ newIdentity?.MergeAllClaims(currentIdentity);
+ }
return Task.CompletedTask;
};
diff --git a/src/Umbraco.Web.Common/Security/IBackOfficeSignInManager.cs b/src/Umbraco.Web.Common/Security/IBackOfficeSignInManager.cs
index 8e674c8b9f..f76912743b 100644
--- a/src/Umbraco.Web.Common/Security/IBackOfficeSignInManager.cs
+++ b/src/Umbraco.Web.Common/Security/IBackOfficeSignInManager.cs
@@ -19,7 +19,7 @@ public interface IBackOfficeSignInManager
Task GetExternalLoginInfoAsync(string? expectedXsrf = null);
- Task GetTwoFactorAuthenticationUserAsync();
+ Task GetTwoFactorAuthenticationUserAsync();
Task PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure);
@@ -29,7 +29,7 @@ public interface IBackOfficeSignInManager
Task CreateUserPrincipalAsync(BackOfficeIdentityUser user);
- Task TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient);
+ Task TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient);
Task UpdateExternalAuthenticationTokensAsync(ExternalLoginInfo externalLogin);
}
diff --git a/src/Umbraco.Web.Common/Security/IMemberSignInManager.cs b/src/Umbraco.Web.Common/Security/IMemberSignInManager.cs
index a5a444bd06..27d034930d 100644
--- a/src/Umbraco.Web.Common/Security/IMemberSignInManager.cs
+++ b/src/Umbraco.Web.Common/Security/IMemberSignInManager.cs
@@ -21,7 +21,7 @@ public interface IMemberSignInManager
Task ExternalLoginSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent, bool bypassTwoFactor = false);
- Task GetTwoFactorAuthenticationUserAsync();
+ Task GetTwoFactorAuthenticationUserAsync();
- Task TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient);
+ Task TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient);
}
diff --git a/src/Umbraco.Web.Common/Security/MemberManager.cs b/src/Umbraco.Web.Common/Security/MemberManager.cs
index 19be3de489..c59f0bd86e 100644
--- a/src/Umbraco.Web.Common/Security/MemberManager.cs
+++ b/src/Umbraco.Web.Common/Security/MemberManager.cs
@@ -188,7 +188,7 @@ public class MemberManager : UmbracoUserManager HasAccessAsync(string path)
{
MemberIdentityUser? currentMember = await GetCurrentMemberAsync();
- if (currentMember == null || !currentMember.IsApproved || currentMember.IsLockedOut)
+ if (currentMember?.UserName is null || !currentMember.IsApproved || currentMember.IsLockedOut)
{
return false;
}
@@ -220,7 +220,7 @@ public class MemberManager : UmbracoUserManager();
MemberIdentityUser? currentMember = await GetCurrentMemberAsync();
- if (currentMember == null || !currentMember.IsApproved || currentMember.IsLockedOut)
+ if (currentMember?.UserName is null || !currentMember.IsApproved || currentMember.IsLockedOut)
{
return result;
}
diff --git a/src/Umbraco.Web.Common/Security/MemberSignInManager.cs b/src/Umbraco.Web.Common/Security/MemberSignInManager.cs
index a624129bab..393d05e9a0 100644
--- a/src/Umbraco.Web.Common/Security/MemberSignInManager.cs
+++ b/src/Umbraco.Web.Common/Security/MemberSignInManager.cs
@@ -159,8 +159,8 @@ public class MemberSignInManager : UmbracoSignInManager, IMe
}
public override AuthenticationProperties ConfigureExternalAuthenticationProperties(
- string provider,
- string redirectUrl,
+ string? provider,
+ string? redirectUrl,
string? userId = null)
{
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
@@ -213,7 +213,7 @@ public class MemberSignInManager : UmbracoSignInManager, IMe
}
// Now we need to perform the auto-link, so first we need to lookup/create a user with the email address
- MemberIdentityUser? autoLinkUser = await UserManager.FindByEmailAsync(email);
+ MemberIdentityUser? autoLinkUser = await UserManager.FindByEmailAsync(email!);
if (autoLinkUser != null)
{
try
@@ -244,7 +244,7 @@ public class MemberSignInManager : UmbracoSignInManager, IMe
throw new InvalidOperationException("The Name value cannot be null");
}
- autoLinkUser = MemberIdentityUser.CreateNew(email, email, autoLinkOptions.DefaultMemberTypeAlias, autoLinkOptions.DefaultIsApproved, name);
+ autoLinkUser = MemberIdentityUser.CreateNew(email!, email!, autoLinkOptions.DefaultMemberTypeAlias, autoLinkOptions.DefaultIsApproved, name);
foreach (var userGroup in autoLinkOptions.DefaultMemberGroups)
{
diff --git a/src/Umbraco.Web.Common/Security/PublicAccessChecker.cs b/src/Umbraco.Web.Common/Security/PublicAccessChecker.cs
index b8b662ef2b..9777f56d7d 100644
--- a/src/Umbraco.Web.Common/Security/PublicAccessChecker.cs
+++ b/src/Umbraco.Web.Common/Security/PublicAccessChecker.cs
@@ -47,7 +47,7 @@ public class PublicAccessChecker : IPublicAccessChecker
return PublicAccessStatus.LockedOut;
}
- if (!_publicAccessService.HasAccess(publishedContentId, _contentService, username, userRoles))
+ if (!_publicAccessService.HasAccess(publishedContentId, _contentService, username!, userRoles))
{
return PublicAccessStatus.AccessDenied;
}
diff --git a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
index 63defed2de..052a3ae631 100644
--- a/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
+++ b/src/Umbraco.Web.Common/Security/UmbracoSignInManager.cs
@@ -86,7 +86,7 @@ public abstract class UmbracoSignInManager : SignInManager
var providerKey = auth.Principal.FindFirstValue(ClaimTypes.NameIdentifier);
var provider = items[UmbracoSignInMgrLoginProviderKey];
- if (providerKey == null || provider == null)
+ if (providerKey is null || provider is null)
{
return null;
}
@@ -102,14 +102,14 @@ public abstract class UmbracoSignInManager : SignInManager
}
///
- public override async Task GetTwoFactorAuthenticationUserAsync()
+ public override async Task GetTwoFactorAuthenticationUserAsync()
{
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs
// replaced in order to use a custom auth type
TwoFactorAuthenticationInfo? info = await RetrieveTwoFactorInfoAsync();
- if (info == null)
+ if (info?.UserId is null)
{
- return null!;
+ return null;
}
return await UserManager.FindByIdAsync(info.UserId);
@@ -142,7 +142,7 @@ public abstract class UmbracoSignInManager : SignInManager
}
///
- public override async Task TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient)
+ public override async Task TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient)
{
// borrowed from https://github.com/dotnet/aspnetcore/blob/master/src/Identity/Core/src/SignInManager.cs#L552
// replaced in order to use a custom auth type and to implement logging/events
diff --git a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
index c75ddfe98f..83aa5bb7bf 100644
--- a/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
+++ b/src/Umbraco.Web.Common/Umbraco.Web.Common.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Library
Umbraco.Cms.Web.Common
Umbraco.Cms.Web.Common
@@ -9,7 +9,7 @@
Contains the Web assembly needed to run Umbraco Cms. This package only contains the assembly, and can be used for package development. Use the template in the Umbraco.Templates package to setup Umbraco
- net6.0
+ net7.0
Library
Umbraco.Cms.Web.Common
Umbraco.Cms.Web.Common
@@ -35,6 +35,8 @@
+
+
diff --git a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
index 2ec54bc2d8..a30d782a43 100644
--- a/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
+++ b/src/Umbraco.Web.UI/Umbraco.Web.UI.csproj
@@ -1,22 +1,38 @@
- net6.0
+ net7.0
Umbraco.Cms.Web.UI
false
+
+
+
+ bin/Release/Umbraco.Web.UI.xml
+
+
+
+ true
+
+
-
-
+
+
+ all
+ runtime; build; native; contentfiles; analyzers; buildtransitive
+
+
+ all
+
@@ -46,6 +62,8 @@
+
+
@@ -59,4 +77,5 @@
+
diff --git a/src/Umbraco.Web.Website/Controllers/UmbExternalLoginController.cs b/src/Umbraco.Web.Website/Controllers/UmbExternalLoginController.cs
index 1ea68f40aa..2cbda678de 100644
--- a/src/Umbraco.Web.Website/Controllers/UmbExternalLoginController.cs
+++ b/src/Umbraco.Web.Website/Controllers/UmbExternalLoginController.cs
@@ -111,7 +111,7 @@ public class UmbExternalLoginController : SurfaceController
if (result == SignInResult.TwoFactorRequired)
{
- MemberIdentityUser attemptedUser =
+ MemberIdentityUser? attemptedUser =
await _memberManager.FindByLoginAsync(loginInfo.LoginProvider, loginInfo.ProviderKey);
if (attemptedUser == null!)
{
@@ -218,7 +218,7 @@ public class UmbExternalLoginController : SurfaceController
[HttpGet]
public async Task ExternalLinkLoginCallback(string returnUrl)
{
- MemberIdentityUser user = await _memberManager.GetUserAsync(User);
+ MemberIdentityUser? user = await _memberManager.GetUserAsync(User);
string? loginProvider = null;
var errors = new List();
if (user == null!)
@@ -272,10 +272,20 @@ public class UmbExternalLoginController : SurfaceController
returnUrl = Request.GetEncodedPathAndQuery();
}
- MemberIdentityUser user = await _memberManager.FindByIdAsync(User.Identity?.GetUserId());
+ var userId = User.Identity?.GetUserId();
+ if (userId is null)
+ {
+ return CurrentUmbracoPage();
+ }
+
+ MemberIdentityUser? user = await _memberManager.FindByIdAsync(userId);
+
+ if (user is null)
+ {
+ return CurrentUmbracoPage();
+ }
IdentityResult result = await _memberManager.RemoveLoginAsync(user, provider, providerKey);
-
if (result.Succeeded)
{
await _memberSignInManager.SignInAsync(user, false);
@@ -283,6 +293,7 @@ public class UmbExternalLoginController : SurfaceController
}
AddModelErrors(result);
+
return CurrentUmbracoPage();
}
}
diff --git a/src/Umbraco.Web.Website/Controllers/UmbLoginController.cs b/src/Umbraco.Web.Website/Controllers/UmbLoginController.cs
index 046849612a..c195b52409 100644
--- a/src/Umbraco.Web.Website/Controllers/UmbLoginController.cs
+++ b/src/Umbraco.Web.Website/Controllers/UmbLoginController.cs
@@ -81,7 +81,7 @@ public class UmbLoginController : SurfaceController
if (result.RequiresTwoFactor)
{
- MemberIdentityUser attemptedUser = await _memberManager.FindByNameAsync(model.Username);
+ MemberIdentityUser? attemptedUser = await _memberManager.FindByNameAsync(model.Username);
if (attemptedUser == null!)
{
return new ValidationErrorResult(
diff --git a/src/Umbraco.Web.Website/Models/ProfileModelBuilder.cs b/src/Umbraco.Web.Website/Models/ProfileModelBuilder.cs
index 982fb127cd..70f034fc79 100644
--- a/src/Umbraco.Web.Website/Models/ProfileModelBuilder.cs
+++ b/src/Umbraco.Web.Website/Models/ProfileModelBuilder.cs
@@ -51,7 +51,7 @@ public class ProfileModelBuilder : MemberModelBuilderBase
? null
: await memberManager.GetUserAsync(_httpContextAccessor.HttpContext.User);
- if (member == null)
+ if (member?.Email is null || member?.UserName is null)
{
return null;
}
diff --git a/src/Umbraco.Web.Website/Security/MemberAuthenticationBuilder.cs b/src/Umbraco.Web.Website/Security/MemberAuthenticationBuilder.cs
index 0029e0b80a..50e6f80b78 100644
--- a/src/Umbraco.Web.Website/Security/MemberAuthenticationBuilder.cs
+++ b/src/Umbraco.Web.Website/Security/MemberAuthenticationBuilder.cs
@@ -62,9 +62,9 @@ public class MemberAuthenticationBuilder : AuthenticationBuilder
private class EnsureMemberScheme : IPostConfigureOptions
where TOptions : RemoteAuthenticationOptions
{
- public void PostConfigure(string name, TOptions options)
+ public void PostConfigure(string? name, TOptions options)
{
- if (!name.StartsWith(Constants.Security.MemberExternalAuthenticationTypePrefix))
+ if (name is null || !name.StartsWith(Constants.Security.MemberExternalAuthenticationTypePrefix))
{
return;
}
diff --git a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
index 176564eaf8..94f3bfa479 100644
--- a/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
+++ b/src/Umbraco.Web.Website/Umbraco.Web.Website.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Library
Umbraco.Cms.Web.Website
Umbraco.Cms.Web.Website
diff --git a/templates/Umbraco.Templates.csproj b/templates/Umbraco.Templates.csproj
index 47b2246835..6f06115dc4 100644
--- a/templates/Umbraco.Templates.csproj
+++ b/templates/Umbraco.Templates.csproj
@@ -3,7 +3,7 @@
- net6.0
+ net7.0
Template
false
.
diff --git a/templates/UmbracoPackage/UmbracoPackage.csproj b/templates/UmbracoPackage/UmbracoPackage.csproj
index cdab2646e0..92c1e78d82 100644
--- a/templates/UmbracoPackage/UmbracoPackage.csproj
+++ b/templates/UmbracoPackage/UmbracoPackage.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net7.0
.
UmbracoPackage
UmbracoPackage
diff --git a/templates/UmbracoProject/UmbracoProject.csproj b/templates/UmbracoProject/UmbracoProject.csproj
index 2880b754e6..c2234b0f1e 100644
--- a/templates/UmbracoProject/UmbracoProject.csproj
+++ b/templates/UmbracoProject/UmbracoProject.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net7.0
enable
enable
Umbraco.Cms.Web.UI
diff --git a/tests/Umbraco.TestData/Umbraco.TestData.csproj b/tests/Umbraco.TestData/Umbraco.TestData.csproj
index b5b2c5c99f..b2c9fa7236 100644
--- a/tests/Umbraco.TestData/Umbraco.TestData.csproj
+++ b/tests/Umbraco.TestData/Umbraco.TestData.csproj
@@ -3,7 +3,7 @@
false
Umbraco.TestData
- net6.0
+ net7.0
diff --git a/tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker b/tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker
index 5ae033d6d3..2efbb9a2da 100644
--- a/tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker
+++ b/tests/Umbraco.Tests.AcceptanceTest/misc/umbraco-linux.docker
@@ -2,7 +2,7 @@
## Build
############################################
-FROM mcr.microsoft.com/dotnet/sdk:6.0.300 AS build
+FROM mcr.microsoft.com/dotnet/nightly/sdk:7.0 AS build
WORKDIR /nupkg
COPY nupkg .
@@ -17,7 +17,7 @@ RUN dotnet publish --no-restore --configuration Release -o /dist
## Run
############################################
-FROM mcr.microsoft.com/dotnet/aspnet:6.0.5 AS run
+FROM mcr.microsoft.com/dotnet/nightly/aspnet:7.0 AS run
WORKDIR /cypress
COPY --from=build dist .
diff --git a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
index 29e0a36353..500f53cb89 100644
--- a/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
+++ b/tests/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net7.0
Exe
false
false
@@ -26,7 +26,7 @@
0.13.1
- 6.0.0
+ 7.0.0-preview.7.22375.6
4.18.1
diff --git a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
index 05a5554db2..25a6559123 100644
--- a/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
+++ b/tests/Umbraco.Tests.Common/Umbraco.Tests.Common.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Tests.Common
Umbraco.Cms.Tests
Umbraco CMS Test Tools
diff --git a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
index 8397da51b4..4d859d3625 100644
--- a/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
+++ b/tests/Umbraco.Tests.Integration/Umbraco.Tests.Integration.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net7.0
Umbraco.Cms.Tests.Integration
Umbraco.Cms.Tests.Integration
Umbraco CMS Integration Tests
@@ -86,8 +86,8 @@
+
-
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs
index 1176b7f571..d850d00d3d 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Published/ModelTypeTests.cs
@@ -46,7 +46,7 @@ public class ModelTypeTests
// Note the inner assembly qualified name
Assert.AreEqual(
- "System.Collections.Generic.IEnumerable`1[[System.Int32[], System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]",
+ "System.Collections.Generic.IEnumerable`1[[System.Int32[], System.Private.CoreLib, Version=7.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]]",
typeof(IEnumerable<>).MakeGenericType(type.MakeArrayType()).FullName);
}
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberPasswordHasherTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberPasswordHasherTests.cs
index 8e8b39bb42..9d26be6ab6 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberPasswordHasherTests.cs
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Infrastructure/Security/MemberPasswordHasherTests.cs
@@ -15,10 +15,11 @@ public class MemberPasswordHasherTests
[Test]
[TestCase(
"Password123!",
- "AQAAAAEAACcQAAAAEGF/tTVoL6ef3bQPZFYfbgKFu1CDQIAMgyY1N4EDt9jqdG/hsOX93X1U6LNvlIQ3mw==",
+ "AQAAAAIAAYagAAAAEJBorDjt+UEvw55UJVsbgAS6T2IGao+2XpCBbO3EKZoAMzoN+CNOpPdu1c0qrFcJVw==", null, ExpectedResult = PasswordVerificationResult.Success, Description = "AspNetCoreIdentityPasswordHash: Correct password")]
+ [TestCase("Password123!", "AQAAAAEAACcQAAAAEGF/tTVoL6ef3bQPZFYfbgKFu1CDQIAMgyY1N4EDt9jqdG/hsOX93X1U6LNvlIQ3mw==",
null,
- ExpectedResult = PasswordVerificationResult.Success,
- Description = "AspNetCoreIdentityPasswordHash: Correct password")]
+ ExpectedResult = PasswordVerificationResult.SuccessRehashNeeded,
+ Description = "GivenALegacyAspNetCoreIdentityPasswordHash: Correct password")]
[TestCase(
"wrongPassword",
"AQAAAAEAACcQAAAAEGF/tTVoL6ef3bQPZFYfbgKFu1CDQIAMgyY1N4EDt9jqdG/hsOX93X1U6LNvlIQ3mw==",
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj
index 55d875d1bc..fdc40c3e2b 100644
--- a/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Tests.UnitTests.csproj
@@ -2,7 +2,7 @@
Exe
- net6.0
+ net7.0
Umbraco.Cms.Tests.UnitTests
false
true
@@ -26,8 +26,8 @@
-
-
+
+