diff --git a/Agent.Installer.Win/Agent.Installer.Win.csproj b/Agent.Installer.Win/Agent.Installer.Win.csproj index 71e2b718..9bcc3460 100644 --- a/Agent.Installer.Win/Agent.Installer.Win.csproj +++ b/Agent.Installer.Win/Agent.Installer.Win.csproj @@ -117,9 +117,6 @@ Models\ConnectionInfo.cs - - Models\InstallerSettings.cs - diff --git a/Agent.Installer.Win/MainWindow.xaml b/Agent.Installer.Win/MainWindow.xaml index de265e72..87a5af68 100644 --- a/Agent.Installer.Win/MainWindow.xaml +++ b/Agent.Installer.Win/MainWindow.xaml @@ -45,14 +45,30 @@ + - - + + Server URL: + + + + + + Organization ID: + + + - - diff --git a/Agent.Installer.Win/ViewModels/MainWindowViewModel.cs b/Agent.Installer.Win/ViewModels/MainWindowViewModel.cs index 958fda48..cc5f3231 100644 --- a/Agent.Installer.Win/ViewModels/MainWindowViewModel.cs +++ b/Agent.Installer.Win/ViewModels/MainWindowViewModel.cs @@ -104,8 +104,8 @@ namespace Remotely.Agent.Installer.Win.ViewModels }); } } - public string OrganizationID { get; set; } - public string OrganizationName + + public string OrganizationID { get { @@ -114,7 +114,7 @@ namespace Remotely.Agent.Installer.Win.ViewModels set { organizationName = value; - FirePropertyChanged(nameof(OrganizationName)); + FirePropertyChanged(nameof(OrganizationID)); } } @@ -190,14 +190,18 @@ namespace Remotely.Agent.Installer.Win.ViewModels "Reinstalling will retain the current settings and install the service again."; } - var installerSettings = ReadInstallerSettings(); - - OrganizationName = installerSettings?.OrganizationName; - ServerUrl = installerSettings?.ServerUrl; - OrganizationID = installerSettings?.OrganizationID; - CopyCommandLineArgs(); + var fileName = Path.GetFileNameWithoutExtension(Assembly.GetExecutingAssembly().Location); + if (fileName.Length > 36) + { + var guid = fileName.Substring(fileName.Length - 36); + if (Guid.TryParse(guid, out _)) + { + OrganizationID = guid; + } + } + if (CommandLineParser.CommandLineArgs.ContainsKey("install")) { await Install(null); @@ -206,10 +210,6 @@ namespace Remotely.Agent.Installer.Win.ViewModels { await Uninstall(null); } - else - { - CheckParams(); - } if (CommandLineParser.CommandLineArgs.ContainsKey("quiet")) { @@ -217,32 +217,6 @@ namespace Remotely.Agent.Installer.Win.ViewModels } } - public InstallerSettings ReadInstallerSettings() - { - try - { - var fileBytes = File.ReadAllBytes(Assembly.GetExecutingAssembly().Location); - using (var peStream = new MemoryStream(fileBytes)) - using (var br = new BinaryReader(peStream)) - { - peStream.Seek(-4, SeekOrigin.End); - var payloadSize = br.ReadInt32(); - peStream.Seek(-4 - payloadSize, SeekOrigin.End); - var payloadBytes = br.ReadBytes(payloadSize); - var payloadJson = Encoding.UTF8.GetString(payloadBytes); - var serializer = new JavaScriptSerializer(); - var installerSettings = serializer.Deserialize(payloadJson); - return installerSettings; - } - } - catch (Exception ex) - { - Logger.Write(ex); - MessageBoxEx.Show("There was an error reading the installer settings. Try re-downloading the installer.", "Configuration Error", MessageBoxButton.OK, MessageBoxImage.Error); - return null; - } - } - private bool CheckIsAdministrator() { var identity = WindowsIdentity.GetCurrent(); @@ -260,18 +234,13 @@ namespace Remotely.Agent.Installer.Win.ViewModels var result = !string.IsNullOrWhiteSpace(OrganizationID) || !string.IsNullOrWhiteSpace(ServerUrl); if (!result) { - MessageBoxEx.Show("Required settings are missing. Try re-downloading the installer.", "Invalid Installer", MessageBoxButton.OK, MessageBoxImage.Error); + MessageBoxEx.Show("Required settings are missing. Please enter a server URL and organization ID.", "Invalid Installer", MessageBoxButton.OK, MessageBoxImage.Error); } return result; } private void CopyCommandLineArgs() { - if (CommandLineParser.CommandLineArgs.TryGetValue("organization", out var orgName)) - { - OrganizationName = orgName; - } - if (CommandLineParser.CommandLineArgs.TryGetValue("organizationid", out var orgID)) { OrganizationID = orgID; @@ -301,11 +270,6 @@ namespace Remotely.Agent.Installer.Win.ViewModels { ServerUrl = ServerUrl.Substring(0, ServerUrl.LastIndexOf("/")); } - - if (string.IsNullOrWhiteSpace(OrganizationName)) - { - OrganizationName = "(IT provider has not set a name.)"; - } } private async Task Install(object param) { @@ -347,8 +311,6 @@ namespace Remotely.Agent.Installer.Win.ViewModels } } - - private async Task Uninstall(object param) { try diff --git a/Server/API/ClientDownloadsController.cs b/Server/API/ClientDownloadsController.cs index 48f36c02..05cc0c65 100644 --- a/Server/API/ClientDownloadsController.cs +++ b/Server/API/ClientDownloadsController.cs @@ -70,27 +70,9 @@ namespace Remotely.Server.API { case "Windows": { - fileName = $"Remotely_Installer.exe"; + fileName = $"Remotely_Installer-{organizationID}.exe"; var filePath = Path.Combine(HostEnv.WebRootPath, "Downloads", $"{fileName}"); - var installerBytes = await System.IO.File.ReadAllBytesAsync(filePath); - - var installerSettings = new InstallerSettings() - { - OrganizationID = organizationID, - ServerUrl = $"{scheme}://{Request.Host}", - OrganizationName = organizationName - }; - - using (var ms = new MemoryStream()) - using (var br = new BinaryWriter(ms)) - { - var payloadBytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(installerSettings)); - br.Write(installerBytes); - br.Write(payloadBytes); - br.Write(payloadBytes.Length); - ms.Seek(0, SeekOrigin.Begin); - fileBytes = ms.ToArray(); - } + fileBytes = await System.IO.File.ReadAllBytesAsync(filePath); break; } // TODO: Remove after a few versions. diff --git a/Server/Areas/Identity/Pages/Account/Register.cshtml.cs b/Server/Areas/Identity/Pages/Account/Register.cshtml.cs index 6ae4abef..746d7ac6 100644 --- a/Server/Areas/Identity/Pages/Account/Register.cshtml.cs +++ b/Server/Areas/Identity/Pages/Account/Register.cshtml.cs @@ -88,7 +88,14 @@ namespace Remotely.Server.Areas.Identity.Pages.Account ExternalLogins = (await _signInManager.GetExternalAuthenticationSchemesAsync()).ToList(); if (ModelState.IsValid) { - var (result, user) = await _dataService.CreateUser(Input.Email, Input.Password, true); + var user = new RemotelyUser + { + UserName = Input.Email, + Email = Input.Email, + IsServerAdmin = organizationCount == 0 + }; + var result = await _userManager.CreateAsync(user, Input.Password); + if (result.Succeeded) { _logger.LogInformation("User created a new account with password."); diff --git a/Server/Services/DataService.cs b/Server/Services/DataService.cs index 483366e6..bb0532ed 100644 --- a/Server/Services/DataService.cs +++ b/Server/Services/DataService.cs @@ -267,21 +267,6 @@ namespace Remotely.Server.Services return newToken; } - - public async Task<(IdentityResult, RemotelyUser)> CreateUser(string email, string password, bool isOrgAdmin) - { - var user = new RemotelyUser - { - UserName = email, - Email = email, - IsServerAdmin = RemotelyContext.Organizations.Count() == 0, - IsAdministrator = isOrgAdmin - }; - var result = await UserManager.CreateAsync(user, password); - - return (result, user); - } - public async Task DeleteApiToken(string userName, string tokenId) { var user = RemotelyContext.Users.FirstOrDefault(x => x.UserName == userName); diff --git a/Shared/Models/InstallerSettings.cs b/Shared/Models/InstallerSettings.cs deleted file mode 100644 index 68b5ef9e..00000000 --- a/Shared/Models/InstallerSettings.cs +++ /dev/null @@ -1,18 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Runtime.Serialization; -using System.Text; -using System.Threading.Tasks; - -namespace Remotely.Shared.Models -{ - public class InstallerSettings - { - public string OrganizationID { get; set; } - - public string OrganizationName { get; set; } - - public string ServerUrl { get; set; } - } -} diff --git a/Tests/DataServiceTests.cs b/Tests/DataServiceTests.cs index e40d1c77..3e24971a 100644 --- a/Tests/DataServiceTests.cs +++ b/Tests/DataServiceTests.cs @@ -127,5 +127,29 @@ namespace Remotely.Tests Assert.IsTrue(TestData.Device1.IsOnline); Assert.AreEqual(Environment.Is64BitOperatingSystem, TestData.Device1.Is64Bit); } + + [TestMethod] + [DoNotParallelize] + public async Task UpdateServerAdmins() + { + var currentAdmins = DataService.GetServerAdmins(); + Assert.AreEqual(1, currentAdmins.Count); + var newAdmins = new List() + { + TestData.Admin2.UserName + }; + + await DataService.UpdateServerAdmins(newAdmins, TestData.Admin1.UserName); + + currentAdmins = DataService.GetServerAdmins(); + Assert.AreEqual(2, currentAdmins.Count); + Assert.IsTrue(currentAdmins.Contains(TestData.Admin1.UserName)); + Assert.IsTrue(currentAdmins.Contains(TestData.Admin2.UserName)); + + await DataService.UpdateServerAdmins(newAdmins, TestData.Admin2.UserName); + currentAdmins = DataService.GetServerAdmins(); + Assert.AreEqual(1, currentAdmins.Count); + Assert.AreEqual(TestData.Admin2.UserName, currentAdmins[0]); + } } } diff --git a/Tests/TestData.cs b/Tests/TestData.cs index 37309c27..224e03cd 100644 --- a/Tests/TestData.cs +++ b/Tests/TestData.cs @@ -20,7 +20,8 @@ namespace Remotely.Tests public static RemotelyUser Admin1 { get; } = new RemotelyUser() { UserName = "admin1@test.com", - IsAdministrator = true + IsAdministrator = true, + IsServerAdmin = true }; public static RemotelyUser Admin2 { get; private set; } = new RemotelyUser()