From deb4d27857089e8f3a3602399c5b52ad8df170f2 Mon Sep 17 00:00:00 2001 From: Greenback Date: Thu, 8 Oct 2020 19:00:55 +0100 Subject: [PATCH] Moved all settings across to network.xml --- .../AppBase/BaseConfigurationManager.cs | 7 +- .../ApplicationHost.cs | 38 +++++++--- .../EntryPoints/ExternalPortForwarding.cs | 11 +-- .../Controllers/ConfigurationController.cs | 12 ++++ Jellyfin.Api/Controllers/StartupController.cs | 8 ++- Jellyfin.Api/Helpers/ClassMigrationHelper.cs | 70 +++++++++++++++++++ .../ApiApplicationBuilderExtensions.cs | 5 +- .../BaseUrlRedirectionMiddleware.cs | 3 +- .../IpBasedAccessValidationMiddleware.cs | 5 +- .../Middleware/LanFilteringMiddleware.cs | 3 +- Jellyfin.Server/Startup.cs | 5 +- .../Configuration/IConfigurationManager.cs | 3 +- 12 files changed, 143 insertions(+), 27 deletions(-) create mode 100644 Jellyfin.Api/Helpers/ClassMigrationHelper.cs diff --git a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs index 4ab0a2a3f..fa4b3080c 100644 --- a/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs +++ b/Emby.Server.Implementations/AppBase/BaseConfigurationManager.cs @@ -10,6 +10,7 @@ using MediaBrowser.Common.Extensions; using MediaBrowser.Model.Configuration; using MediaBrowser.Model.IO; using MediaBrowser.Model.Serialization; +using Microsoft.EntityFrameworkCore.Migrations.Operations; using Microsoft.Extensions.Logging; namespace Emby.Server.Implementations.AppBase @@ -268,7 +269,7 @@ namespace Emby.Server.Implementations.AppBase } /// - public object GetConfiguration(string key) + public object GetConfiguration(string key, Type objectType = null) { return _configurations.GetOrAdd(key, k => { @@ -277,12 +278,12 @@ namespace Emby.Server.Implementations.AppBase var configurationInfo = _configurationStores .FirstOrDefault(i => string.Equals(i.Key, key, StringComparison.OrdinalIgnoreCase)); - if (configurationInfo == null) + if (configurationInfo == null && objectType == null) { throw new ResourceNotFoundException("Configuration with key " + key + " not found."); } - var configurationType = configurationInfo.ConfigurationType; + var configurationType = configurationInfo?.ConfigurationType ?? objectType; lock (_configurationSyncLock) { diff --git a/Emby.Server.Implementations/ApplicationHost.cs b/Emby.Server.Implementations/ApplicationHost.cs index 77584e9d0..9d70c1526 100644 --- a/Emby.Server.Implementations/ApplicationHost.cs +++ b/Emby.Server.Implementations/ApplicationHost.cs @@ -16,6 +16,7 @@ using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading; using System.Threading.Tasks; +using System.Xml.Serialization; using Emby.Dlna; using Emby.Dlna.Main; using Emby.Dlna.Ssdp; @@ -48,6 +49,8 @@ using Emby.Server.Implementations.SyncPlay; using Emby.Server.Implementations.TV; using Emby.Server.Implementations.Updates; using Jellyfin.Api.Helpers; +using Jellyfin.Api.Migrations; +using Jellyfin.Networking.Configuration; using Jellyfin.Networking.Manager; using MediaBrowser.Common; using MediaBrowser.Common.Configuration; @@ -100,6 +103,7 @@ using MediaBrowser.Providers.Manager; using MediaBrowser.Providers.Plugins.TheTvdb; using MediaBrowser.Providers.Subtitles; using MediaBrowser.XbmcMetadata.Providers; +using Microsoft.AspNetCore.DataProtection.Repositories; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.DependencyInjection; @@ -273,6 +277,7 @@ namespace Emby.Server.Implementations ConfigurationManager = new ServerConfigurationManager(ApplicationPaths, LoggerFactory, _xmlSerializer, _fileSystemManager); NetManager = new NetworkManager((IServerConfigurationManager)ConfigurationManager, LoggerFactory.CreateLogger()); + NetManager.UpdateSettings(GetNetworkConfiguration()); Logger = LoggerFactory.CreateLogger(); @@ -298,6 +303,21 @@ namespace Emby.Server.Implementations ApplicationUserAgent = Name.Replace(' ', '-') + "/" + ApplicationVersionString; } + private NetworkConfiguration GetNetworkConfiguration() + { + string path = Path.Combine(ConfigurationManager.CommonApplicationPaths.ConfigurationDirectoryPath, "network.xml"); + if (!File.Exists(path)) + { + var networkSettings = new NetworkConfiguration(); + ClassMigrationHelper.CopyProperties(ServerConfigurationManager.Configuration, networkSettings); + _xmlSerializer.SerializeToFile(networkSettings, path); + + return networkSettings; + } + + return (NetworkConfiguration)ConfigurationManager.GetConfiguration("network", typeof(NetworkConfiguration)); + } + public string ExpandVirtualPath(string path) { var appPaths = ApplicationPaths; @@ -480,14 +500,15 @@ namespace Emby.Server.Implementations /// public void Init() { - HttpPort = ServerConfigurationManager.Configuration.HttpServerPortNumber; - HttpsPort = ServerConfigurationManager.Configuration.HttpsPortNumber; + var networkConfiguration = ServerConfigurationManager.GetNetworkConfiguration(); + HttpPort = networkConfiguration.HttpServerPortNumber; + HttpsPort = networkConfiguration.HttpsPortNumber; // Safeguard against invalid configuration if (HttpPort == HttpsPort) { - HttpPort = ServerConfiguration.DefaultHttpPort; - HttpsPort = ServerConfiguration.DefaultHttpsPort; + HttpPort = NetworkConfiguration.DefaultHttpPort; + HttpsPort = NetworkConfiguration.DefaultHttpsPort; } if (Plugins != null) @@ -929,9 +950,10 @@ namespace Emby.Server.Implementations // Don't do anything if these haven't been set yet if (HttpPort != 0 && HttpsPort != 0) { + var networkConfiguration = ServerConfigurationManager.GetNetworkConfiguration(); // Need to restart if ports have changed - if (ServerConfigurationManager.Configuration.HttpServerPortNumber != HttpPort || - ServerConfigurationManager.Configuration.HttpsPortNumber != HttpsPort) + if (networkConfiguration.HttpServerPortNumber != HttpPort || + networkConfiguration.HttpsPortNumber != HttpsPort) { if (ServerConfigurationManager.Configuration.IsPortAuthorized) { @@ -1253,7 +1275,7 @@ namespace Emby.Server.Implementations } /// - public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.Configuration.EnableHttps; + public bool ListenWithHttps => Certificate != null && ServerConfigurationManager.GetNetworkConfiguration().EnableHttps; /// public string GetSmartApiUrl(IPAddress ipAddress, int? port = null) @@ -1337,7 +1359,7 @@ namespace Emby.Server.Implementations Scheme = scheme ?? (ListenWithHttps ? Uri.UriSchemeHttps : Uri.UriSchemeHttp), Host = host, Port = port ?? (ListenWithHttps ? HttpsPort : HttpPort), - Path = ServerConfigurationManager.Configuration.BaseUrl + Path = ServerConfigurationManager.GetNetworkConfiguration().BaseUrl }.ToString().TrimEnd('/'); } diff --git a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs index 2e8cc76d2..14201ead2 100644 --- a/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs +++ b/Emby.Server.Implementations/EntryPoints/ExternalPortForwarding.cs @@ -8,6 +8,7 @@ using System.Text; using System.Threading; using System.Threading.Tasks; using Jellyfin.Data.Events; +using Jellyfin.Networking.Configuration; using MediaBrowser.Controller; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Plugins; @@ -56,7 +57,7 @@ namespace Emby.Server.Implementations.EntryPoints private string GetConfigIdentifier() { const char Separator = '|'; - var config = _config.Configuration; + var config = _config.GetNetworkConfiguration(); return new StringBuilder(32) .Append(config.EnableUPnP).Append(Separator) @@ -93,7 +94,8 @@ namespace Emby.Server.Implementations.EntryPoints private void Start() { - if (!_config.Configuration.EnableUPnP || !_config.Configuration.EnableRemoteAccess) + var config = _config.GetNetworkConfiguration(); + if (!config.EnableUPnP || !config.EnableRemoteAccess) { return; } @@ -156,11 +158,12 @@ namespace Emby.Server.Implementations.EntryPoints private IEnumerable CreatePortMaps(INatDevice device) { - yield return CreatePortMap(device, _appHost.HttpPort, _config.Configuration.PublicPort); + var config = _config.GetNetworkConfiguration(); + yield return CreatePortMap(device, _appHost.HttpPort, config.PublicPort); if (_appHost.ListenWithHttps) { - yield return CreatePortMap(device, _appHost.HttpsPort, _config.Configuration.PublicHttpsPort); + yield return CreatePortMap(device, _appHost.HttpsPort, config.PublicHttpsPort); } } diff --git a/Jellyfin.Api/Controllers/ConfigurationController.cs b/Jellyfin.Api/Controllers/ConfigurationController.cs index e1c9f69f6..09d72e8b1 100644 --- a/Jellyfin.Api/Controllers/ConfigurationController.cs +++ b/Jellyfin.Api/Controllers/ConfigurationController.cs @@ -4,7 +4,9 @@ using System.Text.Json; using System.Threading.Tasks; using Jellyfin.Api.Attributes; using Jellyfin.Api.Constants; +using Jellyfin.Api.Migrations; using Jellyfin.Api.Models.ConfigurationDtos; +using Jellyfin.Networking.Configuration; using MediaBrowser.Common.Json; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.MediaEncoding; @@ -49,6 +51,10 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status200OK)] public ActionResult GetConfiguration() { + // TODO: Temp workaround until the web can be changed. + var net = _configurationManager.GetNetworkConfiguration(); + ClassMigrationHelper.CopyProperties(net, _configurationManager.Configuration); + return _configurationManager.Configuration; } @@ -64,6 +70,12 @@ namespace Jellyfin.Api.Controllers public ActionResult UpdateConfiguration([FromBody, Required] ServerConfiguration configuration) { _configurationManager.ReplaceConfiguration(configuration); + + // TODO: Temp workaround until the web can be changed. + var network = _configurationManager.GetNetworkConfiguration(); + ClassMigrationHelper.CopyProperties(configuration, network); + _configurationManager.SaveConfiguration("Network", network); + return NoContent(); } diff --git a/Jellyfin.Api/Controllers/StartupController.cs b/Jellyfin.Api/Controllers/StartupController.cs index e59c6e1dd..d9cb34557 100644 --- a/Jellyfin.Api/Controllers/StartupController.cs +++ b/Jellyfin.Api/Controllers/StartupController.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Jellyfin.Api.Constants; using Jellyfin.Api.Models.StartupDtos; +using Jellyfin.Networking.Configuration; using MediaBrowser.Controller.Configuration; using MediaBrowser.Controller.Library; using Microsoft.AspNetCore.Authorization; @@ -89,9 +90,10 @@ namespace Jellyfin.Api.Controllers [ProducesResponseType(StatusCodes.Status204NoContent)] public ActionResult SetRemoteAccess([FromBody, Required] StartupRemoteAccessDto startupRemoteAccessDto) { - _config.Configuration.EnableRemoteAccess = startupRemoteAccessDto.EnableRemoteAccess; - _config.Configuration.EnableUPnP = startupRemoteAccessDto.EnableAutomaticPortMapping; - _config.SaveConfiguration(); + NetworkConfiguration settings = _config.GetNetworkConfiguration(); + settings.EnableRemoteAccess = startupRemoteAccessDto.EnableRemoteAccess; + settings.EnableUPnP = startupRemoteAccessDto.EnableAutomaticPortMapping; + _config.SaveConfiguration("network", settings); return NoContent(); } diff --git a/Jellyfin.Api/Helpers/ClassMigrationHelper.cs b/Jellyfin.Api/Helpers/ClassMigrationHelper.cs new file mode 100644 index 000000000..123fd012d --- /dev/null +++ b/Jellyfin.Api/Helpers/ClassMigrationHelper.cs @@ -0,0 +1,70 @@ +using System; +using System.Reflection; + +namespace Jellyfin.Api.Migrations +{ + /// + /// A static class for reflection type functions. Temporary until web changed. + /// + public static class ClassMigrationHelper + { + /// + /// Extension for 'Object' that copies the properties to a destination object. + /// + /// The source. + /// The destination. + public static void CopyProperties(this object source, object destination) + { + // If any this null throw an exception + if (source == null || destination == null) + { + throw new Exception("Source or/and Destination Objects are null"); + } + + // Getting the Types of the objects + Type typeDest = destination.GetType(); + Type typeSrc = source.GetType(); + + // Iterate the Properties of the source instance and populate them from their desination counterparts. + PropertyInfo[] srcProps = typeSrc.GetProperties(); + foreach (PropertyInfo srcProp in srcProps) + { + if (!srcProp.CanRead) + { + continue; + } + + var targetProperty = typeDest.GetProperty(srcProp.Name); + if (targetProperty == null) + { + continue; + } + + if (!targetProperty.CanWrite) + { + continue; + } + + var obj = targetProperty.GetSetMethod(true); + if (obj != null && obj.IsPrivate) + { + continue; + } + + var target = targetProperty.GetSetMethod(); + if (target != null && (target.Attributes & MethodAttributes.Static) != 0) + { + continue; + } + + if (!targetProperty.PropertyType.IsAssignableFrom(srcProp.PropertyType)) + { + continue; + } + + // Passed all tests, lets set the value + targetProperty.SetValue(destination, srcProp.GetValue(source, null), null); + } + } + } +} diff --git a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs index c7fbfa4d0..6bf6f383f 100644 --- a/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs +++ b/Jellyfin.Server/Extensions/ApiApplicationBuilderExtensions.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Jellyfin.Networking.Configuration; using Jellyfin.Server.Middleware; using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Builder; @@ -24,8 +25,8 @@ namespace Jellyfin.Server.Extensions // Enable middleware to serve swagger-ui (HTML, JS, CSS, etc.), // specifying the Swagger JSON endpoint. - var baseUrl = serverConfigurationManager.Configuration.BaseUrl.Trim('/'); - var apiDocBaseUrl = serverConfigurationManager.Configuration.BaseUrl; + var baseUrl = serverConfigurationManager.GetNetworkConfiguration().BaseUrl.Trim('/'); + var apiDocBaseUrl = serverConfigurationManager.GetNetworkConfiguration().BaseUrl; if (!string.IsNullOrEmpty(baseUrl)) { baseUrl += '/'; diff --git a/Jellyfin.Server/Middleware/BaseUrlRedirectionMiddleware.cs b/Jellyfin.Server/Middleware/BaseUrlRedirectionMiddleware.cs index 9316737bd..c23da2fd6 100644 --- a/Jellyfin.Server/Middleware/BaseUrlRedirectionMiddleware.cs +++ b/Jellyfin.Server/Middleware/BaseUrlRedirectionMiddleware.cs @@ -1,5 +1,6 @@ using System; using System.Threading.Tasks; +using Jellyfin.Networking.Configuration; using MediaBrowser.Controller.Configuration; using Microsoft.AspNetCore.Http; using Microsoft.Extensions.Configuration; @@ -42,7 +43,7 @@ namespace Jellyfin.Server.Middleware public async Task Invoke(HttpContext httpContext, IServerConfigurationManager serverConfigurationManager) { var localPath = httpContext.Request.Path.ToString(); - var baseUrlPrefix = serverConfigurationManager.Configuration.BaseUrl; + var baseUrlPrefix = serverConfigurationManager.GetNetworkConfiguration().BaseUrl; if (string.Equals(localPath, baseUrlPrefix + "/", StringComparison.OrdinalIgnoreCase) || string.Equals(localPath, baseUrlPrefix, StringComparison.OrdinalIgnoreCase) diff --git a/Jellyfin.Server/Middleware/IpBasedAccessValidationMiddleware.cs b/Jellyfin.Server/Middleware/IpBasedAccessValidationMiddleware.cs index 0713d97d6..6f636819f 100644 --- a/Jellyfin.Server/Middleware/IpBasedAccessValidationMiddleware.cs +++ b/Jellyfin.Server/Middleware/IpBasedAccessValidationMiddleware.cs @@ -1,5 +1,6 @@ using System.Net; using System.Threading.Tasks; +using Jellyfin.Networking.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -42,7 +43,7 @@ namespace Jellyfin.Server.Middleware var remoteIp = httpContext.Connection.RemoteIpAddress ?? IPAddress.Loopback; - if (serverConfigurationManager.Configuration.EnableRemoteAccess) + if (serverConfigurationManager.GetNetworkConfiguration().EnableRemoteAccess) { // Comma separated list of IP addresses or IP/netmask entries for networks that will be allowed to connect remotely. // If left blank, all remote addresses will be allowed. @@ -52,7 +53,7 @@ namespace Jellyfin.Server.Middleware { // remoteAddressFilter is a whitelist or blacklist. bool isListed = remoteAddressFilter.Contains(remoteIp); - if (!serverConfigurationManager.Configuration.IsRemoteIPFilterBlacklist) + if (!serverConfigurationManager.GetNetworkConfiguration().IsRemoteIPFilterBlacklist) { // Black list, so flip over. isListed = !isListed; diff --git a/Jellyfin.Server/Middleware/LanFilteringMiddleware.cs b/Jellyfin.Server/Middleware/LanFilteringMiddleware.cs index 1ef460bd7..1f4e80053 100644 --- a/Jellyfin.Server/Middleware/LanFilteringMiddleware.cs +++ b/Jellyfin.Server/Middleware/LanFilteringMiddleware.cs @@ -2,6 +2,7 @@ using System; using System.Linq; using System.Net; using System.Threading.Tasks; +using Jellyfin.Networking.Configuration; using MediaBrowser.Common.Extensions; using MediaBrowser.Common.Net; using MediaBrowser.Controller.Configuration; @@ -37,7 +38,7 @@ namespace Jellyfin.Server.Middleware { var host = httpContext.Connection.RemoteIpAddress ?? IPAddress.Loopback; - if (!networkManager.IsInLocalNetwork(host) && !serverConfigurationManager.Configuration.EnableRemoteAccess) + if (!networkManager.IsInLocalNetwork(host) && !serverConfigurationManager.GetNetworkConfiguration().EnableRemoteAccess) { return; } diff --git a/Jellyfin.Server/Startup.cs b/Jellyfin.Server/Startup.cs index 2f4620aa6..3484598b8 100644 --- a/Jellyfin.Server/Startup.cs +++ b/Jellyfin.Server/Startup.cs @@ -2,6 +2,7 @@ using System; using System.ComponentModel; using System.Net.Http.Headers; using Jellyfin.Api.TypeConverters; +using Jellyfin.Networking.Configuration; using Jellyfin.Server.Extensions; using Jellyfin.Server.Implementations; using Jellyfin.Server.Middleware; @@ -52,7 +53,7 @@ namespace Jellyfin.Server { options.HttpsPort = _serverApplicationHost.HttpsPort; }); - services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.Configuration.KnownProxies); + services.AddJellyfinApi(_serverApplicationHost.GetApiPluginAssemblies(), _serverConfigurationManager.GetNetworkConfiguration().KnownProxies); services.AddJellyfinApiSwagger(); @@ -96,7 +97,7 @@ namespace Jellyfin.Server app.UseBaseUrlRedirection(); // Wrap rest of configuration so everything only listens on BaseUrl. - app.Map(_serverConfigurationManager.Configuration.BaseUrl, mainApp => + app.Map(_serverConfigurationManager.GetNetworkConfiguration().BaseUrl, mainApp => { if (env.IsDevelopment()) { diff --git a/MediaBrowser.Common/Configuration/IConfigurationManager.cs b/MediaBrowser.Common/Configuration/IConfigurationManager.cs index fe726090d..7bcd4d8ed 100644 --- a/MediaBrowser.Common/Configuration/IConfigurationManager.cs +++ b/MediaBrowser.Common/Configuration/IConfigurationManager.cs @@ -50,8 +50,9 @@ namespace MediaBrowser.Common.Configuration /// Gets the configuration. /// /// The key. + /// Optional parameter containing the key object to create, if it hasn't been registered. /// System.Object. - object GetConfiguration(string key); + object GetConfiguration(string key, Type objectType = null); /// /// Gets the type of the configuration.