aboutsummaryrefslogtreecommitdiff
path: root/MediaBrowser.Server.Implementations
diff options
context:
space:
mode:
authorLuke Pulverenti <luke.pulverenti@gmail.com>2014-12-20 01:06:27 -0500
committerLuke Pulverenti <luke.pulverenti@gmail.com>2014-12-20 01:06:27 -0500
commit8807e80d0a04cf0c13a2113fab9917065cb0fdd9 (patch)
treefd71e759fa0de43d07b018a25c4286b54c139514 /MediaBrowser.Server.Implementations
parente55ab989d2077d70568965198139793ca7c116b4 (diff)
start using user policy
Diffstat (limited to 'MediaBrowser.Server.Implementations')
-rw-r--r--MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Connect/ConnectManager.cs35
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs4
-rw-r--r--MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs8
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs18
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs18
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs50
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs6
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs12
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs79
-rw-r--r--MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs16
-rw-r--r--MediaBrowser.Server.Implementations/Library/UserManager.cs163
-rw-r--r--MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs4
-rw-r--r--MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json9
-rw-r--r--MediaBrowser.Server.Implementations/Localization/Server/server.json1
-rw-r--r--MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj1
-rw-r--r--MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs2
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncManager.cs3
-rw-r--r--MediaBrowser.Server.Implementations/Sync/SyncRepository.cs13
19 files changed, 289 insertions, 155 deletions
diff --git a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
index bfdbb8ccf..ce939aeb4 100644
--- a/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
+++ b/MediaBrowser.Server.Implementations/Channels/ChannelDownloadScheduledTask.cs
@@ -95,7 +95,7 @@ namespace MediaBrowser.Server.Implementations.Channels
public static string GetUserDistinctValue(User user)
{
- var channels = user.Configuration.BlockedChannels
+ var channels = user.Policy.BlockedChannels
.OrderBy(i => i)
.ToList();
diff --git a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
index cbd75cdeb..376dc3548 100644
--- a/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
+++ b/MediaBrowser.Server.Implementations/Connect/ConnectManager.cs
@@ -432,9 +432,7 @@ namespace MediaBrowser.Server.Implementations.Connect
await user.UpdateToRepository(ItemUpdateType.MetadataEdit, CancellationToken.None).ConfigureAwait(false);
- user.Configuration.SyncConnectImage = false;
- user.Configuration.SyncConnectName = false;
- _userManager.UpdateConfiguration(user, user.Configuration);
+ await _userManager.UpdateConfiguration(user.Id.ToString("N"), user.Configuration);
await RefreshAuthorizationsInternal(false, CancellationToken.None).ConfigureAwait(false);
@@ -800,23 +798,21 @@ namespace MediaBrowser.Server.Implementations.Connect
await _userManager.UpdateUser(user).ConfigureAwait(false);
- user.Configuration.SyncConnectImage = true;
- user.Configuration.SyncConnectName = true;
- user.Configuration.IsHidden = true;
- user.Configuration.EnableLiveTvManagement = false;
- user.Configuration.EnableContentDeletion = false;
- user.Configuration.EnableRemoteControlOfOtherUsers = false;
- user.Configuration.EnableSharedDeviceControl = false;
- user.Configuration.IsAdministrator = false;
+ user.Policy.IsHidden = true;
+ user.Policy.EnableLiveTvManagement = false;
+ user.Policy.EnableContentDeletion = false;
+ user.Policy.EnableRemoteControlOfOtherUsers = false;
+ user.Policy.EnableSharedDeviceControl = false;
+ user.Policy.IsAdministrator = false;
if (currentPendingEntry != null)
{
- user.Configuration.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv;
- user.Configuration.BlockedMediaFolders = currentPendingEntry.ExcludedLibraries;
- user.Configuration.BlockedChannels = currentPendingEntry.ExcludedChannels;
+ user.Policy.EnableLiveTvAccess = currentPendingEntry.EnableLiveTv;
+ user.Policy.BlockedMediaFolders = currentPendingEntry.ExcludedLibraries;
+ user.Policy.BlockedChannels = currentPendingEntry.ExcludedChannels;
}
- _userManager.UpdateConfiguration(user, user.Configuration);
+ await _userManager.UpdateConfiguration(user.Id.ToString("N"), user.Configuration);
}
}
else if (string.Equals(connectEntry.AcceptStatus, "waiting", StringComparison.OrdinalIgnoreCase))
@@ -844,7 +840,7 @@ namespace MediaBrowser.Server.Implementations.Connect
{
var users = _userManager.Users
.Where(i => !string.IsNullOrEmpty(i.ConnectUserId) &&
- (i.Configuration.SyncConnectImage || i.Configuration.SyncConnectName))
+ (i.ConnectLinkType.HasValue && i.ConnectLinkType.Value == UserLinkType.Guest))
.ToList();
foreach (var user in users)
@@ -857,7 +853,10 @@ namespace MediaBrowser.Server.Implementations.Connect
continue;
}
- if (user.Configuration.SyncConnectName)
+ var syncConnectName = true;
+ var syncConnectImage = true;
+
+ if (syncConnectName)
{
var changed = !string.Equals(authorization.UserName, user.Name, StringComparison.OrdinalIgnoreCase);
@@ -867,7 +866,7 @@ namespace MediaBrowser.Server.Implementations.Connect
}
}
- if (user.Configuration.SyncConnectImage)
+ if (syncConnectImage)
{
var imageUrl = authorization.UserImageUrl;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
index 56e2e5247..b754a943a 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/HttpListenerHost.cs
@@ -206,8 +206,8 @@ namespace MediaBrowser.Server.Implementations.HttpServer
HostContext.Config.HandlerFactoryPath = ListenerRequest.GetHandlerPathIfAny(UrlPrefixes.First());
_listener = _supportsNativeWebSocket && NativeWebSocket.IsSupported
- ? _listener = new HttpListenerServer(_logger, OnRequestReceived)
- //? _listener = new WebSocketSharpListener(_logger, OnRequestReceived)
+ //? _listener = new HttpListenerServer(_logger, OnRequestReceived)
+ ? _listener = new WebSocketSharpListener(_logger, OnRequestReceived)
: _listener = new WebSocketSharpListener(_logger, OnRequestReceived);
_listener.WebSocketHandler = WebSocketHandler;
diff --git a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
index 57d87749c..13563ce19 100644
--- a/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
+++ b/MediaBrowser.Server.Implementations/HttpServer/Security/AuthService.cs
@@ -68,7 +68,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
if (user != null)
{
- if (user.Configuration.IsDisabled)
+ if (user.Policy.IsDisabled)
{
throw new SecurityException("User account has been disabled.")
{
@@ -76,7 +76,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
};
}
- if (!user.Configuration.IsAdministrator &&
+ if (!user.Policy.IsAdministrator &&
!authAttribtues.EscapeParentalControl &&
!user.IsParentalScheduleAllowed())
{
@@ -135,7 +135,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
{
if (roles.Contains("admin", StringComparer.OrdinalIgnoreCase))
{
- if (user == null || !user.Configuration.IsAdministrator)
+ if (user == null || !user.Policy.IsAdministrator)
{
throw new SecurityException("User does not have admin access.")
{
@@ -145,7 +145,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security
}
if (roles.Contains("delete", StringComparer.OrdinalIgnoreCase))
{
- if (user == null || !user.Configuration.EnableContentDeletion)
+ if (user == null || !user.Policy.EnableContentDeletion)
{
throw new SecurityException("User does not have delete access.")
{
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
index f32ed2b20..05ff270fc 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicAlbumResolver.cs
@@ -37,7 +37,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// <value>The priority.</value>
public override ResolverPriority Priority
{
- get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one
+ get
+ {
+ // Behind special folder resolver
+ return ResolverPriority.Second;
+ }
}
/// <summary>
@@ -49,21 +53,13 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
if (!args.IsDirectory) return null;
- //Avoid mis-identifying top folders
- if (args.Parent == null) return null;
+ // Avoid mis-identifying top folders
if (args.Parent.IsRoot) return null;
if (args.HasParent<MusicAlbum>()) return null;
- // Optimization
- if (args.HasParent<BoxSet>() || args.HasParent<Series>() || args.HasParent<Season>())
- {
- return null;
- }
-
var collectionType = args.GetCollectionType();
- var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music,
- StringComparison.OrdinalIgnoreCase);
+ var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase);
// If there's a collection type and it's not music, don't allow it.
if (!isMusicMediaFolder)
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
index 71b6c0843..edbc87415 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Audio/MusicArtistResolver.cs
@@ -34,7 +34,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
/// <value>The priority.</value>
public override ResolverPriority Priority
{
- get { return ResolverPriority.Third; } // we need to be ahead of the generic folder resolver but behind the movie one
+ get
+ {
+ // Behind special folder resolver
+ return ResolverPriority.Second;
+ }
}
/// <summary>
@@ -46,8 +50,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
{
if (!args.IsDirectory) return null;
- //Avoid mis-identifying top folders
- if (args.Parent == null) return null;
+ // Avoid mis-identifying top folders
if (args.Parent.IsRoot) return null;
// Don't allow nested artists
@@ -56,16 +59,9 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Audio
return null;
}
- // Optimization
- if (args.HasParent<BoxSet>() || args.HasParent<Series>() || args.HasParent<Season>())
- {
- return null;
- }
-
var collectionType = args.GetCollectionType();
- var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music,
- StringComparison.OrdinalIgnoreCase);
+ var isMusicMediaFolder = string.Equals(collectionType, CollectionType.Music, StringComparison.OrdinalIgnoreCase);
// If there's a collection type and it's not music, it can't be a series
if (!isMusicMediaFolder)
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs
index 166465f72..34237622d 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/FolderResolver.cs
@@ -1,10 +1,6 @@
-using MediaBrowser.Common.IO;
-using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
using MediaBrowser.Controller.Resolvers;
-using System;
-using System.IO;
-using System.Linq;
namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
@@ -13,13 +9,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
/// </summary>
public class FolderResolver : FolderResolver<Folder>
{
- private readonly IFileSystem _fileSystem;
-
- public FolderResolver(IFileSystem fileSystem)
- {
- _fileSystem = fileSystem;
- }
-
/// <summary>
/// Gets the priority.
/// </summary>
@@ -38,48 +27,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
if (args.IsDirectory)
{
- if (args.IsPhysicalRoot)
- {
- return new AggregateFolder();
- }
- if (args.IsRoot)
- {
- return new UserRootFolder(); //if we got here and still a root - must be user root
- }
- if (args.IsVf)
- {
- return new CollectionFolder
- {
- CollectionType = GetCollectionType(args)
- };
- }
-
return new Folder();
}
return null;
}
-
- private string GetCollectionType(ItemResolveArgs args)
- {
- return args.FileSystemChildren
- .Where(i =>
- {
-
- try
- {
- return (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory &&
- string.Equals(".collection", i.Extension, StringComparison.OrdinalIgnoreCase);
- }
- catch (IOException)
- {
- return false;
- }
-
- })
- .Select(i => _fileSystem.GetFileNameWithoutExtension(i))
- .FirstOrDefault();
- }
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
index 0e5ed1825..58b5dbc6a 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/Movies/MovieResolver.cs
@@ -183,12 +183,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies
return FindMovie<Video>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
- // Since the looping is expensive, this is an optimization to help us avoid it
- if (args.ContainsMetaFileByName("series.xml"))
- {
- return null;
- }
-
return FindMovie<Movie>(args.Path, args.Parent, args.FileSystemChildren.ToList(), args.DirectoryService, collectionType);
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
index 2fcfd7086..acae5b801 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/PhotoAlbumResolver.cs
@@ -1,5 +1,6 @@
using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Resolvers;
using MediaBrowser.Model.Entities;
using System;
using System.IO;
@@ -17,7 +18,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
protected override PhotoAlbum Resolve(ItemResolveArgs args)
{
// Must be an image file within a photo collection
- if (!args.IsRoot && args.IsDirectory && string.Equals(args.GetCollectionType(), CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
+ if (args.IsDirectory && string.Equals(args.GetCollectionType(), CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{
if (HasPhotos(args))
{
@@ -35,5 +36,14 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers
{
return args.FileSystemChildren.Any(i => ((i.Attributes & FileAttributes.Directory) != FileAttributes.Directory) && PhotoResolver.IsImageFile(i.FullName));
}
+
+ public override ResolverPriority Priority
+ {
+ get
+ {
+ // Behind special folder resolver
+ return ResolverPriority.Second;
+ }
+ }
}
}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
new file mode 100644
index 000000000..0a41a6c04
--- /dev/null
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/SpecialFolderResolver.cs
@@ -0,0 +1,79 @@
+using MediaBrowser.Common.IO;
+using MediaBrowser.Controller.Entities;
+using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.Resolvers;
+using System;
+using System.IO;
+using System.Linq;
+
+namespace MediaBrowser.Server.Implementations.Library.Resolvers
+{
+ class SpecialFolderResolver : FolderResolver<Folder>
+ {
+ private readonly IFileSystem _fileSystem;
+
+ public SpecialFolderResolver(IFileSystem fileSystem)
+ {
+ _fileSystem = fileSystem;
+ }
+
+ /// <summary>
+ /// Gets the priority.
+ /// </summary>
+ /// <value>The priority.</value>
+ public override ResolverPriority Priority
+ {
+ get { return ResolverPriority.First; }
+ }
+
+ /// <summary>
+ /// Resolves the specified args.
+ /// </summary>
+ /// <param name="args">The args.</param>
+ /// <returns>Folder.</returns>
+ protected override Folder Resolve(ItemResolveArgs args)
+ {
+ if (args.IsDirectory)
+ {
+ if (args.IsPhysicalRoot)
+ {
+ return new AggregateFolder();
+ }
+ if (args.IsRoot)
+ {
+ return new UserRootFolder(); //if we got here and still a root - must be user root
+ }
+ if (args.IsVf)
+ {
+ return new CollectionFolder
+ {
+ CollectionType = GetCollectionType(args)
+ };
+ }
+ }
+
+ return null;
+ }
+
+ private string GetCollectionType(ItemResolveArgs args)
+ {
+ return args.FileSystemChildren
+ .Where(i =>
+ {
+
+ try
+ {
+ return (i.Attributes & FileAttributes.Directory) != FileAttributes.Directory &&
+ string.Equals(".collection", i.Extension, StringComparison.OrdinalIgnoreCase);
+ }
+ catch (IOException)
+ {
+ return false;
+ }
+
+ })
+ .Select(i => _fileSystem.GetFileNameWithoutExtension(i))
+ .FirstOrDefault();
+ }
+ }
+}
diff --git a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
index 866dc534d..00bed4086 100644
--- a/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
+++ b/MediaBrowser.Server.Implementations/Library/Resolvers/TV/SeriesResolver.cs
@@ -53,13 +53,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
if (args.IsDirectory)
{
// Avoid expensive tests against VF's and all their children by not allowing this
- if (args.Parent == null || args.Parent.IsRoot)
- {
- return null;
- }
-
- // Optimization to avoid running these tests against Seasons
- if (args.HasParent<Series>() || args.HasParent<Season>() || args.HasParent<MusicArtist>() || args.HasParent<MusicAlbum>())
+ if (args.Parent.IsRoot)
{
return null;
}
@@ -69,8 +63,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.TV
var isTvShowsFolder = string.Equals(collectionType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase);
// If there's a collection type and it's not tv, it can't be a series
- if (!string.IsNullOrEmpty(collectionType) &&
- !isTvShowsFolder)
+ if (!isTvShowsFolder)
+ {
+ return null;
+ }
+
+ if (args.HasParent<Series>() || args.HasParent<Season>())
{
return null;
}
diff --git a/MediaBrowser.Server.Implementations/Library/UserManager.cs b/MediaBrowser.Server.Implementations/Library/UserManager.cs
index cf3b4434e..7b95ab681 100644
--- a/MediaBrowser.Server.Implementations/Library/UserManager.cs
+++ b/MediaBrowser.Server.Implementations/Library/UserManager.cs
@@ -1,5 +1,4 @@
-using System.Collections.Concurrent;
-using MediaBrowser.Common.Events;
+using MediaBrowser.Common.Events;
using MediaBrowser.Common.Extensions;
using MediaBrowser.Common.Net;
using MediaBrowser.Controller;
@@ -63,6 +62,7 @@ namespace MediaBrowser.Server.Implementations.Library
public event EventHandler<GenericEventArgs<User>> UserPasswordChanged;
private readonly IXmlSerializer _xmlSerializer;
+ private readonly IJsonSerializer _jsonSerializer;
private readonly INetworkManager _networkManager;
@@ -71,13 +71,7 @@ namespace MediaBrowser.Server.Implementations.Library
private readonly Func<IConnectManager> _connectFactory;
private readonly IServerApplicationHost _appHost;
- /// <summary>
- /// Initializes a new instance of the <see cref="UserManager" /> class.
- /// </summary>
- /// <param name="logger">The logger.</param>
- /// <param name="configurationManager">The configuration manager.</param>
- /// <param name="userRepository">The user repository.</param>
- public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost)
+ public UserManager(ILogger logger, IServerConfigurationManager configurationManager, IUserRepository userRepository, IXmlSerializer xmlSerializer, INetworkManager networkManager, Func<IImageProcessor> imageProcessorFactory, Func<IDtoService> dtoServiceFactory, Func<IConnectManager> connectFactory, IServerApplicationHost appHost, IJsonSerializer jsonSerializer)
{
_logger = logger;
UserRepository = userRepository;
@@ -87,6 +81,7 @@ namespace MediaBrowser.Server.Implementations.Library
_dtoServiceFactory = dtoServiceFactory;
_connectFactory = connectFactory;
_appHost = appHost;
+ _jsonSerializer = jsonSerializer;
ConfigurationManager = configurationManager;
Users = new List<User>();
@@ -164,6 +159,11 @@ namespace MediaBrowser.Server.Implementations.Library
public async Task Initialize()
{
Users = await LoadUsers().ConfigureAwait(false);
+
+ foreach (var user in Users.ToList())
+ {
+ await DoPolicyMigration(user).ConfigureAwait(false);
+ }
}
public Task<bool> AuthenticateUser(string username, string passwordSha1, string remoteEndPoint)
@@ -185,7 +185,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new SecurityException("Invalid username or password entered.");
}
- if (user.Configuration.IsDisabled)
+ if (user.Policy.IsDisabled)
{
throw new SecurityException(string.Format("The {0} account is currently disabled. Please consult with your administrator.", user.Name));
}
@@ -283,14 +283,42 @@ namespace MediaBrowser.Server.Implementations.Library
users.Add(user);
- user.Configuration.IsAdministrator = true;
- user.Configuration.EnableRemoteControlOfOtherUsers = true;
- UpdateConfiguration(user, user.Configuration);
+ user.Policy.IsAdministrator = true;
+ user.Policy.EnableRemoteControlOfOtherUsers = true;
+ await UpdateUserPolicy(user, user.Policy, false).ConfigureAwait(false);
}
return users;
}
+ private async Task DoPolicyMigration(User user)
+ {
+ if (!user.Configuration.ValuesMigratedToPolicy)
+ {
+ user.Policy.AccessSchedules = user.Configuration.AccessSchedules;
+ user.Policy.BlockedChannels = user.Configuration.BlockedChannels;
+ user.Policy.BlockedMediaFolders = user.Configuration.BlockedMediaFolders;
+ user.Policy.BlockedTags = user.Configuration.BlockedTags;
+ user.Policy.BlockUnratedItems = user.Configuration.BlockUnratedItems;
+ user.Policy.EnableContentDeletion = user.Configuration.EnableContentDeletion;
+ user.Policy.EnableLiveTvAccess = user.Configuration.EnableLiveTvAccess;
+ user.Policy.EnableLiveTvManagement = user.Configuration.EnableLiveTvManagement;
+ user.Policy.EnableMediaPlayback = user.Configuration.EnableMediaPlayback;
+ user.Policy.EnableRemoteControlOfOtherUsers = user.Configuration.EnableRemoteControlOfOtherUsers;
+ user.Policy.EnableSharedDeviceControl = user.Configuration.EnableSharedDeviceControl;
+ user.Policy.EnableUserPreferenceAccess = user.Configuration.EnableUserPreferenceAccess;
+ user.Policy.IsAdministrator = user.Configuration.IsAdministrator;
+ user.Policy.IsDisabled = user.Configuration.IsDisabled;
+ user.Policy.IsHidden = user.Configuration.IsHidden;
+ user.Policy.MaxParentalRating = user.Configuration.MaxParentalRating;
+
+ await UpdateUserPolicy(user.Id.ToString("N"), user.Policy);
+
+ user.Configuration.ValuesMigratedToPolicy = true;
+ await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false);
+ }
+ }
+
public UserDto GetUserDto(User user, string remoteEndPoint = null)
{
if (user == null)
@@ -509,7 +537,7 @@ namespace MediaBrowser.Server.Implementations.Library
throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one user in the system.", user.Name));
}
- if (user.Configuration.IsAdministrator && allUsers.Count(i => i.Configuration.IsAdministrator) == 1)
+ if (user.Policy.IsAdministrator && allUsers.Count(i => i.Policy.IsAdministrator) == 1)
{
throw new ArgumentException(string.Format("The user '{0}' cannot be deleted because there must be at least one admin user in the system.", user.Name));
}
@@ -518,17 +546,17 @@ namespace MediaBrowser.Server.Implementations.Library
try
{
- await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
+ var configPath = GetConfigurationFilePath(user);
- var path = user.ConfigurationFilePath;
+ await UserRepository.DeleteUser(user, CancellationToken.None).ConfigureAwait(false);
try
{
- File.Delete(path);
+ File.Delete(configPath);
}
catch (IOException ex)
{
- _logger.ErrorException("Error deleting file {0}", ex, path);
+ _logger.ErrorException("Error deleting file {0}", ex, configPath);
}
DeleteUserPolicy(user);
@@ -613,15 +641,6 @@ namespace MediaBrowser.Server.Implementations.Library
};
}
- public void UpdateConfiguration(User user, UserConfiguration newConfiguration)
- {
- var xmlPath = user.ConfigurationFilePath;
- Directory.CreateDirectory(Path.GetDirectoryName(xmlPath));
- _xmlSerializer.SerializeToFile(newConfiguration, xmlPath);
-
- EventHelper.FireEventIfNotNull(UserConfigurationUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger);
- }
-
private string PasswordResetFile
{
get { return Path.Combine(ConfigurationManager.ApplicationPaths.ProgramDataPath, "passwordreset.txt"); }
@@ -689,7 +708,7 @@ namespace MediaBrowser.Server.Implementations.Library
string pinFile = null;
DateTime? expirationDate = null;
- if (user != null && !user.Configuration.IsAdministrator)
+ if (user != null && !user.Policy.IsAdministrator)
{
action = ForgotPasswordAction.ContactAdmin;
}
@@ -781,7 +800,7 @@ namespace MediaBrowser.Server.Implementations.Library
{
lock (_policySyncLock)
{
- return (UserPolicy) _xmlSerializer.DeserializeFromFile(typeof (UserPolicy), path);
+ return (UserPolicy)_jsonSerializer.DeserializeFromFile(typeof(UserPolicy), path);
}
}
catch (FileNotFoundException)
@@ -805,16 +824,38 @@ namespace MediaBrowser.Server.Implementations.Library
}
private readonly object _policySyncLock = new object();
- public async Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
+ public Task UpdateUserPolicy(string userId, UserPolicy userPolicy)
{
var user = GetUserById(userId);
+ return UpdateUserPolicy(user, userPolicy, true);
+ }
+
+ private async Task UpdateUserPolicy(User user, UserPolicy userPolicy, bool fireEvent)
+ {
+ var updateConfig = user.Policy.IsAdministrator != userPolicy.IsAdministrator ||
+ user.Policy.EnableLiveTvManagement != userPolicy.EnableLiveTvManagement ||
+ user.Policy.EnableLiveTvAccess != userPolicy.EnableLiveTvAccess ||
+ user.Policy.EnableMediaPlayback != userPolicy.EnableMediaPlayback ||
+ user.Policy.EnableContentDeletion != userPolicy.EnableContentDeletion;
+
var path = GetPolifyFilePath(user);
lock (_policySyncLock)
{
- _xmlSerializer.SerializeToFile(userPolicy, path);
+ _jsonSerializer.SerializeToFile(userPolicy, path);
user.Policy = userPolicy;
}
+
+ if (updateConfig)
+ {
+ user.Configuration.IsAdministrator = user.Policy.IsAdministrator;
+ user.Configuration.EnableLiveTvManagement = user.Policy.EnableLiveTvManagement;
+ user.Configuration.EnableLiveTvAccess = user.Policy.EnableLiveTvAccess;
+ user.Configuration.EnableMediaPlayback = user.Policy.EnableMediaPlayback;
+ user.Configuration.EnableContentDeletion = user.Policy.EnableContentDeletion;
+
+ await UpdateConfiguration(user, user.Configuration, true).ConfigureAwait(false);
+ }
}
private void DeleteUserPolicy(User user)
@@ -840,7 +881,65 @@ namespace MediaBrowser.Server.Implementations.Library
private string GetPolifyFilePath(User user)
{
- return Path.Combine(user.ConfigurationDirectoryPath, "policy.xml");
+ return Path.Combine(user.ConfigurationDirectoryPath, "policy.json");
+ }
+
+ private string GetConfigurationFilePath(User user)
+ {
+ return Path.Combine(user.ConfigurationDirectoryPath, "config.xml");
+ }
+
+ public UserConfiguration GetUserConfiguration(User user)
+ {
+ var path = GetConfigurationFilePath(user);
+
+ try
+ {
+ lock (_configSyncLock)
+ {
+ return (UserConfiguration)_xmlSerializer.DeserializeFromFile(typeof(UserConfiguration), path);
+ }
+ }
+ catch (FileNotFoundException)
+ {
+ return new UserConfiguration();
+ }
+ catch (Exception ex)
+ {
+ _logger.ErrorException("Error reading policy file: {0}", ex, path);
+
+ return new UserConfiguration();
+ }
+ }
+
+ private readonly object _configSyncLock = new object();
+ public Task UpdateConfiguration(string userId, UserConfiguration config)
+ {
+ var user = GetUserById(userId);
+ return UpdateConfiguration(user, config, true);
+ }
+
+ private async Task UpdateConfiguration(User user, UserConfiguration config, bool fireEvent)
+ {
+ var path = GetConfigurationFilePath(user);
+
+ // The xml serializer will output differently if the type is not exact
+ if (config.GetType() != typeof (UserConfiguration))
+ {
+ var json = _jsonSerializer.SerializeToString(config);
+ config = _jsonSerializer.DeserializeFromString<UserConfiguration>(json);
+ }
+
+ lock (_configSyncLock)
+ {
+ _xmlSerializer.SerializeToFile(config, path);
+ user.Configuration = config;
+ }
+
+ if (fireEvent)
+ {
+ EventHelper.FireEventIfNotNull(UserConfigurationUpdated, this, new GenericEventArgs<User> { Argument = user }, _logger);
+ }
}
}
}
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 83fe992b6..e67bf10f7 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -1846,7 +1846,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private bool IsLiveTvEnabled(User user)
{
- return user.Configuration.EnableLiveTvAccess && ActiveService != null;
+ return user.Policy.EnableLiveTvAccess && ActiveService != null;
}
public IEnumerable<User> GetEnabledUsers()
@@ -1854,7 +1854,7 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var service = ActiveService;
return _userManager.Users
- .Where(i => i.Configuration.EnableLiveTvAccess && service != null);
+ .Where(i => i.Policy.EnableLiveTvAccess && service != null);
}
/// <summary>
diff --git a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
index debb3c03a..7072f2406 100644
--- a/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
+++ b/MediaBrowser.Server.Implementations/Localization/JavaScript/javascript.json
@@ -418,7 +418,7 @@
"HeaderMediaLocations": "Media Locations",
"LabelFolderTypeValue": "Folder type: {0}",
"LabelPathSubstitutionHelp": "Optional: Path substitution can map server paths to network shares that clients can access for direct playback.",
- "FolderTypeMixed": "Mixed movies & tv",
+ "FolderTypeMixed": "Mixed videos",
"FolderTypeMovies": "Movies",
"FolderTypeMusic": "Music",
"FolderTypeAdultVideos": "Adult videos",
@@ -427,7 +427,7 @@
"FolderTypeHomeVideos": "Home videos",
"FolderTypeGames": "Games",
"FolderTypeBooks": "Books",
- "FolderTypeTvShows": "TV shows",
+ "FolderTypeTvShows": "TV",
"TabMovies": "Movies",
"TabSeries": "Series",
"TabEpisodes": "Episodes",
@@ -654,5 +654,8 @@
"OptionSyncUnwatchedVideosOnly": "Sync unwatched videos only",
"OptionSyncUnwatchedVideosOnlyHelp": "Only unwatched videos will be synced, and videos will be removed from the device as they are watched.",
"LabelItemLimit": "Item limit:",
- "LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced."
+ "LabelItemLimitHelp": "Optional. Set a limit to the number of items that will be synced.",
+ "MessageBookPluginRequired": "Requires installation of the Bookshelf plugin",
+ "MessageGamePluginRequired": "Requires installation of the GameBrowser plugin",
+ "MessageMixedContentHelp": "Content will be displayed with as a plain folder structure"
}
diff --git a/MediaBrowser.Server.Implementations/Localization/Server/server.json b/MediaBrowser.Server.Implementations/Localization/Server/server.json
index 2db5ac634..9bf06c50b 100644
--- a/MediaBrowser.Server.Implementations/Localization/Server/server.json
+++ b/MediaBrowser.Server.Implementations/Localization/Server/server.json
@@ -40,7 +40,6 @@
"HeaderSetupLibrary": "Setup your media library",
"ButtonAddMediaFolder": "Add media folder",
"LabelFolderType": "Folder type:",
- "MediaFolderHelpPluginRequired": "* Requires the use of a plugin, e.g. GameBrowser or MB Bookshelf.",
"ReferToMediaLibraryWiki": "Refer to the media library wiki.",
"LabelCountry": "Country:",
"LabelLanguage": "Language:",
diff --git a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
index dda4cbc58..123f3fe87 100644
--- a/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
+++ b/MediaBrowser.Server.Implementations/MediaBrowser.Server.Implementations.csproj
@@ -183,6 +183,7 @@
<Compile Include="Library\LocalTrailerPostScanTask.cs" />
<Compile Include="Library\MusicManager.cs" />
<Compile Include="Library\PathExtensions.cs" />
+ <Compile Include="Library\Resolvers\SpecialFolderResolver.cs" />
<Compile Include="Library\Resolvers\BaseVideoResolver.cs" />
<Compile Include="Library\Resolvers\PhotoAlbumResolver.cs" />
<Compile Include="Library\Resolvers\PhotoResolver.cs" />
diff --git a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs
index 3f8b61a45..e74225887 100644
--- a/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs
+++ b/MediaBrowser.Server.Implementations/Notifications/NotificationManager.cs
@@ -78,7 +78,7 @@ namespace MediaBrowser.Server.Implementations.Notifications
switch (request.SendToUserMode.Value)
{
case SendToUserType.Admins:
- return _userManager.Users.Where(i => i.Configuration.IsAdministrator)
+ return _userManager.Users.Where(i => i.Policy.IsAdministrator)
.Select(i => i.Id.ToString("N"));
case SendToUserType.All:
return _userManager.Users.Select(i => i.Id.ToString("N"));
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
index 664ec4038..6b15aaed7 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncManager.cs
@@ -4,6 +4,7 @@ using MediaBrowser.Controller.Entities;
using MediaBrowser.Controller.Entities.Audio;
using MediaBrowser.Controller.Entities.TV;
using MediaBrowser.Controller.Library;
+using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Sync;
using MediaBrowser.Model.Dlna;
using MediaBrowser.Model.Entities;
@@ -242,7 +243,7 @@ namespace MediaBrowser.Server.Implementations.Sync
return true;
}
- return item.LocationType == LocationType.FileSystem || item is Season;
+ return item.LocationType == LocationType.FileSystem || item is Season || item is ILiveTvRecording;
}
private string GetDefaultName(BaseItem item)
diff --git a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
index 7825b9e9a..e65d4c66e 100644
--- a/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
+++ b/MediaBrowser.Server.Implementations/Sync/SyncRepository.cs
@@ -24,6 +24,7 @@ namespace MediaBrowser.Server.Implementations.Sync
private readonly CultureInfo _usCulture = new CultureInfo("en-US");
private IDbCommand _deleteJobCommand;
+ private IDbCommand _deleteJobItemsCommand;
private IDbCommand _saveJobCommand;
private IDbCommand _saveJobItemCommand;
@@ -61,9 +62,13 @@ namespace MediaBrowser.Server.Implementations.Sync
private void PrepareStatements()
{
_deleteJobCommand = _connection.CreateCommand();
- _deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id; delete from SyncJobItems where JobId=@Id";
+ _deleteJobCommand.CommandText = "delete from SyncJobs where Id=@Id";
_deleteJobCommand.Parameters.Add(_deleteJobCommand, "@Id");
+ _deleteJobItemsCommand = _connection.CreateCommand();
+ _deleteJobItemsCommand.CommandText = "delete from SyncJobItems where JobId=@JobId";
+ _deleteJobItemsCommand.Parameters.Add(_deleteJobItemsCommand, "@JobId");
+
_saveJobCommand = _connection.CreateCommand();
_saveJobCommand.CommandText = "replace into SyncJobs (Id, TargetId, Name, Quality, Status, Progress, UserId, ItemIds, Category, ParentId, UnwatchedOnly, ItemLimit, SyncNewContent, DateCreated, DateLastModified, ItemCount) values (@Id, @TargetId, @Name, @Quality, @Status, @Progress, @UserId, @ItemIds, @Category, @ParentId, @UnwatchedOnly, @ItemLimit, @SyncNewContent, @DateCreated, @DateLastModified, @ItemCount)";
@@ -289,11 +294,13 @@ namespace MediaBrowser.Server.Implementations.Sync
var index = 0;
_deleteJobCommand.GetParameter(index++).Value = new Guid(id);
-
_deleteJobCommand.Transaction = transaction;
-
_deleteJobCommand.ExecuteNonQuery();
+ _deleteJobItemsCommand.GetParameter(index++).Value = new Guid(id);
+ _deleteJobItemsCommand.Transaction = transaction;
+ _deleteJobItemsCommand.ExecuteNonQuery();
+
transaction.Commit();
}
catch (OperationCanceledException)