aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library
diff options
context:
space:
mode:
Diffstat (limited to 'Emby.Server.Implementations/Library')
-rw-r--r--Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs115
-rw-r--r--Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs257
-rw-r--r--Emby.Server.Implementations/Library/ExclusiveLiveStream.cs3
-rw-r--r--Emby.Server.Implementations/Library/InvalidAuthProvider.cs11
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs14
-rw-r--r--Emby.Server.Implementations/Library/LiveStreamHelper.cs2
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs6
-rw-r--r--Emby.Server.Implementations/Library/UserDataManager.cs2
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs49
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs9
-rw-r--r--Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs3
-rw-r--r--Emby.Server.Implementations/Library/Validators/PeopleValidator.cs4
-rw-r--r--Emby.Server.Implementations/Library/Validators/StudiosValidator.cs3
13 files changed, 236 insertions, 242 deletions
diff --git a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
index fe09b07ff..b07244fda 100644
--- a/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
+++ b/Emby.Server.Implementations/Library/DefaultAuthenticationProvider.cs
@@ -11,9 +11,9 @@ namespace Emby.Server.Implementations.Library
public class DefaultAuthenticationProvider : IAuthenticationProvider, IRequiresResolvedUser
{
private readonly ICryptoProvider _cryptographyProvider;
- public DefaultAuthenticationProvider(ICryptoProvider crypto)
+ public DefaultAuthenticationProvider(ICryptoProvider cryptographyProvider)
{
- _cryptographyProvider = crypto;
+ _cryptographyProvider = cryptographyProvider;
}
public string Name => "Default";
@@ -28,17 +28,17 @@ namespace Emby.Server.Implementations.Library
throw new NotImplementedException();
}
- // This is the verson that we need to use for local users. Because reasons.
+ // This is the version that we need to use for local users. Because reasons.
public Task<ProviderAuthenticationResult> Authenticate(string username, string password, User resolvedUser)
{
bool success = false;
if (resolvedUser == null)
{
- throw new Exception("Invalid username or password");
+ throw new ArgumentNullException(nameof(resolvedUser));
}
// As long as jellyfin supports passwordless users, we need this little block here to accomodate
- if (IsPasswordEmpty(resolvedUser, password))
+ if (!HasPassword(resolvedUser) && string.IsNullOrEmpty(password))
{
return Task.FromResult(new ProviderAuthenticationResult
{
@@ -50,37 +50,24 @@ namespace Emby.Server.Implementations.Library
byte[] passwordbytes = Encoding.UTF8.GetBytes(password);
PasswordHash readyHash = new PasswordHash(resolvedUser.Password);
- byte[] calculatedHash;
- string calculatedHashString;
- if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id) || _cryptographyProvider.DefaultHashMethod == readyHash.Id)
+ if (_cryptographyProvider.GetSupportedHashMethods().Contains(readyHash.Id)
+ || _cryptographyProvider.DefaultHashMethod == readyHash.Id)
{
- if (string.IsNullOrEmpty(readyHash.Salt))
- {
- calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes);
- calculatedHashString = BitConverter.ToString(calculatedHash).Replace("-", string.Empty);
- }
- else
- {
- calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes, readyHash.SaltBytes);
- calculatedHashString = BitConverter.ToString(calculatedHash).Replace("-", string.Empty);
- }
+ byte[] calculatedHash = _cryptographyProvider.ComputeHash(readyHash.Id, passwordbytes, readyHash.Salt);
- if (calculatedHashString == readyHash.Hash)
+ if (calculatedHash.SequenceEqual(readyHash.Hash))
{
success = true;
- // throw new Exception("Invalid username or password");
}
}
else
{
- throw new Exception(string.Format($"Requested crypto method not available in provider: {readyHash.Id}"));
+ throw new AuthenticationException($"Requested crypto method not available in provider: {readyHash.Id}");
}
- // var success = string.Equals(GetPasswordHash(resolvedUser), GetHashedString(resolvedUser, password), StringComparison.OrdinalIgnoreCase);
-
if (!success)
{
- throw new Exception("Invalid username or password");
+ throw new AuthenticationException("Invalid username or password");
}
return Task.FromResult(new ProviderAuthenticationResult
@@ -98,29 +85,22 @@ namespace Emby.Server.Implementations.Library
return;
}
- if (!user.Password.Contains("$"))
+ if (user.Password.IndexOf('$') == -1)
{
string hash = user.Password;
user.Password = string.Format("$SHA1${0}", hash);
}
- if (user.EasyPassword != null && !user.EasyPassword.Contains("$"))
+ if (user.EasyPassword != null
+ && user.EasyPassword.IndexOf('$') == -1)
{
string hash = user.EasyPassword;
user.EasyPassword = string.Format("$SHA1${0}", hash);
}
}
- public Task<bool> HasPassword(User user)
- {
- var hasConfiguredPassword = !IsPasswordEmpty(user, GetPasswordHash(user));
- return Task.FromResult(hasConfiguredPassword);
- }
-
- private bool IsPasswordEmpty(User user, string password)
- {
- return (string.IsNullOrEmpty(user.Password) && string.IsNullOrEmpty(password));
- }
+ public bool HasPassword(User user)
+ => !string.IsNullOrEmpty(user.Password);
public Task ChangePassword(User user, string newPassword)
{
@@ -129,30 +109,24 @@ namespace Emby.Server.Implementations.Library
if (string.IsNullOrEmpty(user.Password))
{
PasswordHash newPasswordHash = new PasswordHash(_cryptographyProvider);
- newPasswordHash.SaltBytes = _cryptographyProvider.GenerateSalt();
- newPasswordHash.Salt = PasswordHash.ConvertToByteString(newPasswordHash.SaltBytes);
+ newPasswordHash.Salt = _cryptographyProvider.GenerateSalt();
newPasswordHash.Id = _cryptographyProvider.DefaultHashMethod;
- newPasswordHash.Hash = GetHashedStringChangeAuth(newPassword, newPasswordHash);
+ newPasswordHash.Hash = GetHashedChangeAuth(newPassword, newPasswordHash);
user.Password = newPasswordHash.ToString();
return Task.CompletedTask;
}
PasswordHash passwordHash = new PasswordHash(user.Password);
- if (passwordHash.Id == "SHA1" && string.IsNullOrEmpty(passwordHash.Salt))
+ if (passwordHash.Id == "SHA1"
+ && passwordHash.Salt.Length == 0)
{
- passwordHash.SaltBytes = _cryptographyProvider.GenerateSalt();
- passwordHash.Salt = PasswordHash.ConvertToByteString(passwordHash.SaltBytes);
+ passwordHash.Salt = _cryptographyProvider.GenerateSalt();
passwordHash.Id = _cryptographyProvider.DefaultHashMethod;
- passwordHash.Hash = GetHashedStringChangeAuth(newPassword, passwordHash);
+ passwordHash.Hash = GetHashedChangeAuth(newPassword, passwordHash);
}
else if (newPassword != null)
{
- passwordHash.Hash = GetHashedString(user, newPassword);
- }
-
- if (string.IsNullOrWhiteSpace(passwordHash.Hash))
- {
- throw new ArgumentNullException(nameof(passwordHash.Hash));
+ passwordHash.Hash = GetHashed(user, newPassword);
}
user.Password = passwordHash.ToString();
@@ -160,11 +134,6 @@ namespace Emby.Server.Implementations.Library
return Task.CompletedTask;
}
- public string GetPasswordHash(User user)
- {
- return user.Password;
- }
-
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
ConvertPasswordFormat(user);
@@ -190,13 +159,13 @@ namespace Emby.Server.Implementations.Library
return string.IsNullOrEmpty(user.EasyPassword)
? null
- : (new PasswordHash(user.EasyPassword)).Hash;
+ : PasswordHash.ConvertToByteString(new PasswordHash(user.EasyPassword).Hash);
}
- public string GetHashedStringChangeAuth(string newPassword, PasswordHash passwordHash)
+ internal byte[] GetHashedChangeAuth(string newPassword, PasswordHash passwordHash)
{
- passwordHash.HashBytes = Encoding.UTF8.GetBytes(newPassword);
- return PasswordHash.ConvertToByteString(_cryptographyProvider.ComputeHash(passwordHash));
+ passwordHash.Hash = Encoding.UTF8.GetBytes(newPassword);
+ return _cryptographyProvider.ComputeHash(passwordHash);
}
/// <summary>
@@ -215,10 +184,10 @@ namespace Emby.Server.Implementations.Library
passwordHash = new PasswordHash(user.Password);
}
- if (passwordHash.SaltBytes != null)
+ if (passwordHash.Salt != null)
{
// the password is modern format with PBKDF and we should take advantage of that
- passwordHash.HashBytes = Encoding.UTF8.GetBytes(str);
+ passwordHash.Hash = Encoding.UTF8.GetBytes(str);
return PasswordHash.ConvertToByteString(_cryptographyProvider.ComputeHash(passwordHash));
}
else
@@ -227,5 +196,31 @@ namespace Emby.Server.Implementations.Library
return PasswordHash.ConvertToByteString(_cryptographyProvider.ComputeHash(passwordHash.Id, Encoding.UTF8.GetBytes(str)));
}
}
+
+ public byte[] GetHashed(User user, string str)
+ {
+ PasswordHash passwordHash;
+ if (string.IsNullOrEmpty(user.Password))
+ {
+ passwordHash = new PasswordHash(_cryptographyProvider);
+ }
+ else
+ {
+ ConvertPasswordFormat(user);
+ passwordHash = new PasswordHash(user.Password);
+ }
+
+ if (passwordHash.Salt != null)
+ {
+ // the password is modern format with PBKDF and we should take advantage of that
+ passwordHash.Hash = Encoding.UTF8.GetBytes(str);
+ return _cryptographyProvider.ComputeHash(passwordHash);
+ }
+ else
+ {
+ // the password has no salt and should be called with the older method for safety
+ return _cryptographyProvider.ComputeHash(passwordHash.Id, Encoding.UTF8.GetBytes(str));
+ }
+ }
}
}
diff --git a/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
index e218749d9..c7044820c 100644
--- a/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
+++ b/Emby.Server.Implementations/Library/DefaultPasswordResetProvider.cs
@@ -1,132 +1,125 @@
-using System;
-using System.Collections.Generic;
-using System.Globalization;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using MediaBrowser.Common.Extensions;
-using MediaBrowser.Controller.Authentication;
-using MediaBrowser.Controller.Configuration;
-using MediaBrowser.Controller.Library;
-using MediaBrowser.Model.Cryptography;
-using MediaBrowser.Model.Serialization;
-using MediaBrowser.Model.Users;
-
-namespace Emby.Server.Implementations.Library
-{
- public class DefaultPasswordResetProvider : IPasswordResetProvider
- {
- public string Name => "Default Password Reset Provider";
-
- public bool IsEnabled => true;
-
- private readonly string _passwordResetFileBase;
- private readonly string _passwordResetFileBaseDir;
- private readonly string _passwordResetFileBaseName = "passwordreset";
-
- private readonly IJsonSerializer _jsonSerializer;
- private readonly IUserManager _userManager;
- private readonly ICryptoProvider _crypto;
-
- public DefaultPasswordResetProvider(IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IUserManager userManager, ICryptoProvider cryptoProvider)
- {
- _passwordResetFileBaseDir = configurationManager.ApplicationPaths.ProgramDataPath;
- _passwordResetFileBase = Path.Combine(_passwordResetFileBaseDir, _passwordResetFileBaseName);
- _jsonSerializer = jsonSerializer;
- _userManager = userManager;
- _crypto = cryptoProvider;
- }
-
- public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin)
- {
- SerializablePasswordReset spr;
- HashSet<string> usersreset = new HashSet<string>();
- foreach (var resetfile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{_passwordResetFileBaseName}*"))
- {
- using (var str = File.OpenRead(resetfile))
- {
- spr = await _jsonSerializer.DeserializeFromStreamAsync<SerializablePasswordReset>(str).ConfigureAwait(false);
- }
-
- if (spr.ExpirationDate < DateTime.Now)
- {
- File.Delete(resetfile);
- }
- else if (spr.Pin.Replace("-", "").Equals(pin.Replace("-", ""), StringComparison.InvariantCultureIgnoreCase))
- {
- var resetUser = _userManager.GetUserByName(spr.UserName);
- if (resetUser == null)
- {
- throw new Exception($"User with a username of {spr.UserName} not found");
- }
-
- await _userManager.ChangePassword(resetUser, pin).ConfigureAwait(false);
- usersreset.Add(resetUser.Name);
- File.Delete(resetfile);
- }
- }
-
- if (usersreset.Count < 1)
- {
- throw new ResourceNotFoundException($"No Users found with a password reset request matching pin {pin}");
- }
- else
- {
- return new PinRedeemResult
- {
- Success = true,
- UsersReset = usersreset.ToArray()
- };
- }
- }
-
- public async Task<ForgotPasswordResult> StartForgotPasswordProcess(MediaBrowser.Controller.Entities.User user, bool isInNetwork)
- {
- string pin = string.Empty;
- using (var cryptoRandom = System.Security.Cryptography.RandomNumberGenerator.Create())
- {
- byte[] bytes = new byte[4];
- cryptoRandom.GetBytes(bytes);
- pin = BitConverter.ToString(bytes);
- }
-
- DateTime expireTime = DateTime.Now.AddMinutes(30);
- string filePath = _passwordResetFileBase + user.InternalId + ".json";
- SerializablePasswordReset spr = new SerializablePasswordReset
- {
- ExpirationDate = expireTime,
- Pin = pin,
- PinFile = filePath,
- UserName = user.Name
- };
-
- try
- {
- using (FileStream fileStream = File.OpenWrite(filePath))
- {
- _jsonSerializer.SerializeToStream(spr, fileStream);
- await fileStream.FlushAsync().ConfigureAwait(false);
- }
- }
- catch (Exception e)
- {
- throw new Exception($"Error serializing or writing password reset for {user.Name} to location: {filePath}", e);
- }
-
- return new ForgotPasswordResult
- {
- Action = ForgotPasswordAction.PinCode,
- PinExpirationDate = expireTime,
- PinFile = filePath
- };
- }
-
- private class SerializablePasswordReset : PasswordPinCreationResult
- {
- public string Pin { get; set; }
-
- public string UserName { get; set; }
- }
- }
-}
+using System;
+using System.Collections.Generic;
+using System.Globalization;
+using System.IO;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using MediaBrowser.Common.Extensions;
+using MediaBrowser.Controller.Authentication;
+using MediaBrowser.Controller.Configuration;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Model.Cryptography;
+using MediaBrowser.Model.Serialization;
+using MediaBrowser.Model.Users;
+
+namespace Emby.Server.Implementations.Library
+{
+ public class DefaultPasswordResetProvider : IPasswordResetProvider
+ {
+ public string Name => "Default Password Reset Provider";
+
+ public bool IsEnabled => true;
+
+ private readonly string _passwordResetFileBase;
+ private readonly string _passwordResetFileBaseDir;
+ private readonly string _passwordResetFileBaseName = "passwordreset";
+
+ private readonly IJsonSerializer _jsonSerializer;
+ private readonly IUserManager _userManager;
+ private readonly ICryptoProvider _crypto;
+
+ public DefaultPasswordResetProvider(IServerConfigurationManager configurationManager, IJsonSerializer jsonSerializer, IUserManager userManager, ICryptoProvider cryptoProvider)
+ {
+ _passwordResetFileBaseDir = configurationManager.ApplicationPaths.ProgramDataPath;
+ _passwordResetFileBase = Path.Combine(_passwordResetFileBaseDir, _passwordResetFileBaseName);
+ _jsonSerializer = jsonSerializer;
+ _userManager = userManager;
+ _crypto = cryptoProvider;
+ }
+
+ public async Task<PinRedeemResult> RedeemPasswordResetPin(string pin)
+ {
+ SerializablePasswordReset spr;
+ HashSet<string> usersreset = new HashSet<string>();
+ foreach (var resetfile in Directory.EnumerateFiles(_passwordResetFileBaseDir, $"{_passwordResetFileBaseName}*"))
+ {
+ using (var str = File.OpenRead(resetfile))
+ {
+ spr = await _jsonSerializer.DeserializeFromStreamAsync<SerializablePasswordReset>(str).ConfigureAwait(false);
+ }
+
+ if (spr.ExpirationDate < DateTime.Now)
+ {
+ File.Delete(resetfile);
+ }
+ else if (spr.Pin.Replace("-", "").Equals(pin.Replace("-", ""), StringComparison.InvariantCultureIgnoreCase))
+ {
+ var resetUser = _userManager.GetUserByName(spr.UserName);
+ if (resetUser == null)
+ {
+ throw new Exception($"User with a username of {spr.UserName} not found");
+ }
+
+ await _userManager.ChangePassword(resetUser, pin).ConfigureAwait(false);
+ usersreset.Add(resetUser.Name);
+ File.Delete(resetfile);
+ }
+ }
+
+ if (usersreset.Count < 1)
+ {
+ throw new ResourceNotFoundException($"No Users found with a password reset request matching pin {pin}");
+ }
+ else
+ {
+ return new PinRedeemResult
+ {
+ Success = true,
+ UsersReset = usersreset.ToArray()
+ };
+ }
+ }
+
+ public async Task<ForgotPasswordResult> StartForgotPasswordProcess(MediaBrowser.Controller.Entities.User user, bool isInNetwork)
+ {
+ string pin = string.Empty;
+ using (var cryptoRandom = System.Security.Cryptography.RandomNumberGenerator.Create())
+ {
+ byte[] bytes = new byte[4];
+ cryptoRandom.GetBytes(bytes);
+ pin = BitConverter.ToString(bytes);
+ }
+
+ DateTime expireTime = DateTime.Now.AddMinutes(30);
+ string filePath = _passwordResetFileBase + user.InternalId + ".json";
+ SerializablePasswordReset spr = new SerializablePasswordReset
+ {
+ ExpirationDate = expireTime,
+ Pin = pin,
+ PinFile = filePath,
+ UserName = user.Name
+ };
+
+ using (FileStream fileStream = File.OpenWrite(filePath))
+ {
+ _jsonSerializer.SerializeToStream(spr, fileStream);
+ await fileStream.FlushAsync().ConfigureAwait(false);
+ }
+
+ return new ForgotPasswordResult
+ {
+ Action = ForgotPasswordAction.PinCode,
+ PinExpirationDate = expireTime,
+ PinFile = filePath
+ };
+ }
+
+ private class SerializablePasswordReset : PasswordPinCreationResult
+ {
+ public string Pin { get; set; }
+
+ public string UserName { get; set; }
+ }
+ }
+}
diff --git a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
index 45a33a296..a3c879f12 100644
--- a/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
+++ b/Emby.Server.Implementations/Library/ExclusiveLiveStream.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Library;
@@ -26,7 +27,7 @@ namespace Emby.Server.Implementations.Library
EnableStreamSharing = false;
_closeFn = closeFn;
ConsumerCount = 1;
- UniqueId = Guid.NewGuid().ToString("N");
+ UniqueId = Guid.NewGuid().ToString("N", CultureInfo.InvariantCulture);
}
public Task Close()
diff --git a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
index 25d233137..6956369dc 100644
--- a/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
+++ b/Emby.Server.Implementations/Library/InvalidAuthProvider.cs
@@ -1,6 +1,3 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
using System.Threading.Tasks;
using MediaBrowser.Controller.Authentication;
using MediaBrowser.Controller.Entities;
@@ -16,12 +13,12 @@ namespace Emby.Server.Implementations.Library
public Task<ProviderAuthenticationResult> Authenticate(string username, string password)
{
- throw new SecurityException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
+ throw new AuthenticationException("User Account cannot login with this provider. The Normal provider for this user cannot be found");
}
- public Task<bool> HasPassword(User user)
+ public bool HasPassword(User user)
{
- return Task.FromResult(true);
+ return true;
}
public Task ChangePassword(User user, string newPassword)
@@ -31,7 +28,7 @@ namespace Emby.Server.Implementations.Library
public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
- // Nothing here
+ // Nothing here
}
public string GetPasswordHash(User user)
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 4b5063ada..30ff855cc 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -1187,12 +1187,12 @@ namespace Emby.Server.Implementations.Library
if (libraryFolder != null && libraryFolder.HasImage(ImageType.Primary))
{
- info.PrimaryImageItemId = libraryFolder.Id.ToString("N");
+ info.PrimaryImageItemId = libraryFolder.Id.ToString("N", CultureInfo.InvariantCulture);
}
if (libraryFolder != null)
{
- info.ItemId = libraryFolder.Id.ToString("N");
+ info.ItemId = libraryFolder.Id.ToString("N", CultureInfo.InvariantCulture);
info.LibraryOptions = GetLibraryOptions(libraryFolder);
if (refreshQueue != null)
@@ -2135,12 +2135,12 @@ namespace Emby.Server.Implementations.Library
string viewType,
string sortName)
{
- var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N");
- var idValues = "38_namedview_" + name + user.Id.ToString("N") + (parentIdString ?? string.Empty) + (viewType ?? string.Empty);
+ var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N", CultureInfo.InvariantCulture);
+ var idValues = "38_namedview_" + name + user.Id.ToString("N", CultureInfo.InvariantCulture) + (parentIdString ?? string.Empty) + (viewType ?? string.Empty);
var id = GetNewItemId(idValues, typeof(UserView));
- var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
+ var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
var item = GetItemById(id) as UserView;
@@ -2271,7 +2271,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException(nameof(name));
}
- var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N");
+ var parentIdString = parentId.Equals(Guid.Empty) ? null : parentId.ToString("N", CultureInfo.InvariantCulture);
var idValues = "37_namedview_" + name + (parentIdString ?? string.Empty) + (viewType ?? string.Empty);
if (!string.IsNullOrEmpty(uniqueId))
{
@@ -2280,7 +2280,7 @@ namespace Emby.Server.Implementations.Library
var id = GetNewItemId(idValues, typeof(UserView));
- var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N"));
+ var path = Path.Combine(ConfigurationManager.ApplicationPaths.InternalMetadataPath, "views", id.ToString("N", CultureInfo.InvariantCulture));
var item = GetItemById(id) as UserView;
diff --git a/Emby.Server.Implementations/Library/LiveStreamHelper.cs b/Emby.Server.Implementations/Library/LiveStreamHelper.cs
index c3082a78a..33e6f2434 100644
--- a/Emby.Server.Implementations/Library/LiveStreamHelper.cs
+++ b/Emby.Server.Implementations/Library/LiveStreamHelper.cs
@@ -40,7 +40,7 @@ namespace Emby.Server.Implementations.Library
var now = DateTime.UtcNow;
MediaInfo mediaInfo = null;
- var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N") + ".json");
+ var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N", CultureInfo.InvariantCulture) + ".json");
if (!string.IsNullOrEmpty(cacheKey))
{
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 24ab8e761..d83e1fc02 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -269,7 +269,7 @@ namespace Emby.Server.Implementations.Library
private static void SetKeyProperties(IMediaSourceProvider provider, MediaSourceInfo mediaSource)
{
- var prefix = provider.GetType().FullName.GetMD5().ToString("N") + LiveStreamIdDelimeter;
+ var prefix = provider.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture) + LiveStreamIdDelimeter;
if (!string.IsNullOrEmpty(mediaSource.OpenToken) && !mediaSource.OpenToken.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
@@ -626,7 +626,7 @@ namespace Emby.Server.Implementations.Library
var now = DateTime.UtcNow;
MediaInfo mediaInfo = null;
- var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N") + ".json");
+ var cacheFilePath = string.IsNullOrEmpty(cacheKey) ? null : Path.Combine(_appPaths.CachePath, "mediainfo", cacheKey.GetMD5().ToString("N", CultureInfo.InvariantCulture) + ".json");
if (!string.IsNullOrEmpty(cacheKey))
{
@@ -854,7 +854,7 @@ namespace Emby.Server.Implementations.Library
var keys = key.Split(new[] { LiveStreamIdDelimeter }, 2);
- var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N"), keys[0], StringComparison.OrdinalIgnoreCase));
+ var provider = _providers.FirstOrDefault(i => string.Equals(i.GetType().FullName.GetMD5().ToString("N", CultureInfo.InvariantCulture), keys[0], StringComparison.OrdinalIgnoreCase));
var splitIndex = key.IndexOf(LiveStreamIdDelimeter);
var keyId = key.Substring(splitIndex + 1);
diff --git a/Emby.Server.Implementations/Library/UserDataManager.cs b/Emby.Server.Implementations/Library/UserDataManager.cs
index dfa1edaff..36adc0b9c 100644
--- a/Emby.Server.Implementations/Library/UserDataManager.cs
+++ b/Emby.Server.Implementations/Library/UserDataManager.cs
@@ -152,7 +152,7 @@ namespace Emby.Server.Implementations.Library
/// <returns>System.String.</returns>
private static string GetCacheKey(long internalUserId, Guid itemId)
{
- return internalUserId.ToString(CultureInfo.InvariantCulture) + "-" + itemId.ToString("N");
+ return internalUserId.ToString(CultureInfo.InvariantCulture) + "-" + itemId.ToString("N", CultureInfo.InvariantCulture);
}
public UserItemData GetUserData(User user, BaseItem item)
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index 1701ced42..c8c8a108d 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -266,6 +266,7 @@ namespace Emby.Server.Implementations.Library
builder.Append(c);
}
}
+
return builder.ToString();
}
@@ -286,17 +287,17 @@ namespace Emby.Server.Implementations.Library
if (user != null)
{
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, user, remoteEndPoint).ConfigureAwait(false);
- authenticationProvider = authResult.Item1;
- updatedUsername = authResult.Item2;
- success = authResult.Item3;
+ authenticationProvider = authResult.authenticationProvider;
+ updatedUsername = authResult.username;
+ success = authResult.success;
}
else
{
// user is null
var authResult = await AuthenticateLocalUser(username, password, hashedPassword, null, remoteEndPoint).ConfigureAwait(false);
- authenticationProvider = authResult.Item1;
- updatedUsername = authResult.Item2;
- success = authResult.Item3;
+ authenticationProvider = authResult.authenticationProvider;
+ updatedUsername = authResult.username;
+ success = authResult.success;
if (success && authenticationProvider != null && !(authenticationProvider is DefaultAuthenticationProvider))
{
@@ -331,22 +332,25 @@ namespace Emby.Server.Implementations.Library
if (user == null)
{
- throw new SecurityException("Invalid username or password entered.");
+ throw new AuthenticationException("Invalid username or password entered.");
}
if (user.Policy.IsDisabled)
{
- throw new SecurityException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name));
+ throw new AuthenticationException(string.Format(
+ CultureInfo.InvariantCulture,
+ "The {0} account is currently disabled. Please consult with your administrator.",
+ user.Name));
}
if (!user.Policy.EnableRemoteAccess && !_networkManager.IsInLocalNetwork(remoteEndPoint))
{
- throw new SecurityException("Forbidden.");
+ throw new AuthenticationException("Forbidden.");
}
if (!user.IsParentalScheduleAllowed())
{
- throw new SecurityException("User is not allowed access at this time.");
+ throw new AuthenticationException("User is not allowed access at this time.");
}
// Update LastActivityDate and LastLoginDate, then save
@@ -357,6 +361,7 @@ namespace Emby.Server.Implementations.Library
user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
UpdateUser(user);
}
+
UpdateInvalidLoginAttemptCount(user, 0);
}
else
@@ -429,7 +434,7 @@ namespace Emby.Server.Implementations.Library
return providers;
}
- private async Task<Tuple<string, bool>> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
+ private async Task<(string username, bool success)> AuthenticateWithProvider(IAuthenticationProvider provider, string username, string password, User resolvedUser)
{
try
{
@@ -444,23 +449,23 @@ namespace Emby.Server.Implementations.Library
authenticationResult = await provider.Authenticate(username, password).ConfigureAwait(false);
}
- if(authenticationResult.Username != username)
+ if (authenticationResult.Username != username)
{
_logger.LogDebug("Authentication provider provided updated username {1}", authenticationResult.Username);
username = authenticationResult.Username;
}
- return new Tuple<string, bool>(username, true);
+ return (username, true);
}
- catch (Exception ex)
+ catch (AuthenticationException ex)
{
- _logger.LogError(ex, "Error authenticating with provider {provider}", provider.Name);
+ _logger.LogError(ex, "Error authenticating with provider {Provider}", provider.Name);
- return new Tuple<string, bool>(username, false);
+ return (username, false);
}
}
- private async Task<Tuple<IAuthenticationProvider, string, bool>> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
+ private async Task<(IAuthenticationProvider authenticationProvider, string username, bool success)> AuthenticateLocalUser(string username, string password, string hashedPassword, User user, string remoteEndPoint)
{
string updatedUsername = null;
bool success = false;
@@ -475,15 +480,15 @@ namespace Emby.Server.Implementations.Library
if (password == null)
{
// legacy
- success = string.Equals(GetAuthenticationProvider(user).GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
+ success = string.Equals(user.Password, hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
}
else
{
foreach (var provider in GetAuthenticationProviders(user))
{
var providerAuthResult = await AuthenticateWithProvider(provider, username, password, user).ConfigureAwait(false);
- updatedUsername = providerAuthResult.Item1;
- success = providerAuthResult.Item2;
+ updatedUsername = providerAuthResult.username;
+ success = providerAuthResult.success;
if (success)
{
@@ -510,7 +515,7 @@ namespace Emby.Server.Implementations.Library
}
}
- return new Tuple<IAuthenticationProvider, string, bool>(authenticationProvider, username, success);
+ return (authenticationProvider, username, success);
}
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
@@ -593,7 +598,7 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentNullException(nameof(user));
}
- bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user).Result;
+ bool hasConfiguredPassword = GetAuthenticationProvider(user).HasPassword(user);
bool hasConfiguredEasyPassword = !string.IsNullOrEmpty(GetAuthenticationProvider(user).GetEasyPasswordHash(user));
bool hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index e9ce682ee..71f16ac3e 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
+using System.Globalization;
using System.Linq;
using System.Threading;
using MediaBrowser.Controller.Channels;
@@ -117,7 +118,7 @@ namespace Emby.Server.Implementations.Library
if (!query.IncludeHidden)
{
- list = list.Where(i => !user.Configuration.MyMediaExcludes.Contains(i.Id.ToString("N"))).ToList();
+ list = list.Where(i => !user.Configuration.MyMediaExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture))).ToList();
}
var sorted = _libraryManager.Sort(list, user, new[] { ItemSortBy.SortName }, SortOrder.Ascending).ToList();
@@ -127,7 +128,7 @@ namespace Emby.Server.Implementations.Library
return list
.OrderBy(i =>
{
- var index = orders.IndexOf(i.Id.ToString("N"));
+ var index = orders.IndexOf(i.Id.ToString("N", CultureInfo.InvariantCulture));
if (index == -1)
{
@@ -136,7 +137,7 @@ namespace Emby.Server.Implementations.Library
{
if (!view.DisplayParentId.Equals(Guid.Empty))
{
- index = orders.IndexOf(view.DisplayParentId.ToString("N"));
+ index = orders.IndexOf(view.DisplayParentId.ToString("N", CultureInfo.InvariantCulture));
}
}
}
@@ -269,7 +270,7 @@ namespace Emby.Server.Implementations.Library
{
parents = _libraryManager.GetUserRootFolder().GetChildren(user, true)
.Where(i => i is Folder)
- .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N")))
+ .Where(i => !user.Configuration.LatestItemsExcludes.Contains(i.Id.ToString("N", CultureInfo.InvariantCulture)))
.ToList();
}
diff --git a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
index 294348660..b584cc649 100644
--- a/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/ArtistsValidator.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
@@ -91,7 +92,7 @@ namespace Emby.Server.Implementations.Library.Validators
continue;
}
- _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name);
+ _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name);
_libraryManager.DeleteItem(item, new DeleteOptions
{
diff --git a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
index 7899cf01b..d00c6cde1 100644
--- a/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/PeopleValidator.cs
@@ -1,7 +1,7 @@
using System;
+using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
-using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Providers;
@@ -96,7 +96,7 @@ namespace Emby.Server.Implementations.Library.Validators
foreach (var item in deadEntities)
{
- _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name);
+ _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name);
_libraryManager.DeleteItem(item, new DeleteOptions
{
diff --git a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
index da4645a11..93ded9e7b 100644
--- a/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
+++ b/Emby.Server.Implementations/Library/Validators/StudiosValidator.cs
@@ -1,4 +1,5 @@
using System;
+using System.Globalization;
using System.Threading;
using System.Threading.Tasks;
using MediaBrowser.Controller.Entities;
@@ -76,7 +77,7 @@ namespace Emby.Server.Implementations.Library.Validators
foreach (var item in deadEntities)
{
- _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N"), item.Name, item.GetType().Name);
+ _logger.LogInformation("Deleting dead {2} {0} {1}.", item.Id.ToString("N", CultureInfo.InvariantCulture), item.Name, item.GetType().Name);
_libraryManager.DeleteItem(item, new DeleteOptions
{