mirror of
https://github.com/Sonarr/Sonarr.git
synced 2025-02-04 11:43:19 +02:00
Fixed: Default Windows Service Account
This commit is contained in:
parent
e3b3e65409
commit
5666369cc4
@ -1,7 +1,7 @@
|
|||||||
REM SET BUILD_NUMBER=1
|
REM SET BUILD_NUMBER=1
|
||||||
REM SET BRANCH=develop
|
REM SET BRANCH=develop
|
||||||
echo ##teamcity[progressStart 'Building setup file']
|
echo ##teamcity[progressStart 'Building setup file']
|
||||||
inno\ISCC.exe nzbdrone.iss
|
inno\ISCC.exe sonarr.iss
|
||||||
echo ##teamcity[progressFinish 'Building setup file']
|
echo ##teamcity[progressFinish 'Building setup file']
|
||||||
|
|
||||||
echo ##teamcity[publishArtifacts 'setup\output\*.exe']
|
echo ##teamcity[publishArtifacts 'setup\output\*.exe']
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
#define AppURL "https://sonarr.tv/"
|
#define AppURL "https://sonarr.tv/"
|
||||||
#define ForumsURL "https://forums.sonarr.tv/"
|
#define ForumsURL "https://forums.sonarr.tv/"
|
||||||
#define AppExeName "Sonarr.exe"
|
#define AppExeName "Sonarr.exe"
|
||||||
#define BuildNumber "2.0"
|
#define BuildNumber "3.0"
|
||||||
#define BuildNumber GetEnv('BUILD_NUMBER')
|
#define BuildNumber GetEnv('BUILD_NUMBER')
|
||||||
#define BranchName GetEnv('BRANCH')
|
#define BranchName GetEnv('BRANCH')
|
||||||
|
|
||||||
@ -60,8 +60,9 @@ Name: "{userstartup}\{#AppName}"; Filename: "{app}\Sonarr.exe"; WorkingDir: "{ap
|
|||||||
Name: "{commonappdata}\NzbDrone\bin"; Type: filesandordirs
|
Name: "{commonappdata}\NzbDrone\bin"; Type: filesandordirs
|
||||||
|
|
||||||
[Run]
|
[Run]
|
||||||
Filename: "{app}\Sonarr.Console.exe"; Parameters: "/u"; Flags: runhidden waituntilterminated;
|
Filename: "{app}\Sonarr.Console.exe"; StatusMsg: "Removing previous Windows Service"; Parameters: "/u"; Flags: runhidden waituntilterminated;
|
||||||
Filename: "{app}\Sonarr.Console.exe"; Parameters: "/i"; Flags: runhidden waituntilterminated; Tasks: windowsService
|
Filename: "{app}\Sonarr.Console.exe"; Description: "Enable Access from Other Devices"; StatusMsg: "Enabling Remote access"; Parameters: "/registerurl"; Flags: postinstall runascurrentuser runhidden waituntilterminated; Tasks: startupShortcut none;
|
||||||
|
Filename: "{app}\Sonarr.Console.exe"; StatusMsg: "Installing Windows Service"; Parameters: "/i"; Flags: runhidden waituntilterminated; Tasks: windowsService
|
||||||
Filename: "{app}\Sonarr.exe"; Description: "Open Sonarr Web UI"; Flags: postinstall skipifsilent nowait; Tasks: windowsService;
|
Filename: "{app}\Sonarr.exe"; Description: "Open Sonarr Web UI"; Flags: postinstall skipifsilent nowait; Tasks: windowsService;
|
||||||
Filename: "{app}\Sonarr.exe"; Description: "Start Sonarr"; Flags: postinstall skipifsilent nowait; Tasks: startupShortcut none;
|
Filename: "{app}\Sonarr.exe"; Description: "Start Sonarr"; Flags: postinstall skipifsilent nowait; Tasks: startupShortcut none;
|
||||||
|
|
@ -1,4 +1,4 @@
|
|||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using Moq;
|
using Moq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
@ -42,13 +42,13 @@ namespace NzbDrone.App.Test
|
|||||||
public void Route_should_call_uninstall_service_when_application_mode_is_uninstall()
|
public void Route_should_call_uninstall_service_when_application_mode_is_uninstall()
|
||||||
{
|
{
|
||||||
var serviceProviderMock = Mocker.GetMock<IServiceProvider>();
|
var serviceProviderMock = Mocker.GetMock<IServiceProvider>();
|
||||||
serviceProviderMock.Setup(c => c.UnInstall(ServiceProvider.SERVICE_NAME));
|
serviceProviderMock.Setup(c => c.Uninstall(ServiceProvider.SERVICE_NAME));
|
||||||
Mocker.GetMock<IRuntimeInfo>().SetupGet(c => c.IsUserInteractive).Returns(true);
|
Mocker.GetMock<IRuntimeInfo>().SetupGet(c => c.IsUserInteractive).Returns(true);
|
||||||
serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.SERVICE_NAME)).Returns(true);
|
serviceProviderMock.Setup(c => c.ServiceExist(ServiceProvider.SERVICE_NAME)).Returns(true);
|
||||||
|
|
||||||
Subject.Route(ApplicationModes.UninstallService);
|
Subject.Route(ApplicationModes.UninstallService);
|
||||||
|
|
||||||
serviceProviderMock.Verify(c => c.UnInstall(ServiceProvider.SERVICE_NAME), Times.Once());
|
serviceProviderMock.Verify(c => c.Uninstall(ServiceProvider.SERVICE_NAME), Times.Once());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -36,7 +36,7 @@ namespace NzbDrone.Common.Test
|
|||||||
{
|
{
|
||||||
if (Subject.ServiceExist(TEMP_SERVICE_NAME))
|
if (Subject.ServiceExist(TEMP_SERVICE_NAME))
|
||||||
{
|
{
|
||||||
Subject.UnInstall(TEMP_SERVICE_NAME);
|
Subject.Uninstall(TEMP_SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Subject.IsServiceRunning(ALWAYS_INSTALLED_SERVICE))
|
if (Subject.IsServiceRunning(ALWAYS_INSTALLED_SERVICE))
|
||||||
@ -65,7 +65,7 @@ namespace NzbDrone.Common.Test
|
|||||||
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse("Service already installed");
|
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse("Service already installed");
|
||||||
Subject.Install(TEMP_SERVICE_NAME);
|
Subject.Install(TEMP_SERVICE_NAME);
|
||||||
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeTrue();
|
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeTrue();
|
||||||
Subject.UnInstall(TEMP_SERVICE_NAME);
|
Subject.Uninstall(TEMP_SERVICE_NAME);
|
||||||
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse();
|
Subject.ServiceExist(TEMP_SERVICE_NAME).Should().BeFalse();
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
@ -76,7 +76,7 @@ namespace NzbDrone.Common.Test
|
|||||||
[ManualTest]
|
[ManualTest]
|
||||||
public void UnInstallService()
|
public void UnInstallService()
|
||||||
{
|
{
|
||||||
Subject.UnInstall(ServiceProvider.SERVICE_NAME);
|
Subject.Uninstall(ServiceProvider.SERVICE_NAME);
|
||||||
Subject.ServiceExist(ServiceProvider.SERVICE_NAME).Should().BeFalse();
|
Subject.ServiceExist(ServiceProvider.SERVICE_NAME).Should().BeFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -21,8 +21,14 @@ namespace NzbDrone.Common
|
|||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.WriteLine(" Usage: {0} <command> ", Process.GetCurrentProcess().MainModule.ModuleName);
|
Console.WriteLine(" Usage: {0} <command> ", Process.GetCurrentProcess().MainModule.ModuleName);
|
||||||
Console.WriteLine(" Commands:");
|
Console.WriteLine(" Commands:");
|
||||||
|
|
||||||
|
if (OsInfo.IsWindows)
|
||||||
|
{
|
||||||
Console.WriteLine(" /{0} Install the application as a Windows Service ({1}).", StartupContext.INSTALL_SERVICE, ServiceProvider.SERVICE_NAME);
|
Console.WriteLine(" /{0} Install the application as a Windows Service ({1}).", StartupContext.INSTALL_SERVICE, ServiceProvider.SERVICE_NAME);
|
||||||
Console.WriteLine(" /{0} Uninstall already installed Windows Service ({1}).", StartupContext.UNINSTALL_SERVICE, ServiceProvider.SERVICE_NAME);
|
Console.WriteLine(" /{0} Uninstall already installed Windows Service ({1}).", StartupContext.UNINSTALL_SERVICE, ServiceProvider.SERVICE_NAME);
|
||||||
|
Console.WriteLine(" /{0} Register URL and open firewall port (allows access from other devices on your network).", StartupContext.REGISTER_URL);
|
||||||
|
}
|
||||||
|
|
||||||
Console.WriteLine(" /{0} Don't open Sonarr in a browser", StartupContext.NO_BROWSER);
|
Console.WriteLine(" /{0} Don't open Sonarr in a browser", StartupContext.NO_BROWSER);
|
||||||
Console.WriteLine(" /{0} Start Sonarr terminating any other instances", StartupContext.TERMINATE);
|
Console.WriteLine(" /{0} Start Sonarr terminating any other instances", StartupContext.TERMINATE);
|
||||||
Console.WriteLine(" /{0}=path Path to use as the AppData location (stores database, config, logs, etc)", StartupContext.APPDATA);
|
Console.WriteLine(" /{0}=path Path to use as the AppData location (stores database, config, logs, etc)", StartupContext.APPDATA);
|
||||||
|
@ -29,7 +29,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
if (entry != null)
|
if (entry != null)
|
||||||
{
|
{
|
||||||
ExecutingApplication = entry.Location;
|
ExecutingApplication = entry.Location;
|
||||||
IsWindowsTray = entry.ManifestModule.Name == $"{ProcessProvider.SONARR_PROCESS_NAME}.exe";
|
IsWindowsTray = OsInfo.IsWindows && entry.ManifestModule.Name == $"{ProcessProvider.SONARR_PROCESS_NAME}.exe";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace NzbDrone.Common.EnvironmentInfo
|
namespace NzbDrone.Common.EnvironmentInfo
|
||||||
{
|
{
|
||||||
@ -6,8 +6,10 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
{
|
{
|
||||||
HashSet<string> Flags { get; }
|
HashSet<string> Flags { get; }
|
||||||
Dictionary<string, string> Args { get; }
|
Dictionary<string, string> Args { get; }
|
||||||
|
bool Help { get; }
|
||||||
bool InstallService { get; }
|
bool InstallService { get; }
|
||||||
bool UninstallService { get; }
|
bool UninstallService { get; }
|
||||||
|
bool RegisterUrl { get; }
|
||||||
|
|
||||||
string PreservedArguments { get; }
|
string PreservedArguments { get; }
|
||||||
}
|
}
|
||||||
@ -21,6 +23,7 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
public const string HELP = "?";
|
public const string HELP = "?";
|
||||||
public const string TERMINATE = "terminateexisting";
|
public const string TERMINATE = "terminateexisting";
|
||||||
public const string RESTART = "restart";
|
public const string RESTART = "restart";
|
||||||
|
public const string REGISTER_URL = "registerurl";
|
||||||
|
|
||||||
public StartupContext(params string[] args)
|
public StartupContext(params string[] args)
|
||||||
{
|
{
|
||||||
@ -47,9 +50,10 @@ namespace NzbDrone.Common.EnvironmentInfo
|
|||||||
public HashSet<string> Flags { get; private set; }
|
public HashSet<string> Flags { get; private set; }
|
||||||
public Dictionary<string, string> Args { get; private set; }
|
public Dictionary<string, string> Args { get; private set; }
|
||||||
|
|
||||||
|
public bool Help => Flags.Contains(HELP);
|
||||||
public bool InstallService => Flags.Contains(INSTALL_SERVICE);
|
public bool InstallService => Flags.Contains(INSTALL_SERVICE);
|
||||||
|
|
||||||
public bool UninstallService => Flags.Contains(UNINSTALL_SERVICE);
|
public bool UninstallService => Flags.Contains(UNINSTALL_SERVICE);
|
||||||
|
public bool RegisterUrl => Flags.Contains(REGISTER_URL);
|
||||||
|
|
||||||
public string PreservedArguments
|
public string PreservedArguments
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace NzbDrone.Common.Processes
|
|||||||
bool Exists(string processName);
|
bool Exists(string processName);
|
||||||
ProcessPriorityClass GetCurrentProcessPriority();
|
ProcessPriorityClass GetCurrentProcessPriority();
|
||||||
Process Start(string path, string args = null, StringDictionary environmentVariables = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null);
|
Process Start(string path, string args = null, StringDictionary environmentVariables = null, Action<string> onOutputDataReceived = null, Action<string> onErrorDataReceived = null);
|
||||||
Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null);
|
Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null, bool noWindow = false);
|
||||||
ProcessOutput StartAndCapture(string path, string args = null, StringDictionary environmentVariables = null);
|
ProcessOutput StartAndCapture(string path, string args = null, StringDictionary environmentVariables = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -190,7 +190,7 @@ namespace NzbDrone.Common.Processes
|
|||||||
return process;
|
return process;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null)
|
public Process SpawnNewProcess(string path, string args = null, StringDictionary environmentVariables = null, bool noWindow = false)
|
||||||
{
|
{
|
||||||
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
if (PlatformInfo.IsMono && path.EndsWith(".exe", StringComparison.InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
@ -201,6 +201,9 @@ namespace NzbDrone.Common.Processes
|
|||||||
_logger.Debug("Starting {0} {1}", path, args);
|
_logger.Debug("Starting {0} {1}", path, args);
|
||||||
|
|
||||||
var startInfo = new ProcessStartInfo(path, args);
|
var startInfo = new ProcessStartInfo(path, args);
|
||||||
|
startInfo.CreateNoWindow = noWindow;
|
||||||
|
startInfo.UseShellExecute = !noWindow;
|
||||||
|
|
||||||
var process = new Process
|
var process = new Process
|
||||||
{
|
{
|
||||||
StartInfo = startInfo
|
StartInfo = startInfo
|
||||||
|
@ -5,6 +5,7 @@ using System.Diagnostics;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.ServiceProcess;
|
using System.ServiceProcess;
|
||||||
using NLog;
|
using NLog;
|
||||||
|
using NzbDrone.Common.Extensions;
|
||||||
using NzbDrone.Common.Processes;
|
using NzbDrone.Common.Processes;
|
||||||
|
|
||||||
namespace NzbDrone.Common
|
namespace NzbDrone.Common
|
||||||
@ -14,13 +15,14 @@ namespace NzbDrone.Common
|
|||||||
bool ServiceExist(string name);
|
bool ServiceExist(string name);
|
||||||
bool IsServiceRunning(string name);
|
bool IsServiceRunning(string name);
|
||||||
void Install(string serviceName);
|
void Install(string serviceName);
|
||||||
void UnInstall(string serviceName);
|
void Uninstall(string serviceName);
|
||||||
void Run(ServiceBase service);
|
void Run(ServiceBase service);
|
||||||
ServiceController GetService(string serviceName);
|
ServiceController GetService(string serviceName);
|
||||||
void Stop(string serviceName);
|
void Stop(string serviceName);
|
||||||
void Start(string serviceName);
|
void Start(string serviceName);
|
||||||
ServiceControllerStatus GetStatus(string serviceName);
|
ServiceControllerStatus GetStatus(string serviceName);
|
||||||
void Restart(string serviceName);
|
void Restart(string serviceName);
|
||||||
|
void SetPermissions(string serviceName);
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ServiceProvider : IServiceProvider
|
public class ServiceProvider : IServiceProvider
|
||||||
@ -30,7 +32,6 @@ namespace NzbDrone.Common
|
|||||||
private readonly IProcessProvider _processProvider;
|
private readonly IProcessProvider _processProvider;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
|
|
||||||
public ServiceProvider(IProcessProvider processProvider, Logger logger)
|
public ServiceProvider(IProcessProvider processProvider, Logger logger)
|
||||||
{
|
{
|
||||||
_processProvider = processProvider;
|
_processProvider = processProvider;
|
||||||
@ -66,7 +67,7 @@ namespace NzbDrone.Common
|
|||||||
|
|
||||||
var installer = new ServiceProcessInstaller
|
var installer = new ServiceProcessInstaller
|
||||||
{
|
{
|
||||||
Account = ServiceAccount.LocalSystem
|
Account = ServiceAccount.LocalService
|
||||||
};
|
};
|
||||||
|
|
||||||
var serviceInstaller = new ServiceInstaller();
|
var serviceInstaller = new ServiceInstaller();
|
||||||
@ -89,7 +90,7 @@ namespace NzbDrone.Common
|
|||||||
_logger.Info("Service Has installed successfully.");
|
_logger.Info("Service Has installed successfully.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void UnInstall(string serviceName)
|
public virtual void Uninstall(string serviceName)
|
||||||
{
|
{
|
||||||
_logger.Info("Uninstalling {0} service", serviceName);
|
_logger.Info("Uninstalling {0} service", serviceName);
|
||||||
|
|
||||||
@ -189,5 +190,42 @@ namespace NzbDrone.Common
|
|||||||
|
|
||||||
_processProvider.Start("cmd.exe", args);
|
_processProvider.Start("cmd.exe", args);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void SetPermissions(string serviceName)
|
||||||
|
{
|
||||||
|
var dacls = GetServiceDacls(serviceName);
|
||||||
|
SetServiceDacls(serviceName, dacls);
|
||||||
|
}
|
||||||
|
|
||||||
|
private string GetServiceDacls(string serviceName)
|
||||||
|
{
|
||||||
|
var output = _processProvider.StartAndCapture("sc.exe", $"sdshow {serviceName}");
|
||||||
|
|
||||||
|
var dacls = output.Standard.Select(s => s.Content).Where(s => s.IsNotNullOrWhiteSpace()).ToList();
|
||||||
|
|
||||||
|
if (dacls.Count == 1)
|
||||||
|
{
|
||||||
|
return dacls[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new ArgumentException("Invalid DACL output");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetServiceDacls(string serviceName, string dacls)
|
||||||
|
{
|
||||||
|
const string authenticatedUsersDacl = "(A;;CCLCSWRPWPLOCRRC;;;AU)";
|
||||||
|
|
||||||
|
if (dacls.Contains(authenticatedUsersDacl))
|
||||||
|
{
|
||||||
|
// Permssions already set
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var indexOfS = dacls.IndexOf("S:", StringComparison.InvariantCultureIgnoreCase);
|
||||||
|
|
||||||
|
dacls = indexOfS == -1 ? $"{dacls}{authenticatedUsersDacl}" : dacls.Insert(indexOfS, authenticatedUsersDacl);
|
||||||
|
|
||||||
|
_processProvider.Start("sc.exe", $"sdset {serviceName} {dacls}").WaitForExit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,11 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Net.Sockets;
|
using System.Net.Sockets;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
using NzbDrone.Common.Exceptions;
|
using NzbDrone.Common.Exceptions;
|
||||||
using NzbDrone.Common.Instrumentation;
|
using NzbDrone.Common.Instrumentation;
|
||||||
using NzbDrone.Host;
|
using NzbDrone.Host;
|
||||||
|
using NzbDrone.Host.AccessControl;
|
||||||
|
|
||||||
namespace NzbDrone.Console
|
namespace NzbDrone.Console
|
||||||
{
|
{
|
||||||
@ -50,6 +51,13 @@ namespace NzbDrone.Console
|
|||||||
Logger.Fatal(ex.Message + ". This can happen if another instance of Sonarr is already running another application is using the same port (default: 8989) or the user has insufficient permissions");
|
Logger.Fatal(ex.Message + ". This can happen if another instance of Sonarr is already running another application is using the same port (default: 8989) or the user has insufficient permissions");
|
||||||
Exit(ExitCodes.RecoverableFailure);
|
Exit(ExitCodes.RecoverableFailure);
|
||||||
}
|
}
|
||||||
|
catch (RemoteAccessException ex)
|
||||||
|
{
|
||||||
|
System.Console.WriteLine("");
|
||||||
|
System.Console.WriteLine("");
|
||||||
|
Logger.Fatal(ex, "EPIC FAIL!");
|
||||||
|
Exit(ExitCodes.Normal);
|
||||||
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
System.Console.WriteLine("");
|
System.Console.WriteLine("");
|
||||||
|
46
src/NzbDrone.Host/AccessControl/RemoteAccessAdapter.cs
Normal file
46
src/NzbDrone.Host/AccessControl/RemoteAccessAdapter.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
|
||||||
|
namespace NzbDrone.Host.AccessControl
|
||||||
|
{
|
||||||
|
public interface IRemoteAccessAdapter
|
||||||
|
{
|
||||||
|
void MakeAccessible(bool passive);
|
||||||
|
}
|
||||||
|
|
||||||
|
public class RemoteAccessAdapter : IRemoteAccessAdapter
|
||||||
|
{
|
||||||
|
private readonly IRuntimeInfo _runtimeInfo;
|
||||||
|
private readonly IUrlAclAdapter _urlAclAdapter;
|
||||||
|
private readonly IFirewallAdapter _firewallAdapter;
|
||||||
|
private readonly ISslAdapter _sslAdapter;
|
||||||
|
|
||||||
|
public RemoteAccessAdapter(IRuntimeInfo runtimeInfo,
|
||||||
|
IUrlAclAdapter urlAclAdapter,
|
||||||
|
IFirewallAdapter firewallAdapter,
|
||||||
|
ISslAdapter sslAdapter)
|
||||||
|
{
|
||||||
|
_runtimeInfo = runtimeInfo;
|
||||||
|
_urlAclAdapter = urlAclAdapter;
|
||||||
|
_firewallAdapter = firewallAdapter;
|
||||||
|
_sslAdapter = sslAdapter;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void MakeAccessible(bool passive)
|
||||||
|
{
|
||||||
|
if (OsInfo.IsWindows)
|
||||||
|
{
|
||||||
|
if (_runtimeInfo.IsAdmin)
|
||||||
|
{
|
||||||
|
_firewallAdapter.MakeAccessible();
|
||||||
|
_sslAdapter.Register();
|
||||||
|
}
|
||||||
|
else if (!passive)
|
||||||
|
{
|
||||||
|
throw new RemoteAccessException("Failed to register URLs for Sonarr. Sonarr will not be accessible remotely");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_urlAclAdapter.ConfigureUrls();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
24
src/NzbDrone.Host/AccessControl/RemoteAccessException.cs
Normal file
24
src/NzbDrone.Host/AccessControl/RemoteAccessException.cs
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
using System;
|
||||||
|
using NzbDrone.Common.Exceptions;
|
||||||
|
|
||||||
|
namespace NzbDrone.Host.AccessControl
|
||||||
|
{
|
||||||
|
public class RemoteAccessException : NzbDroneException
|
||||||
|
{
|
||||||
|
public RemoteAccessException(string message, params object[] args) : base(message, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAccessException(string message) : base(message)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAccessException(string message, Exception innerException, params object[] args) : base(message, innerException, args)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public RemoteAccessException(string message, Exception innerException) : base(message, innerException)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
namespace NzbDrone.Host
|
namespace NzbDrone.Host
|
||||||
{
|
{
|
||||||
public enum ApplicationModes
|
public enum ApplicationModes
|
||||||
{
|
{
|
||||||
@ -7,5 +7,6 @@
|
|||||||
InstallService,
|
InstallService,
|
||||||
UninstallService,
|
UninstallService,
|
||||||
Service,
|
Service,
|
||||||
|
RegisterUrl
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -112,11 +112,16 @@ namespace NzbDrone.Host
|
|||||||
|
|
||||||
private static ApplicationModes GetApplicationMode(IStartupContext startupContext)
|
private static ApplicationModes GetApplicationMode(IStartupContext startupContext)
|
||||||
{
|
{
|
||||||
if (startupContext.Flags.Contains(StartupContext.HELP))
|
if (startupContext.Help)
|
||||||
{
|
{
|
||||||
return ApplicationModes.Help;
|
return ApplicationModes.Help;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (OsInfo.IsWindows && startupContext.RegisterUrl)
|
||||||
|
{
|
||||||
|
return ApplicationModes.RegisterUrl;
|
||||||
|
}
|
||||||
|
|
||||||
if (OsInfo.IsWindows && startupContext.InstallService)
|
if (OsInfo.IsWindows && startupContext.InstallService)
|
||||||
{
|
{
|
||||||
return ApplicationModes.InstallService;
|
return ApplicationModes.InstallService;
|
||||||
@ -141,6 +146,7 @@ namespace NzbDrone.Host
|
|||||||
{
|
{
|
||||||
case ApplicationModes.InstallService:
|
case ApplicationModes.InstallService:
|
||||||
case ApplicationModes.UninstallService:
|
case ApplicationModes.UninstallService:
|
||||||
|
case ApplicationModes.RegisterUrl:
|
||||||
case ApplicationModes.Help:
|
case ApplicationModes.Help:
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
|
@ -125,6 +125,8 @@
|
|||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="AccessControl\FirewallAdapter.cs" />
|
<Compile Include="AccessControl\FirewallAdapter.cs" />
|
||||||
<Compile Include="AccessControl\NetshProvider.cs" />
|
<Compile Include="AccessControl\NetshProvider.cs" />
|
||||||
|
<Compile Include="AccessControl\RemoteAccessAdapter.cs" />
|
||||||
|
<Compile Include="AccessControl\RemoteAccessException.cs" />
|
||||||
<Compile Include="AccessControl\UrlAcl.cs" />
|
<Compile Include="AccessControl\UrlAcl.cs" />
|
||||||
<Compile Include="AccessControl\SslAdapter.cs" />
|
<Compile Include="AccessControl\SslAdapter.cs" />
|
||||||
<Compile Include="AccessControl\UrlAclAdapter.cs" />
|
<Compile Include="AccessControl\UrlAclAdapter.cs" />
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
|
||||||
using NzbDrone.Host.AccessControl;
|
using NzbDrone.Host.AccessControl;
|
||||||
|
|
||||||
namespace NzbDrone.Host.Owin
|
namespace NzbDrone.Host.Owin
|
||||||
@ -8,41 +7,26 @@ namespace NzbDrone.Host.Owin
|
|||||||
public class OwinHostController : IHostController
|
public class OwinHostController : IHostController
|
||||||
{
|
{
|
||||||
private readonly IOwinAppFactory _owinAppFactory;
|
private readonly IOwinAppFactory _owinAppFactory;
|
||||||
private readonly IRuntimeInfo _runtimeInfo;
|
private readonly IRemoteAccessAdapter _remoteAccessAdapter;
|
||||||
private readonly IUrlAclAdapter _urlAclAdapter;
|
private readonly IUrlAclAdapter _urlAclAdapter;
|
||||||
private readonly IFirewallAdapter _firewallAdapter;
|
|
||||||
private readonly ISslAdapter _sslAdapter;
|
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
private IDisposable _owinApp;
|
private IDisposable _owinApp;
|
||||||
|
|
||||||
public OwinHostController(
|
public OwinHostController(
|
||||||
IOwinAppFactory owinAppFactory,
|
IOwinAppFactory owinAppFactory,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRemoteAccessAdapter remoteAccessAdapter,
|
||||||
IUrlAclAdapter urlAclAdapter,
|
IUrlAclAdapter urlAclAdapter,
|
||||||
IFirewallAdapter firewallAdapter,
|
|
||||||
ISslAdapter sslAdapter,
|
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_owinAppFactory = owinAppFactory;
|
_owinAppFactory = owinAppFactory;
|
||||||
_runtimeInfo = runtimeInfo;
|
_remoteAccessAdapter = remoteAccessAdapter;
|
||||||
_urlAclAdapter = urlAclAdapter;
|
_urlAclAdapter = urlAclAdapter;
|
||||||
_firewallAdapter = firewallAdapter;
|
|
||||||
_sslAdapter = sslAdapter;
|
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void StartServer()
|
public void StartServer()
|
||||||
{
|
{
|
||||||
if (OsInfo.IsWindows)
|
_remoteAccessAdapter.MakeAccessible(true);
|
||||||
{
|
|
||||||
if (_runtimeInfo.IsAdmin)
|
|
||||||
{
|
|
||||||
_firewallAdapter.MakeAccessible();
|
|
||||||
_sslAdapter.Register();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_urlAclAdapter.ConfigureUrls();
|
|
||||||
|
|
||||||
_logger.Info("Listening on the following URLs:");
|
_logger.Info("Listening on the following URLs:");
|
||||||
foreach (var url in _urlAclAdapter.Urls)
|
foreach (var url in _urlAclAdapter.Urls)
|
||||||
@ -53,7 +37,6 @@ namespace NzbDrone.Host.Owin
|
|||||||
_owinApp = _owinAppFactory.CreateApp(_urlAclAdapter.Urls);
|
_owinApp = _owinAppFactory.CreateApp(_urlAclAdapter.Urls);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public void StopServer()
|
public void StopServer()
|
||||||
{
|
{
|
||||||
if (_owinApp == null) return;
|
if (_owinApp == null) return;
|
||||||
@ -63,8 +46,5 @@ namespace NzbDrone.Host.Owin
|
|||||||
_owinApp = null;
|
_owinApp = null;
|
||||||
_logger.Info("Host has stopped");
|
_logger.Info("Host has stopped");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
using NLog;
|
using NLog;
|
||||||
using NzbDrone.Common;
|
using NzbDrone.Common;
|
||||||
using NzbDrone.Common.EnvironmentInfo;
|
using NzbDrone.Common.EnvironmentInfo;
|
||||||
|
using NzbDrone.Common.Processes;
|
||||||
|
using NzbDrone.Host.AccessControl;
|
||||||
|
using IServiceProvider = NzbDrone.Common.IServiceProvider;
|
||||||
|
|
||||||
namespace NzbDrone.Host
|
namespace NzbDrone.Host
|
||||||
{
|
{
|
||||||
@ -10,18 +13,24 @@ namespace NzbDrone.Host
|
|||||||
private readonly IServiceProvider _serviceProvider;
|
private readonly IServiceProvider _serviceProvider;
|
||||||
private readonly IConsoleService _consoleService;
|
private readonly IConsoleService _consoleService;
|
||||||
private readonly IRuntimeInfo _runtimeInfo;
|
private readonly IRuntimeInfo _runtimeInfo;
|
||||||
|
private readonly IProcessProvider _processProvider;
|
||||||
|
private readonly IRemoteAccessAdapter _remoteAccessAdapter;
|
||||||
private readonly Logger _logger;
|
private readonly Logger _logger;
|
||||||
|
|
||||||
public Router(INzbDroneServiceFactory nzbDroneServiceFactory,
|
public Router(INzbDroneServiceFactory nzbDroneServiceFactory,
|
||||||
IServiceProvider serviceProvider,
|
IServiceProvider serviceProvider,
|
||||||
IConsoleService consoleService,
|
IConsoleService consoleService,
|
||||||
IRuntimeInfo runtimeInfo,
|
IRuntimeInfo runtimeInfo,
|
||||||
|
IProcessProvider processProvider,
|
||||||
|
IRemoteAccessAdapter remoteAccessAdapter,
|
||||||
Logger logger)
|
Logger logger)
|
||||||
{
|
{
|
||||||
_nzbDroneServiceFactory = nzbDroneServiceFactory;
|
_nzbDroneServiceFactory = nzbDroneServiceFactory;
|
||||||
_serviceProvider = serviceProvider;
|
_serviceProvider = serviceProvider;
|
||||||
_consoleService = consoleService;
|
_consoleService = consoleService;
|
||||||
_runtimeInfo = runtimeInfo;
|
_runtimeInfo = runtimeInfo;
|
||||||
|
_processProvider = processProvider;
|
||||||
|
_remoteAccessAdapter = remoteAccessAdapter;
|
||||||
_logger = logger;
|
_logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,8 +66,13 @@ namespace NzbDrone.Host
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
_remoteAccessAdapter.MakeAccessible(true);
|
||||||
_serviceProvider.Install(ServiceProvider.SERVICE_NAME);
|
_serviceProvider.Install(ServiceProvider.SERVICE_NAME);
|
||||||
_serviceProvider.Start(ServiceProvider.SERVICE_NAME);
|
_serviceProvider.SetPermissions(ServiceProvider.SERVICE_NAME);
|
||||||
|
|
||||||
|
// Start the service and exit.
|
||||||
|
// Ensures that there isn't an instance of Sonarr already running that the service account cannot stop.
|
||||||
|
_processProvider.SpawnNewProcess("sc.exe", $"start {ServiceProvider.SERVICE_NAME}", null, true);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -71,9 +85,16 @@ namespace NzbDrone.Host
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
_serviceProvider.UnInstall(ServiceProvider.SERVICE_NAME);
|
_serviceProvider.Uninstall(ServiceProvider.SERVICE_NAME);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case ApplicationModes.RegisterUrl:
|
||||||
|
{
|
||||||
|
_logger.Debug("Regiser URL selected");
|
||||||
|
_remoteAccessAdapter.MakeAccessible(false);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -32,7 +32,7 @@ namespace NzbDrone.Update.Test
|
|||||||
|
|
||||||
Subject.Start(AppType.Service, targetFolder);
|
Subject.Start(AppType.Service, targetFolder);
|
||||||
|
|
||||||
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\Sonarr\\Sonarr.Console.exe", "/" + StartupContext.NO_BROWSER, null), Times.Once());
|
Mocker.GetMock<IProcessProvider>().Verify(c => c.SpawnNewProcess("c:\\Sonarr\\Sonarr.Console.exe", "/" + StartupContext.NO_BROWSER, null, false), Times.Once());
|
||||||
|
|
||||||
ExceptionVerification.ExpectedWarns(1);
|
ExceptionVerification.ExpectedWarns(1);
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,11 @@ namespace ServiceInstall
|
|||||||
process.BeginOutputReadLine();
|
process.BeginOutputReadLine();
|
||||||
|
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
|
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e.Data);
|
Console.WriteLine(e.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,13 +50,11 @@ namespace ServiceUninstall
|
|||||||
process.BeginOutputReadLine();
|
process.BeginOutputReadLine();
|
||||||
|
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
|
private static void OnDataReceived(object sender, DataReceivedEventArgs e)
|
||||||
{
|
{
|
||||||
Console.WriteLine(e.Data);
|
Console.WriteLine(e.Data);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user