V11/feature/update to dotnet 7 (#12712)
* Update projects to .NET 7 * Fix nullability errors * Fix up pipelines to run 7.0 * Update langversion to preview * Revert "Fix up pipelines to run 7.0" This reverts commit d0fa8d01b8126a4eaa59832a3814a567705419ae. * Fix up pipelines again, this time without indentation changes * Include preview versions * Versions not Version * Fix ModelTypeTests * Fix MemberPasswordHasherTests Microsoft wants to use SHA512 instead of SHA256, so our old hashes will return SuccessRehashNeeded now * Use dotnet cli instead of nuget restore * Update src/Umbraco.Web.UI/Umbraco.Web.UI.csproj * Update dependencies * Fix nullability issues * Fix unit test * Fix nullability in ChangingPasswordModel OldPassword can be null, if we're changing the password with password reset enabled. Additionally, we might as well use the new required keyword instead of supressing null. * Use required keyword instead of supressing null * Fix up pipelines again * fix up spelling-error * Use dotnet cli instead of nuget restore * Fix up another NuGet command * Use dotnet version 7 before building * Include preview versions * Remove condition * Use dotnet 7 before running powershell script * Update templates to .net 7 * Download version 7 before running linux container * Move use dotnet 7 even earlier in E2E process * Remove dotnet 7 * Reintroduce .NET 7 task * Update linux docker container and remove dotnet 7 from yml * Fix up dockerfile with ARG * Fix up docker file with nightly builds of dotnet 7 * Reintroduce dotnet 7 so windows can use it * Use aspnet 7 in docker Co-authored-by: Nikolaj <nikolajlauridsen@protonmail.ch> Co-authored-by: Zeegaan <nge@umbraco.dk>
This commit is contained in:
@@ -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:
|
||||
@@ -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:
|
||||
@@ -397,6 +402,11 @@ 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'))
|
||||
- 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'))
|
||||
@@ -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:
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
<AssemblyVersion>10.0.0</AssemblyVersion>
|
||||
<InformationalVersion>10.0.0-rc1</InformationalVersion>
|
||||
<FileVersion>10.0.0</FileVersion>
|
||||
<LangVersion Condition="'$(LangVersion)' == ''">10.0</LangVersion>
|
||||
<LangVersion Condition="'$(LangVersion)' == ''">preview</LangVersion>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<Company>Umbraco CMS</Company>
|
||||
<Copyright>Copyright © Umbraco 2021</Copyright>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||
<IsPackable>false</IsPackable>
|
||||
<EnablePackageValidation>false</EnablePackageValidation>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<PackageId>Umbraco.Cms.Persistence.SqlServer</PackageId>
|
||||
<Title>Umbraco.Cms.Persistence.SqlServer</Title>
|
||||
<Description>Adds support for SQL Server to Umbraco CMS.</Description>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<PackageId>Umbraco.Cms.Persistence.Sqlite</PackageId>
|
||||
<Title>Umbraco.Cms.Persistence.Sqlite</Title>
|
||||
<Description>Adds support for SQLite to Umbraco CMS.</Description>
|
||||
@@ -12,6 +12,7 @@
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Data.Sqlite" Version="6.0.5" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Razor">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<AddRazorSupportForMvc>true</AddRazorSupportForMvc>
|
||||
<PackageId>Umbraco.Cms.StaticAssets</PackageId>
|
||||
<Description>Contains the static assets that is required to run Umbraco CMS.</Description>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<PackageId>Umbraco.Cms</PackageId>
|
||||
<Title>Umbraco.Cms</Title>
|
||||
|
||||
@@ -23,8 +23,13 @@ public class ConfigureConnectionStrings : IConfigureNamedOptions<ConnectionStrin
|
||||
public void Configure(ConnectionStrings options) => Configure(Options.DefaultName, options);
|
||||
|
||||
/// <inheritdoc />
|
||||
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)
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Configuration.Models.Validation;
|
||||
public class ContentSettingsValidator : ConfigurationValidatorBase, IValidateOptions<ContentSettings>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ValidateOptionsResult Validate(string name, ContentSettings options)
|
||||
public ValidateOptionsResult Validate(string? name, ContentSettings options)
|
||||
{
|
||||
if (!ValidateError404Collection(options.Error404Collection, out var message))
|
||||
{
|
||||
|
||||
@@ -12,7 +12,7 @@ public class GlobalSettingsValidator
|
||||
: ConfigurationValidatorBase, IValidateOptions<GlobalSettings>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ValidateOptionsResult Validate(string name, GlobalSettings options)
|
||||
public ValidateOptionsResult Validate(string? name, GlobalSettings options)
|
||||
{
|
||||
if (!ValidateSmtpSetting(options.Smtp, out var message))
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ public class HealthChecksSettingsValidator : ConfigurationValidatorBase, IValida
|
||||
public HealthChecksSettingsValidator(ICronTabParser cronTabParser) => _cronTabParser = cronTabParser;
|
||||
|
||||
/// <inheritdoc />
|
||||
public ValidateOptionsResult Validate(string name, HealthChecksSettings options)
|
||||
public ValidateOptionsResult Validate(string? name, HealthChecksSettings options)
|
||||
{
|
||||
if (!ValidateNotificationFirstRunTime(options.Notification.FirstRunTime, out var message))
|
||||
{
|
||||
|
||||
@@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.Configuration.Models.Validation;
|
||||
public class RequestHandlerSettingsValidator : ConfigurationValidatorBase, IValidateOptions<RequestHandlerSettings>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ValidateOptionsResult Validate(string name, RequestHandlerSettings options)
|
||||
public ValidateOptionsResult Validate(string? name, RequestHandlerSettings options)
|
||||
{
|
||||
if (!ValidateConvertUrlsToAscii(options.ConvertUrlsToAscii, out var message))
|
||||
{
|
||||
|
||||
@@ -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<UnattendedSettings>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
public ValidateOptionsResult Validate(string name, UnattendedSettings options)
|
||||
public ValidateOptionsResult Validate(string? name, UnattendedSettings options)
|
||||
{
|
||||
if (options.InstallUnattended)
|
||||
{
|
||||
|
||||
@@ -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<CharItem> GetReplacements(IConfiguration configuration, string key)
|
||||
{
|
||||
var replacements = new List<CharItem>();
|
||||
IEnumerable<IConfigurationSection> config = configuration.GetSection(key).GetChildren();
|
||||
|
||||
foreach (IConfigurationSection section in config)
|
||||
{
|
||||
var @char = section.GetValue<string>(nameof(CharItem.Char));
|
||||
var replacement = section.GetValue<string>(nameof(CharItem.Replacement));
|
||||
|
||||
if (@char is null || replacement is null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
replacements.Add(new CharItem { Char = @char, Replacement = replacement });
|
||||
}
|
||||
|
||||
return replacements;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -2,7 +2,7 @@ namespace Umbraco.Cms.Core.Hosting;
|
||||
|
||||
public interface IHostingEnvironment
|
||||
{
|
||||
string SiteName { get; }
|
||||
string? SiteName { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The unique application ID for this Umbraco website.
|
||||
|
||||
@@ -11,7 +11,7 @@ public class ChangingPasswordModel
|
||||
/// The password value
|
||||
/// </summary>
|
||||
[DataMember(Name = "newPassword")]
|
||||
public string? NewPassword { get; set; }
|
||||
public required string NewPassword { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The old password - used to change a password when: EnablePasswordRetrieval = false
|
||||
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// Flag indicating whether the sign-in cookie should persist after the browser is closed.
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Core</RootNamespace>
|
||||
<Product>Umbraco CMS</Product>
|
||||
<PackageId>Umbraco.Cms.Core</PackageId>
|
||||
@@ -15,6 +15,15 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Core" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Options.DataAnnotations" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" Version="6.0.0" />
|
||||
@@ -30,7 +39,7 @@
|
||||
</PackageReference>
|
||||
<PackageReference Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageReference Include="System.Reflection.Emit.Lightweight" Version="4.7.0" />
|
||||
<PackageReference Include="System.Runtime.Caching" Version="6.0.0" />
|
||||
<PackageReference Include="System.Runtime.Caching" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Umbraco.Code" Version="2.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
|
||||
@@ -5,12 +5,12 @@ public interface IRequestAccessor
|
||||
/// <summary>
|
||||
/// Returns the request/form/querystring value for the given name
|
||||
/// </summary>
|
||||
string GetRequestValue(string name);
|
||||
string? GetRequestValue(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the query string value for the given name
|
||||
/// </summary>
|
||||
string GetQueryStringValue(string name);
|
||||
string? GetQueryStringValue(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Returns the current request uri
|
||||
|
||||
@@ -25,7 +25,7 @@ public sealed class ConfigureIndexOptions : IConfigureNamedOptions<LuceneDirecto
|
||||
_settings = settings.Value;
|
||||
}
|
||||
|
||||
public void Configure(string name, LuceneDirectoryIndexOptions options)
|
||||
public void Configure(string? name, LuceneDirectoryIndexOptions options)
|
||||
{
|
||||
switch (name)
|
||||
{
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Infrastructure.Examine</RootNamespace>
|
||||
<Product>Umbraco CMS</Product>
|
||||
<Title>Umbraco.Examine.Lucene</Title>
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -46,12 +46,12 @@ public class BackOfficeClaimsPrincipalFactory : UserClaimsPrincipalFactory<BackO
|
||||
// ensure our required claims are there
|
||||
id.AddRequiredClaims(
|
||||
user.Id,
|
||||
user.UserName,
|
||||
user.UserName!,
|
||||
user.Name!,
|
||||
user.CalculatedContentStartNodeIds,
|
||||
user.CalculatedMediaStartNodeIds,
|
||||
user.Culture,
|
||||
user.SecurityStamp,
|
||||
user.SecurityStamp!,
|
||||
user.AllowedSections,
|
||||
user.Roles.Select(x => x.RoleId).ToArray());
|
||||
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -117,6 +117,11 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
|
||||
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.
|
||||
@@ -255,16 +260,14 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<BackOfficeIdentityUser> FindByNameAsync(
|
||||
string userName,
|
||||
CancellationToken cancellationToken = default)
|
||||
public override Task<BackOfficeIdentityUser?> 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<BackOfficeIdentityUser?>(null);
|
||||
}
|
||||
|
||||
BackOfficeIdentityUser? result = AssignLoginsCallback(_mapper.Map<BackOfficeIdentityUser>(user));
|
||||
@@ -273,7 +276,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<BackOfficeIdentityUser> FindUserAsync(string userId, CancellationToken cancellationToken)
|
||||
protected override Task<BackOfficeIdentityUser?> FindUserAsync(string userId, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
@@ -288,7 +291,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<BackOfficeIdentityUser> FindByEmailAsync(
|
||||
public override Task<BackOfficeIdentityUser?> FindByEmailAsync(
|
||||
string email,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -299,11 +302,11 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
? null
|
||||
: _mapper.Map<BackOfficeIdentityUser>(user);
|
||||
|
||||
return Task.FromResult(AssignLoginsCallback(result))!;
|
||||
return Task.FromResult(AssignLoginsCallback(result));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<BackOfficeIdentityUser, Iden
|
||||
/// tracking ORMs like EFCore.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
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<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<IdentityUserLogin<string>> FindUserLoginAsync(string userId, string loginProvider, string providerKey, CancellationToken cancellationToken)
|
||||
protected override async Task<IdentityUserLogin<string>?> 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<UserLoginInfo> logins = await GetLoginsAsync(user, cancellationToken);
|
||||
@@ -453,7 +456,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
logins.FirstOrDefault(x => x.ProviderKey == providerKey && x.LoginProvider == loginProvider);
|
||||
if (found == null)
|
||||
{
|
||||
return null!;
|
||||
return null;
|
||||
}
|
||||
|
||||
return new IdentityUserLogin<string>
|
||||
@@ -466,7 +469,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<IdentityUserLogin<string>> FindUserLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
|
||||
protected override Task<IdentityUserLogin<string>?> FindUserLoginAsync(string loginProvider, string providerKey, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
@@ -474,11 +477,11 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
var logins = _externalLoginService.Find(loginProvider, providerKey).ToList();
|
||||
if (logins.Count == 0)
|
||||
{
|
||||
return Task.FromResult((IdentityUserLogin<string>)null!);
|
||||
return Task.FromResult<IdentityUserLogin<string>?>(null);
|
||||
}
|
||||
|
||||
IIdentityUserLogin found = logins[0];
|
||||
return Task.FromResult(new IdentityUserLogin<string>
|
||||
return Task.FromResult<IdentityUserLogin<string>?>(new IdentityUserLogin<string>
|
||||
{
|
||||
LoginProvider = found.LoginProvider,
|
||||
ProviderKey = found.ProviderKey,
|
||||
@@ -488,30 +491,33 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<IdentityRole<string>> FindRoleAsync(
|
||||
protected override Task<IdentityRole<string>?> FindRoleAsync(
|
||||
string normalizedRoleName,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
IUserGroup? group = _userService.GetUserGroupByAlias(normalizedRoleName);
|
||||
if (group == null)
|
||||
if (group?.Name is null)
|
||||
{
|
||||
return Task.FromResult((IdentityRole<string>)null!);
|
||||
return Task.FromResult<IdentityRole<string>?>(null);
|
||||
}
|
||||
|
||||
return Task.FromResult(new IdentityRole<string>(group.Name) { Id = group.Alias });
|
||||
return Task.FromResult<IdentityRole<string>?>(new IdentityRole<string>(group.Name)
|
||||
{
|
||||
Id = group.Alias,
|
||||
});
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<IdentityUserRole<string>> FindUserRoleAsync(string userId, string roleId, CancellationToken cancellationToken)
|
||||
protected override async Task<IdentityUserRole<string>?> 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<string>? 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<BackOfficeIdentityUser, Iden
|
||||
&& user.Email != identityUser.Email && identityUser.Email.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
anythingChanged = true;
|
||||
user.Email = identityUser.Email;
|
||||
user.Email = identityUser.Email!;
|
||||
}
|
||||
|
||||
if (identityUser.IsPropertyDirty(nameof(BackOfficeIdentityUser.AccessFailedCount))
|
||||
@@ -615,7 +621,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
&& user.Username != identityUser.UserName && identityUser.UserName.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
anythingChanged = true;
|
||||
user.Username = identityUser.UserName;
|
||||
user.Username = identityUser.UserName!;
|
||||
}
|
||||
|
||||
if (identityUser.IsPropertyDirty(nameof(BackOfficeIdentityUser.PasswordHash))
|
||||
@@ -691,8 +697,7 @@ public class BackOfficeUserStore : UmbracoUserStore<BackOfficeIdentityUser, Iden
|
||||
/// Overridden to support Umbraco's own data storage requirements
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The base class's implementation of this calls into FindTokenAsync, RemoveUserTokenAsync and AddUserTokenAsync, both
|
||||
/// methods will only work with ORMs that are change
|
||||
/// 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.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -38,9 +38,9 @@ public static class MergeClaimsIdentityExtensions
|
||||
{
|
||||
foreach (IdentityUserClaim<string> 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!));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,14 +22,14 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// </summary>
|
||||
/// <param name="principal">The <see cref="ClaimsPrincipal" /></param>
|
||||
/// <returns>A <see cref="Task{TResult}" /> representing the result of the asynchronous operation.</returns>
|
||||
Task<TUser> GetUserAsync(ClaimsPrincipal principal);
|
||||
Task<TUser?> GetUserAsync(ClaimsPrincipal principal);
|
||||
|
||||
/// <summary>
|
||||
/// Get the user id from the <see cref="ClaimsPrincipal" />
|
||||
/// </summary>
|
||||
/// <param name="principal">the <see cref="ClaimsPrincipal" /></param>
|
||||
/// <returns>Returns the user id from the <see cref="ClaimsPrincipal" /></returns>
|
||||
string GetUserId(ClaimsPrincipal principal);
|
||||
string? GetUserId(ClaimsPrincipal principal);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the external logins for the user
|
||||
@@ -47,7 +47,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// Finds a user by the external login provider
|
||||
/// </summary>
|
||||
/// <returns>A <see cref="Task{TResult}" /> representing the result of the asynchronous operation.</returns>
|
||||
Task<TUser> FindByLoginAsync(string loginProvider, string providerKey);
|
||||
Task<TUser?> FindByLoginAsync(string loginProvider, string providerKey);
|
||||
|
||||
/// <summary>
|
||||
/// Finds and returns a user, if any, who has the specified <paramref name="userId" />.
|
||||
@@ -57,7 +57,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the user matching the specified
|
||||
/// <paramref name="userId" /> if it exists.
|
||||
/// </returns>
|
||||
Task<TUser> FindByIdAsync(string? userId);
|
||||
Task<TUser?> FindByIdAsync(string userId);
|
||||
|
||||
/// <summary>
|
||||
/// Generates a password reset token for the specified <paramref name="user" />, using
|
||||
@@ -80,7 +80,7 @@ public interface IUmbracoUserManager<TUser> : 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
|
||||
/// </remarks>
|
||||
Task<IdentityResult> ChangePasswordWithResetAsync(string userId, string token, string? newPassword);
|
||||
Task<IdentityResult> ChangePasswordWithResetAsync(string userId, string token, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// Validates that an email confirmation token matches the specified <paramref name="user" />.
|
||||
@@ -91,7 +91,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="IdentityResult" />
|
||||
/// of the operation.
|
||||
/// </returns>
|
||||
Task<IdentityResult> ConfirmEmailAsync(TUser user, string? token);
|
||||
Task<IdentityResult> ConfirmEmailAsync(TUser user, string token);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user, if any, associated with the normalized value of the specified email address.
|
||||
@@ -103,7 +103,7 @@ public interface IUmbracoUserManager<TUser> : 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.
|
||||
/// </returns>
|
||||
Task<TUser> FindByEmailAsync(string email);
|
||||
Task<TUser?> FindByEmailAsync(string email);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the <paramref name="user" />'s password to the specified <paramref name="newPassword" /> after
|
||||
@@ -116,7 +116,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="IdentityResult" />
|
||||
/// of the operation.
|
||||
/// </returns>
|
||||
Task<IdentityResult> ResetPasswordAsync(TUser user, string? token, string? newPassword);
|
||||
Task<IdentityResult> ResetPasswordAsync(TUser user, string token, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// 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<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="IdentityResult" />
|
||||
/// of the operation.
|
||||
/// </returns>
|
||||
Task<IdentityResult> ChangePasswordAsync(TUser user, string? currentPassword, string? newPassword);
|
||||
Task<IdentityResult> ChangePasswordAsync(TUser user, string currentPassword, string newPassword);
|
||||
|
||||
/// <summary>
|
||||
/// Used to validate a user's session
|
||||
@@ -268,7 +268,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the <see cref="IdentityResult" />
|
||||
/// of the operation.
|
||||
/// </returns>
|
||||
Task<IdentityResult> CreateAsync(TUser user, string? password);
|
||||
Task<IdentityResult> CreateAsync(TUser user, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Generate a password for a user based on the current password validator
|
||||
@@ -302,7 +302,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The <see cref="Task" /> that represents the asynchronous operation, containing the user matching the specified
|
||||
/// <paramref name="userName" /> if it exists.
|
||||
/// </returns>
|
||||
Task<TUser> FindByNameAsync(string userName);
|
||||
Task<TUser?> FindByNameAsync(string userName);
|
||||
|
||||
/// <summary>
|
||||
/// Increments the access failed count for the user as an asynchronous operation.
|
||||
@@ -373,7 +373,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The System.Threading.Tasks.Task that represents the asynchronous operation, containing the
|
||||
/// Microsoft.AspNetCore.Identity.IdentityResult of the operation.
|
||||
/// </returns>
|
||||
Task<IdentityResult> RemoveLoginAsync(TUser user, string? loginProvider, string? providerKey);
|
||||
Task<IdentityResult> RemoveLoginAsync(TUser user, string loginProvider, string providerKey);
|
||||
|
||||
/// <summary>
|
||||
/// Resets the access failed count for the user
|
||||
@@ -395,7 +395,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// The task object containing the results of the asynchronous operation, the email address for the specified
|
||||
/// user.
|
||||
/// </returns>
|
||||
Task<string> GetEmailAsync(TUser user);
|
||||
Task<string?> GetEmailAsync(TUser user);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the telephone number, if any, for the specified user.
|
||||
@@ -409,7 +409,7 @@ public interface IUmbracoUserManager<TUser> : IDisposable
|
||||
/// A user can only support a phone number if the BackOfficeUserStore is replaced with another that implements
|
||||
/// IUserPhoneNumberStore
|
||||
/// </remarks>
|
||||
Task<string> GetPhoneNumberAsync(TUser user);
|
||||
Task<string?> GetPhoneNumberAsync(TUser user);
|
||||
|
||||
/// <summary>
|
||||
/// Validates that a user's credentials are correct without actually logging them in.
|
||||
|
||||
@@ -131,7 +131,7 @@ public class MemberRoleStore : IQueryableRoleStore<UmbracoIdentityRole>
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<string> GetRoleNameAsync(UmbracoIdentityRole role, CancellationToken cancellationToken = default)
|
||||
public Task<string?> GetRoleNameAsync(UmbracoIdentityRole role, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
@@ -141,11 +141,11 @@ public class MemberRoleStore : IQueryableRoleStore<UmbracoIdentityRole>
|
||||
throw new ArgumentNullException(nameof(role));
|
||||
}
|
||||
|
||||
return Task.FromResult(role.Name)!;
|
||||
return Task.FromResult(role.Name);
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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<UmbracoIdentityRole>
|
||||
throw new ArgumentNullException(nameof(role));
|
||||
}
|
||||
|
||||
|
||||
role.Name = roleName;
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<string> GetNormalizedRoleNameAsync(
|
||||
public Task<string?> GetNormalizedRoleNameAsync(
|
||||
UmbracoIdentityRole role,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> GetRoleNameAsync(role, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task SetNormalizedRoleNameAsync(UmbracoIdentityRole role, string normalizedName,
|
||||
public Task SetNormalizedRoleNameAsync(UmbracoIdentityRole role, string? normalizedName,
|
||||
CancellationToken cancellationToken = default)
|
||||
=> SetRoleNameAsync(role, normalizedName, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<UmbracoIdentityRole> FindByIdAsync(string roleId, CancellationToken cancellationToken = default)
|
||||
public Task<UmbracoIdentityRole?> FindByIdAsync(string roleId, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
@@ -198,11 +199,11 @@ public class MemberRoleStore : IQueryableRoleStore<UmbracoIdentityRole>
|
||||
memberGroup = _memberGroupService.GetById(id);
|
||||
}
|
||||
|
||||
return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup))!;
|
||||
return Task.FromResult(memberGroup == null ? null : MapFromMemberGroup(memberGroup));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<UmbracoIdentityRole> FindByNameAsync(string name, CancellationToken cancellationToken = default)
|
||||
public Task<UmbracoIdentityRole?> FindByNameAsync(string name, CancellationToken cancellationToken = default)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
|
||||
@@ -91,7 +91,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
if (user == null)
|
||||
if (user is null)
|
||||
{
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
}
|
||||
@@ -100,9 +100,9 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
|
||||
// create member
|
||||
IMember memberEntity = _memberService.CreateMember(
|
||||
user.UserName,
|
||||
user.Email,
|
||||
user.Name.IsNullOrWhiteSpace() ? user.UserName : user.Name!,
|
||||
user.UserName!,
|
||||
user.Email!,
|
||||
user.Name.IsNullOrWhiteSpace() ? user.UserName! : user.Name!,
|
||||
user.MemberTypeAlias.IsNullOrWhiteSpace()
|
||||
? Constants.Security.DefaultMemberTypeAlias
|
||||
: user.MemberTypeAlias!);
|
||||
@@ -255,21 +255,19 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<MemberIdentityUser> FindByNameAsync(
|
||||
string userName,
|
||||
CancellationToken cancellationToken = default)
|
||||
public override Task<MemberIdentityUser?> 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<MemberIdentityUser?>(null);
|
||||
}
|
||||
|
||||
MemberIdentityUser result = AssignLoginsCallback(_mapper.Map<MemberIdentityUser>(user))!;
|
||||
MemberIdentityUser? result = AssignLoginsCallback(_mapper.Map<MemberIdentityUser>(user))!;
|
||||
|
||||
return Task.FromResult(result);
|
||||
return Task.FromResult<MemberIdentityUser?>(result);
|
||||
}
|
||||
|
||||
public IPublishedContent? GetPublishedMember(MemberIdentityUser? user)
|
||||
@@ -290,7 +288,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<MemberIdentityUser> FindByEmailAsync(
|
||||
public override Task<MemberIdentityUser?> FindByEmailAsync(
|
||||
string email,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -301,11 +299,11 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
? null
|
||||
: _mapper.Map<MemberIdentityUser>(member);
|
||||
|
||||
return Task.FromResult(AssignLoginsCallback(result))!;
|
||||
return Task.FromResult(AssignLoginsCallback(result));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<MemberIdentityUser> FindUserAsync(string userId, CancellationToken cancellationToken)
|
||||
protected override Task<MemberIdentityUser?> FindUserAsync(string userId, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
ThrowIfDisposed();
|
||||
@@ -320,7 +318,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
: _memberService.GetById(UserIdToInt(userId));
|
||||
if (user == null)
|
||||
{
|
||||
return Task.FromResult((MemberIdentityUser)null!);
|
||||
return Task.FromResult((MemberIdentityUser)null!)!;
|
||||
}
|
||||
|
||||
return Task.FromResult(AssignLoginsCallback(_mapper.Map<MemberIdentityUser>(user)))!;
|
||||
@@ -440,7 +438,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<IdentityUserLogin<string>> FindUserLoginAsync(string userId, string loginProvider,
|
||||
protected override async Task<IdentityUserLogin<string>?> FindUserLoginAsync(string userId, string loginProvider,
|
||||
string providerKey, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -456,38 +454,32 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
throw new ArgumentNullException(nameof(providerKey));
|
||||
}
|
||||
|
||||
MemberIdentityUser user = await FindUserAsync(userId, cancellationToken);
|
||||
if (user == null)
|
||||
MemberIdentityUser? user = await FindUserAsync(userId, cancellationToken);
|
||||
if (user?.Id is null)
|
||||
{
|
||||
return await Task.FromResult((IdentityUserLogin<string>)null!);
|
||||
return await Task.FromResult<IdentityUserLogin<string>?>(null);
|
||||
}
|
||||
|
||||
IList<UserLoginInfo> 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<string>)null!);
|
||||
return await Task.FromResult<IdentityUserLogin<string>?>(null);
|
||||
}
|
||||
|
||||
if (user.Id is not null)
|
||||
{
|
||||
return new IdentityUserLogin<string>
|
||||
{
|
||||
LoginProvider = found.LoginProvider,
|
||||
ProviderKey = found.ProviderKey,
|
||||
|
||||
// TODO: We don't store this value so it will be null
|
||||
ProviderDisplayName = found.ProviderDisplayName,
|
||||
UserId = user.Id,
|
||||
UserId = user.Id
|
||||
};
|
||||
}
|
||||
|
||||
return null!;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<IdentityUserLogin<string>> FindUserLoginAsync(string loginProvider, string providerKey,
|
||||
protected override Task<IdentityUserLogin<string>?> FindUserLoginAsync(string loginProvider, string providerKey,
|
||||
CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
@@ -506,11 +498,11 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
var logins = _externalLoginService.Find(loginProvider, providerKey).ToList();
|
||||
if (logins.Count == 0)
|
||||
{
|
||||
return Task.FromResult((IdentityUserLogin<string>)null!);
|
||||
return Task.FromResult<IdentityUserLogin<string>?>(null);
|
||||
}
|
||||
|
||||
IIdentityUserLogin found = logins[0];
|
||||
return Task.FromResult(new IdentityUserLogin<string>
|
||||
return Task.FromResult<IdentityUserLogin<string>?>(new IdentityUserLogin<string>
|
||||
{
|
||||
LoginProvider = found.LoginProvider,
|
||||
ProviderKey = found.ProviderKey,
|
||||
@@ -527,7 +519,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
{
|
||||
// if there are no roles, they either haven't been loaded since we don't eagerly
|
||||
// load for members, or they just have no roles.
|
||||
IEnumerable<string> currentRoles = _memberService.GetAllRoles(user.UserName);
|
||||
IEnumerable<string> currentRoles = _memberService.GetAllRoles(user.UserName!);
|
||||
ICollection<IdentityUserRole<string>> roles = currentRoles
|
||||
.Select(role => new IdentityUserRole<string> { RoleId = role, UserId = user.Id }).ToList();
|
||||
|
||||
@@ -538,7 +530,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
/// <summary>
|
||||
/// Lists all users of a given role.
|
||||
/// </summary>
|
||||
public override Task<IList<MemberIdentityUser>?> GetUsersInRoleAsync(
|
||||
public override Task<IList<MemberIdentityUser>> GetUsersInRoleAsync(
|
||||
string roleName,
|
||||
CancellationToken cancellationToken = default)
|
||||
{
|
||||
@@ -550,10 +542,10 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
throw new ArgumentNullException(nameof(roleName));
|
||||
}
|
||||
|
||||
IEnumerable<IMember>? members = _memberService.GetMembersByMemberType(roleName);
|
||||
IEnumerable<IMember> members = _memberService.GetMembersByMemberType(roleName);
|
||||
|
||||
IList<MemberIdentityUser>? membersIdentityUsers =
|
||||
members?.Select(x => _mapper.Map<MemberIdentityUser>(x)!).ToList();
|
||||
IList<MemberIdentityUser> membersIdentityUsers =
|
||||
members.Select(x => _mapper.Map<MemberIdentityUser>(x)!).ToList();
|
||||
|
||||
return Task.FromResult(membersIdentityUsers);
|
||||
}
|
||||
@@ -567,8 +559,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
/// tracking ORMs like EFCore.
|
||||
/// </remarks>
|
||||
/// <inheritdoc />
|
||||
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<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override Task<UmbracoIdentityRole> FindRoleAsync(string roleName, CancellationToken cancellationToken)
|
||||
protected override Task<UmbracoIdentityRole?> FindRoleAsync(string roleName, CancellationToken cancellationToken)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(roleName))
|
||||
{
|
||||
@@ -634,12 +625,12 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
IMemberGroup? group = _memberService.GetAllRoles().SingleOrDefault(x => x.Name == roleName);
|
||||
if (group == null)
|
||||
if (group?.Name is null)
|
||||
{
|
||||
return Task.FromResult((UmbracoIdentityRole)null!);
|
||||
return Task.FromResult<UmbracoIdentityRole?>(null);
|
||||
}
|
||||
|
||||
return Task.FromResult(new UmbracoIdentityRole(group.Name)
|
||||
return Task.FromResult<UmbracoIdentityRole?>(new UmbracoIdentityRole(group.Name)
|
||||
{
|
||||
// TODO: what should the alias be?
|
||||
Id = group.Id.ToString(),
|
||||
@@ -647,27 +638,25 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
protected override async Task<IdentityUserRole<string>> FindUserRoleAsync(string userId, string roleId,
|
||||
protected override async Task<IdentityUserRole<string>?> 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<string>? 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<IEnumerable<IIdentityUserLogin>?>(() => _externalLoginService.GetExternalLogins(user.Key)));
|
||||
user.SetTokensCallback(new Lazy<IEnumerable<IIdentityUserToken>?>(() =>
|
||||
_externalLoginService.GetExternalLoginTokens(user.Key)));
|
||||
user.SetLoginsCallback(new Lazy<IEnumerable<IIdentityUserLogin>?>(() => _externalLoginService.GetExternalLogins(user.Key)));
|
||||
user.SetTokensCallback(new Lazy<IEnumerable<IIdentityUserToken>?>(() => _externalLoginService.GetExternalLoginTokens(user.Key)));
|
||||
}
|
||||
|
||||
return user;
|
||||
@@ -729,7 +718,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
&& member.Email != identityUser.Email && identityUser.Email.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
anythingChanged = true;
|
||||
member.Email = identityUser.Email;
|
||||
member.Email = identityUser.Email!;
|
||||
}
|
||||
|
||||
if (identityUser.IsPropertyDirty(nameof(MemberIdentityUser.AccessFailedCount))
|
||||
@@ -761,7 +750,7 @@ public class MemberUserStore : UmbracoUserStore<MemberIdentityUser, UmbracoIdent
|
||||
&& member.Username != identityUser.UserName && identityUser.UserName.IsNullOrWhiteSpace() == false)
|
||||
{
|
||||
anythingChanged = true;
|
||||
member.Username = identityUser.UserName;
|
||||
member.Username = identityUser.UserName!;
|
||||
}
|
||||
|
||||
if (identityUser.IsPropertyDirty(nameof(MemberIdentityUser.PasswordHash))
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Umbraco.Cms.Core.Security;
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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"),
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
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));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override string NormalizedName { get => base.Name; set => base.Name = value; }
|
||||
public override string? NormalizedName { get => base.Name ?? string.Empty; set => base.Name = value; }
|
||||
|
||||
/// <summary>
|
||||
/// 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; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the <see cref="BeingDirty" /> for change tracking
|
||||
|
||||
@@ -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; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets last login date
|
||||
@@ -85,7 +85,7 @@ public abstract class UmbracoIdentityUser : IdentityUser, IRememberBeingDirty
|
||||
/// <summary>
|
||||
/// Gets or sets email
|
||||
/// </summary>
|
||||
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
|
||||
/// <summary>
|
||||
/// Gets or sets user name
|
||||
/// </summary>
|
||||
public override string UserName
|
||||
public override string? UserName
|
||||
{
|
||||
get => _userName;
|
||||
set => BeingDirty.SetPropertyValueAndDetectChanges(value, ref _userName!, nameof(UserName));
|
||||
|
||||
@@ -134,8 +134,8 @@ public abstract class UmbracoUserManager<TUser, TPasswordConfig> : UserManager<T
|
||||
/// <inheritdoc />
|
||||
public override async Task<bool> 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<TUser, TPasswordConfig> : UserManager<T
|
||||
/// is to generate a token and reset it, however, when we do this we want to track a password change, not a password
|
||||
/// reset
|
||||
/// </remarks>
|
||||
public virtual async Task<IdentityResult> ChangePasswordWithResetAsync(string userId, string token, string? newPassword)
|
||||
public virtual async Task<IdentityResult> 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<TUser, TPasswordConfig> : UserManager<T
|
||||
|
||||
public async Task<bool> ValidateCredentialsAsync(string username, string password)
|
||||
{
|
||||
TUser user = await FindByNameAsync(username);
|
||||
if (user == null)
|
||||
TUser? user = await FindByNameAsync(username);
|
||||
if (user is null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ public abstract class UmbracoUserStore<TUser, TRole>
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<TUser> FindByIdAsync(string userId, CancellationToken cancellationToken = default) =>
|
||||
public override Task<TUser?> FindByIdAsync(string userId, CancellationToken cancellationToken = default) =>
|
||||
FindUserAsync(userId, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -96,11 +96,11 @@ public abstract class UmbracoUserStore<TUser, TRole>
|
||||
throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<string> GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken)
|
||||
public override Task<string?> GetNormalizedEmailAsync(TUser user, CancellationToken cancellationToken)
|
||||
=> GetEmailAsync(user, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<string> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default)
|
||||
public override Task<string?> GetNormalizedUserNameAsync(TUser user, CancellationToken cancellationToken = default)
|
||||
=> GetUserNameAsync(user, cancellationToken);
|
||||
|
||||
/// <summary>
|
||||
@@ -221,15 +221,15 @@ public abstract class UmbracoUserStore<TUser, TRole>
|
||||
public override Task ReplaceClaimAsync(TUser user, Claim claim, Claim newClaim, CancellationToken cancellationToken = default) => throw new NotImplementedException();
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task SetNormalizedEmailAsync(TUser user, string normalizedEmail, CancellationToken cancellationToken)
|
||||
public override Task SetNormalizedEmailAsync(TUser user, string? normalizedEmail, CancellationToken cancellationToken)
|
||||
=> SetEmailAsync(user, normalizedEmail, cancellationToken);
|
||||
|
||||
/// <inheritdoc />
|
||||
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);
|
||||
|
||||
/// <inheritdoc />
|
||||
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<TUser, TRole>
|
||||
/// </summary>
|
||||
/// <inheritdoc />
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
protected override Task<IdentityUserToken<string>> FindTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) => throw new NotImplementedException();
|
||||
protected override Task<IdentityUserToken<string>?> FindTokenAsync(TUser user, string loginProvider, string name, CancellationToken cancellationToken) => throw new NotImplementedException();
|
||||
|
||||
/// <summary>
|
||||
/// Not supported in Umbraco, see comments above on GetTokenAsync, RemoveTokenAsync, SetTokenAsync
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Infrastructure</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Infrastructure</PackageId>
|
||||
<Title>Umbraco CMS Infrastructure</Title>
|
||||
@@ -24,6 +24,11 @@
|
||||
<PackageReference Include="Markdown" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.0.1" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Http" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Identity.Stores" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="6.0.0" />
|
||||
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="6.0.0" />
|
||||
@@ -50,6 +55,9 @@
|
||||
<PackageReference Include="Serilog.Sinks.Map" Version="1.0.2" />
|
||||
<PackageReference Include="SixLabors.ImageSharp" Version="2.1.3" />
|
||||
<PackageReference Include="System.IO.FileSystem.AccessControl" Version="5.0.0" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="7.0.0-preview.7.22375.6" /> <!-- Explicit updated this nested dependency due to this https://github.com/dotnet/announcements/issues/178-->
|
||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Examine.Core" Version="3.0.0-beta.9" />
|
||||
<PackageReference Include="System.Security.Cryptography.Pkcs" Version="6.0.1" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="6.0.0" /> <!-- Explicit updated this nested dependency due to this https://github.com/dotnet/announcements/issues/178-->
|
||||
<PackageReference Include="System.Threading.Tasks.Dataflow" Version="6.0.0" />
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Infrastructure.PublishedCache</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.PublishedCache.NuCache</PackageId>
|
||||
<Title>Umbraco CMS Published Cache</Title>
|
||||
|
||||
@@ -186,11 +186,13 @@ public class AuthenticationController : UmbracoApiControllerBase
|
||||
[ValidateAngularAntiForgeryToken]
|
||||
public async Task<IActionResult> 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);
|
||||
@@ -487,12 +489,15 @@ public class AuthenticationController : UmbracoApiControllerBase
|
||||
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);
|
||||
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)
|
||||
|
||||
@@ -379,7 +379,7 @@ public class BackOfficeController : UmbracoController
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> 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}");
|
||||
|
||||
@@ -376,7 +376,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers
|
||||
},
|
||||
{
|
||||
"currentUserApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl<CurrentUserController>(
|
||||
controller => controller.PostChangePassword(new ChangingPasswordModel()))
|
||||
controller => controller.PostSetAvatar(new List<IFormFile>()))
|
||||
},
|
||||
{
|
||||
"entityApiBaseUrl", _linkGenerator.GetUmbracoApiServiceBaseUrl<EntityController>(
|
||||
|
||||
@@ -198,12 +198,13 @@ public class CurrentUserController : UmbracoAuthorizedJsonController
|
||||
[AllowAnonymous]
|
||||
public async Task<ActionResult<UserDetail?>> 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<Dictionary<string, string>> 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)
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -65,7 +65,11 @@ public class TwoFactorLoginController : UmbracoAuthorizedJsonController
|
||||
[HttpGet]
|
||||
public async Task<ActionResult<IEnumerable<UserTwoFactorProviderModel>>> 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<string>(await _twoFactorLoginService.GetEnabledTwoFactorProviderNamesAsync(user.Key));
|
||||
|
||||
@@ -565,10 +565,20 @@ public class UsersController : BackOfficeNotificationsController
|
||||
return new ActionResult<IUser?>(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
|
||||
|
||||
@@ -48,7 +48,7 @@ namespace Umbraco.Extensions
|
||||
|
||||
IEnumerable<LocalizedTextServiceSupplementaryFileSource> 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)
|
||||
{
|
||||
|
||||
@@ -75,7 +75,7 @@ public class CreateUnattendedUserNotificationHandler : INotificationAsyncHandler
|
||||
using IServiceScope scope = _serviceScopeFactory.CreateScope();
|
||||
IBackOfficeUserManager backOfficeUserManager =
|
||||
scope.ServiceProvider.GetRequiredService<IBackOfficeUserManager>();
|
||||
BackOfficeIdentityUser membershipUser =
|
||||
BackOfficeIdentityUser? membershipUser =
|
||||
await backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
|
||||
if (membershipUser == null)
|
||||
{
|
||||
|
||||
@@ -88,9 +88,11 @@ public class InstallApiController : ControllerBase
|
||||
{
|
||||
await _runtime.RestartAsync();
|
||||
|
||||
BackOfficeIdentityUser identityUser =
|
||||
await _backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
|
||||
BackOfficeIdentityUser? identityUser = await _backOfficeUserManager.FindByIdAsync(Constants.Security.SuperUserIdAsString);
|
||||
if (identityUser is not null)
|
||||
{
|
||||
_backOfficeSignInManager.SignInAsync(identityUser, false);
|
||||
}
|
||||
|
||||
return NoContent();
|
||||
}
|
||||
|
||||
@@ -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
|
||||
/// </summary>
|
||||
/// <param name="name"></param>
|
||||
/// <param name="options"></param>
|
||||
public void PostConfigure(string name, GlobalSettings options) =>
|
||||
public void PostConfigure(string? name, GlobalSettings options) =>
|
||||
options.ReservedUrls += _keepAliveSettings.Value.KeepAlivePingUrl;
|
||||
}
|
||||
|
||||
@@ -62,10 +62,10 @@ public class BackOfficeAuthenticationBuilder : AuthenticationBuilder
|
||||
internal class EnsureBackOfficeScheme<TOptions> : IPostConfigureOptions<TOptions>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -117,7 +117,7 @@ public class BackOfficeSignInManager : UmbracoSignInManager<BackOfficeIdentityUs
|
||||
/// <param name="redirectUrl">The external login URL users should be redirected to during the login flow.</param>
|
||||
/// <param name="userId">The current user's identifier, which will be used to provide CSRF protection.</param>
|
||||
/// <returns>A configured <see cref="AuthenticationProperties" />.</returns>
|
||||
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<BackOfficeIdentityUs
|
||||
}
|
||||
|
||||
//Now we need to perform the auto-link, so first we need to lookup/create a user with the email address
|
||||
BackOfficeIdentityUser? autoLinkUser = await UserManager.FindByEmailAsync(email);
|
||||
BackOfficeIdentityUser? autoLinkUser = await UserManager.FindByEmailAsync(email!);
|
||||
if (autoLinkUser != null)
|
||||
{
|
||||
try
|
||||
@@ -228,7 +228,7 @@ public class BackOfficeSignInManager : UmbracoSignInManager<BackOfficeIdentityUs
|
||||
throw new InvalidOperationException("The Name value cannot be null");
|
||||
}
|
||||
|
||||
autoLinkUser = BackOfficeIdentityUser.CreateNew(_globalSettings, email, email, autoLinkOptions.GetUserAutoLinkCulture(_globalSettings), name);
|
||||
autoLinkUser = BackOfficeIdentityUser.CreateNew(_globalSettings, email, email!, autoLinkOptions.GetUserAutoLinkCulture(_globalSettings), name);
|
||||
|
||||
foreach (var userGroup in autoLinkOptions.DefaultUserGroups)
|
||||
{
|
||||
|
||||
@@ -80,7 +80,7 @@ public class ConfigureBackOfficeCookieOptions : IConfigureNamedOptions<CookieAut
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public void Configure(string name, CookieAuthenticationOptions options)
|
||||
public void Configure(string? name, CookieAuthenticationOptions options)
|
||||
{
|
||||
if (name != Constants.Security.BackOfficeAuthenticationType)
|
||||
{
|
||||
|
||||
@@ -52,7 +52,7 @@ internal class PasswordChanger<TUser> : IPasswordChanger<TUser> 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<TUser> : IPasswordChanger<TUser> 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"
|
||||
|
||||
@@ -141,7 +141,7 @@ public class IconService : IIconService
|
||||
|
||||
IEnumerable<FileInfo> 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);
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Umbraco.Cms.Web.BackOffice</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Web.BackOffice</PackageId>
|
||||
|
||||
@@ -82,7 +82,7 @@ public class AspNetCoreHostingEnvironment : IHostingEnvironment
|
||||
public Uri ApplicationMainUrl { get; private set; } = null!;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string SiteName { get; private set; } = null!;
|
||||
public string? SiteName { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public string ApplicationId
|
||||
|
||||
@@ -44,10 +44,10 @@ public class AspNetCoreRequestAccessor : IRequestAccessor, INotificationHandler<
|
||||
});
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetRequestValue(string name) => GetFormValue(name) ?? GetQueryStringValue(name);
|
||||
public string? GetRequestValue(string name) => GetFormValue(name) ?? GetQueryStringValue(name);
|
||||
|
||||
/// <inheritdoc />
|
||||
public string GetQueryStringValue(string name) => _httpContextAccessor.GetRequiredHttpContext().Request.Query[name];
|
||||
public string? GetQueryStringValue(string name) => _httpContextAccessor.GetRequiredHttpContext().Request.Query[name];
|
||||
|
||||
/// <inheritdoc />
|
||||
public Uri? GetRequestUrl() => _httpContextAccessor.HttpContext != null
|
||||
|
||||
@@ -15,7 +15,7 @@ internal class OptionsMonitorAdapter<T> : IOptionsMonitor<T>
|
||||
|
||||
public T CurrentValue { get; }
|
||||
|
||||
public T Get(string name) => CurrentValue;
|
||||
public T Get(string? name) => CurrentValue;
|
||||
|
||||
public IDisposable OnChange(Action<T, string> listener) => throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public static class FormCollectionExtensions
|
||||
/// <param name="items"></param>
|
||||
/// <param name="key"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetRequiredString(this FormCollection items, string key)
|
||||
public static string? GetRequiredString(this FormCollection items, string key)
|
||||
{
|
||||
if (items.HasKey(key) == false)
|
||||
{
|
||||
|
||||
@@ -65,7 +65,7 @@ public static class HttpContextExtensions
|
||||
/// <summary>
|
||||
/// Get the value in the request form or query string for the key
|
||||
/// </summary>
|
||||
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];
|
||||
}
|
||||
|
||||
|
||||
@@ -70,7 +70,7 @@ public sealed class RoutableDocumentFilter : IRoutableDocumentFilter
|
||||
return maybeDoc;
|
||||
}
|
||||
|
||||
private void EndpointsChanged(object value)
|
||||
private void EndpointsChanged(object? value)
|
||||
{
|
||||
lock (_routeLocker)
|
||||
{
|
||||
|
||||
@@ -90,7 +90,7 @@ public class BackOfficeUserManager : UmbracoUserManager<BackOfficeIdentityUser,
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task<IdentityResult> ChangePasswordWithResetAsync(string userId, string token, string? newPassword)
|
||||
public override async Task<IdentityResult> 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<BackOfficeIdentityUser,
|
||||
return result;
|
||||
}
|
||||
|
||||
public override async Task<IdentityResult> ChangePasswordAsync(BackOfficeIdentityUser user, string? currentPassword, string? newPassword)
|
||||
public override async Task<IdentityResult> ChangePasswordAsync(BackOfficeIdentityUser user, string currentPassword, string newPassword)
|
||||
{
|
||||
IdentityResult result = await base.ChangePasswordAsync(user, currentPassword, newPassword);
|
||||
if (result.Succeeded)
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed class ConfigureMemberCookieOptions : IConfigureNamedOptions<Cookie
|
||||
_umbracoRequestPaths = umbracoRequestPaths;
|
||||
}
|
||||
|
||||
public void Configure(string name, CookieAuthenticationOptions options)
|
||||
public void Configure(string? name, CookieAuthenticationOptions options)
|
||||
{
|
||||
if (name == IdentityConstants.ApplicationScheme || name == IdentityConstants.ExternalScheme)
|
||||
{
|
||||
|
||||
@@ -21,11 +21,14 @@ public class ConfigureSecurityStampOptions : IConfigureOptions<SecurityStampVali
|
||||
// to flow through to this new one.
|
||||
options.OnRefreshingPrincipal = refreshingPrincipal =>
|
||||
{
|
||||
ClaimsIdentity newIdentity = refreshingPrincipal.NewPrincipal.Identities.First();
|
||||
ClaimsIdentity currentIdentity = refreshingPrincipal.CurrentPrincipal.Identities.First();
|
||||
ClaimsIdentity? newIdentity = refreshingPrincipal.NewPrincipal?.Identities.First();
|
||||
ClaimsIdentity? currentIdentity = refreshingPrincipal.CurrentPrincipal?.Identities.First();
|
||||
|
||||
if (currentIdentity is not null)
|
||||
{
|
||||
// Since this is refreshing an existing principal, we want to merge all claims.
|
||||
newIdentity.MergeAllClaims(currentIdentity);
|
||||
newIdentity?.MergeAllClaims(currentIdentity);
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
};
|
||||
|
||||
@@ -19,7 +19,7 @@ public interface IBackOfficeSignInManager
|
||||
|
||||
Task<ExternalLoginInfo?> GetExternalLoginInfoAsync(string? expectedXsrf = null);
|
||||
|
||||
Task<BackOfficeIdentityUser> GetTwoFactorAuthenticationUserAsync();
|
||||
Task<BackOfficeIdentityUser?> GetTwoFactorAuthenticationUserAsync();
|
||||
|
||||
Task<SignInResult> PasswordSignInAsync(string userName, string password, bool isPersistent, bool lockoutOnFailure);
|
||||
|
||||
@@ -29,7 +29,7 @@ public interface IBackOfficeSignInManager
|
||||
|
||||
Task<ClaimsPrincipal> CreateUserPrincipalAsync(BackOfficeIdentityUser user);
|
||||
|
||||
Task<SignInResult> TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient);
|
||||
Task<SignInResult> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient);
|
||||
|
||||
Task<IdentityResult> UpdateExternalAuthenticationTokensAsync(ExternalLoginInfo externalLogin);
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ public interface IMemberSignInManager
|
||||
|
||||
Task<SignInResult> ExternalLoginSignInAsync(ExternalLoginInfo loginInfo, bool isPersistent, bool bypassTwoFactor = false);
|
||||
|
||||
Task<MemberIdentityUser> GetTwoFactorAuthenticationUserAsync();
|
||||
Task<MemberIdentityUser?> GetTwoFactorAuthenticationUserAsync();
|
||||
|
||||
Task<SignInResult> TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient);
|
||||
Task<SignInResult> TwoFactorSignInAsync(string provider, string code, bool isPersistent, bool rememberClient);
|
||||
}
|
||||
|
||||
@@ -188,7 +188,7 @@ public class MemberManager : UmbracoUserManager<MemberIdentityUser, MemberPasswo
|
||||
return null;
|
||||
}
|
||||
|
||||
_currentMember = await GetUserAsync(_httpContextAccessor.HttpContext?.User);
|
||||
_currentMember = await GetUserAsync(_httpContextAccessor.HttpContext?.User!);
|
||||
}
|
||||
|
||||
return _currentMember;
|
||||
@@ -204,7 +204,7 @@ public class MemberManager : UmbracoUserManager<MemberIdentityUser, MemberPasswo
|
||||
private async Task<bool> 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, MemberPasswo
|
||||
var result = new Dictionary<string, bool>();
|
||||
MemberIdentityUser? currentMember = await GetCurrentMemberAsync();
|
||||
|
||||
if (currentMember == null || !currentMember.IsApproved || currentMember.IsLockedOut)
|
||||
if (currentMember?.UserName is null || !currentMember.IsApproved || currentMember.IsLockedOut)
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -159,8 +159,8 @@ public class MemberSignInManager : UmbracoSignInManager<MemberIdentityUser>, 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<MemberIdentityUser>, 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<MemberIdentityUser>, 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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -86,7 +86,7 @@ public abstract class UmbracoSignInManager<TUser> : SignInManager<TUser>
|
||||
|
||||
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<TUser> : SignInManager<TUser>
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<TUser> GetTwoFactorAuthenticationUserAsync()
|
||||
public override async Task<TUser?> 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<TUser> : SignInManager<TUser>
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task<SignInResult> TwoFactorSignInAsync(string? provider, string? code, bool isPersistent, bool rememberClient)
|
||||
public override async Task<SignInResult> 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
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Umbraco.Cms.Web.Common</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Web.Common</PackageId>
|
||||
@@ -9,7 +9,7 @@
|
||||
<Description>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</Description>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Umbraco.Cms.Web.Common</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Web.Common</PackageId>
|
||||
@@ -35,6 +35,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Dazinator.Extensions.FileProviders" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Razor.RuntimeCompilation" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
|
||||
|
||||
@@ -1,22 +1,38 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Web.UI</RootNamespace>
|
||||
<EnablePackageValidation>false</EnablePackageValidation>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Umbraco.Cms\buildTransitive\Umbraco.Cms.props" />
|
||||
|
||||
<PropertyGroup Condition="'$(Configuration)' == 'Release'">
|
||||
<DocumentationFile>bin/Release/Umbraco.Web.UI.xml</DocumentationFile>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<CopyRazorGenerateFilesToPublishDirectory>true</CopyRazorGenerateFilesToPublishDirectory>
|
||||
</PropertyGroup>
|
||||
|
||||
<Import Project="..\Umbraco.Cms\buildTransitive\Umbraco.Cms.props" />
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Umbraco.Cms\Umbraco.Cms.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="6.0.5" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1" PrivateAssets="all" />
|
||||
<PackageReference Include="Umbraco.Code" Version="2.0.0" PrivateAssets="all" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.NewtonsoftJson" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.SourceLink.GitHub" Version="1.1.1">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Umbraco.Code" Version="2.0.0">
|
||||
<PrivateAssets>all</PrivateAssets>
|
||||
</PackageReference>
|
||||
<!-- Opt-in to app-local ICU to ensure consistent globalization APIs across different platforms -->
|
||||
<PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
|
||||
<RuntimeHostConfigurationOption Include="System.Globalization.AppLocalIcu" Value="68.2.0.9" Condition="$(RuntimeIdentifier.StartsWith('linux')) or $(RuntimeIdentifier.StartsWith('win')) or ('$(RuntimeIdentifier)' == '' and !$([MSBuild]::IsOSPlatform('osx')))" />
|
||||
@@ -46,6 +62,8 @@
|
||||
<CallTarget Targets="AppsettingsDevBuild" Condition="!Exists('appsettings.Development.json')" />
|
||||
</Target>
|
||||
|
||||
|
||||
|
||||
<Target Name="JsonSchemaBuild">
|
||||
<Exec Command="dotnet run -c Release --project $(JsonSchemaProjectPath) -o "$(ProjectDir)appsettings-schema.json"" />
|
||||
</Target>
|
||||
@@ -59,4 +77,5 @@
|
||||
<Message Text="Generating appsettings.Development.json because it doesnt exist" Importance="High" />
|
||||
<Copy SourceFiles="$(ProjectDir)appsettings.Development.template.json" DestinationFiles="$(ProjectDir)appsettings.Development.json" />
|
||||
</Target>
|
||||
|
||||
</Project>
|
||||
|
||||
@@ -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<IActionResult> ExternalLinkLoginCallback(string returnUrl)
|
||||
{
|
||||
MemberIdentityUser user = await _memberManager.GetUserAsync(User);
|
||||
MemberIdentityUser? user = await _memberManager.GetUserAsync(User);
|
||||
string? loginProvider = null;
|
||||
var errors = new List<string>();
|
||||
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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -62,9 +62,9 @@ public class MemberAuthenticationBuilder : AuthenticationBuilder
|
||||
private class EnsureMemberScheme<TOptions> : IPostConfigureOptions<TOptions>
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<RootNamespace>Umbraco.Cms.Web.Website</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Web.Website</PackageId>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<Import Project="$([MSBuild]::GetPathOfFileAbove('Directory.Build.props', '$(MSBuildThisFileDirectory)../src/'))" />
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<PackageType>Template</PackageType>
|
||||
<IncludeBuildOutput>false</IncludeBuildOutput>
|
||||
<ContentTargetFolders>.</ContentTargetFolders>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ContentTargetFolders>.</ContentTargetFolders>
|
||||
<Product>UmbracoPackage</Product>
|
||||
<PackageId>UmbracoPackage</PackageId>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
<RootNamespace Condition="'$(name)' != '$(name{-VALUE-FORMS-}safe_namespace)'">Umbraco.Cms.Web.UI</RootNamespace>
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
<PropertyGroup>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Umbraco.TestData</RootNamespace>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
@@ -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 .
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
|
||||
<IsPackable>false</IsPackable>
|
||||
@@ -26,7 +26,7 @@
|
||||
<Version>0.13.1</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Microsoft.Extensions.Logging.Debug">
|
||||
<Version>6.0.0</Version>
|
||||
<Version>7.0.0-preview.7.22375.6</Version>
|
||||
</PackageReference>
|
||||
<PackageReference Include="Moq">
|
||||
<Version>4.18.1</Version>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Tests.Common</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Tests</PackageId>
|
||||
<Title>Umbraco CMS Test Tools</Title>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Tests.Integration</RootNamespace>
|
||||
<PackageId>Umbraco.Cms.Tests.Integration</PackageId>
|
||||
<Title>Umbraco CMS Integration Tests</Title>
|
||||
@@ -86,8 +86,8 @@
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Examine.Lucene" Version="3.0.0" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="Microsoft.AspNet.WebApi.Client" Version="5.2.9" />
|
||||
<PackageReference Include="Microsoft.AspNetCore.Mvc.Testing" Version="6.0.5" />
|
||||
<PackageReference Include="Bogus" Version="34.0.2" />
|
||||
<PackageReference Include="Microsoft.ICU.ICU4C.Runtime" Version="68.2.0.9" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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==",
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>Exe</OutputType>
|
||||
<TargetFramework>net6.0</TargetFramework>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<RootNamespace>Umbraco.Cms.Tests.UnitTests</RootNamespace>
|
||||
<IsPackable>false</IsPackable>
|
||||
<IsTestProject>true</IsTestProject>
|
||||
@@ -26,8 +26,8 @@
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="4.2.1" />
|
||||
<PackageReference Include="System.Data.Odbc" Version="6.0.0" />
|
||||
<PackageReference Include="System.Data.OleDb" Version="6.0.0" />
|
||||
<PackageReference Include="System.Data.Odbc" Version="7.0.0-preview.7.22375.6" />
|
||||
<PackageReference Include="System.Data.OleDb" Version="7.0.0-preview.7.22375.6" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user