using MediaBrowser.Common.Configuration; using MediaBrowser.Controller.Library; using MediaBrowser.Controller.Providers; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.Connect; using MediaBrowser.Model.Serialization; using System; using System.IO; using System.Linq; using System.Runtime.Serialization; using System.Threading; using System.Threading.Tasks; namespace MediaBrowser.Controller.Entities { /// /// Class User /// public class User : BaseItem { public static IUserManager UserManager { get; set; } public static IXmlSerializer XmlSerializer { get; set; } /// /// From now on all user paths will be Id-based. /// This is for backwards compatibility. /// public bool UsesIdForConfigurationPath { get; set; } /// /// Gets or sets the password. /// /// The password. public string Password { get; set; } public string LocalPassword { get; set; } public string ConnectUserName { get; set; } public string ConnectUserId { get; set; } public UserLinkType? ConnectLinkType { get; set; } public string ConnectAccessKey { get; set; } /// /// Gets or sets the path. /// /// The path. [IgnoreDataMember] public override string Path { get { // Return this so that metadata providers will look in here return ConfigurationDirectoryPath; } set { base.Path = value; } } /// /// Returns the folder containing the item. /// If the item is a folder, it returns the folder itself /// /// The containing folder path. public override string ContainingFolderPath { get { return Path; } } /// /// Gets a value indicating whether this instance is owned item. /// /// true if this instance is owned item; otherwise, false. public override bool IsOwnedItem { get { return false; } } /// /// Gets the root folder. /// /// The root folder. [IgnoreDataMember] public Folder RootFolder { get { return LibraryManager.GetUserRootFolder(); } } /// /// Gets or sets the last login date. /// /// The last login date. public DateTime? LastLoginDate { get; set; } /// /// Gets or sets the last activity date. /// /// The last activity date. public DateTime? LastActivityDate { get; set; } /// /// The _configuration /// private UserConfiguration _configuration; /// /// The _configuration initialized /// private bool _configurationInitialized; /// /// The _configuration sync lock /// private object _configurationSyncLock = new object(); /// /// Gets the user's configuration /// /// The configuration. [IgnoreDataMember] public UserConfiguration Configuration { get { // Lazy load LazyInitializer.EnsureInitialized(ref _configuration, ref _configurationInitialized, ref _configurationSyncLock, () => (UserConfiguration)ConfigurationHelper.GetXmlConfiguration(typeof(UserConfiguration), ConfigurationFilePath, XmlSerializer)); return _configuration; } private set { _configuration = value; _configurationInitialized = value != null; } } /// /// Renames the user. /// /// The new name. /// Task. /// public Task Rename(string newName) { if (string.IsNullOrEmpty(newName)) { throw new ArgumentNullException("newName"); } // If only the casing is changing, leave the file system alone if (!UsesIdForConfigurationPath && !newName.Equals(Name, StringComparison.OrdinalIgnoreCase)) { UsesIdForConfigurationPath = true; // Move configuration var newConfigDirectory = GetConfigurationDirectoryPath(newName); var oldConfigurationDirectory = ConfigurationDirectoryPath; // Exceptions will be thrown if these paths already exist if (Directory.Exists(newConfigDirectory)) { Directory.Delete(newConfigDirectory, true); } if (Directory.Exists(oldConfigurationDirectory)) { Directory.Move(oldConfigurationDirectory, newConfigDirectory); } else { Directory.CreateDirectory(newConfigDirectory); } } Name = newName; return RefreshMetadata(new MetadataRefreshOptions(new DirectoryService()) { ReplaceAllMetadata = true, ImageRefreshMode = ImageRefreshMode.FullRefresh, MetadataRefreshMode = MetadataRefreshMode.FullRefresh, ForceSave = true }, CancellationToken.None); } public override Task UpdateToRepository(ItemUpdateType updateReason, CancellationToken cancellationToken) { return UserManager.UpdateUser(this); } /// /// Gets the path to the user's configuration directory /// /// The configuration directory path. [IgnoreDataMember] private string ConfigurationDirectoryPath { get { return GetConfigurationDirectoryPath(Name); } } /// /// Gets the configuration directory path. /// /// The username. /// System.String. private string GetConfigurationDirectoryPath(string username) { if (string.IsNullOrEmpty(username)) { throw new ArgumentNullException("username"); } var parentPath = ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath; // Legacy if (!UsesIdForConfigurationPath) { var safeFolderName = FileSystem.GetValidFilename(username); return System.IO.Path.Combine(ConfigurationManager.ApplicationPaths.UserConfigurationDirectoryPath, safeFolderName); } return System.IO.Path.Combine(parentPath, Id.ToString("N")); } /// /// Gets the path to the user's configuration file /// /// The configuration file path. [IgnoreDataMember] public string ConfigurationFilePath { get { return System.IO.Path.Combine(ConfigurationDirectoryPath, "config.xml"); } } /// /// Updates the configuration. /// /// The config. /// config public void UpdateConfiguration(UserConfiguration config) { if (config == null) { throw new ArgumentNullException("config"); } Configuration = config; UserManager.UpdateConfiguration(this, Configuration); } public bool IsParentalScheduleAllowed() { return IsParentalScheduleAllowed(DateTime.UtcNow); } public bool IsParentalScheduleAllowed(DateTime date) { var schedules = Configuration.AccessSchedules; if (schedules.Length == 0) { return true; } return schedules.Any(i => IsParentalScheduleAllowed(i, date)); } private bool IsParentalScheduleAllowed(AccessSchedule schedule, DateTime date) { if (date.Kind != DateTimeKind.Utc) { throw new ArgumentException("Utc date expected"); } var localTime = date.ToLocalTime(); return DayOfWeekHelper.GetDaysOfWeek(schedule.DayOfWeek).Contains(localTime.DayOfWeek) && IsWithinTime(schedule, localTime); } private bool IsWithinTime(AccessSchedule schedule, DateTime localTime) { var hour = localTime.TimeOfDay.TotalHours; return hour >= schedule.StartHour && hour <= schedule.EndHour; } } }