mirror of
				https://github.com/jellyfin/jellyfin.git
				synced 2025-10-31 10:37:22 -04:00 
			
		
		
		
	enable user device access
This commit is contained in:
		
							parent
							
								
									800a16a213
								
							
						
					
					
						commit
						8a9f16ff6a
					
				| @ -1,4 +1,5 @@ | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Controller.Devices; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Controller.Net; | ||||
| using MediaBrowser.Controller.Security; | ||||
| using MediaBrowser.Controller.Session; | ||||
| @ -299,6 +300,7 @@ namespace MediaBrowser.Api.Session | ||||
|         private readonly IUserManager _userManager; | ||||
|         private readonly IAuthorizationContext _authContext; | ||||
|         private readonly IAuthenticationRepository _authRepo; | ||||
|         private readonly IDeviceManager _deviceManager; | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Initializes a new instance of the <see cref="SessionsService" /> class. | ||||
| @ -307,12 +309,13 @@ namespace MediaBrowser.Api.Session | ||||
|         /// <param name="userManager">The user manager.</param> | ||||
|         /// <param name="authContext">The authentication context.</param> | ||||
|         /// <param name="authRepo">The authentication repo.</param> | ||||
|         public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext, IAuthenticationRepository authRepo) | ||||
|         public SessionsService(ISessionManager sessionManager, IUserManager userManager, IAuthorizationContext authContext, IAuthenticationRepository authRepo, IDeviceManager deviceManager) | ||||
|         { | ||||
|             _sessionManager = sessionManager; | ||||
|             _userManager = userManager; | ||||
|             _authContext = authContext; | ||||
|             _authRepo = authRepo; | ||||
|             _deviceManager = deviceManager; | ||||
|         } | ||||
| 
 | ||||
|         public void Delete(RevokeKey request) | ||||
| @ -382,6 +385,21 @@ namespace MediaBrowser.Api.Session | ||||
|                 { | ||||
|                     result = result.Where(i => !i.UserId.HasValue); | ||||
|                 } | ||||
| 
 | ||||
|                 result = result.Where(i => | ||||
|                 { | ||||
|                     var deviceId = i.DeviceId; | ||||
| 
 | ||||
|                     if (!string.IsNullOrWhiteSpace(deviceId)) | ||||
|                     { | ||||
|                         if (!_deviceManager.CanAccessDevice(user.Id.ToString("N"), deviceId)) | ||||
|                         { | ||||
|                             return false; | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     return true; | ||||
|                 }); | ||||
|             } | ||||
| 
 | ||||
|             return ToOptimizedResult(result.Select(_sessionManager.GetSessionInfoDto).ToList()); | ||||
|  | ||||
| @ -52,6 +52,10 @@ | ||||
|       <SpecificVersion>False</SpecificVersion> | ||||
|       <HintPath>..\packages\NLog.3.1.0.0\lib\net45\NLog.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="SharpCompress, Version=0.10.2.0, Culture=neutral, PublicKeyToken=beaf6f427e128133, processorArchitecture=MSIL"> | ||||
|       <SpecificVersion>False</SpecificVersion> | ||||
|       <HintPath>..\ThirdParty\SharpCompress\SharpCompress.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="SimpleInjector, Version=2.6.1.0, Culture=neutral, PublicKeyToken=984cb50dea722e99, processorArchitecture=MSIL"> | ||||
|       <SpecificVersion>False</SpecificVersion> | ||||
|       <HintPath>..\packages\SimpleInjector.2.6.1\lib\net45\SimpleInjector.dll</HintPath> | ||||
| @ -65,9 +69,6 @@ | ||||
|     <Reference Include="Microsoft.CSharp" /> | ||||
|     <Reference Include="System.Net" /> | ||||
|     <Reference Include="System.Xml" /> | ||||
|     <Reference Include="SharpCompress"> | ||||
|       <HintPath>..\packages\sharpcompress.0.10.2\lib\net40\SharpCompress.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="ServiceStack.Text"> | ||||
|       <HintPath>..\ThirdParty\ServiceStack.Text\ServiceStack.Text.dll</HintPath> | ||||
|     </Reference> | ||||
|  | ||||
| @ -1,6 +1,5 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <packages> | ||||
|   <package id="NLog" version="3.1.0.0" targetFramework="net45" /> | ||||
|   <package id="SharpCompress" version="0.10.2" targetFramework="net45" /> | ||||
|   <package id="SimpleInjector" version="2.6.1" targetFramework="net45" /> | ||||
| </packages> | ||||
|  | ||||
| @ -85,5 +85,13 @@ namespace MediaBrowser.Controller.Devices | ||||
|         /// <param name="file">The file.</param> | ||||
|         /// <returns>Task.</returns> | ||||
|         Task AcceptCameraUpload(string deviceId, Stream stream, LocalFileInfo file); | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Determines whether this instance [can access device] the specified user identifier. | ||||
|         /// </summary> | ||||
|         /// <param name="userId">The user identifier.</param> | ||||
|         /// <param name="deviceId">The device identifier.</param> | ||||
|         /// <returns><c>true</c> if this instance [can access device] the specified user identifier; otherwise, <c>false</c>.</returns> | ||||
|         bool CanAccessDevice(string userId, string deviceId); | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -89,6 +89,21 @@ namespace MediaBrowser.Controller.Entities.Audio | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         [IgnoreDataMember] | ||||
|         public bool IsArchive | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (string.IsNullOrWhiteSpace(Path)) | ||||
|                 { | ||||
|                     return false; | ||||
|                 } | ||||
|                 var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; | ||||
| 
 | ||||
|                 return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets or sets the artist. | ||||
|         /// </summary> | ||||
|  | ||||
| @ -91,6 +91,21 @@ namespace MediaBrowser.Controller.Entities | ||||
|             get { return LocalAlternateVersions.Count > 0; } | ||||
|         } | ||||
| 
 | ||||
