diff --git a/MediaBrowser.Api/BaseApiService.cs b/MediaBrowser.Api/BaseApiService.cs
index 91e1c7d9a..e009ccfac 100644
--- a/MediaBrowser.Api/BaseApiService.cs
+++ b/MediaBrowser.Api/BaseApiService.cs
@@ -41,6 +41,8 @@ namespace MediaBrowser.Api
public ISessionContext SessionContext { get; set; }
public IAuthorizationContext AuthorizationContext { get; set; }
+ public IUserManager UserManager { get; set; }
+
public string GetHeader(string name)
{
return Request.Headers[name];
@@ -73,6 +75,29 @@ namespace MediaBrowser.Api
return ResultFactory.GetOptimizedResultUsingCache(Request, cacheKey, lastDateModified, cacheDuration, factoryFn);
}
+ protected void AssertCanUpdateUser(string userId)
+ {
+ var auth = AuthorizationContext.GetAuthorizationInfo(Request);
+
+ var authenticatedUser = UserManager.GetUserById(auth.UserId);
+
+ // If they're going to update the record of another user, they must be an administrator
+ if (!string.Equals(userId, auth.UserId, StringComparison.OrdinalIgnoreCase))
+ {
+ if (!authenticatedUser.Policy.IsAdministrator)
+ {
+ throw new SecurityException("Unauthorized access.");
+ }
+ }
+ else
+ {
+ if (!authenticatedUser.Policy.EnableUserPreferenceAccess)
+ {
+ throw new SecurityException("Unauthorized access.");
+ }
+ }
+ }
+
///
/// To the optimized serialized result using cache.
///
diff --git a/MediaBrowser.Api/Images/ImageService.cs b/MediaBrowser.Api/Images/ImageService.cs
index 0a39b51c3..6afd88515 100644
--- a/MediaBrowser.Api/Images/ImageService.cs
+++ b/MediaBrowser.Api/Images/ImageService.cs
@@ -56,7 +56,7 @@ namespace MediaBrowser.Api.Images
/// Class UpdateItemImageIndex
///
[Route("/Items/{Id}/Images/{Type}/{Index}/Index", "POST", Summary = "Updates the index for an item image")]
- [Authenticated]
+ [Authenticated(Roles = "admin")]
public class UpdateItemImageIndex : IReturnVoid
{
///
@@ -64,7 +64,7 @@ namespace MediaBrowser.Api.Images
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
///
/// Gets or sets the type of the image.
@@ -143,7 +143,7 @@ namespace MediaBrowser.Api.Images
///
/// The id.
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "GET")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
///
@@ -151,7 +151,7 @@ namespace MediaBrowser.Api.Images
///
[Route("/Items/{Id}/Images/{Type}", "DELETE")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "DELETE")]
- [Authenticated]
+ [Authenticated(Roles = "admin")]
public class DeleteItemImage : DeleteImageRequest, IReturnVoid
{
///
@@ -159,7 +159,7 @@ namespace MediaBrowser.Api.Images
///
/// The id.
[ApiMember(Name = "Id", Description = "Item Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
///
@@ -175,7 +175,7 @@ namespace MediaBrowser.Api.Images
///
/// The id.
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "DELETE")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
}
///
@@ -191,7 +191,7 @@ namespace MediaBrowser.Api.Images
///
/// The id.
[ApiMember(Name = "Id", Description = "User Id", IsRequired = true, DataType = "string", ParameterType = "path", Verb = "POST")]
- public Guid Id { get; set; }
+ public string Id { get; set; }
///
/// The raw Http Request Input Stream
@@ -206,7 +206,7 @@ namespace MediaBrowser.Api.Images
[Route("/Items/{Id}/Images/{Type}", "POST")]
[Route("/Items/{Id}/Images/{Type}/{Index}", "POST")]
[Api(Description = "Posts an item image")]
- [Authenticated]
+ [Authenticated(Roles = "admin")]
public class PostItemImage : DeleteImageRequest, IRequiresRequestStream, IReturnVoid
{
///
@@ -417,11 +417,12 @@ namespace MediaBrowser.Api.Images
/// The request.
public void Post(PostUserImage request)
{
- var id = new Guid(GetPathValue(1));
+ var userId = GetPathValue(1);
+ AssertCanUpdateUser(userId);
request.Type = (ImageType)Enum.Parse(typeof(ImageType), GetPathValue(3), true);
- var item = _userManager.GetUserById(id);
+ var item = _userManager.GetUserById(userId);
var task = PostImage(item, request.RequestStream, request.Type, Request.ContentType);
@@ -434,7 +435,7 @@ namespace MediaBrowser.Api.Images
/// The request.
public void Post(PostItemImage request)
{
- var id = new Guid(GetPathValue(1));
+ var id = GetPathValue(1);
request.Type = (ImageType)Enum.Parse(typeof(ImageType), GetPathValue(3), true);
@@ -451,7 +452,10 @@ namespace MediaBrowser.Api.Images
/// The request.
public void Delete(DeleteUserImage request)
{
- var item = _userManager.GetUserById(request.Id);
+ var userId = request.Id;
+ AssertCanUpdateUser(userId);
+
+ var item = _userManager.GetUserById(userId);
var task = item.DeleteImage(request.Type, request.Index ?? 0);
@@ -492,7 +496,6 @@ namespace MediaBrowser.Api.Images
/// Index of the current.
/// The new index.
/// Task.
- /// The change index operation is only applicable to backdrops and screenshots
private Task UpdateItemIndex(IHasImages item, ImageType type, int currentIndex, int newIndex)
{
return item.SwapImages(type, currentIndex, newIndex);
diff --git a/MediaBrowser.Api/ItemUpdateService.cs b/MediaBrowser.Api/ItemUpdateService.cs
index 86689f5cf..013838091 100644
--- a/MediaBrowser.Api/ItemUpdateService.cs
+++ b/MediaBrowser.Api/ItemUpdateService.cs
@@ -41,8 +41,8 @@ namespace MediaBrowser.Api
[ApiMember(Name = "ContentType", Description = "The content type of the item", IsRequired = true, DataType = "string", ParameterType = "query", Verb = "POST")]
public string ContentType { get; set; }
}
-
- [Authenticated]
+
+ [Authenticated(Roles = "admin")]
public class ItemUpdateService : BaseApiService
{
private readonly ILibraryManager _libraryManager;
@@ -61,7 +61,7 @@ namespace MediaBrowser.Api
public object Get(GetMetadataEditorInfo request)
{
var item = _libraryManager.GetItemById(request.ItemId);
-
+
var info = new MetadataEditorInfo
{
ParentalRatingOptions = _localizationManager.GetParentalRatings().ToList(),
@@ -131,7 +131,7 @@ namespace MediaBrowser.Api
Value = ""
});
}
-
+
list.Add(new NameValuePair
{
Name = "FolderTypeMovies",
@@ -406,7 +406,7 @@ namespace MediaBrowser.Api
.Select(i => i.Name)
.ToList();
}
-
+
var song = item as Audio;
if (song != null)
{
diff --git a/MediaBrowser.Api/UserService.cs b/MediaBrowser.Api/UserService.cs
index c17f33348..cbb2a1799 100644
--- a/MediaBrowser.Api/UserService.cs
+++ b/MediaBrowser.Api/UserService.cs
@@ -253,18 +253,14 @@ namespace MediaBrowser.Api
/// The _user manager
///
private readonly IUserManager _userManager;
- private readonly IDtoService _dtoService;
private readonly ISessionManager _sessionMananger;
private readonly IServerConfigurationManager _config;
private readonly INetworkManager _networkManager;
private readonly IDeviceManager _deviceManager;
- public IAuthorizationContext AuthorizationContext { get; set; }
-
- public UserService(IUserManager userManager, IDtoService dtoService, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager, IDeviceManager deviceManager)
+ public UserService(IUserManager userManager, ISessionManager sessionMananger, IServerConfigurationManager config, INetworkManager networkManager, IDeviceManager deviceManager)
{
_userManager = userManager;
- _dtoService = dtoService;
_sessionMananger = sessionMananger;
_config = config;
_networkManager = networkManager;
@@ -591,22 +587,6 @@ namespace MediaBrowser.Api
Task.WaitAll(task);
}
- private void AssertCanUpdateUser(string userId)
- {
- var auth = AuthorizationContext.GetAuthorizationInfo(Request);
-
- // If they're going to update the record of another user, they must be an administrator
- if (!string.Equals(userId, auth.UserId, StringComparison.OrdinalIgnoreCase))
- {
- var authenticatedUser = _userManager.GetUserById(auth.UserId);
-
- if (!authenticatedUser.Policy.IsAdministrator)
- {
- throw new SecurityException("Unauthorized access.");
- }
- }
- }
-
public void Post(UpdateUserPolicy request)
{
var task = UpdateUserPolicy(request);
diff --git a/MediaBrowser.Model/Dlna/StreamBuilder.cs b/MediaBrowser.Model/Dlna/StreamBuilder.cs
index b798da748..5d0cd5203 100644
--- a/MediaBrowser.Model/Dlna/StreamBuilder.cs
+++ b/MediaBrowser.Model/Dlna/StreamBuilder.cs
@@ -25,19 +25,14 @@ namespace MediaBrowser.Model.Dlna
{
ValidateAudioInput(options);
- List mediaSources = options.MediaSources;
-
- // If the client wants a specific media source, filter now
- if (!string.IsNullOrEmpty(options.MediaSourceId))
+ List mediaSources = new List();
+ foreach (MediaSourceInfo i in options.MediaSources)
{
- List newMediaSources = new List();
- foreach (MediaSourceInfo i in mediaSources)
+ if (!string.IsNullOrEmpty(options.MediaSourceId) ||
+ StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId))
{
- if (StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId))
- newMediaSources.Add(i);
+ mediaSources.Add(i);
}
-
- mediaSources = newMediaSources;
}
List streams = new List();
@@ -63,19 +58,14 @@ namespace MediaBrowser.Model.Dlna
{
ValidateInput(options);
- List mediaSources = options.MediaSources;
-
- // If the client wants a specific media source, filter now
- if (!string.IsNullOrEmpty(options.MediaSourceId))
+ List mediaSources = new List();
+ foreach (MediaSourceInfo i in options.MediaSources)
{
- List newMediaSources = new List();
- foreach (MediaSourceInfo i in mediaSources)
+ if (!string.IsNullOrEmpty(options.MediaSourceId) ||
+ StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId))
{
- if (StringHelper.EqualsIgnoreCase(i.Id, options.MediaSourceId))
- newMediaSources.Add(i);
+ mediaSources.Add(i);
}
-
- mediaSources = newMediaSources;
}
List streams = new List();
diff --git a/MediaBrowser.Providers/FolderImages/DefaultImageProvider.cs b/MediaBrowser.Providers/FolderImages/DefaultImageProvider.cs
index 73a1de889..3550ee688 100644
--- a/MediaBrowser.Providers/FolderImages/DefaultImageProvider.cs
+++ b/MediaBrowser.Providers/FolderImages/DefaultImageProvider.cs
@@ -77,35 +77,35 @@ namespace MediaBrowser.Providers.FolderImages
if (string.Equals(viewType, CollectionType.Books, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "books.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.Games, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "games.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.Music, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "music.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.Photos, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "photos.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.TvShows, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "tv.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.Channels, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "channels.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.LiveTv, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "livetv.png";
+ return null;
}
if (string.Equals(viewType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase))
{
- return urlPrefix + "movies.png";
+ return null;
}
if (isSubView)
diff --git a/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs b/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs
index 326450ad4..a2d35b500 100644
--- a/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs
+++ b/MediaBrowser.Providers/Movies/LiveTvMovieDbProvider.cs
@@ -2,14 +2,13 @@
using MediaBrowser.Controller.LiveTv;
using MediaBrowser.Controller.Providers;
using MediaBrowser.Model.Providers;
-using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
namespace MediaBrowser.Providers.Movies
{
- public class LiveTvMovieDbProvider : IRemoteMetadataProvider, IDisposable, IHasOrder
+ public class LiveTvMovieDbProvider : IRemoteMetadataProvider, IHasOrder
{
public Task> GetSearchResults(LiveTvProgramLookupInfo searchInfo, CancellationToken cancellationToken)
{
@@ -31,10 +30,6 @@ namespace MediaBrowser.Providers.Movies
return MovieDbProvider.Current.GetImageResponse(url, cancellationToken);
}
- public void Dispose()
- {
- }
-
public int Order
{
get { return 1; }
diff --git a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
index 19b4939dd..192addfb8 100644
--- a/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
+++ b/MediaBrowser.Providers/Movies/MovieDbImageProvider.cs
@@ -61,9 +61,7 @@ namespace MediaBrowser.Providers.Movies
public IEnumerable GetSupportedImages(IHasImages item)
{
- var channelItem = item as ChannelVideoItem;
-
- if (channelItem != null)
+ if (item is ChannelVideoItem || item is LiveTvProgram)
{
// Too many channel items to allow backdrops here
return new List
diff --git a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
index 6b66ed9b8..41d8604de 100644
--- a/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
+++ b/MediaBrowser.Server.Implementations/LiveTv/LiveTvManager.cs
@@ -37,7 +37,6 @@ namespace MediaBrowser.Server.Implementations.LiveTv
public class LiveTvManager : ILiveTvManager, IDisposable
{
private readonly IServerConfigurationManager _config;
- private readonly IFileSystem _fileSystem;
private readonly ILogger _logger;
private readonly IItemRepository _itemRepo;
private readonly IUserManager _userManager;
@@ -63,10 +62,9 @@ namespace MediaBrowser.Server.Implementations.LiveTv
private readonly SemaphoreSlim _refreshSemaphore = new SemaphoreSlim(1, 1);
- public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, IFileSystem fileSystem, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
+ public LiveTvManager(IApplicationHost appHost, IServerConfigurationManager config, ILogger logger, IItemRepository itemRepo, IImageProcessor imageProcessor, IUserDataManager userDataManager, IDtoService dtoService, IUserManager userManager, ILibraryManager libraryManager, ITaskManager taskManager, ILocalizationManager localization, IJsonSerializer jsonSerializer, IProviderManager providerManager)
{
_config = config;
- _fileSystem = fileSystem;
_logger = logger;
_itemRepo = itemRepo;
_userManager = userManager;
@@ -474,11 +472,11 @@ namespace MediaBrowser.Server.Implementations.LiveTv
return item;
}
- private LiveTvProgram GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
+ private async Task GetProgram(ProgramInfo info, ChannelType channelType, string serviceName, CancellationToken cancellationToken)
{
var id = _tvDtoService.GetInternalProgramId(serviceName, info.Id);
- var item = _itemRepo.RetrieveItem(id) as LiveTvProgram;
+ var item = _libraryManager.GetItemById(id) as LiveTvProgram;
if (item == null)
{
@@ -521,6 +519,8 @@ namespace MediaBrowser.Server.Implementations.LiveTv
item.StartDate = info.StartDate;
item.ProductionYear = info.ProductionYear;
+ await item.UpdateToRepository(ItemUpdateType.MetadataImport, cancellationToken).ConfigureAwait(false);
+
return item;
}
@@ -992,9 +992,10 @@ namespace MediaBrowser.Server.Implementations.LiveTv
var channelPrograms = await service.GetProgramsAsync(currentChannel.ExternalId, start, end, cancellationToken).ConfigureAwait(false);
- var programEntities = channelPrograms.Select(program => GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken));
-
- programs.AddRange(programEntities);
+ foreach (var program in channelPrograms)
+ {
+ programs.Add(await GetProgram(program, currentChannel.ChannelType, service.Name, cancellationToken).ConfigureAwait(false));
+ }
}
catch (OperationCanceledException)
{
diff --git a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
index b3b79ae7e..4ff42c1fd 100644
--- a/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/Photos/BaseDynamicImageProvider.cs
@@ -60,7 +60,7 @@ namespace MediaBrowser.Server.Implementations.Photos
protected async Task FetchAsync(IHasImages item, ImageType imageType, MetadataRefreshOptions options, CancellationToken cancellationToken)
{
var items = await GetItemsWithImages(item).ConfigureAwait(false);
- var cacheKey = GetConfigurationCacheKey(items);
+ var cacheKey = GetConfigurationCacheKey(items, item.Name);
if (!HasChanged(item, imageType, cacheKey))
{
@@ -110,7 +110,7 @@ namespace MediaBrowser.Server.Implementations.Photos
public async Task GetImage(IHasImages item, ImageType type, CancellationToken cancellationToken)
{
var items = await GetItemsWithImages(item).ConfigureAwait(false);
- var cacheKey = GetConfigurationCacheKey(items);
+ var cacheKey = GetConfigurationCacheKey(items, item.Name);
var result = await CreateImageAsync(item, items, type, 0).ConfigureAwait(false);
@@ -126,9 +126,9 @@ namespace MediaBrowser.Server.Implementations.Photos
protected abstract Task> GetItemsWithImages(IHasImages item);
private const string Version = "3";
- protected string GetConfigurationCacheKey(List items)
+ protected string GetConfigurationCacheKey(List items, string itemName)
{
- return (Version + "_" + string.Join(",", items.Select(i => i.Id.ToString("N")).ToArray())).GetMD5().ToString("N");
+ return (Version + "_" + (itemName ?? string.Empty) + "_" + string.Join(",", items.Select(i => i.Id.ToString("N")).ToArray())).GetMD5().ToString("N");
}
protected Task GetThumbCollage(List items)
@@ -185,7 +185,7 @@ namespace MediaBrowser.Server.Implementations.Photos
}
var items = GetItemsWithImages(item).Result;
- var cacheKey = GetConfigurationCacheKey(items);
+ var cacheKey = GetConfigurationCacheKey(items, item.Name);
return HasChanged(item, ImageType.Primary, cacheKey) || HasChanged(item, ImageType.Thumb, cacheKey);
}
diff --git a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
index c47a116ca..6ea3233f2 100644
--- a/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
+++ b/MediaBrowser.Server.Implementations/UserViews/DynamicImageProvider.cs
@@ -227,7 +227,9 @@ namespace MediaBrowser.Server.Implementations.UserViews
CollectionType.BoxSets,
CollectionType.Playlists,
CollectionType.Channels,
- CollectionType.LiveTv
+ CollectionType.LiveTv,
+ CollectionType.Books,
+ CollectionType.Photos
};
return collectionStripViewTypes.Contains(view.ViewType ?? string.Empty);
@@ -235,6 +237,11 @@ namespace MediaBrowser.Server.Implementations.UserViews
protected override Task CreateImageAsync(IHasImages item, List itemsWithImages, ImageType imageType, int imageIndex)
{
+ if (itemsWithImages.Count == 0)
+ {
+ return null;
+ }
+
var view = (UserView)item;
if (imageType == ImageType.Primary && IsUsingCollectionStrip(view))
{
diff --git a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
index e80f94e15..0173000cf 100644
--- a/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
+++ b/MediaBrowser.Server.Startup.Common/ApplicationHost.cs
@@ -495,7 +495,7 @@ namespace MediaBrowser.Server.Startup.Common
PlaylistManager = new PlaylistManager(LibraryManager, FileSystemManager, LibraryMonitor, LogManager.GetLogger("PlaylistManager"), UserManager);
RegisterSingleInstance(PlaylistManager);
- LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, FileSystemManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager);
+ LiveTvManager = new LiveTvManager(this, ServerConfigurationManager, Logger, ItemRepository, ImageProcessor, UserDataManager, DtoService, UserManager, LibraryManager, TaskManager, LocalizationManager, JsonSerializer, ProviderManager);
RegisterSingleInstance(LiveTvManager);
UserViewManager = new UserViewManager(LibraryManager, LocalizationManager, UserManager, ChannelManager, LiveTvManager, PlaylistManager, CollectionManager, ServerConfigurationManager);