From 2d06095447b972c8c7239277428e2c67c8b7ca86 Mon Sep 17 00:00:00 2001 From: LukePulverenti Date: Mon, 25 Feb 2013 22:43:04 -0500 Subject: plugin security fixes and other abstractions --- MediaBrowser.ServerApplication/App.xaml.cs | 15 +- MediaBrowser.ServerApplication/ApplicationHost.cs | 318 +++------------------ .../LibraryExplorer.xaml.cs | 7 +- MediaBrowser.ServerApplication/MainWindow.xaml.cs | 17 +- .../MediaBrowser.ServerApplication.csproj | 12 + MediaBrowser.ServerApplication/packages.config | 2 + 6 files changed, 78 insertions(+), 293 deletions(-) (limited to 'MediaBrowser.ServerApplication') diff --git a/MediaBrowser.ServerApplication/App.xaml.cs b/MediaBrowser.ServerApplication/App.xaml.cs index 5808120adf..f6f70b382e 100644 --- a/MediaBrowser.ServerApplication/App.xaml.cs +++ b/MediaBrowser.ServerApplication/App.xaml.cs @@ -1,8 +1,6 @@ using MediaBrowser.ClickOnce; -using MediaBrowser.Common.Implementations.Serialization; using MediaBrowser.Common.Kernel; using MediaBrowser.Controller; -using MediaBrowser.Logging.Nlog; using MediaBrowser.Model.Logging; using MediaBrowser.Server.Uninstall; using Microsoft.Win32; @@ -30,7 +28,7 @@ namespace MediaBrowser.ServerApplication [STAThread] public static void Main() { - var application = new App(new NLogger("App")); + var application = new App(); application.Run(); } @@ -74,10 +72,8 @@ namespace MediaBrowser.ServerApplication /// Initializes a new instance of the class. /// /// The logger. - public App(ILogger logger) + public App() { - Logger = logger; - InitializeComponent(); } @@ -174,13 +170,16 @@ namespace MediaBrowser.ServerApplication /// protected async void LoadKernel() { - CompositionRoot = new ApplicationHost(Logger); + CompositionRoot = new ApplicationHost(); + Logger = CompositionRoot.Logger; Kernel = CompositionRoot.Kernel; try { - new MainWindow(new JsonSerializer(), Logger).Show(); + var win = (MainWindow)CompositionRoot.CreateInstance(typeof(MainWindow)); + + win.Show(); var now = DateTime.UtcNow; diff --git a/MediaBrowser.ServerApplication/ApplicationHost.cs b/MediaBrowser.ServerApplication/ApplicationHost.cs index 5a98e7d93d..e862a394e5 100644 --- a/MediaBrowser.ServerApplication/ApplicationHost.cs +++ b/MediaBrowser.ServerApplication/ApplicationHost.cs @@ -1,5 +1,6 @@ using BDInfo; using MediaBrowser.ClickOnce; +using MediaBrowser.Common.Implementations; using MediaBrowser.Common.Implementations.ScheduledTasks; using MediaBrowser.Common.Implementations.Serialization; using MediaBrowser.Common.IO; @@ -10,7 +11,6 @@ using MediaBrowser.Controller; using MediaBrowser.IsoMounter; using MediaBrowser.Logging.Nlog; using MediaBrowser.Model.IO; -using MediaBrowser.Model.Logging; using MediaBrowser.Model.MediaInfo; using MediaBrowser.Model.Serialization; using MediaBrowser.Model.System; @@ -22,7 +22,6 @@ using MediaBrowser.Networking.Udp; using MediaBrowser.Networking.WebSocket; using MediaBrowser.Server.Implementations; using MediaBrowser.ServerApplication.Implementations; -using SimpleInjector; using System; using System.Collections.Generic; using System.Diagnostics; @@ -37,56 +36,19 @@ namespace MediaBrowser.ServerApplication /// /// Class CompositionRoot /// - public class ApplicationHost : IApplicationHost, IDisposable + public class ApplicationHost : BaseApplicationHost, IApplicationHost { - /// - /// Gets or sets the logger. - /// - /// The logger. - private ILogger Logger { get; set; } - /// /// Gets or sets the log file path. /// /// The log file path. public string LogFilePath { get; private set; } - /// - /// The container - /// - private readonly Container _container = new Container(); - /// /// Gets or sets the kernel. /// /// The kernel. - public Kernel Kernel { get; private set; } - - private readonly List _failedAssemblies = new List(); - /// - /// Gets assemblies that failed to load - /// - public IEnumerable FailedAssemblies - { - get { return _failedAssemblies; } - } - - /// - /// Gets all types within all running assemblies - /// - /// All types. - public Type[] AllTypes { get; private set; } - - /// - /// Gets all concrete types. - /// - /// All concrete types. - public Type[] AllConcreteTypes { get; private set; } - - /// - /// The disposable parts - /// - private readonly List _disposableParts = new List(); + internal Kernel Kernel { get; private set; } /// /// The json serializer @@ -107,20 +69,40 @@ namespace MediaBrowser.ServerApplication /// The _task manager /// private readonly ITaskManager _taskManager; - + + /// + /// The _task manager + /// + private readonly IHttpServer _httpServer; + + /// + /// Gets a value indicating whether this instance is first run. + /// + /// true if this instance is first run; otherwise, false. + public bool IsFirstRun { get; private set; } + /// /// Initializes a new instance of the class. /// /// The logger. - public ApplicationHost(ILogger logger) + public ApplicationHost() + : base() { - Logger = logger; + IsFirstRun = !File.Exists(_applicationPaths.SystemConfigurationFilePath); + + Logger = new NLogger("App"); + + DiscoverTypes(); _taskManager = new TaskManager(_applicationPaths, _jsonSerializer, Logger); Kernel = new Kernel(this, _applicationPaths, _xmlSerializer, _taskManager, Logger); ReloadLogger(); + Logger.Info("Version {0} initializing", ApplicationVersion); + + _httpServer = ServerFactory.CreateServer(this, ProtobufSerializer, Logger, "Media Browser", "index.html"); + RegisterResources(); FindParts(); @@ -129,42 +111,28 @@ namespace MediaBrowser.ServerApplication /// /// Registers resources that classes will depend on /// - internal void RegisterResources() + private void RegisterResources() { - DiscoverTypes(); - RegisterSingleInstance(Kernel); RegisterSingleInstance(Kernel); - + RegisterSingleInstance(this); RegisterSingleInstance(Logger); RegisterSingleInstance(_applicationPaths); RegisterSingleInstance(_applicationPaths); RegisterSingleInstance(_taskManager); - RegisterSingleInstance(() => new PismoIsoManager(Logger)); - RegisterSingleInstance(() => new BdInfoExaminer()); - RegisterSingleInstance(() => new HttpManager(_applicationPaths, Logger)); - RegisterSingleInstance(() => new NetworkManager()); - RegisterSingleInstance(() => new DotNetZipClient()); + RegisterSingleInstance(new PismoIsoManager(Logger)); + RegisterSingleInstance(new BdInfoExaminer()); + RegisterSingleInstance(new HttpManager(_applicationPaths, Logger)); + RegisterSingleInstance(new NetworkManager()); + RegisterSingleInstance(new DotNetZipClient()); RegisterSingleInstance(() => new AlchemyServer(Logger)); RegisterSingleInstance(_jsonSerializer); RegisterSingleInstance(_xmlSerializer); - RegisterSingleInstance(() => ProtobufSerializer); - Register(typeof(IUdpServer), typeof(UdpServer)); - RegisterSingleInstance(() => ServerFactory.CreateServer(this, Kernel, ProtobufSerializer, Logger, "Media Browser", "index.html")); - } - - /// - /// Discovers the types. - /// - private void DiscoverTypes() - { - _failedAssemblies.Clear(); - - AllTypes = GetComposablePartAssemblies().SelectMany(GetTypes).ToArray(); - - AllConcreteTypes = AllTypes.Where(t => t.IsClass && !t.IsAbstract && !t.IsInterface && !t.IsGenericType).ToArray(); + RegisterSingleInstance(ProtobufSerializer); + RegisterSingleInstance(new UdpServer()); + RegisterSingleInstance(_httpServer); } /// @@ -173,150 +141,8 @@ namespace MediaBrowser.ServerApplication private void FindParts() { _taskManager.AddTasks(GetExports(false)); - } - - /// - /// Gets a list of types within an assembly - /// This will handle situations that would normally throw an exception - such as a type within the assembly that depends on some other non-existant reference - /// - /// The assembly. - /// IEnumerable{Type}. - /// assembly - private IEnumerable GetTypes(Assembly assembly) - { - if (assembly == null) - { - throw new ArgumentNullException("assembly"); - } - - try - { - return assembly.GetTypes(); - } - catch (ReflectionTypeLoadException ex) - { - // If it fails we can still get a list of the Types it was able to resolve - return ex.Types.Where(t => t != null); - } - } - - /// - /// The _protobuf serializer initialized - /// - private bool _protobufSerializerInitialized; - /// - /// The _protobuf serializer sync lock - /// - private object _protobufSerializerSyncLock = new object(); - /// - /// Gets a dynamically compiled generated serializer that can serialize protocontracts without reflection - /// - private ProtobufSerializer _protobufSerializer; - /// - /// Gets the protobuf serializer. - /// - /// The protobuf serializer. - public ProtobufSerializer ProtobufSerializer - { - get - { - // Lazy load - LazyInitializer.EnsureInitialized(ref _protobufSerializer, ref _protobufSerializerInitialized, ref _protobufSerializerSyncLock, () => ProtobufSerializer.Create(AllTypes)); - return _protobufSerializer; - } - private set - { - _protobufSerializer = value; - _protobufSerializerInitialized = value != null; - } - } - - /// - /// Creates an instance of type and resolves all constructor dependancies - /// - /// The type. - /// System.Object. - public object CreateInstance(Type type) - { - try - { - return _container.GetInstance(type); - } - catch - { - Logger.Error("Error creating {0}", type.Name); - throw; - } - } - - /// - /// Registers the specified obj. - /// - /// - /// The obj. - public void RegisterSingleInstance(T obj) - where T : class - { - _container.RegisterSingle(obj); - } - - /// - /// Registers the specified func. - /// - /// - /// The func. - public void Register(Func func) - where T : class - { - _container.Register(func); - } - - /// - /// Registers the single instance. - /// - /// - /// The func. - public void RegisterSingleInstance(Func func) - where T : class - { - _container.RegisterSingle(func); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T Resolve() - { - return (T)_container.GetRegistration(typeof(T), true).GetInstance(); - } - - /// - /// Resolves this instance. - /// - /// - /// ``0. - public T TryResolve() - { - var result = _container.GetRegistration(typeof(T), false); - - if (result == null) - { - return default(T); - } - return (T)result.GetInstance(); - } - - /// - /// Registers the specified service type. - /// - /// Type of the service. - /// Type of the concrete. - public void Register(Type serviceType, Type implementation) - { - _container.Register(serviceType, implementation); + _httpServer.Init(GetExports(false)); } /// @@ -374,12 +200,12 @@ namespace MediaBrowser.ServerApplication /// Gets the composable part assemblies. /// /// IEnumerable{Assembly}. - private IEnumerable GetComposablePartAssemblies() + protected override IEnumerable GetComposablePartAssemblies() { // Gets all plugin assemblies by first reading all bytes of the .dll and calling Assembly.Load against that // This will prevent the .dll file from getting locked, and allow us to replace it when needed foreach (var pluginAssembly in Directory - .EnumerateFiles(Kernel.ApplicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) + .EnumerateFiles(_applicationPaths.PluginsPath, "*.dll", SearchOption.TopDirectoryOnly) .Select(LoadAssembly).Where(a => a != null)) { yield return pluginAssembly; @@ -410,73 +236,9 @@ namespace MediaBrowser.ServerApplication // Server implementations yield return typeof(ServerApplicationPaths).Assembly; - + // Include composable parts in the running assembly yield return GetType().Assembly; } - - /// - /// Loads the assembly. - /// - /// The file. - /// Assembly. - private Assembly LoadAssembly(string file) - { - try - { - return Assembly.Load(File.ReadAllBytes((file))); - } - catch (Exception ex) - { - _failedAssemblies.Add(file); - Logger.ErrorException("Error loading assembly {0}", ex, file); - return null; - } - } - - /// - /// Gets the exports. - /// - /// - /// All types. - /// if set to true [manage liftime]. - /// IEnumerable{``0}. - public IEnumerable GetExports(bool manageLiftime = true) - { - var currentType = typeof(T); - - Logger.Info("Composing instances of " + currentType.Name); - - var parts = AllConcreteTypes.Where(currentType.IsAssignableFrom).Select(CreateInstance).Cast().ToArray(); - - if (manageLiftime) - { - _disposableParts.AddRange(parts.OfType()); - } - - return parts; - } - - /// - /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources. - /// - public void Dispose() - { - Dispose(true); - } - - /// - /// Releases unmanaged and - optionally - managed resources. - /// - /// true to release both managed and unmanaged resources; false to release only unmanaged resources. - protected virtual void Dispose(bool dispose) - { - foreach (var part in _disposableParts) - { - part.Dispose(); - } - - _disposableParts.Clear(); - } } } diff --git a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs index 59961a9418..cb5c62ff08 100644 --- a/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs +++ b/MediaBrowser.ServerApplication/LibraryExplorer.xaml.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using MediaBrowser.Common.Kernel; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Entities.Movies; using MediaBrowser.Controller.Entities.TV; @@ -38,13 +39,13 @@ namespace MediaBrowser.ServerApplication /// /// Initializes a new instance of the class. /// - public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger) + public LibraryExplorer(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost) { _logger = logger; _jsonSerializer = jsonSerializer; InitializeComponent(); - lblVersion.Content = "Version: " + Kernel.Instance.ApplicationVersion; + lblVersion.Content = "Version: " + appHost.ApplicationVersion; foreach (var user in Kernel.Instance.Users) ddlProfile.Items.Add(user); ddlProfile.Items.Insert(0,new User {Name = "Physical"}); diff --git a/MediaBrowser.ServerApplication/MainWindow.xaml.cs b/MediaBrowser.ServerApplication/MainWindow.xaml.cs index 332bb1daa9..fc0f0efc9b 100644 --- a/MediaBrowser.ServerApplication/MainWindow.xaml.cs +++ b/MediaBrowser.ServerApplication/MainWindow.xaml.cs @@ -1,4 +1,5 @@ -using MediaBrowser.Controller; +using MediaBrowser.Common.Kernel; +using MediaBrowser.Controller; using MediaBrowser.Controller.Entities; using MediaBrowser.Controller.Library; using MediaBrowser.Model.Logging; @@ -49,12 +50,19 @@ namespace MediaBrowser.ServerApplication /// private readonly ILogger _logger; + /// + /// The _app host + /// + private readonly IApplicationHost _appHost; + /// /// Initializes a new instance of the class. /// + /// The json serializer. /// The logger. + /// The app host. /// logger - public MainWindow(IJsonSerializer jsonSerializer, ILogger logger) + public MainWindow(IJsonSerializer jsonSerializer, ILogger logger, IApplicationHost appHost) { if (jsonSerializer == null) { @@ -67,6 +75,7 @@ namespace MediaBrowser.ServerApplication _jsonSerializer = jsonSerializer; _logger = logger; + _appHost = appHost; InitializeComponent(); @@ -236,7 +245,7 @@ namespace MediaBrowser.ServerApplication Kernel.Instance.LibraryManager.LibraryChanged -= Instance_LibraryChanged; Kernel.Instance.LibraryManager.LibraryChanged += Instance_LibraryChanged; - if (Kernel.Instance.IsFirstRun) + if (_appHost.IsFirstRun) { LaunchStartupWizard(); } @@ -293,7 +302,7 @@ namespace MediaBrowser.ServerApplication /// The instance containing the event data. private void cmOpenExplorer_click(object sender, RoutedEventArgs e) { - (new LibraryExplorer(_jsonSerializer, _logger)).Show(); + (new LibraryExplorer(_jsonSerializer, _logger, _appHost)).Show(); } /// diff --git a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj index c843242c32..50cb0be6ca 100644 --- a/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj +++ b/MediaBrowser.ServerApplication/MediaBrowser.ServerApplication.csproj @@ -128,6 +128,18 @@ False ..\ThirdParty\UPnP\Libs\Platinum.Managed.dll + + False + ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Common.dll + + + False + ..\packages\ServiceStack.Common.3.9.37\lib\net35\ServiceStack.Interfaces.dll + + + False + ..\packages\ServiceStack.Text.3.9.37\lib\net35\ServiceStack.Text.dll + False ..\packages\SimpleInjector.2.0.0-beta5\lib\net40-client\SimpleInjector.dll diff --git a/MediaBrowser.ServerApplication/packages.config b/MediaBrowser.ServerApplication/packages.config index e1beae6da2..71e2844fc1 100644 --- a/MediaBrowser.ServerApplication/packages.config +++ b/MediaBrowser.ServerApplication/packages.config @@ -3,6 +3,8 @@ + + \ No newline at end of file -- cgit v1.2.3