Validate the new username when renaming

This commit is contained in:
cvium 2021-02-17 11:30:14 +01:00
parent b4c2086138
commit 442e770688
4 changed files with 65 additions and 9 deletions

View File

@ -0,0 +1,23 @@
using System.Reflection;
using System.Resources;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Jellyfin.Server.Implementations")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("Jellyfin Project")]
[assembly: AssemblyProduct("Jellyfin Server")]
[assembly: AssemblyCopyright("Copyright © 2019 Jellyfin Contributors. Code released under the GNU General Public License")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: NeutralResourcesLanguage("en")]
[assembly: InternalsVisibleTo("Jellyfin.Server.Implementations.Tests")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]

View File

@ -137,10 +137,7 @@ namespace Jellyfin.Server.Implementations.Users
throw new ArgumentNullException(nameof(user)); throw new ArgumentNullException(nameof(user));
} }
if (string.IsNullOrWhiteSpace(newName)) ThrowIfInvalidUsername(newName);
{
throw new ArgumentException("Invalid username", nameof(newName));
}
if (user.Username.Equals(newName, StringComparison.Ordinal)) if (user.Username.Equals(newName, StringComparison.Ordinal))
{ {
@ -201,10 +198,7 @@ namespace Jellyfin.Server.Implementations.Users
/// <inheritdoc/> /// <inheritdoc/>
public async Task<User> CreateUserAsync(string name) public async Task<User> CreateUserAsync(string name)
{ {
if (!IsValidUsername(name)) ThrowIfInvalidUsername(name);
{
throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)");
}
if (Users.Any(u => u.Username.Equals(name, StringComparison.OrdinalIgnoreCase))) if (Users.Any(u => u.Username.Equals(name, StringComparison.OrdinalIgnoreCase)))
{ {
@ -733,12 +727,22 @@ namespace Jellyfin.Server.Implementations.Users
_users[user.Id] = user; _users[user.Id] = user;
} }
internal static void ThrowIfInvalidUsername(string name)
{
if (!string.IsNullOrWhiteSpace(name) && IsValidUsername(name))
{
return;
}
throw new ArgumentException("Usernames can contain unicode symbols, numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)", nameof(name));
}
private static bool IsValidUsername(string name) private static bool IsValidUsername(string name)
{ {
// This is some regex that matches only on unicode "word" characters, as well as -, _ and @ // This is some regex that matches only on unicode "word" characters, as well as -, _ and @
// In theory this will cut out most if not all 'control' characters which should help minimize any weirdness // In theory this will cut out most if not all 'control' characters which should help minimize any weirdness
// Usernames can contain letters (a-z + whatever else unicode is cool with), numbers (0-9), at-signs (@), dashes (-), underscores (_), apostrophes ('), periods (.) and spaces ( ) // Usernames can contain letters (a-z + whatever else unicode is cool with), numbers (0-9), at-signs (@), dashes (-), underscores (_), apostrophes ('), periods (.) and spaces ( )
return Regex.IsMatch(name, @"^[\w\ \-'._@]*$"); return Regex.IsMatch(name, @"^[\w\ \-'._@]+$");
} }
private IAuthenticationProvider GetAuthenticationProvider(User user) private IAuthenticationProvider GetAuthenticationProvider(User user)

View File

@ -39,6 +39,7 @@
<ItemGroup> <ItemGroup>
<ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" /> <ProjectReference Include="..\..\Emby.Server.Implementations\Emby.Server.Implementations.csproj" />
<ProjectReference Include="..\..\Jellyfin.Server.Implementations\Jellyfin.Server.Implementations.csproj" />
</ItemGroup> </ItemGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' "> <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

View File

@ -0,0 +1,28 @@
using System;
using Jellyfin.Server.Implementations.Users;
using Xunit;
namespace Jellyfin.Server.Implementations.Tests.Users
{
public class UserManagerTests
{
[Theory]
[InlineData("this_is_valid", true)]
[InlineData("this is also valid", true)]
[InlineData(" ", false)]
[InlineData("", false)]
[InlineData("0@_-' .", true)]
public void ThrowIfInvalidUsername_WhenInvalidUsername_ThrowsArgumentException(string username, bool isValid)
{
var ex = Record.Exception(() => UserManager.ThrowIfInvalidUsername(username));
var argumentExceptionNotThrown = ex is not ArgumentException;
if (ex != null)
{
Assert.Equal(typeof(ArgumentException), ex.GetType());
}
Assert.Equal(isValid, argumentExceptionNotThrown);
}
}
}