|         [IgnoreDataMember] | ||||
|         public bool IsArchive | ||||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if (string.IsNullOrWhiteSpace(Path)) | ||||
|                 { | ||||
|                     return false; | ||||
|                 } | ||||
|                 var ext = System.IO.Path.GetExtension(Path) ?? string.Empty; | ||||
| 
 | ||||
|                 return new[] { ".zip", ".rar", ".7z" }.Contains(ext, StringComparer.OrdinalIgnoreCase); | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public IEnumerable<Guid> GetAdditionalPartIds() | ||||
|         { | ||||
|             return AdditionalParts.Select(i => LibraryManager.GetNewItemId(i, typeof(Video))); | ||||
| @ -246,7 +261,7 @@ namespace MediaBrowser.Controller.Entities | ||||
|                     { | ||||
|                         return System.IO.Path.GetFileName(Path); | ||||
|                     } | ||||
|                      | ||||
| 
 | ||||
|                     return System.IO.Path.GetFileNameWithoutExtension(Path); | ||||
|                 } | ||||
| 
 | ||||
|  | ||||
| @ -73,10 +73,18 @@ namespace MediaBrowser.Model.Net | ||||
|                 {".m4v", "video/x-m4v"} | ||||
|             }; | ||||
| 
 | ||||
|         private static readonly Dictionary<string, string> ExtensionLookup = | ||||
|            MimeTypeLookup | ||||
|            .GroupBy(i => i.Value) | ||||
|            .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); | ||||
|         private static readonly Dictionary<string, string> ExtensionLookup = CreateExtensionLookup(); | ||||
| 
 | ||||
