mirror of
https://github.com/jellyfin/jellyfin.git
synced 2026-04-10 04:12:10 +01:00
combined usermanager and userdata manager
This commit is contained in:
@@ -1205,7 +1205,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <param name="wasPlayed">if set to <c>true</c> [was played].</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public virtual Task SetPlayedStatus(User user, bool wasPlayed)
|
||||
public virtual Task SetPlayedStatus(User user, bool wasPlayed, IUserManager userManager)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
@@ -1235,7 +1235,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
|
||||
data.Played = wasPlayed;
|
||||
|
||||
return Kernel.Instance.UserDataManager.SaveUserDataForItem(user, this, data);
|
||||
return userManager.SaveUserDataForItem(user, this, data);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -962,12 +962,12 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="wasPlayed">if set to <c>true</c> [was played].</param>
|
||||
/// <returns>Task.</returns>
|
||||
public override async Task SetPlayedStatus(User user, bool wasPlayed)
|
||||
public override async Task SetPlayedStatus(User user, bool wasPlayed, IUserManager userManager)
|
||||
{
|
||||
await base.SetPlayedStatus(user, wasPlayed).ConfigureAwait(false);
|
||||
await base.SetPlayedStatus(user, wasPlayed, userManager).ConfigureAwait(false);
|
||||
|
||||
// Now sweep through recursively and update status
|
||||
var tasks = GetChildren(user).Select(c => c.SetPlayedStatus(user, wasPlayed));
|
||||
var tasks = GetChildren(user).Select(c => c.SetPlayedStatus(user, wasPlayed, userManager));
|
||||
|
||||
await Task.WhenAll(tasks).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Controller.IO;
|
||||
using MediaBrowser.Controller.Library;
|
||||
using MediaBrowser.Model.Configuration;
|
||||
using System;
|
||||
using System.IO;
|
||||
@@ -16,6 +17,8 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
public class User : BaseItem
|
||||
{
|
||||
internal static IUserManager UserManager { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The _root folder path
|
||||
/// </summary>
|
||||
@@ -236,7 +239,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
internal Task Rename(string newName)
|
||||
public Task Rename(string newName)
|
||||
{
|
||||
if (string.IsNullOrEmpty(newName))
|
||||
{
|
||||
@@ -364,7 +367,7 @@ namespace MediaBrowser.Controller.Entities
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
await Kernel.Instance.UserManager.UpdateUser(this).ConfigureAwait(false);
|
||||
await UserManager.UpdateUser(this).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
return changed;
|
||||
@@ -425,9 +428,9 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// Resets the password by clearing it.
|
||||
/// </summary>
|
||||
/// <returns>Task.</returns>
|
||||
public Task ResetPassword()
|
||||
public Task ResetPassword(IUserManager userManager)
|
||||
{
|
||||
return ChangePassword(string.Empty);
|
||||
return ChangePassword(string.Empty, userManager);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -435,11 +438,11 @@ namespace MediaBrowser.Controller.Entities
|
||||
/// </summary>
|
||||
/// <param name="newPassword">The new password.</param>
|
||||
/// <returns>Task.</returns>
|
||||
public Task ChangePassword(string newPassword)
|
||||
public Task ChangePassword(string newPassword, IUserManager userManager)
|
||||
{
|
||||
Password = string.IsNullOrEmpty(newPassword) ? string.Empty : newPassword.GetMD5().ToString();
|
||||
|
||||
return Kernel.Instance.UserManager.UpdateUser(this);
|
||||
return userManager.UpdateUser(this);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
using MediaBrowser.Common.Kernel;
|
||||
using MediaBrowser.Common.Plugins;
|
||||
using MediaBrowser.Common.ScheduledTasks;
|
||||
using MediaBrowser.Common.Security;
|
||||
using MediaBrowser.Common.Updates;
|
||||
using MediaBrowser.Controller.Drawing;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Controller.IO;
|
||||
@@ -51,12 +48,6 @@ namespace MediaBrowser.Controller
|
||||
/// <value>The image manager.</value>
|
||||
public ImageManager ImageManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user manager.
|
||||
/// </summary>
|
||||
/// <value>The user manager.</value>
|
||||
public UserManager UserManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the FFMPEG controller.
|
||||
/// </summary>
|
||||
@@ -81,47 +72,6 @@ namespace MediaBrowser.Controller
|
||||
/// <value>The provider manager.</value>
|
||||
public ProviderManager ProviderManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the user data manager.
|
||||
/// </summary>
|
||||
/// <value>The user data manager.</value>
|
||||
public UserDataManager UserDataManager { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The _users
|
||||
/// </summary>
|
||||
private IEnumerable<User> _users;
|
||||
/// <summary>
|
||||
/// The _user lock
|
||||
/// </summary>
|
||||
private object _usersSyncLock = new object();
|
||||
/// <summary>
|
||||
/// The _users initialized
|
||||
/// </summary>
|
||||
private bool _usersInitialized;
|
||||
/// <summary>
|
||||
/// Gets the users.
|
||||
/// </summary>
|
||||
/// <value>The users.</value>
|
||||
public IEnumerable<User> Users
|
||||
{
|
||||
get
|
||||
{
|
||||
// Call ToList to exhaust the stream because we'll be iterating over this multiple times
|
||||
LazyInitializer.EnsureInitialized(ref _users, ref _usersInitialized, ref _usersSyncLock, UserManager.LoadUsers);
|
||||
return _users;
|
||||
}
|
||||
internal set
|
||||
{
|
||||
_users = value;
|
||||
|
||||
if (value == null)
|
||||
{
|
||||
_usersInitialized = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _root folder
|
||||
/// </summary>
|
||||
@@ -304,13 +254,14 @@ namespace MediaBrowser.Controller
|
||||
/// </summary>
|
||||
protected override void FindParts()
|
||||
{
|
||||
// For now there's no real way to inject this properly
|
||||
User.UserManager = ApplicationHost.Resolve<IUserManager>();
|
||||
|
||||
InstallationManager = (InstallationManager)ApplicationHost.CreateInstance(typeof(InstallationManager));
|
||||
FFMpegManager = (FFMpegManager)ApplicationHost.CreateInstance(typeof(FFMpegManager));
|
||||
LibraryManager = (LibraryManager)ApplicationHost.CreateInstance(typeof(LibraryManager));
|
||||
UserManager = (UserManager)ApplicationHost.CreateInstance(typeof(UserManager));
|
||||
ImageManager = (ImageManager)ApplicationHost.CreateInstance(typeof(ImageManager));
|
||||
ProviderManager = (ProviderManager)ApplicationHost.CreateInstance(typeof(ProviderManager));
|
||||
UserDataManager = (UserDataManager)ApplicationHost.CreateInstance(typeof(UserDataManager));
|
||||
SecurityManager = (PluginSecurityManager)ApplicationHost.CreateInstance(typeof(PluginSecurityManager));
|
||||
|
||||
base.FindParts();
|
||||
@@ -337,7 +288,6 @@ namespace MediaBrowser.Controller
|
||||
protected override async Task ReloadInternal()
|
||||
{
|
||||
// Reset these so that they can be lazy loaded again
|
||||
Users = null;
|
||||
RootFolder = null;
|
||||
|
||||
await base.ReloadInternal().ConfigureAwait(false);
|
||||
@@ -346,7 +296,7 @@ namespace MediaBrowser.Controller
|
||||
|
||||
ReloadFileSystemManager();
|
||||
|
||||
await UserManager.RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false);
|
||||
await ApplicationHost.Resolve<IUserManager>().RefreshUsersMetadata(CancellationToken.None).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -453,30 +403,15 @@ namespace MediaBrowser.Controller
|
||||
FileSystemManager.StartWatchers();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a User by Id
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>User.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public User GetUserById(Guid id)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
return Users.FirstOrDefault(u => u.Id == id);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Finds a library item by Id and UserId.
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="userManager">The user manager.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">id</exception>
|
||||
public BaseItem GetItemById(Guid id, Guid userId)
|
||||
public BaseItem GetItemById(Guid id, Guid userId, IUserManager userManager)
|
||||
{
|
||||
if (id == Guid.Empty)
|
||||
{
|
||||
@@ -488,7 +423,7 @@ namespace MediaBrowser.Controller
|
||||
throw new ArgumentNullException("userId");
|
||||
}
|
||||
|
||||
var user = GetUserById(userId);
|
||||
var user = userManager.GetUserById(userId);
|
||||
var userRoot = user.RootFolder;
|
||||
|
||||
return userRoot.FindItemById(id, user);
|
||||
|
||||
@@ -823,7 +823,7 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
public static BaseItem GetItemByClientId(string id, Guid? userId = null)
|
||||
public static BaseItem GetItemByClientId(string id, IUserManager userManager, Guid? userId = null)
|
||||
{
|
||||
var isIdEmpty = string.IsNullOrEmpty(id);
|
||||
|
||||
@@ -835,7 +835,7 @@ namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
if (userId.HasValue)
|
||||
{
|
||||
return GetIndexFolder(id, userId.Value);
|
||||
return GetIndexFolder(id, userId.Value, userManager);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -844,8 +844,8 @@ namespace MediaBrowser.Controller.Library
|
||||
if (userId.HasValue)
|
||||
{
|
||||
item = isIdEmpty
|
||||
? Kernel.Instance.GetUserById(userId.Value).RootFolder
|
||||
: Kernel.Instance.GetItemById(new Guid(id), userId.Value);
|
||||
? userManager.GetUserById(userId.Value).RootFolder
|
||||
: Kernel.Instance.GetItemById(new Guid(id), userId.Value, userManager);
|
||||
}
|
||||
else if (!isIndexFolder)
|
||||
{
|
||||
@@ -855,9 +855,9 @@ namespace MediaBrowser.Controller.Library
|
||||
// If we still don't find it, look within individual user views
|
||||
if (item == null && !userId.HasValue)
|
||||
{
|
||||
foreach (var user in Kernel.Instance.Users)
|
||||
foreach (var user in userManager.Users)
|
||||
{
|
||||
item = GetItemByClientId(id, user.Id);
|
||||
item = GetItemByClientId(id, userManager, user.Id);
|
||||
|
||||
if (item != null)
|
||||
{
|
||||
@@ -875,9 +875,9 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="id">The id.</param>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <returns>BaseItem.</returns>
|
||||
private static BaseItem GetIndexFolder(string id, Guid userId)
|
||||
private static BaseItem GetIndexFolder(string id, Guid userId, IUserManager userManager)
|
||||
{
|
||||
var user = Kernel.Instance.GetUserById(userId);
|
||||
var user = userManager.GetUserById(userId);
|
||||
|
||||
var stringSeparators = new[] { IndexFolderDelimeter };
|
||||
|
||||
@@ -885,7 +885,7 @@ namespace MediaBrowser.Controller.Library
|
||||
var values = id.Split(stringSeparators, StringSplitOptions.None).ToList();
|
||||
|
||||
// Get the top folder normally using the first id
|
||||
var folder = GetItemByClientId(values[0], userId) as Folder;
|
||||
var folder = GetItemByClientId(values[0], userManager, userId) as Folder;
|
||||
|
||||
values.RemoveAt(0);
|
||||
|
||||
|
||||
169
MediaBrowser.Controller/Library/IUserManager.cs
Normal file
169
MediaBrowser.Controller/Library/IUserManager.cs
Normal file
@@ -0,0 +1,169 @@
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Connectivity;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
public interface IUserManager
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the users.
|
||||
/// </summary>
|
||||
/// <value>The users.</value>
|
||||
IEnumerable<User> Users { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active connections.
|
||||
/// </summary>
|
||||
/// <value>The active connections.</value>
|
||||
IEnumerable<ClientConnectionInfo> ConnectedUsers { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [playback start].
|
||||
/// </summary>
|
||||
event EventHandler<PlaybackProgressEventArgs> PlaybackStart;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [playback progress].
|
||||
/// </summary>
|
||||
event EventHandler<PlaybackProgressEventArgs> PlaybackProgress;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [playback stopped].
|
||||
/// </summary>
|
||||
event EventHandler<PlaybackProgressEventArgs> PlaybackStopped;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [user updated].
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<User>> UserUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Occurs when [user deleted].
|
||||
/// </summary>
|
||||
event EventHandler<GenericEventArgs<User>> UserDeleted;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a User by Id
|
||||
/// </summary>
|
||||
/// <param name="id">The id.</param>
|
||||
/// <returns>User.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
User GetUserById(Guid id);
|
||||
|
||||
/// <summary>
|
||||
/// Authenticates a User and returns a result indicating whether or not it succeeded
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>Task{System.Boolean}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
Task<bool> AuthenticateUser(User user, string password);
|
||||
|
||||
/// <summary>
|
||||
/// Logs the user activity.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
Task LogUserActivity(User user, ClientType clientType, string deviceName);
|
||||
|
||||
/// <summary>
|
||||
/// Loads the users from the repository
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{User}.</returns>
|
||||
IEnumerable<User> LoadUsers();
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes metadata for each user
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="force">if set to <c>true</c> [force].</param>
|
||||
/// <returns>Task.</returns>
|
||||
Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false);
|
||||
|
||||
/// <summary>
|
||||
/// Renames the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
Task RenameUser(User user, string newName);
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
Task UpdateUser(User user);
|
||||
|
||||
/// <summary>
|
||||
/// Creates the user.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>User.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">name</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
Task<User> CreateUser(string name);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
Task DeleteUser(User user);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has started for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceName);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report playback progress for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName);
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has ended for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName);
|
||||
|
||||
/// <summary>
|
||||
/// Saves user data for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
Task SaveUserDataForItem(User user, BaseItem item, UserItemData data);
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,8 @@ namespace MediaBrowser.Controller.Library
|
||||
/// </summary>
|
||||
private readonly ITaskManager _taskManager;
|
||||
|
||||
private readonly IUserManager _userManager;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the kernel.
|
||||
/// </summary>
|
||||
@@ -76,11 +78,12 @@ namespace MediaBrowser.Controller.Library
|
||||
/// <param name="kernel">The kernel.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
/// <param name="taskManager">The task manager.</param>
|
||||
public LibraryManager(Kernel kernel, ILogger logger, ITaskManager taskManager)
|
||||
public LibraryManager(Kernel kernel, ILogger logger, ITaskManager taskManager, IUserManager userManager)
|
||||
{
|
||||
Kernel = kernel;
|
||||
_logger = logger;
|
||||
_taskManager = taskManager;
|
||||
_userManager = userManager;
|
||||
|
||||
kernel.ConfigurationUpdated += kernel_ConfigurationUpdated;
|
||||
}
|
||||
@@ -490,13 +493,13 @@ namespace MediaBrowser.Controller.Library
|
||||
await Kernel.RootFolder.ValidateChildren(new Progress<double> { }, cancellationToken, recursive: false);
|
||||
|
||||
// Validate only the collection folders for each user, just to make them available as quickly as possible
|
||||
var userCollectionFolderTasks = Kernel.Users.AsParallel().Select(user => user.ValidateCollectionFolders(new Progress<double> { }, cancellationToken));
|
||||
var userCollectionFolderTasks = _userManager.Users.AsParallel().Select(user => user.ValidateCollectionFolders(new Progress<double> { }, cancellationToken));
|
||||
await Task.WhenAll(userCollectionFolderTasks).ConfigureAwait(false);
|
||||
|
||||
// Now validate the entire media library
|
||||
await Kernel.RootFolder.ValidateChildren(progress, cancellationToken, recursive: true).ConfigureAwait(false);
|
||||
|
||||
foreach (var user in Kernel.Users)
|
||||
foreach (var user in _userManager.Users)
|
||||
{
|
||||
await user.ValidateMediaLibrary(new Progress<double> { }, cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -1,226 +0,0 @@
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Kernel;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Connectivity;
|
||||
using MediaBrowser.Model.Logging;
|
||||
using System;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class UserDataManager
|
||||
/// </summary>
|
||||
public class UserDataManager : BaseManager<Kernel>
|
||||
{
|
||||
#region Events
|
||||
/// <summary>
|
||||
/// Occurs when [playback start].
|
||||
/// </summary>
|
||||
public event EventHandler<PlaybackProgressEventArgs> PlaybackStart;
|
||||
/// <summary>
|
||||
/// Occurs when [playback progress].
|
||||
/// </summary>
|
||||
public event EventHandler<PlaybackProgressEventArgs> PlaybackProgress;
|
||||
/// <summary>
|
||||
/// Occurs when [playback stopped].
|
||||
/// </summary>
|
||||
public event EventHandler<PlaybackProgressEventArgs> PlaybackStopped;
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserDataManager" /> class.
|
||||
/// </summary>
|
||||
/// <param name="kernel">The kernel.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public UserDataManager(Kernel kernel, ILogger logger)
|
||||
: base(kernel)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has started for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public void OnPlaybackStart(User user, BaseItem item, ClientType clientType, string deviceName)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Kernel.UserManager.UpdateNowPlayingItemId(user, clientType, deviceName, item);
|
||||
|
||||
// Nothing to save here
|
||||
// Fire events to inform plugins
|
||||
EventHelper.QueueEventIfNotNull(PlaybackStart, this, new PlaybackProgressEventArgs
|
||||
{
|
||||
Argument = item,
|
||||
User = user
|
||||
}, _logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to report playback progress for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public async Task OnPlaybackProgress(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Kernel.UserManager.UpdateNowPlayingItemId(user, clientType, deviceName, item, positionTicks);
|
||||
|
||||
if (positionTicks.HasValue)
|
||||
{
|
||||
var data = item.GetUserData(user, true);
|
||||
|
||||
UpdatePlayState(item, data, positionTicks.Value, false);
|
||||
await SaveUserDataForItem(user, item, data).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
EventHelper.QueueEventIfNotNull(PlaybackProgress, this, new PlaybackProgressEventArgs
|
||||
{
|
||||
Argument = item,
|
||||
User = user,
|
||||
PlaybackPositionTicks = positionTicks
|
||||
}, _logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to report that playback has ended for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="positionTicks">The position ticks.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException"></exception>
|
||||
public async Task OnPlaybackStopped(User user, BaseItem item, long? positionTicks, ClientType clientType, string deviceName)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
if (item == null)
|
||||
{
|
||||
throw new ArgumentNullException();
|
||||
}
|
||||
|
||||
Kernel.UserManager.RemoveNowPlayingItemId(user, clientType, deviceName, item);
|
||||
|
||||
var data = item.GetUserData(user, true);
|
||||
|
||||
if (positionTicks.HasValue)
|
||||
{
|
||||
UpdatePlayState(item, data, positionTicks.Value, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
// If the client isn't able to report this, then we'll just have to make an assumption
|
||||
data.PlayCount++;
|
||||
data.Played = true;
|
||||
}
|
||||
|
||||
await SaveUserDataForItem(user, item, data).ConfigureAwait(false);
|
||||
|
||||
EventHelper.QueueEventIfNotNull(PlaybackStopped, this, new PlaybackProgressEventArgs
|
||||
{
|
||||
Argument = item,
|
||||
User = user,
|
||||
PlaybackPositionTicks = positionTicks
|
||||
}, _logger);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates playstate position for an item but does not save
|
||||
/// </summary>
|
||||
/// <param name="item">The item</param>
|
||||
/// <param name="data">User data for the item</param>
|
||||
/// <param name="positionTicks">The current playback position</param>
|
||||
/// <param name="incrementPlayCount">Whether or not to increment playcount</param>
|
||||
private void UpdatePlayState(BaseItem item, UserItemData data, long positionTicks, bool incrementPlayCount)
|
||||
{
|
||||
// If a position has been reported, and if we know the duration
|
||||
if (positionTicks > 0 && item.RunTimeTicks.HasValue && item.RunTimeTicks > 0)
|
||||
{
|
||||
var pctIn = Decimal.Divide(positionTicks, item.RunTimeTicks.Value) * 100;
|
||||
|
||||
// Don't track in very beginning
|
||||
if (pctIn < Kernel.Configuration.MinResumePct)
|
||||
{
|
||||
positionTicks = 0;
|
||||
incrementPlayCount = false;
|
||||
}
|
||||
|
||||
// If we're at the end, assume completed
|
||||
else if (pctIn > Kernel.Configuration.MaxResumePct || positionTicks >= item.RunTimeTicks.Value)
|
||||
{
|
||||
positionTicks = 0;
|
||||
data.Played = true;
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
// Enforce MinResumeDuration
|
||||
var durationSeconds = TimeSpan.FromTicks(item.RunTimeTicks.Value).TotalSeconds;
|
||||
|
||||
if (durationSeconds < Kernel.Configuration.MinResumeDurationSeconds)
|
||||
{
|
||||
positionTicks = 0;
|
||||
data.Played = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data.PlaybackPositionTicks = positionTicks;
|
||||
|
||||
if (incrementPlayCount)
|
||||
{
|
||||
data.PlayCount++;
|
||||
data.LastPlayedDate = DateTime.UtcNow;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves user data for an item
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="data">The data.</param>
|
||||
public Task SaveUserDataForItem(User user, BaseItem item, UserItemData data)
|
||||
{
|
||||
item.AddOrUpdateUserData(user, data);
|
||||
|
||||
return Kernel.UserDataRepository.SaveUserData(item, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,403 +0,0 @@
|
||||
using MediaBrowser.Common.Events;
|
||||
using MediaBrowser.Common.Extensions;
|
||||
using MediaBrowser.Common.Kernel;
|
||||
using MediaBrowser.Controller.Entities;
|
||||
using MediaBrowser.Model.Connectivity;
|
||||
using System;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using MediaBrowser.Model.Logging;
|
||||
|
||||
namespace MediaBrowser.Controller.Library
|
||||
{
|
||||
/// <summary>
|
||||
/// Class UserManager
|
||||
/// </summary>
|
||||
public class UserManager : BaseManager<Kernel>
|
||||
{
|
||||
/// <summary>
|
||||
/// The _active connections
|
||||
/// </summary>
|
||||
private readonly ConcurrentBag<ClientConnectionInfo> _activeConnections =
|
||||
new ConcurrentBag<ClientConnectionInfo>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets all connections.
|
||||
/// </summary>
|
||||
/// <value>All connections.</value>
|
||||
public IEnumerable<ClientConnectionInfo> AllConnections
|
||||
{
|
||||
get { return _activeConnections.Where(c => Kernel.GetUserById(c.UserId) != null).OrderByDescending(c => c.LastActivityDate); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the active connections.
|
||||
/// </summary>
|
||||
/// <value>The active connections.</value>
|
||||
public IEnumerable<ClientConnectionInfo> ActiveConnections
|
||||
{
|
||||
get { return AllConnections.Where(c => (DateTime.UtcNow - c.LastActivityDate).TotalMinutes <= 10); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The _logger
|
||||
/// </summary>
|
||||
private readonly ILogger _logger;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="UserManager" /> class.
|
||||
/// </summary>
|
||||
/// <param name="kernel">The kernel.</param>
|
||||
/// <param name="logger">The logger.</param>
|
||||
public UserManager(Kernel kernel, ILogger logger)
|
||||
: base(kernel)
|
||||
{
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
#region UserUpdated Event
|
||||
/// <summary>
|
||||
/// Occurs when [user updated].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<User>> UserUpdated;
|
||||
|
||||
/// <summary>
|
||||
/// Called when [user updated].
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
internal void OnUserUpdated(User user)
|
||||
{
|
||||
EventHelper.QueueEventIfNotNull(UserUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger);
|
||||
|
||||
// Notify connected ui's
|
||||
Kernel.ServerManager.SendWebSocketMessage("UserUpdated", new DtoBuilder(_logger).GetDtoUser(user));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region UserDeleted Event
|
||||
/// <summary>
|
||||
/// Occurs when [user deleted].
|
||||
/// </summary>
|
||||
public event EventHandler<GenericEventArgs<User>> UserDeleted;
|
||||
/// <summary>
|
||||
/// Called when [user deleted].
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
internal void OnUserDeleted(User user)
|
||||
{
|
||||
EventHelper.QueueEventIfNotNull(UserDeleted, this, new GenericEventArgs<User> { Argument = user }, _logger);
|
||||
|
||||
// Notify connected ui's
|
||||
Kernel.ServerManager.SendWebSocketMessage("UserDeleted", user.Id.ToString());
|
||||
}
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Authenticates a User and returns a result indicating whether or not it succeeded
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="password">The password.</param>
|
||||
/// <returns>Task{System.Boolean}.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
public async Task<bool> AuthenticateUser(User user, string password)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
password = password ?? string.Empty;
|
||||
var existingPassword = string.IsNullOrEmpty(user.Password) ? string.Empty.GetMD5().ToString() : user.Password;
|
||||
|
||||
var success = password.GetMD5().ToString().Equals(existingPassword);
|
||||
|
||||
// Update LastActivityDate and LastLoginDate, then save
|
||||
if (success)
|
||||
{
|
||||
user.LastActivityDate = user.LastLoginDate = DateTime.UtcNow;
|
||||
await UpdateUser(user).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
_logger.Info("Authentication request for {0} {1}.", user.Name, (success ? "has succeeded" : "has been denied"));
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the user activity.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
public Task LogUserActivity(User user, ClientType clientType, string deviceName)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
var activityDate = DateTime.UtcNow;
|
||||
|
||||
user.LastActivityDate = activityDate;
|
||||
|
||||
LogConnection(user.Id, clientType, deviceName, activityDate);
|
||||
|
||||
// Save this directly. No need to fire off all the events for this.
|
||||
return Kernel.UserRepository.SaveUser(user, CancellationToken.None);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the now playing item id.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
/// <param name="currentPositionTicks">The current position ticks.</param>
|
||||
public void UpdateNowPlayingItemId(User user, ClientType clientType, string deviceName, BaseItem item, long? currentPositionTicks = null)
|
||||
{
|
||||
var conn = GetConnection(user.Id, clientType, deviceName);
|
||||
|
||||
conn.NowPlayingPositionTicks = currentPositionTicks;
|
||||
conn.NowPlayingItem = DtoBuilder.GetBaseItemInfo(item);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes the now playing item id.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="item">The item.</param>
|
||||
public void RemoveNowPlayingItemId(User user, ClientType clientType, string deviceName, BaseItem item)
|
||||
{
|
||||
var conn = GetConnection(user.Id, clientType, deviceName);
|
||||
|
||||
if (conn.NowPlayingItem != null && conn.NowPlayingItem.Id.Equals(item.Id.ToString()))
|
||||
{
|
||||
conn.NowPlayingItem = null;
|
||||
conn.NowPlayingPositionTicks = null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs the connection.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <param name="lastActivityDate">The last activity date.</param>
|
||||
private void LogConnection(Guid userId, ClientType clientType, string deviceName, DateTime lastActivityDate)
|
||||
{
|
||||
GetConnection(userId, clientType, deviceName).LastActivityDate = lastActivityDate;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the connection.
|
||||
/// </summary>
|
||||
/// <param name="userId">The user id.</param>
|
||||
/// <param name="clientType">Type of the client.</param>
|
||||
/// <param name="deviceName">Name of the device.</param>
|
||||
/// <returns>ClientConnectionInfo.</returns>
|
||||
private ClientConnectionInfo GetConnection(Guid userId, ClientType clientType, string deviceName)
|
||||
{
|
||||
var conn = _activeConnections.FirstOrDefault(c => c.UserId == userId && c.ClientType == clientType && string.Equals(deviceName, c.DeviceName, StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (conn == null)
|
||||
{
|
||||
conn = new ClientConnectionInfo
|
||||
{
|
||||
UserId = userId,
|
||||
ClientType = clientType,
|
||||
DeviceName = deviceName
|
||||
};
|
||||
|
||||
_activeConnections.Add(conn);
|
||||
}
|
||||
|
||||
return conn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads the users from the repository
|
||||
/// </summary>
|
||||
/// <returns>IEnumerable{User}.</returns>
|
||||
internal IEnumerable<User> LoadUsers()
|
||||
{
|
||||
var users = Kernel.UserRepository.RetrieveAllUsers().ToList();
|
||||
|
||||
// There always has to be at least one user.
|
||||
if (users.Count == 0)
|
||||
{
|
||||
var name = Environment.UserName;
|
||||
|
||||
var user = InstantiateNewUser(name);
|
||||
|
||||
var task = Kernel.UserRepository.SaveUser(user, CancellationToken.None);
|
||||
|
||||
// Hate having to block threads
|
||||
Task.WaitAll(task);
|
||||
|
||||
users.Add(user);
|
||||
}
|
||||
|
||||
return users;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Refreshes metadata for each user
|
||||
/// </summary>
|
||||
/// <param name="cancellationToken">The cancellation token.</param>
|
||||
/// <param name="force">if set to <c>true</c> [force].</param>
|
||||
/// <returns>Task.</returns>
|
||||
public Task RefreshUsersMetadata(CancellationToken cancellationToken, bool force = false)
|
||||
{
|
||||
var tasks = Kernel.Users.Select(user => user.RefreshMetadata(cancellationToken, forceRefresh: force)).ToList();
|
||||
|
||||
return Task.WhenAll(tasks);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Renames the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <param name="newName">The new name.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public async Task RenameUser(User user, string newName)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(newName))
|
||||
{
|
||||
throw new ArgumentNullException("newName");
|
||||
}
|
||||
|
||||
if (Kernel.Users.Any(u => u.Id != user.Id && u.Name.Equals(newName, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", newName));
|
||||
}
|
||||
|
||||
if (user.Name.Equals(newName, StringComparison.Ordinal))
|
||||
{
|
||||
throw new ArgumentException("The new and old names must be different.");
|
||||
}
|
||||
|
||||
await user.Rename(newName);
|
||||
|
||||
OnUserUpdated(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public async Task UpdateUser(User user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
if (user.Id == Guid.Empty || !Kernel.Users.Any(u => u.Id.Equals(user.Id)))
|
||||
{
|
||||
throw new ArgumentException(string.Format("User with name '{0}' and Id {1} does not exist.", user.Name, user.Id));
|
||||
}
|
||||
|
||||
user.DateModified = DateTime.UtcNow;
|
||||
|
||||
await Kernel.UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
OnUserUpdated(user);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates the user.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>User.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">name</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public async Task<User> CreateUser(string name)
|
||||
{
|
||||
if (string.IsNullOrEmpty(name))
|
||||
{
|
||||
throw new ArgumentNullException("name");
|
||||
}
|
||||
|
||||
if (Kernel.Users.Any(u => u.Name.Equals(name, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
throw new ArgumentException(string.Format("A user with the name '{0}' already exists.", name));
|
||||
}
|
||||
|
||||
var user = InstantiateNewUser(name);
|
||||
|
||||
var list = Kernel.Users.ToList();
|
||||
list.Add(user);
|
||||
Kernel.Users = list;
|
||||
|
||||
await Kernel.UserRepository.SaveUser(user, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes the user.
|
||||
/// </summary>
|
||||
/// <param name="user">The user.</param>
|
||||
/// <returns>Task.</returns>
|
||||
/// <exception cref="System.ArgumentNullException">user</exception>
|
||||
/// <exception cref="System.ArgumentException"></exception>
|
||||
public async Task DeleteUser(User user)
|
||||
{
|
||||
if (user == null)
|
||||
{
|
||||
throw new ArgumentNullException("user");
|
||||
}
|
||||
|
||||
if (Kernel.Users.FirstOrDefault(u => u.Id == user.Id) == null)
|
||||
{
|
||||
throw new ArgumentException(string.Format("The user cannot be deleted because there is no user with the Name {0} and Id {1}.", user.Name, user.Id));
|
||||
}
|
||||
|
||||
if (Kernel.Users.Count() == 1)
|
||||
{
|
||||
throw new ArgumentException(string.Format("The user '{0}' be deleted because there must be at least one user in the system.", user.Name));
|
||||
}
|
||||
|
||||
await Kernel.UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
|
||||
|
||||
OnUserDeleted(user);
|
||||
|
||||
// Force this to be lazy loaded again
|
||||
Kernel.Users = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Instantiates the new user.
|
||||
/// </summary>
|
||||
/// <param name="name">The name.</param>
|
||||
/// <returns>User.</returns>
|
||||
private User InstantiateNewUser(string name)
|
||||
{
|
||||
return new User
|
||||
{
|
||||
Name = name,
|
||||
Id = ("MBUser" + name).GetMD5(),
|
||||
DateCreated = DateTime.UtcNow,
|
||||
DateModified = DateTime.UtcNow
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -113,9 +113,8 @@
|
||||
<Compile Include="IServerApplicationPaths.cs" />
|
||||
<Compile Include="Library\ChildrenChangedEventArgs.cs" />
|
||||
<Compile Include="Library\DtoBuilder.cs" />
|
||||
<Compile Include="Library\IUserManager.cs" />
|
||||
<Compile Include="Library\Profiler.cs" />
|
||||
<Compile Include="Library\UserDataManager.cs" />
|
||||
<Compile Include="Library\UserManager.cs" />
|
||||
<Compile Include="Localization\AURatingsDictionary.cs" />
|
||||
<Compile Include="Localization\BaseStrings.cs" />
|
||||
<Compile Include="Localization\GBRatingsDictionary.cs" />
|
||||
|
||||
Reference in New Issue
Block a user