Add normalized username column

This commit is contained in:
JPVenson
2026-05-22 10:42:00 +00:00
parent 03ff69a6e1
commit 6de99306ec
5 changed files with 1776 additions and 4 deletions

View File

@@ -165,7 +165,7 @@ namespace Jellyfin.Server.Implementations.Users
#pragma warning disable CA1311 // Specify a culture or use an invariant version to avoid implicit dependency on current culture
#pragma warning disable CA1304 // The behavior of 'string.ToUpper()' could vary based on the current user's locale settings
return UserQuery(dbContext)
.FirstOrDefault(u => u.Username.ToUpper() == name.ToUpper());
.FirstOrDefault(u => u.NormalizedUsername == name.ToUpperInvariant());
#pragma warning restore CA1304 // The behavior of 'string.ToUpper()' could vary based on the current user's locale settings
#pragma warning restore CA1311 // Specify a culture or use an invariant version to avoid implicit dependency on current culture
#pragma warning restore CA1862 // Use the 'StringComparison' method overloads to perform case-insensitive string comparisons
@@ -191,7 +191,7 @@ namespace Jellyfin.Server.Implementations.Users
#pragma warning disable CA1311 // Specify a culture or use an invariant version to avoid implicit dependency on current culture
#pragma warning disable CA1304 // The behavior of 'string.ToUpper()' could vary based on the current user's locale settings
if (await dbContext.Users
.AnyAsync(u => u.Username.ToUpper() == newName.ToUpper() && u.Id != userId)
.AnyAsync(u => u.NormalizedUsername == newName.ToUpperInvariant() && u.Id != userId)
.ConfigureAwait(false))
{
throw new ArgumentException(string.Format(
@@ -262,7 +262,7 @@ namespace Jellyfin.Server.Implementations.Users
#pragma warning disable CA1311 // Specify a culture or use an invariant version to avoid implicit dependency on current culture
#pragma warning disable CA1304 // The behavior of 'string.ToUpper()' could vary based on the current user's locale settings
if (await dbContext.Users
.AnyAsync(u => u.Username.ToUpper() == name.ToUpper())
.AnyAsync(u => u.NormalizedUsername == name.ToUpperInvariant())
.ConfigureAwait(false))
{
throw new ArgumentException(string.Format(

View File

@@ -27,6 +27,7 @@ namespace Jellyfin.Database.Implementations.Entities
ArgumentException.ThrowIfNullOrEmpty(passwordResetProviderId);
Username = username;
NormalizedUsername = username.ToUpperInvariant();
AuthenticationProviderId = authenticationProviderId;
PasswordResetProviderId = passwordResetProviderId;
@@ -73,6 +74,16 @@ namespace Jellyfin.Database.Implementations.Entities
[StringLength(255)]
public string Username { get; set; }
/// <summary>
/// Gets or sets the user's normalized name.
/// </summary>
/// <remarks>
/// Required, Max length = 255.
/// </remarks>
[MaxLength(255)]
[StringLength(255)]
public string NormalizedUsername { get; set; }
/// <summary>
/// Gets or sets the user's password, or <c>null</c> if none is set.
/// </summary>

View File

@@ -0,0 +1,30 @@
using Microsoft.EntityFrameworkCore.Migrations;
#nullable disable
namespace Jellyfin.Server.Implementations.Migrations
{
/// <inheritdoc />
public partial class AddNormalizedUsername : Migration
{
/// <inheritdoc />
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.AddColumn<string>(
name: "NormalizedUsername",
table: "Users",
type: "TEXT",
maxLength: 255,
nullable: false,
defaultValue: "(UPPER([Username]))");
}
/// <inheritdoc />
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropColumn(
name: "NormalizedUsername",
table: "Users");
}
}
}

View File

@@ -15,7 +15,7 @@ namespace Jellyfin.Server.Implementations.Migrations
protected override void BuildModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder.HasAnnotation("ProductVersion", "9.0.9");
modelBuilder.HasAnnotation("ProductVersion", "9.0.11");
modelBuilder.Entity("Jellyfin.Database.Implementations.Entities.AccessSchedule", b =>
{
@@ -1303,6 +1303,11 @@ namespace Jellyfin.Server.Implementations.Migrations
b.Property<bool>("MustUpdatePassword")
.HasColumnType("INTEGER");
b.Property<string>("NormalizedUsername")
.IsRequired()
.HasMaxLength(255)
.HasColumnType("TEXT");
b.Property<string>("Password")
.HasMaxLength(65535)
.HasColumnType("TEXT");