|         private static Dictionary<string, string> CreateExtensionLookup() | ||||
|         { | ||||
|             var dict = MimeTypeLookup | ||||
|                 .GroupBy(i => i.Value) | ||||
|                 .ToDictionary(x => x.Key, x => x.First().Key, StringComparer.OrdinalIgnoreCase); | ||||
| 
 | ||||
|             dict["image/jpg"] = ".jpg"; | ||||
| 
 | ||||
|             return dict; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Gets the type of the MIME. | ||||
|  | ||||
| @ -49,6 +49,9 @@ namespace MediaBrowser.Model.Users | ||||
|         /// <value><c>true</c> if [enable synchronize]; otherwise, <c>false</c>.</value> | ||||
|         public bool EnableSync { get; set; } | ||||
| 
 | ||||
|         public string[] EnabledDevices { get; set; } | ||||
|         public bool EnableAllDevices { get; set; } | ||||
| 
 | ||||
|         public UserPolicy() | ||||
|         { | ||||
|             EnableLiveTvManagement = true; | ||||
| @ -64,6 +67,9 @@ namespace MediaBrowser.Model.Users | ||||
|             EnableUserPreferenceAccess = true; | ||||
| 
 | ||||
|             AccessSchedules = new AccessSchedule[] { }; | ||||
| 
 | ||||
|             EnabledDevices = new string[] { }; | ||||
|             EnableAllDevices = true; | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -6,7 +6,6 @@ using MediaBrowser.Controller.Entities.Audio; | ||||
| using MediaBrowser.Controller.MediaEncoding; | ||||
| using MediaBrowser.Controller.Providers; | ||||
| using MediaBrowser.Model.Entities; | ||||
| using System; | ||||
| using System.Collections.Concurrent; | ||||
| using System.Collections.Generic; | ||||
| using System.IO; | ||||
| @ -132,7 +131,9 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
| 
 | ||||
|         public bool Supports(IHasImages item) | ||||
|         { | ||||
|             return item is Audio; | ||||
|             var audio = item as Audio; | ||||
| 
 | ||||
|             return item.LocationType == LocationType.FileSystem && audio != null && !audio.IsArchive; | ||||
|         } | ||||
| 
 | ||||
|         public bool HasChanged(IHasMetadata item, MetadataStatus status, IDirectoryService directoryService) | ||||
|  | ||||
| @ -38,6 +38,13 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|         public async Task<ItemUpdateType> Probe<T>(T item, CancellationToken cancellationToken) | ||||
|             where T : Audio | ||||
|         { | ||||
|             if (item.IsArchive) | ||||
|             { | ||||
|                 var ext = Path.GetExtension(item.Path) ?? string.Empty; | ||||
|                 item.Container = ext.TrimStart('.'); | ||||
|                 return ItemUpdateType.MetadataImport; | ||||
|             } | ||||
| 
 | ||||
|             var result = await GetMediaInfo(item, cancellationToken).ConfigureAwait(false); | ||||
| 
 | ||||
|             cancellationToken.ThrowIfCancellationRequested(); | ||||
| @ -58,8 +65,8 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|             cancellationToken.ThrowIfCancellationRequested(); | ||||
| 
 | ||||
|             var idString = item.Id.ToString("N"); | ||||
|             var cachePath = Path.Combine(_appPaths.CachePath,  | ||||
|                 "ffprobe-audio",  | ||||
|             var cachePath = Path.Combine(_appPaths.CachePath, | ||||
|                 "ffprobe-audio", | ||||
|                 idString.Substring(0, 2), idString, "v" + SchemaVersion + _mediaEncoder.Version + item.DateModified.Ticks.ToString(_usCulture) + ".json"); | ||||
| 
 | ||||
|             try | ||||
| @ -132,7 +139,7 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
| 
 | ||||
|                 if (!string.IsNullOrEmpty(data.format.size)) | ||||
|                 { | ||||
|                     audio.Size = long.Parse(data.format.size , _usCulture); | ||||
|                     audio.Size = long.Parse(data.format.size, _usCulture); | ||||
|                 } | ||||
|                 else | ||||
|                 { | ||||
| @ -217,9 +224,9 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|             audio.ProductionYear = FFProbeHelpers.GetDictionaryNumericValue(tags, "date"); | ||||
| 
 | ||||
|             // Several different forms of retaildate | ||||
|             audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ??  | ||||
|                 FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ??  | ||||
|                 FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ??  | ||||
|             audio.PremiereDate = FFProbeHelpers.GetDictionaryDateTime(tags, "retaildate") ?? | ||||
|                 FFProbeHelpers.GetDictionaryDateTime(tags, "retail date") ?? | ||||
|                 FFProbeHelpers.GetDictionaryDateTime(tags, "retail_date") ?? | ||||
|                 FFProbeHelpers.GetDictionaryDateTime(tags, "date"); | ||||
| 
 | ||||
|             // If we don't have a ProductionYear try and get it from PremiereDate | ||||
| @ -261,8 +268,8 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|         { | ||||
|             // Only use the comma as a delimeter if there are no slashes or pipes.  | ||||
|             // We want to be careful not to split names that have commas in them | ||||
|             var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ?  | ||||
|                 _nameDelimiters :  | ||||
|             var delimeter = !allowCommaDelimiter || _nameDelimiters.Any(i => val.IndexOf(i) != -1) ? | ||||
|                 _nameDelimiters : | ||||
|                 new[] { ',' }; | ||||
| 
 | ||||
|             return val.Split(delimeter, StringSplitOptions.RemoveEmptyEntries) | ||||
|  | ||||
| @ -71,6 +71,13 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|             CancellationToken cancellationToken) | ||||
|             where T : Video | ||||
|         { | ||||
|             if (item.IsArchive) | ||||
|             { | ||||
|                 var ext = Path.GetExtension(item.Path) ?? string.Empty; | ||||
|                 item.Container = ext.TrimStart('.'); | ||||
|                 return ItemUpdateType.MetadataImport; | ||||
|             } | ||||
| 
 | ||||
|             var isoMount = await MountIsoIfNeeded(item, cancellationToken).ConfigureAwait(false); | ||||
| 
 | ||||
|             BlurayDiscInfo blurayDiscInfo = null; | ||||
|  | ||||
| @ -123,7 +123,7 @@ namespace MediaBrowser.Providers.MediaInfo | ||||
|         { | ||||
|             var video = item as Video; | ||||
| 
 | ||||
|             return item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut; | ||||
|             return item.LocationType == LocationType.FileSystem && video != null && !video.IsPlaceHolder && !video.IsShortcut && !video.IsArchive; | ||||
|         } | ||||
| 
 | ||||
|         public int Order | ||||
|  | ||||
| @ -5,6 +5,7 @@ using MediaBrowser.Controller.Devices; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Model.Devices; | ||||
| using MediaBrowser.Model.Events; | ||||
| using MediaBrowser.Model.Extensions; | ||||
| using MediaBrowser.Model.Logging; | ||||
| using MediaBrowser.Model.Querying; | ||||
| using MediaBrowser.Model.Session; | ||||
| @ -13,6 +14,7 @@ using System.Collections.Generic; | ||||
| using System.IO; | ||||
| using System.Linq; | ||||
| using System.Threading.Tasks; | ||||
| using MediaBrowser.Model.Users; | ||||
| 
 | ||||
| namespace MediaBrowser.Server.Implementations.Devices | ||||
| { | ||||
| @ -188,6 +190,41 @@ namespace MediaBrowser.Server.Implementations.Devices | ||||
| 
 | ||||
|             EventHelper.FireEventIfNotNull(DeviceOptionsUpdated, this, new GenericEventArgs<DeviceInfo>(device), _logger); | ||||
|         } | ||||
| 
 | ||||
|         public bool CanAccessDevice(string userId, string deviceId) | ||||
|         { | ||||
|             if (string.IsNullOrWhiteSpace(userId)) | ||||
|             { | ||||
|                 throw new ArgumentNullException("userId"); | ||||
|             } | ||||
|             if (string.IsNullOrWhiteSpace(deviceId)) | ||||
|             { | ||||
|                 throw new ArgumentNullException("deviceId"); | ||||
|             } | ||||
| 
 | ||||
|             var user = _userManager.GetUserById(userId); | ||||
|             if (!CanAccessDevice(user.Policy, deviceId)) | ||||
|             { | ||||
|                 var capabilities = GetCapabilities(deviceId); | ||||
| 
 | ||||
|                 if (capabilities.SupportsUniqueIdentifier) | ||||
|                 { | ||||
|                     return false; | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             return true; | ||||
|         } | ||||
| 
 | ||||
|         private bool CanAccessDevice(UserPolicy policy, string id) | ||||
|         { | ||||
|             if (policy.EnableAllDevices) | ||||
|             { | ||||
|                 return true; | ||||
|             } | ||||
| 
 | ||||
|             return ListHelper.ContainsIgnoreCase(policy.EnabledDevices, id); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     public class DevicesConfigStore : IConfigurationFactory | ||||
|  | ||||
| @ -1,5 +1,6 @@ | ||||
| using MediaBrowser.Controller.Configuration; | ||||
| using MediaBrowser.Controller.Connect; | ||||
| using MediaBrowser.Controller.Devices; | ||||
| using MediaBrowser.Controller.Entities; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Controller.Net; | ||||
| @ -15,10 +16,11 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security | ||||
|     { | ||||
|         private readonly IServerConfigurationManager _config; | ||||
| 
 | ||||
|         public AuthService(IUserManager userManager, IAuthorizationContext authorizationContext, IServerConfigurationManager config, IConnectManager connectManager, ISessionManager sessionManager) | ||||
|         public AuthService(IUserManager userManager, IAuthorizationContext authorizationContext, IServerConfigurationManager config, IConnectManager connectManager, ISessionManager sessionManager, IDeviceManager deviceManager) | ||||
|         { | ||||
|             AuthorizationContext = authorizationContext; | ||||
|             _config = config; | ||||
|             DeviceManager = deviceManager; | ||||
|             SessionManager = sessionManager; | ||||
|             ConnectManager = connectManager; | ||||
|             UserManager = userManager; | ||||
| @ -28,6 +30,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security | ||||
|         public IAuthorizationContext AuthorizationContext { get; private set; } | ||||
|         public IConnectManager ConnectManager { get; private set; } | ||||
|         public ISessionManager SessionManager { get; private set; } | ||||
|         public IDeviceManager DeviceManager { get; private set; } | ||||
| 
 | ||||
|         /// <summary> | ||||
|         /// Redirect the client to a specific URL if authentication failed. | ||||
| @ -68,24 +71,7 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security | ||||
| 
 | ||||
|             if (user != null) | ||||
|             { | ||||
|                 if (user.Policy.IsDisabled) | ||||
|                 { | ||||
|                     throw new SecurityException("User account has been disabled.") | ||||
|                     { | ||||
|                         SecurityExceptionType = SecurityExceptionType.Unauthenticated | ||||
|                     }; | ||||
|                 } | ||||
| 
 | ||||
|                 if (!user.Policy.IsAdministrator && | ||||
|                     !authAttribtues.EscapeParentalControl && | ||||
|                     !user.IsParentalScheduleAllowed()) | ||||
|                 { | ||||
|                     request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); | ||||
|                     throw new SecurityException("This user account is not allowed access at this time.") | ||||
|                     { | ||||
|                         SecurityExceptionType = SecurityExceptionType.ParentalControl | ||||
|                     }; | ||||
|                 } | ||||
|                 ValidateUserAccess(user, request, authAttribtues, auth); | ||||
|             } | ||||
| 
 | ||||
|             if (!IsExemptFromRoles(auth, authAttribtues)) | ||||
| @ -108,6 +94,42 @@ namespace MediaBrowser.Server.Implementations.HttpServer.Security | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private void ValidateUserAccess(User user, IServiceRequest request, | ||||
|             IAuthenticationAttributes authAttribtues, | ||||
|             AuthorizationInfo auth) | ||||
|         { | ||||
|             if (user.Policy.IsDisabled) | ||||
|             { | ||||
|                 throw new SecurityException("User account has been disabled.") | ||||
|                 { | ||||
|                     SecurityExceptionType = SecurityExceptionType.Unauthenticated | ||||
|                 }; | ||||
|             } | ||||
| 
 | ||||
|             if (!user.Policy.IsAdministrator && | ||||
|                 !authAttribtues.EscapeParentalControl && | ||||
|                 !user.IsParentalScheduleAllowed()) | ||||
|             { | ||||
|                 request.AddResponseHeader("X-Application-Error-Code", "ParentalControl"); | ||||
| 
 | ||||
|                 throw new SecurityException("This user account is not allowed access at this time.") | ||||
|                 { | ||||
|                     SecurityExceptionType = SecurityExceptionType.ParentalControl | ||||
|                 }; | ||||
|             } | ||||
| 
 | ||||
|             if (!string.IsNullOrWhiteSpace(auth.DeviceId)) | ||||
|             { | ||||
|                 if (!DeviceManager.CanAccessDevice(user.Id.ToString("N"), auth.DeviceId)) | ||||
|                 { | ||||
|                     throw new SecurityException("User is not allowed access from this device.") | ||||
|                     { | ||||
|                         SecurityExceptionType = SecurityExceptionType.ParentalControl | ||||
|                     }; | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private bool IsExemptFromAuthenticationToken(AuthorizationInfo auth, IAuthenticationAttributes authAttribtues) | ||||
|         { | ||||
|             if (!_config.Configuration.IsStartupWizardCompleted && | ||||
|  | ||||
| @ -25,11 +25,6 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|             // Contains [boxset] in the path | ||||
|             if (args.IsDirectory) | ||||
|             { | ||||
|                 if (IsInvalid(args.GetCollectionType())) | ||||
|                 { | ||||
|                     return null; | ||||
|                 } | ||||
|                  | ||||
|                 var filename = Path.GetFileName(args.Path); | ||||
| 
 | ||||
|                 if (string.IsNullOrEmpty(filename)) | ||||
|  | ||||
| @ -1,12 +1,9 @@ | ||||
| using MediaBrowser.Common.IO; | ||||
| using MediaBrowser.Controller; | ||||
| using MediaBrowser.Controller.Entities; | ||||
| using MediaBrowser.Controller.Entities; | ||||
| using MediaBrowser.Controller.Entities.Movies; | ||||
| using MediaBrowser.Controller.Library; | ||||
| using MediaBrowser.Controller.Providers; | ||||
| using MediaBrowser.Controller.Resolvers; | ||||
| using MediaBrowser.Model.Entities; | ||||
| using MediaBrowser.Model.Logging; | ||||
| using MediaBrowser.Naming.Common; | ||||
| using MediaBrowser.Naming.IO; | ||||
| using MediaBrowser.Naming.Video; | ||||
| @ -22,16 +19,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|     /// </summary> | ||||
|     public class MovieResolver : BaseVideoResolver<Video>, IMultiItemResolver | ||||
|     { | ||||
|         private readonly IServerApplicationPaths _applicationPaths; | ||||
|         private readonly ILogger _logger; | ||||
|         private readonly IFileSystem _fileSystem; | ||||
| 
 | ||||
|         public MovieResolver(ILibraryManager libraryManager, IServerApplicationPaths applicationPaths, ILogger logger, IFileSystem fileSystem) | ||||
|             : base(libraryManager) | ||||
|         public MovieResolver(ILibraryManager libraryManager) : base(libraryManager) | ||||
|         { | ||||
|             _applicationPaths = applicationPaths; | ||||
|             _logger = logger; | ||||
|             _fileSystem = fileSystem; | ||||
|         } | ||||
| 
 | ||||
|         /// <summary> | ||||
| @ -62,12 +51,12 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
| 
 | ||||
|             if (string.Equals(collectionType, CollectionType.MusicVideos, StringComparison.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return ResolveVideos<MusicVideo>(parent, files, directoryService, collectionType); | ||||
|                 return ResolveVideos<MusicVideo>(parent, files, directoryService, collectionType, false); | ||||
|             } | ||||
| 
 | ||||
|             if (string.Equals(collectionType, CollectionType.HomeVideos, StringComparison.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return ResolveVideos<Video>(parent, files, directoryService, collectionType); | ||||
|                 return ResolveVideos<Video>(parent, files, directoryService, collectionType, false); | ||||
|             } | ||||
| 
 | ||||
|             if (string.IsNullOrEmpty(collectionType)) | ||||
| @ -75,21 +64,21 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|                 // Owned items should just use the plain video type | ||||
|                 if (parent == null) | ||||
|                 { | ||||
|                     return ResolveVideos<Video>(parent, files, directoryService, collectionType); | ||||
|                     return ResolveVideos<Video>(parent, files, directoryService, collectionType, false); | ||||
|                 } | ||||
| 
 | ||||
|                 return ResolveVideos<Video>(parent, files, directoryService, collectionType); | ||||
|                 return ResolveVideos<Video>(parent, files, directoryService, collectionType, false); | ||||
|             } | ||||
| 
 | ||||
|             if (string.Equals(collectionType, CollectionType.Movies, StringComparison.OrdinalIgnoreCase)) | ||||
|             { | ||||
|                 return ResolveVideos<Movie>(parent, files, directoryService, collectionType); | ||||
|                 return ResolveVideos<Movie>(parent, files, directoryService, collectionType, false); | ||||
|             } | ||||
| 
 | ||||
|             return null; | ||||
|         } | ||||
| 
 | ||||
|         private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType) | ||||
|         private MultiItemResolverResult ResolveVideos<T>(Folder parent, IEnumerable<FileSystemInfo> fileSystemEntries, IDirectoryService directoryService, string collectionType, bool suppportMultiEditions) | ||||
|             where T : Video, new() | ||||
|         { | ||||
|             var files = new List<FileSystemInfo>(); | ||||
| @ -115,7 +104,7 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|                 FullName = i.FullName, | ||||
|                 Type = FileInfoType.File | ||||
| 
 | ||||
|             }).ToList(), false).ToList(); | ||||
|             }).ToList(), suppportMultiEditions).ToList(); | ||||
| 
 | ||||
|             var result = new MultiItemResolverResult | ||||
|             { | ||||
| @ -135,7 +124,8 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|                     IsInMixedFolder = isInMixedFolder, | ||||
|                     ProductionYear = video.Year, | ||||
|                     Name = video.Name, | ||||
|                     AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToList() | ||||
|                     AdditionalParts = video.Files.Skip(1).Select(i => i.Path).ToList(), | ||||
|                     LocalAlternateVersions = video.AlternateVersions.Select(i => i.Path).ToList() | ||||
|                 }; | ||||
| 
 | ||||
|                 SetVideoType(videoItem, firstVideo); | ||||
| @ -314,32 +304,11 @@ namespace MediaBrowser.Server.Implementations.Library.Resolvers.Movies | ||||
|                     return movie; | ||||
|                 } | ||||
|             } | ||||
|              | ||||
|             var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, collectionType); | ||||
| 
 | ||||
|             var supportsMultiVersion = !string.Equals(collectionType, CollectionType.HomeVideos) && | ||||
|                                        !string.Equals(collectionType, CollectionType.MusicVideos); | ||||
|                                     !string.Equals(collectionType, CollectionType.MusicVideos); | ||||
| 
 | ||||
|             // Test for multi-editions | ||||
|             if (result.Items.Count > 1 && supportsMultiVersion) | ||||
|             { | ||||
|                 var filenamePrefix = Path.GetFileName(path); | ||||
| 
 | ||||
|                 if (!string.IsNullOrWhiteSpace(filenamePrefix)) | ||||
|                 { | ||||
|                     if (result.Items.All(i => _fileSystem.GetFileNameWithoutExtension(i.Path).StartsWith(filenamePrefix + " - ", StringComparison.OrdinalIgnoreCase))) | ||||
|                     { | ||||
|                         var movie = (T)result.Items[0]; | ||||
|                         movie.Name = filenamePrefix; | ||||
|                         movie.LocalAlternateVersions = result.Items.Skip(1).Select(i => i.Path).ToList(); | ||||
|                         movie.IsInMixedFolder = false; | ||||
| 
 | ||||
|                         _logger.Debug("Multi-version video found: " + movie.Path); | ||||
| 
 | ||||
|                         return movie; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             var result = ResolveVideos<T>(parent, fileSystemEntries, directoryService, collectionType, supportsMultiVersion); | ||||
| 
 | ||||
|             if (result.Items.Count == 1) | ||||
|             { | ||||
|  | ||||
| @ -41,6 +41,10 @@ | ||||
|     "LabelCancelled": "(cancelled)", | ||||
|     "LabelFailed": "(failed)", | ||||
|     "ButtonHelp": "Help", | ||||
|     "HeaderLibraryAccess": "Library Access", | ||||
|     "HeaderChannelAccess": "Channel Access", | ||||
|     "HeaderDeviceAccess": "Device Access", | ||||
|     "HeaderSelectDevices": "Select Devices", | ||||
|     "LabelAbortedByServerShutdown": "(Aborted by server shutdown)", | ||||
|     "LabelScheduledTaskLastRan": "Last ran {0}, taking {1}.", | ||||
|     "HeaderDeleteTaskTrigger": "Delete Task Trigger", | ||||
|  | ||||
| @ -63,12 +63,16 @@ | ||||
|     "TabPreferences": "Preferences", | ||||
|     "TabPassword": "Password", | ||||
|     "TabLibraryAccess": "Library Access", | ||||
|     "TabAccess": "Access", | ||||
|     "TabImage": "Image", | ||||
|     "TabProfile": "Profile", | ||||
|     "TabMetadata": "Metadata", | ||||
|     "TabImages": "Images", | ||||
|     "TabNotifications": "Notifications", | ||||
|     "TabCollectionTitles": "Titles", | ||||
|     "HeaderDeviceAccess": "Device Access", | ||||
|     "OptionEnableAccessFromAllDevices": "Enable access from all devices", | ||||
|     "DeviceAccessHelp": "This only applies to devices that can be uniquely identified and will not prevent browser access.", | ||||
|     "LabelDisplayMissingEpisodesWithinSeasons": "Display missing episodes within seasons", | ||||
|     "LabelUnairedMissingEpisodesWithinSeasons": "Display unaired episodes within seasons", | ||||
|     "HeaderVideoPlaybackSettings": "Video Playback Settings", | ||||
|  | ||||
| @ -51,7 +51,7 @@ | ||||
|     </Reference> | ||||
|     <Reference Include="MediaBrowser.Naming, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL"> | ||||
|       <SpecificVersion>False</SpecificVersion> | ||||
|       <HintPath>..\packages\MediaBrowser.Naming.1.0.0.23\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath> | ||||
|       <HintPath>..\packages\MediaBrowser.Naming.1.0.0.24\lib\portable-net45+sl4+wp71+win8+wpa81\MediaBrowser.Naming.dll</HintPath> | ||||
|     </Reference> | ||||
|     <Reference Include="Mono.Nat, Version=1.2.21.0, Culture=neutral, processorArchitecture=MSIL"> | ||||
|       <SpecificVersion>False</SpecificVersion> | ||||
|  | ||||
| @ -1191,6 +1191,14 @@ namespace MediaBrowser.Server.Implementations.Session | ||||
|             var user = _userManager.Users | ||||
|                 .FirstOrDefault(i => string.Equals(request.Username, i.Name, StringComparison.OrdinalIgnoreCase)); | ||||
| 
 | ||||
|             if (user != null && !string.IsNullOrWhiteSpace(request.DeviceId)) | ||||
|             { | ||||
|                 if (!_deviceManager.CanAccessDevice(user.Id.ToString("N"), request.DeviceId)) | ||||
|                 { | ||||
|                     throw new UnauthorizedAccessException("User is not allowed access from this device."); | ||||
|                 } | ||||
|             } | ||||
| 
 | ||||
|             var result = await _userManager.AuthenticateUser(request.Username, request.PasswordSha1, request.PasswordMd5, request.RemoteEndPoint).ConfigureAwait(false); | ||||
| 
 | ||||
|             if (!result) | ||||
|  | ||||
| @ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <packages> | ||||
|   <package id="MediaBrowser.Naming" version="1.0.0.23" targetFramework="net45" /> | ||||
|   <package id="MediaBrowser.Naming" version="1.0.0.24" targetFramework="net45" /> | ||||
|   <package id="Mono.Nat" version="1.2.21.0" targetFramework="net45" /> | ||||
|   <package id="morelinq" version="1.1.0" targetFramework="net45" /> | ||||
| </packages> | ||||
| @ -558,7 +558,7 @@ namespace MediaBrowser.Server.Startup.Common | ||||
|             var authContext = new AuthorizationContext(AuthenticationRepository); | ||||
|             RegisterSingleInstance<IAuthorizationContext>(authContext); | ||||
|             RegisterSingleInstance<ISessionContext>(new SessionContext(UserManager, authContext, SessionManager)); | ||||
|             RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager)); | ||||
|             RegisterSingleInstance<IAuthService>(new AuthService(UserManager, authContext, ServerConfigurationManager, ConnectManager, SessionManager, DeviceManager)); | ||||
| 
 | ||||
|             RegisterSingleInstance<ISubtitleEncoder>(new SubtitleEncoder(LibraryManager, LogManager.GetLogger("SubtitleEncoder"), ApplicationPaths, FileSystemManager, MediaEncoder, JsonSerializer)); | ||||
| 
 | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> | ||||
|     <metadata> | ||||
|         <id>MediaBrowser.Common.Internal</id> | ||||
|         <version>3.0.537</version> | ||||
|         <version>3.0.538</version> | ||||
|         <title>MediaBrowser.Common.Internal</title> | ||||
|         <authors>Luke</authors> | ||||
|         <owners>ebr,Luke,scottisafool</owners> | ||||
| @ -12,10 +12,9 @@ | ||||
|         <description>Contains common components shared by Media Browser Theater and Media Browser Server. Not intended for plugin developer consumption.</description> | ||||
|         <copyright>Copyright © Media Browser 2013</copyright> | ||||
|         <dependencies> | ||||
|             <dependency id="MediaBrowser.Common" version="3.0.537" /> | ||||
|             <dependency id="MediaBrowser.Common" version="3.0.538" /> | ||||
|             <dependency id="NLog" version="3.1.0.0" /> | ||||
|             <dependency id="SimpleInjector" version="2.6.1" /> | ||||
|             <dependency id="sharpcompress" version="0.10.2" /> | ||||
|         </dependencies> | ||||
|     </metadata> | ||||
|     <files> | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> | ||||
|     <metadata> | ||||
|         <id>MediaBrowser.Common</id> | ||||
|         <version>3.0.537</version> | ||||
|         <version>3.0.538</version> | ||||
|         <title>MediaBrowser.Common</title> | ||||
|         <authors>Media Browser Team</authors> | ||||
|         <owners>ebr,Luke,scottisafool</owners> | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| <package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd"> | ||||
|     <metadata> | ||||
|         <id>MediaBrowser.Model.Signed</id> | ||||
|         <version>3.0.537</version> | ||||
|         <version>3.0.538</version> | ||||
|         <title>MediaBrowser.Model - Signed Edition</title> | ||||
|         <authors>Media Browser Team</authors> | ||||
|         <owners>ebr,Luke,scottisafool</owners> | ||||
|  | ||||
| @ -2,7 +2,7 @@ | ||||
| <package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd"> | ||||
|     <metadata> | ||||
|         <id>MediaBrowser.Server.Core</id> | ||||
|         <version>3.0.537</version> | ||||
|         <version>3.0.538</version> | ||||
|         <title>Media Browser.Server.Core</title> | ||||
|         <authors>Media Browser Team</authors> | ||||
|         <owners>ebr,Luke,scottisafool</owners> | ||||
| @ -12,7 +12,7 @@ | ||||
|         <description>Contains core components required to build plugins for Media Browser Server.</description> | ||||
|         <copyright>Copyright © Media Browser 2013</copyright> | ||||
|         <dependencies> | ||||
|             <dependency id="MediaBrowser.Common" version="3.0.537" /> | ||||
|             <dependency id="MediaBrowser.Common" version="3.0.538" /> | ||||
|         </dependencies> | ||||
|     </metadata> | ||||
|     <files> | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user