aboutsummaryrefslogtreecommitdiff
path: root/Emby.Server.Implementations/Library
diff options
context:
space:
mode:
authorLuke <luke.pulverenti@gmail.com>2017-09-20 13:22:39 -0400
committerGitHub <noreply@github.com>2017-09-20 13:22:39 -0400
commiteb2a1330045d802bfe0366df7105c220a36f111f (patch)
tree2c1638c424ee9c0837c5de6d6e08a2398da69cdb /Emby.Server.Implementations/Library
parentec426d5c92875639ceac64477ce10fab3e639335 (diff)
parenta015e1208885bc6a8788db683c4fe47e93dc26b7 (diff)
Merge pull request #2897 from MediaBrowser/beta
Beta
Diffstat (limited to 'Emby.Server.Implementations/Library')
-rw-r--r--Emby.Server.Implementations/Library/LibraryManager.cs122
-rw-r--r--Emby.Server.Implementations/Library/MediaSourceManager.cs1
-rw-r--r--Emby.Server.Implementations/Library/MusicManager.cs3
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs6
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs4
-rw-r--r--Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs8
-rw-r--r--Emby.Server.Implementations/Library/SearchEngine.cs3
-rw-r--r--Emby.Server.Implementations/Library/UserManager.cs140
-rw-r--r--Emby.Server.Implementations/Library/UserViewManager.cs3
11 files changed, 179 insertions, 121 deletions
diff --git a/Emby.Server.Implementations/Library/LibraryManager.cs b/Emby.Server.Implementations/Library/LibraryManager.cs
index 57e42985d..eab52e5e8 100644
--- a/Emby.Server.Implementations/Library/LibraryManager.cs
+++ b/Emby.Server.Implementations/Library/LibraryManager.cs
@@ -14,10 +14,10 @@ using MediaBrowser.Model.Configuration;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
using MediaBrowser.Model.Querying;
-using MediaBrowser.Naming.Audio;
-using MediaBrowser.Naming.Common;
-using MediaBrowser.Naming.TV;
-using MediaBrowser.Naming.Video;
+using Emby.Naming.Audio;
+using Emby.Naming.Common;
+using Emby.Naming.TV;
+using Emby.Naming.Video;
using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
@@ -38,7 +38,7 @@ using MediaBrowser.Model.Extensions;
using MediaBrowser.Model.Library;
using MediaBrowser.Model.Net;
using SortOrder = MediaBrowser.Model.Entities.SortOrder;
-using VideoResolver = MediaBrowser.Naming.Video.VideoResolver;
+using VideoResolver = Emby.Naming.Video.VideoResolver;
using MediaBrowser.Common.Configuration;
using MediaBrowser.Controller.Dto;
@@ -386,7 +386,7 @@ namespace Emby.Server.Implementations.Library
item.Id);
}
- var parent = item.Parent;
+ var parent = item.IsOwnedItem ? item.GetOwner() : item.GetParent();
var locationType = item.LocationType;
@@ -453,12 +453,28 @@ namespace Emby.Server.Implementations.Library
if (parent != null)
{
- await parent.ValidateChildren(new SimpleProgress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
+ var parentFolder = parent as Folder;
+ if (parentFolder != null)
+ {
+ await parentFolder.ValidateChildren(new SimpleProgress<double>(), CancellationToken.None, new MetadataRefreshOptions(_fileSystem), false).ConfigureAwait(false);
+ }
+ else
+ {
+ await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
+ }
}
}
else if (parent != null)
{
- parent.RemoveChild(item);
+ var parentFolder = parent as Folder;
+ if (parentFolder != null)
+ {
+ parentFolder.RemoveChild(item);
+ }
+ else
+ {
+ await parent.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), CancellationToken.None).ConfigureAwait(false);
+ }
}
ItemRepository.DeleteItem(item.Id, CancellationToken.None);
@@ -620,37 +636,12 @@ namespace Emby.Server.Implementations.Library
return ResolveItem(args, resolvers);
}
- private readonly List<string> _ignoredPaths = new List<string>();
-
- public void RegisterIgnoredPath(string path)
- {
- lock (_ignoredPaths)
- {
- _ignoredPaths.Add(path);
- }
- }
- public void UnRegisterIgnoredPath(string path)
- {
- lock (_ignoredPaths)
- {
- _ignoredPaths.Remove(path);
- }
- }
-
public bool IgnoreFile(FileSystemMetadata file, BaseItem parent)
{
if (EntityResolutionIgnoreRules.Any(r => r.ShouldIgnore(file, parent)))
{
return true;
}
-
- //lock (_ignoredPaths)
- {
- if (_ignoredPaths.Contains(file.FullName, StringComparer.OrdinalIgnoreCase))
- {
- return true;
- }
- }
return false;
}
@@ -846,8 +837,7 @@ namespace Emby.Server.Implementations.Library
{
Path = path,
IsFolder = isFolder,
- SortBy = new[] { ItemSortBy.DateCreated },
- SortOrder = SortOrder.Descending,
+ OrderBy = new[] { ItemSortBy.DateCreated }.Select(i => new Tuple<string, SortOrder>(i, SortOrder.Descending)).ToArray(),
Limit = 1,
DtoOptions = new DtoOptions(true)
};
@@ -1777,6 +1767,37 @@ namespace Emby.Server.Implementations.Library
return orderedItems ?? items;
}
+ public IEnumerable<BaseItem> Sort(IEnumerable<BaseItem> items, User user, IEnumerable<Tuple<string, SortOrder>> orderByList)
+ {
+ var isFirst = true;
+
+ IOrderedEnumerable<BaseItem> orderedItems = null;
+
+ foreach (var orderBy in orderByList)
+ {
+ var comparer = GetComparer(orderBy.Item1, user);
+ if (comparer == null)
+ {
+ continue;
+ }
+
+ var sortOrder = orderBy.Item2;
+
+ if (isFirst)
+ {
+ orderedItems = sortOrder == SortOrder.Descending ? items.OrderByDescending(i => i, comparer) : items.OrderBy(i => i, comparer);
+ }
+ else
+ {
+ orderedItems = sortOrder == SortOrder.Descending ? orderedItems.ThenByDescending(i => i, comparer) : orderedItems.ThenBy(i => i, comparer);
+ }
+
+ isFirst = false;
+ }
+
+ return orderedItems ?? items;
+ }
+
/// <summary>
/// Gets the comparer.
/// </summary>
@@ -2341,7 +2362,7 @@ namespace Emby.Server.Implementations.Library
public bool IsVideoFile(string path, LibraryOptions libraryOptions)
{
- var resolver = new VideoResolver(GetNamingOptions(), new NullLogger());
+ var resolver = new VideoResolver(GetNamingOptions());
return resolver.IsVideoFile(path);
}
@@ -2368,8 +2389,7 @@ namespace Emby.Server.Implementations.Library
public bool FillMissingEpisodeNumbersFromPath(Episode episode)
{
- var resolver = new EpisodeResolver(GetNamingOptions(),
- new NullLogger());
+ var resolver = new EpisodeResolver(GetNamingOptions());
var isFolder = episode.VideoType == VideoType.BluRay || episode.VideoType == VideoType.Dvd;
@@ -2377,11 +2397,11 @@ namespace Emby.Server.Implementations.Library
var episodeInfo = locationType == LocationType.FileSystem || locationType == LocationType.Offline ?
resolver.Resolve(episode.Path, isFolder) :
- new MediaBrowser.Naming.TV.EpisodeInfo();
+ new Emby.Naming.TV.EpisodeInfo();
if (episodeInfo == null)
{
- episodeInfo = new MediaBrowser.Naming.TV.EpisodeInfo();
+ episodeInfo = new Emby.Naming.TV.EpisodeInfo();
}
var changed = false;
@@ -2552,7 +2572,7 @@ namespace Emby.Server.Implementations.Library
public ItemLookupInfo ParseName(string name)
{
- var resolver = new VideoResolver(GetNamingOptions(), new NullLogger());
+ var resolver = new VideoResolver(GetNamingOptions());
var result = resolver.CleanDateTime(name);
var cleanName = resolver.CleanString(result.Name);
@@ -2573,7 +2593,7 @@ namespace Emby.Server.Implementations.Library
.SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false))
.ToList();
- var videoListResolver = new VideoListResolver(namingOptions, new NullLogger());
+ var videoListResolver = new VideoListResolver(namingOptions);
var videos = videoListResolver.Resolve(fileSystemChildren);
@@ -2600,8 +2620,11 @@ namespace Emby.Server.Implementations.Library
{
video = dbItem;
}
-
- video.ExtraType = ExtraType.Trailer;
+ else
+ {
+ // item is new
+ video.ExtraType = ExtraType.Trailer;
+ }
video.TrailerTypes = new List<TrailerType> { TrailerType.LocalTrailer };
return video;
@@ -2621,7 +2644,7 @@ namespace Emby.Server.Implementations.Library
.SelectMany(i => _fileSystem.GetFiles(i.FullName, _videoFileExtensions, false, false))
.ToList();
- var videoListResolver = new VideoListResolver(namingOptions, new NullLogger());
+ var videoListResolver = new VideoListResolver(namingOptions);
var videos = videoListResolver.Resolve(fileSystemChildren);
@@ -2747,7 +2770,7 @@ namespace Emby.Server.Implementations.Library
private void SetExtraTypeFromFilename(Video item)
{
- var resolver = new ExtraResolver(GetNamingOptions(), new NullLogger(), new RegexProvider());
+ var resolver = new ExtraResolver(GetNamingOptions(), new RegexProvider());
var result = resolver.GetExtraInfo(item.Path);
@@ -2842,13 +2865,6 @@ namespace Emby.Server.Implementations.Library
await _providerManagerFactory().SaveImage(item, url, image.Type, imageIndex, CancellationToken.None).ConfigureAwait(false);
- var newImage = item.GetImageInfo(image.Type, imageIndex);
-
- if (newImage != null)
- {
- newImage.IsPlaceholder = image.IsPlaceholder;
- }
-
await item.UpdateToRepository(ItemUpdateType.ImageUpdate, CancellationToken.None).ConfigureAwait(false);
return item.GetImageInfo(image.Type, imageIndex);
diff --git a/Emby.Server.Implementations/Library/MediaSourceManager.cs b/Emby.Server.Implementations/Library/MediaSourceManager.cs
index 6e0489d88..d60a04353 100644
--- a/Emby.Server.Implementations/Library/MediaSourceManager.cs
+++ b/Emby.Server.Implementations/Library/MediaSourceManager.cs
@@ -524,6 +524,7 @@ namespace Emby.Server.Implementations.Library
public void Dispose()
{
Dispose(true);
+ GC.SuppressFinalize(this);
}
private readonly object _disposeLock = new object();
diff --git a/Emby.Server.Implementations/Library/MusicManager.cs b/Emby.Server.Implementations/Library/MusicManager.cs
index 7f77170ad..1cbf4235a 100644
--- a/Emby.Server.Implementations/Library/MusicManager.cs
+++ b/Emby.Server.Implementations/Library/MusicManager.cs
@@ -6,6 +6,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using MediaBrowser.Controller.Dto;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Querying;
namespace Emby.Server.Implementations.Library
@@ -88,7 +89,7 @@ namespace Emby.Server.Implementations.Library
Limit = 200,
- SortBy = new[] { ItemSortBy.Random },
+ OrderBy = new [] { new Tuple<string, SortOrder>(ItemSortBy.Random, SortOrder.Ascending) },
DtoOptions = dtoOptions
diff --git a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index 70fe8d9ef..b8ec41805 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -4,7 +4,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Naming.Audio;
+using Emby.Naming.Audio;
using System;
using System.Collections.Generic;
using System.IO;
@@ -165,7 +165,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Audio
{
var namingOptions = ((LibraryManager)_libraryManager).GetNamingOptions();
- var parser = new AlbumParser(namingOptions, new NullLogger());
+ var parser = new AlbumParser(namingOptions);
var result = parser.ParseMultiPart(path);
return result.IsMultiPart;
diff --git a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
index fa4f026f4..e3200a099 100644
--- a/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/BaseVideoResolver.cs
@@ -1,7 +1,7 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Entities;
-using MediaBrowser.Naming.Video;
+using Emby.Naming.Video;
using System;
using System.IO;
using System.Linq;
@@ -50,7 +50,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
// If the path is a file check for a matching extensions
- var parser = new MediaBrowser.Naming.Video.VideoResolver(namingOptions, new NullLogger());
+ var parser = new Emby.Naming.Video.VideoResolver(namingOptions);
if (args.IsDirectory)
{
@@ -258,7 +258,7 @@ namespace Emby.Server.Implementations.Library.Resolvers
{
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new Format3DParser(namingOptions, new NullLogger());
+ var resolver = new Format3DParser(namingOptions);
var result = resolver.Parse(video.Path);
Set3DFormat(video, result.Is3D, result.Format3D);
diff --git a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 1e5c0beed..cd1264754 100644
--- a/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -6,7 +6,7 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
-using MediaBrowser.Naming.Video;
+using Emby.Naming.Video;
using System;
using System.Collections.Generic;
using System.IO;
@@ -138,7 +138,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new VideoListResolver(namingOptions, new NullLogger());
+ var resolver = new VideoListResolver(namingOptions);
var resolverResult = resolver.Resolve(files, suppportMultiEditions).ToList();
var result = new MultiItemResolverResult
@@ -490,7 +490,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.Movies
}
var namingOptions = ((LibraryManager)LibraryManager).GetNamingOptions();
- var resolver = new StackResolver(namingOptions, new NullLogger());
+ var resolver = new StackResolver(namingOptions);
var result = resolver.ResolveDirectories(folderPaths);
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
index 830bd9d85..bbe1bba85 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeasonResolver.cs
@@ -3,8 +3,8 @@ using MediaBrowser.Controller.Configuration;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
using MediaBrowser.Model.Globalization;
-using MediaBrowser.Naming.Common;
-using MediaBrowser.Naming.TV;
+using Emby.Naming.Common;
+using Emby.Naming.TV;
namespace Emby.Server.Implementations.Library.Resolvers.TV
{
diff --git a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index e1c18c913..a693e3b26 100644
--- a/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/Emby.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -4,8 +4,8 @@ using MediaBrowser.Controller.Providers;
using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Logging;
-using MediaBrowser.Naming.Common;
-using MediaBrowser.Naming.TV;
+using Emby.Naming.Common;
+using Emby.Naming.TV;
using System;
using System.Collections.Generic;
using System.IO;
@@ -163,7 +163,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
var allowOptimisticEpisodeDetection = isTvContentType;
var namingOptions = ((LibraryManager)libraryManager).GetNamingOptions(allowOptimisticEpisodeDetection);
- var episodeResolver = new MediaBrowser.Naming.TV.EpisodeResolver(namingOptions, new NullLogger());
+ var episodeResolver = new Emby.Naming.TV.EpisodeResolver(namingOptions);
var episodeInfo = episodeResolver.Resolve(fullName, false, false);
if (episodeInfo != null && episodeInfo.EpisodeNumber.HasValue)
{
@@ -173,7 +173,7 @@ namespace Emby.Server.Implementations.Library.Resolvers.TV
}
}
- logger.Debug("{0} is not a series folder.", path);
+ //logger.Debug("{0} is not a series folder.", path);
return false;
}
diff --git a/Emby.Server.Implementations/Library/SearchEngine.cs b/Emby.Server.Implementations/Library/SearchEngine.cs
index d4c4f2794..b1ed034ca 100644
--- a/Emby.Server.Implementations/Library/SearchEngine.cs
+++ b/Emby.Server.Implementations/Library/SearchEngine.cs
@@ -10,6 +10,7 @@ using System.Linq;
using System.Threading.Tasks;
using MediaBrowser.Controller.Dto;
using MediaBrowser.Controller.Extensions;
+using MediaBrowser.Model.Entities;
using MediaBrowser.Model.Extensions;
namespace Emby.Server.Implementations.Library
@@ -169,7 +170,7 @@ namespace Emby.Server.Implementations.Library
Limit = query.Limit,
IncludeItemsByName = string.IsNullOrWhiteSpace(query.ParentId),
ParentId = string.IsNullOrWhiteSpace(query.ParentId) ? (Guid?)null : new Guid(query.ParentId),
- SortBy = new[] { ItemSortBy.SortName },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.SortName, SortOrder.Ascending) },
Recursive = true,
IsKids = query.IsKids,
diff --git a/Emby.Server.Implementations/Library/UserManager.cs b/Emby.Server.Implementations/Library/UserManager.cs
index e5fe2969f..0f48ff46b 100644
--- a/Emby.Server.Implementations/Library/UserManager.cs
+++ b/Emby.Server.Implementations/Library/UserManager.cs
@@ -180,11 +180,6 @@ namespace Emby.Server.Implementations.Library
}
}
- public Task<User> AuthenticateUser(string username, string passwordSha1, string remoteEndPoint)
- {
- return AuthenticateUser(username, passwordSha1, null, remoteEndPoint);
- }
-
public bool IsValidUsername(string username)
{
// Usernames can contain letters (a-z), numbers (0-9), dashes (-), underscores (_), apostrophes ('), and periods (.)
@@ -223,7 +218,7 @@ namespace Emby.Server.Implementations.Library
return builder.ToString();
}
- public async Task<User> AuthenticateUser(string username, string passwordSha1, string passwordMd5, string remoteEndPoint)
+ public async Task<User> AuthenticateUser(string username, string password, string hashedPassword, string passwordMd5, string remoteEndPoint)
{
if (string.IsNullOrWhiteSpace(username))
{
@@ -237,23 +232,23 @@ namespace Emby.Server.Implementations.Library
if (user != null)
{
+ if (password != null)
+ {
+ hashedPassword = GetHashedString(user, password);
+ }
+
// Authenticate using local credentials if not a guest
if (!user.ConnectLinkType.HasValue || user.ConnectLinkType.Value != UserLinkType.Guest)
{
- success = string.Equals(GetPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
-
- if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) && user.Configuration.EnableLocalPassword)
- {
- success = string.Equals(GetLocalPasswordHash(user), passwordSha1.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
- }
+ success = AuthenticateLocalUser(user, password, hashedPassword, remoteEndPoint);
}
// Maybe user accidently entered connect credentials. let's be flexible
- if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(passwordMd5) && !string.IsNullOrWhiteSpace(user.ConnectUserName))
+ if (!success && user.ConnectLinkType.HasValue && !string.IsNullOrWhiteSpace(user.ConnectUserName))
{
try
{
- await _connectFactory().Authenticate(user.ConnectUserName, passwordMd5).ConfigureAwait(false);
+ await _connectFactory().Authenticate(user.ConnectUserName, password, passwordMd5).ConfigureAwait(false);
success = true;
}
catch
@@ -268,7 +263,7 @@ namespace Emby.Server.Implementations.Library
{
try
{
- var connectAuthResult = await _connectFactory().Authenticate(username, passwordMd5).ConfigureAwait(false);
+ var connectAuthResult = await _connectFactory().Authenticate(username, password, passwordMd5).ConfigureAwait(false);
user = Users.FirstOrDefault(i => string.Equals(i.ConnectUserId, connectAuthResult.User.Id, StringComparison.OrdinalIgnoreCase));
@@ -307,6 +302,36 @@ namespace Emby.Server.Implementations.Library
return success ? user : null;
}
+ private bool AuthenticateLocalUser(User user, string password, string hashedPassword, string remoteEndPoint)
+ {
+ bool success;
+
+ if (password == null)
+ {
+ // legacy
+ success = string.Equals(GetPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
+ }
+ else
+ {
+ success = string.Equals(GetPasswordHash(user), GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
+ }
+
+ if (!success && _networkManager.IsInLocalNetwork(remoteEndPoint) && user.Configuration.EnableLocalPassword)
+ {
+ if (password == null)
+ {
+ // legacy
+ success = string.Equals(GetLocalPasswordHash(user), hashedPassword.Replace("-", string.Empty), StringComparison.OrdinalIgnoreCase);
+ }
+ else
+ {
+ success = string.Equals(GetLocalPasswordHash(user), GetHashedString(user, password), StringComparison.OrdinalIgnoreCase);
+ }
+ }
+
+ return success;
+ }
+
private void UpdateInvalidLoginAttemptCount(User user, int newValue)
{
if (user.Policy.InvalidLoginAttemptCount != newValue || newValue > 0)
@@ -342,29 +367,39 @@ namespace Emby.Server.Implementations.Library
private string GetPasswordHash(User user)
{
return string.IsNullOrEmpty(user.Password)
- ? GetSha1String(string.Empty)
+ ? GetEmptyHashedString(user)
: user.Password;
}
private string GetLocalPasswordHash(User user)
{
return string.IsNullOrEmpty(user.EasyPassword)
- ? GetSha1String(string.Empty)
+ ? GetEmptyHashedString(user)
: user.EasyPassword;
}
- private bool IsPasswordEmpty(string passwordHash)
+ private bool IsPasswordEmpty(User user, string passwordHash)
+ {
+ return string.Equals(passwordHash, GetEmptyHashedString(user), StringComparison.OrdinalIgnoreCase);
+ }
+
+ private string GetEmptyHashedString(User user)
{
- return string.Equals(passwordHash, GetSha1String(string.Empty), StringComparison.OrdinalIgnoreCase);
+ return GetHashedString(user, string.Empty);
}
/// <summary>
- /// Gets the sha1 string.
+ /// Gets the hashed string.
/// </summary>
- /// <param name="str">The STR.</param>
- /// <returns>System.String.</returns>
- private string GetSha1String(string str)
+ private string GetHashedString(User user, string str)
{
+ var salt = user.Salt;
+ if (salt != null)
+ {
+ // return BCrypt.HashPassword(str, salt);
+ }
+
+ // legacy
return BitConverter.ToString(_cryptographyProvider.ComputeSHA1(Encoding.UTF8.GetBytes(str))).Replace("-", string.Empty);
}
@@ -407,8 +442,8 @@ namespace Emby.Server.Implementations.Library
var passwordHash = GetPasswordHash(user);
- var hasConfiguredPassword = !IsPasswordEmpty(passwordHash);
- var hasConfiguredEasyPassword = !IsPasswordEmpty(GetLocalPasswordHash(user));
+ var hasConfiguredPassword = !IsPasswordEmpty(user, passwordHash);
+ var hasConfiguredEasyPassword = !IsPasswordEmpty(user, GetLocalPasswordHash(user));
var hasPassword = user.Configuration.EnableLocalPassword && !string.IsNullOrEmpty(remoteEndPoint) && _networkManager.IsInLocalNetwork(remoteEndPoint) ?
hasConfiguredEasyPassword :
@@ -460,14 +495,6 @@ namespace Emby.Server.Implementations.Library
{
var dto = GetUserDto(user);
- var offlinePasswordHash = GetLocalPasswordHash(user);
- dto.HasPassword = !IsPasswordEmpty(offlinePasswordHash);
-
- dto.OfflinePasswordSalt = Guid.NewGuid().ToString("N");
-
- // Hash the pin with the device Id to create a unique result for this device
- dto.OfflinePassword = GetSha1String((offlinePasswordHash + dto.OfflinePasswordSalt).ToLower());
-
dto.ServerName = _appHost.FriendlyName;
return dto;
@@ -491,11 +518,12 @@ namespace Emby.Server.Implementations.Library
/// </summary>
/// <param name="cancellationToken">The cancellation token.</param>
/// <returns>Task.</returns>
- public Task RefreshUsersMetadata(CancellationToken cancellationToken)
+ public async Task RefreshUsersMetadata(CancellationToken cancellationToken)
{
- var tasks = Users.Select(user => user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken)).ToList();
-
- return Task.WhenAll(tasks);
+ foreach (var user in Users)
+ {
+ await user.RefreshMetadata(new MetadataRefreshOptions(_fileSystem), cancellationToken).ConfigureAwait(false);
+ }
}
/// <summary>
@@ -666,8 +694,7 @@ namespace Emby.Server.Implementations.Library
DeleteUserPolicy(user);
- // Force this to be lazy loaded again
- Users = LoadUsers();
+ Users = allUsers.Where(i => i.Id != user.Id).ToList();
OnUserDeleted(user);
}
@@ -683,23 +710,29 @@ namespace Emby.Server.Implementations.Library
/// <returns>Task.</returns>
public void ResetPassword(User user)
{
- ChangePassword(user, GetSha1String(string.Empty));
+ ChangePassword(user, string.Empty, null);
}
public void ResetEasyPassword(User user)
{
- ChangeEasyPassword(user, GetSha1String(string.Empty));
+ ChangeEasyPassword(user, string.Empty, null);
}
- public void ChangePassword(User user, string newPasswordSha1)
+ public void ChangePassword(User user, string newPassword, string newPasswordHash)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
- if (string.IsNullOrWhiteSpace(newPasswordSha1))
+
+ if (newPassword != null)
{
- throw new ArgumentNullException("newPasswordSha1");
+ newPasswordHash = GetHashedString(user, newPassword);
+ }
+
+ if (string.IsNullOrWhiteSpace(newPasswordHash))
+ {
+ throw new ArgumentNullException("newPasswordHash");
}
if (user.ConnectLinkType.HasValue && user.ConnectLinkType.Value == UserLinkType.Guest)
@@ -707,25 +740,31 @@ namespace Emby.Server.Implementations.Library
throw new ArgumentException("Passwords for guests cannot be changed.");
}
- user.Password = newPasswordSha1;
+ user.Password = newPasswordHash;
UpdateUser(user);
EventHelper.FireEventIfNotNull(UserPasswordChanged, this, new GenericEventArgs<User>(user), _logger);
}
- public void ChangeEasyPassword(User user, string newPasswordSha1)
+ public void ChangeEasyPassword(User user, string newPassword, string newPasswordHash)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
- if (string.IsNullOrWhiteSpace(newPasswordSha1))
+
+ if (newPassword != null)
+ {
+ newPasswordHash = GetHashedString(user, newPassword);
+ }
+
+ if (string.IsNullOrWhiteSpace(newPasswordHash))
{
- throw new ArgumentNullException("newPasswordSha1");
+ throw new ArgumentNullException("newPasswordHash");
}
- user.EasyPassword = newPasswordSha1;
+ user.EasyPassword = newPasswordHash;
UpdateUser(user);
@@ -745,7 +784,8 @@ namespace Emby.Server.Implementations.Library
Id = Guid.NewGuid(),
DateCreated = DateTime.UtcNow,
DateModified = DateTime.UtcNow,
- UsesIdForConfigurationPath = true
+ UsesIdForConfigurationPath = true,
+ //Salt = BCrypt.GenerateSalt()
};
}
diff --git a/Emby.Server.Implementations/Library/UserViewManager.cs b/Emby.Server.Implementations/Library/UserViewManager.cs
index b02c114bb..8c9377291 100644
--- a/Emby.Server.Implementations/Library/UserViewManager.cs
+++ b/Emby.Server.Implementations/Library/UserViewManager.cs
@@ -319,8 +319,7 @@ namespace Emby.Server.Implementations.Library
var query = new InternalItemsQuery(user)
{
IncludeItemTypes = includeItemTypes,
- SortOrder = SortOrder.Descending,
- SortBy = new[] { ItemSortBy.DateCreated },
+ OrderBy = new[] { new Tuple<string, SortOrder>(ItemSortBy.DateCreated, SortOrder.Descending) },
IsFolder = includeItemTypes.Length == 0 ? false : (bool?)null,
ExcludeItemTypes = excludeItemTypes,
IsVirtualItem = false,