diff --git a/TGS.CommandLine/Program.cs b/TGS.CommandLine/Program.cs
index 262c2a4031..0e2986d944 100644
--- a/TGS.CommandLine/Program.cs
+++ b/TGS.CommandLine/Program.cs
@@ -52,7 +52,7 @@ namespace TGS.CommandLine
}
argsAsList.RemoveAt(I);
argsAsList.RemoveAt(I);
- ReplaceInterface(new ServerInterface(address, port, username, password));
+ ReplaceInterface(new ServerInterface(new RemoteLoginInfo(address, port, username, password)));
break;
}
}
@@ -230,7 +230,7 @@ namespace TGS.CommandLine
var username = Console.ReadLine();
Console.Write("Enter password: ");
var password = ReadLineSecure();
- ReplaceInterface(new ServerInterface(address, port, username, password));
+ ReplaceInterface(new ServerInterface(new RemoteLoginInfo(address, port, username, password)));
var res = currentInterface.ConnectionStatus(out string error);
if (!res.HasFlag(ConnectivityLevel.Connected))
{
diff --git a/TGS.ControlPanel/App.config b/TGS.ControlPanel/App.config
index f753d0fbb0..e5a8ddbf55 100644
--- a/TGS.ControlPanel/App.config
+++ b/TGS.ControlPanel/App.config
@@ -26,24 +26,9 @@
0
-
-
-
-
-
-
-
- 38607
-
False
-
-
-
-
-
-
diff --git a/TGS.ControlPanel/ControlPanel/ControlPanel.cs b/TGS.ControlPanel/ControlPanel/ControlPanel.cs
index a6d66c86a3..5ebbf73f1b 100644
--- a/TGS.ControlPanel/ControlPanel/ControlPanel.cs
+++ b/TGS.ControlPanel/ControlPanel/ControlPanel.cs
@@ -32,7 +32,7 @@ namespace TGS.ControlPanel
FormClosed += ControlPanel_FormClosed;
Interface = I;
if (Interface.IsRemoteConnection)
- Text = String.Format("TGS {0}: {1}:{2}", Interface.ServerVersion, Interface.HTTPSURL, Interface.HTTPSPort);
+ Text = String.Format("TGS {0}: {1}:{2}", Interface.ServerVersion, Interface.LoginInfo.IP, Interface.LoginInfo.Port);
Text = String.Format("{0} Instance: {1}", Text, I.InstanceName);
Panels.SelectedIndexChanged += Panels_SelectedIndexChanged;
Panels.SelectedIndex += Math.Min(Properties.Settings.Default.LastPageIndex, Panels.TabCount - 1);
diff --git a/TGS.ControlPanel/CountedForm.cs b/TGS.ControlPanel/CountedForm.cs
index 03ac979ab5..8f79f1c400 100644
--- a/TGS.ControlPanel/CountedForm.cs
+++ b/TGS.ControlPanel/CountedForm.cs
@@ -6,10 +6,9 @@ namespace TGS.ControlPanel
/// Calls when all s are d
///
#if !DEBUG
- abstract class CountedForm : ServerOpForm
-#else
- class CountedForm : ServerOpForm
+ abstract
#endif
+ class CountedForm : ServerOpForm
{
///
/// The current number of active s
diff --git a/TGS.ControlPanel/InstanceSelector.cs b/TGS.ControlPanel/InstanceSelector.cs
index 504b2218b9..0d8a606d74 100644
--- a/TGS.ControlPanel/InstanceSelector.cs
+++ b/TGS.ControlPanel/InstanceSelector.cs
@@ -100,7 +100,7 @@ namespace TGS.ControlPanel
activeCP.BringToFront();
return;
}
- var InstanceAccessor = new ServerInterface(masterInterface as ServerInterface);
+ var InstanceAccessor = new ServerInterface(masterInterface.LoginInfo);
try
{
ConnectivityLevel res = ConnectivityLevel.None;
diff --git a/TGS.ControlPanel/Login.Designer.cs b/TGS.ControlPanel/Login.Designer.cs
index 2e7a9afbc6..e4f9a30693 100644
--- a/TGS.ControlPanel/Login.Designer.cs
+++ b/TGS.ControlPanel/Login.Designer.cs
@@ -31,16 +31,17 @@
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Login));
this.LocalLoginButton = new System.Windows.Forms.Button();
this.CurrentRevisionTitle = new System.Windows.Forms.Label();
- this.IPTextBox = new System.Windows.Forms.TextBox();
this.UsernameTextBox = new System.Windows.Forms.TextBox();
this.PasswordTextBox = new System.Windows.Forms.TextBox();
this.RemoteLoginButton = new System.Windows.Forms.Button();
- this.label1 = new System.Windows.Forms.Label();
+ this.AddressLabel = new System.Windows.Forms.Label();
this.label2 = new System.Windows.Forms.Label();
this.label3 = new System.Windows.Forms.Label();
this.label4 = new System.Windows.Forms.Label();
this.PortSelector = new System.Windows.Forms.NumericUpDown();
this.SavePasswordCheckBox = new System.Windows.Forms.CheckBox();
+ this.IPComboBox = new System.Windows.Forms.ComboBox();
+ this.DeleteLoginButton = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.PortSelector)).BeginInit();
this.SuspendLayout();
//
@@ -50,7 +51,7 @@
this.LocalLoginButton.Location = new System.Drawing.Point(102, 12);
this.LocalLoginButton.Name = "LocalLoginButton";
this.LocalLoginButton.Size = new System.Drawing.Size(157, 25);
- this.LocalLoginButton.TabIndex = 13;
+ this.LocalLoginButton.TabIndex = 1;
this.LocalLoginButton.Text = "Connect to Local Service";
this.LocalLoginButton.UseVisualStyleBackColor = true;
this.LocalLoginButton.Click += new System.EventHandler(this.LocalLoginButton_Click);
@@ -67,13 +68,6 @@
this.CurrentRevisionTitle.Text = "Remote Login:";
this.CurrentRevisionTitle.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
- // IPTextBox
- //
- this.IPTextBox.Location = new System.Drawing.Point(129, 99);
- this.IPTextBox.Name = "IPTextBox";
- this.IPTextBox.Size = new System.Drawing.Size(146, 20);
- this.IPTextBox.TabIndex = 15;
- //
// UsernameTextBox
//
this.UsernameTextBox.Location = new System.Drawing.Point(129, 132);
@@ -100,17 +94,17 @@
this.RemoteLoginButton.UseVisualStyleBackColor = true;
this.RemoteLoginButton.Click += new System.EventHandler(this.RemoteLoginButton_Click);
//
- // label1
+ // AddressLabel
//
- this.label1.AutoSize = true;
- this.label1.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
- this.label1.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
- this.label1.Location = new System.Drawing.Point(9, 99);
- this.label1.Name = "label1";
- this.label1.Size = new System.Drawing.Size(120, 18);
- this.label1.TabIndex = 19;
- this.label1.Text = "Address/Port:";
- this.label1.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
+ this.AddressLabel.AutoSize = true;
+ this.AddressLabel.Font = new System.Drawing.Font("Verdana", 12F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
+ this.AddressLabel.ForeColor = System.Drawing.Color.FromArgb(((int)(((byte)(248)))), ((int)(((byte)(248)))), ((int)(((byte)(242)))));
+ this.AddressLabel.Location = new System.Drawing.Point(9, 99);
+ this.AddressLabel.Name = "AddressLabel";
+ this.AddressLabel.Size = new System.Drawing.Size(80, 18);
+ this.AddressLabel.TabIndex = 19;
+ this.AddressLabel.Text = "Address:";
+ this.AddressLabel.TextAlign = System.Drawing.ContentAlignment.MiddleCenter;
//
// label2
//
@@ -165,7 +159,7 @@
this.PortSelector.Size = new System.Drawing.Size(80, 20);
this.PortSelector.TabIndex = 16;
this.PortSelector.Value = new decimal(new int[] {
- 1,
+ 38607,
0,
0,
0});
@@ -182,22 +176,42 @@
this.SavePasswordCheckBox.UseVisualStyleBackColor = true;
this.SavePasswordCheckBox.CheckedChanged += new System.EventHandler(this.SavePasswordCheckBox_CheckedChanged);
//
+ // IPComboBox
+ //
+ this.IPComboBox.FormattingEnabled = true;
+ this.IPComboBox.Location = new System.Drawing.Point(130, 98);
+ this.IPComboBox.Name = "IPComboBox";
+ this.IPComboBox.Size = new System.Drawing.Size(146, 21);
+ this.IPComboBox.TabIndex = 24;
+ //
+ // DeleteLoginButton
+ //
+ this.DeleteLoginButton.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
+ this.DeleteLoginButton.Location = new System.Drawing.Point(105, 98);
+ this.DeleteLoginButton.Name = "DeleteLoginButton";
+ this.DeleteLoginButton.Size = new System.Drawing.Size(19, 19);
+ this.DeleteLoginButton.TabIndex = 25;
+ this.DeleteLoginButton.Text = "x";
+ this.DeleteLoginButton.UseVisualStyleBackColor = true;
+ this.DeleteLoginButton.Click += new System.EventHandler(this.DeleteLoginButton_Click);
+ //
// Login
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.FromArgb(((int)(((byte)(39)))), ((int)(((byte)(40)))), ((int)(((byte)(34)))));
this.ClientSize = new System.Drawing.Size(374, 237);
+ this.Controls.Add(this.DeleteLoginButton);
+ this.Controls.Add(this.IPComboBox);
this.Controls.Add(this.SavePasswordCheckBox);
this.Controls.Add(this.PortSelector);
this.Controls.Add(this.label4);
this.Controls.Add(this.label3);
this.Controls.Add(this.label2);
- this.Controls.Add(this.label1);
+ this.Controls.Add(this.AddressLabel);
this.Controls.Add(this.RemoteLoginButton);
this.Controls.Add(this.PasswordTextBox);
this.Controls.Add(this.UsernameTextBox);
- this.Controls.Add(this.IPTextBox);
this.Controls.Add(this.CurrentRevisionTitle);
this.Controls.Add(this.LocalLoginButton);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
@@ -216,15 +230,16 @@
private System.Windows.Forms.Button LocalLoginButton;
private System.Windows.Forms.Label CurrentRevisionTitle;
- private System.Windows.Forms.TextBox IPTextBox;
private System.Windows.Forms.TextBox UsernameTextBox;
private System.Windows.Forms.TextBox PasswordTextBox;
private System.Windows.Forms.Button RemoteLoginButton;
- private System.Windows.Forms.Label label1;
+ private System.Windows.Forms.Label AddressLabel;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Label label4;
private System.Windows.Forms.NumericUpDown PortSelector;
private System.Windows.Forms.CheckBox SavePasswordCheckBox;
+ private System.Windows.Forms.ComboBox IPComboBox;
+ private System.Windows.Forms.Button DeleteLoginButton;
}
}
\ No newline at end of file
diff --git a/TGS.ControlPanel/Login.cs b/TGS.ControlPanel/Login.cs
index 8b03af0ee1..1a1328cbda 100644
--- a/TGS.ControlPanel/Login.cs
+++ b/TGS.ControlPanel/Login.cs
@@ -1,4 +1,5 @@
using System;
+using System.Collections.Specialized;
using System.Windows.Forms;
using TGS.Interface;
@@ -7,58 +8,123 @@ namespace TGS.ControlPanel
sealed partial class Login : CountedForm
{
///
- /// Create a form
+ /// Currently selected saved
///
+ RemoteLoginInfo currentLoginInfo;
+
+ bool updatingFields;
+
+ ///
+ /// Construct a
+ ///
public Login()
{
InitializeComponent();
var Config = Properties.Settings.Default;
- IPTextBox.Text = Config.RemoteIP;
- UsernameTextBox.Text = Config.RemoteUsername;
- PortSelector.Value = Config.RemotePort;
AcceptButton = RemoteLoginButton;
if(Config.RemoteDefault)
RemoteLoginButton.TabIndex = 0; //make this the first thing selected when loading
- var decrypted = Helpers.DecryptData(Config.RemotePassword, Config.RemoteEntropy);
- if (decrypted != null)
+
+ IPComboBox.SelectedIndexChanged += IPComboBox_SelectedIndexChanged;
+ var loginInfo = Config.RemoteLoginInfo;
+ if (loginInfo != null)
{
- PasswordTextBox.Text = decrypted;
- SavePasswordCheckBox.Checked = true;
+ foreach(var I in loginInfo)
+ IPComboBox.Items.Add(new RemoteLoginInfo(I));
+ if (IPComboBox.Items.Count > 0)
+ IPComboBox.SelectedIndex = 0;
}
+
+ UsernameTextBox.TextChanged += (a, b) => ClearFields();
+ PortSelector.ValueChanged += (a, b) => ClearFields();
+ PasswordTextBox.TextChanged += (a, b) => ClearFields();
+ IPComboBox.TextChanged += (a, b) => ClearFields();
}
- private void RemoteLoginButton_Click(object sender, EventArgs e)
+ void ClearFields()
{
- IPTextBox.Text = IPTextBox.Text.Trim();
- UsernameTextBox.Text = UsernameTextBox.Text.Trim();
- using (var I = new ServerInterface(IPTextBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text, PasswordTextBox.Text))
+ if (updatingFields || currentLoginInfo == null)
+ return;
+ updatingFields = true;
+ currentLoginInfo = null;
+ IPComboBox.Text = "";
+ PortSelector.Value = 38607;
+ UsernameTextBox.Text = "";
+ PasswordTextBox.Text = "";
+ updatingFields = false;
+ }
+
+ void IPComboBox_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ currentLoginInfo = IPComboBox.SelectedItem as RemoteLoginInfo;
+ //new thing
+ if (currentLoginInfo == null)
+ {
+ ClearFields();
+ return;
+ }
+ updatingFields = true;
+ IPComboBox.Text = currentLoginInfo.IP;
+ PortSelector.Value = currentLoginInfo.Port;
+ UsernameTextBox.Text = currentLoginInfo.Username;
+ SavePasswordCheckBox.Checked = currentLoginInfo.HasPassword;
+ if (currentLoginInfo.HasPassword)
+ PasswordTextBox.Text = "************";
+ else
+ PasswordTextBox.Text = "";
+ updatingFields = false;
+ }
+
+ void RemoteLoginButton_Click(object sender, EventArgs e)
+ {
+ if (String.IsNullOrWhiteSpace(PasswordTextBox.Text) || String.IsNullOrWhiteSpace(UsernameTextBox.Text) || String.IsNullOrWhiteSpace(IPComboBox.Text) || PortSelector.Value == 0)
+ return;
+
+ RemoteLoginInfo loginInfo;
+ if (currentLoginInfo == null)
+ {
+ loginInfo = new RemoteLoginInfo(IPComboBox.Text, (ushort)PortSelector.Value, UsernameTextBox.Text.Trim(), PasswordTextBox.Text);
+ }
+ else
+ {
+ loginInfo = (RemoteLoginInfo)IPComboBox.SelectedItem;
+ if (!loginInfo.HasPassword)
+ loginInfo.Password = PasswordTextBox.Text;
+ }
+
+ using (var I = new ServerInterface(loginInfo))
{
var Config = Properties.Settings.Default;
- Config.RemoteIP = IPTextBox.Text;
- Config.RemotePort = (ushort)PortSelector.Value;
- Config.RemoteUsername = UsernameTextBox.Text;
- if (SavePasswordCheckBox.Checked)
+ //This needs to be read here because V&C Closing us will corrupt the data
+ var savePassword = SavePasswordCheckBox.Checked;
+ if (VerifyAndConnect(I))
{
- Config.RemotePassword = Helpers.EncryptData(PasswordTextBox.Text, out string entrop);
- Config.RemoteEntropy = entrop;
+ Config.RemoteDefault = true;
+
+ if (!savePassword)
+ loginInfo.Password = null;
+
+ Config.RemoteLoginInfo = new StringCollection { loginInfo.ToJSON() };
+
+ foreach (RemoteLoginInfo info in IPComboBox.Items)
+ if (!info.Equals(loginInfo))
+ Config.RemoteLoginInfo.Add(info.ToJSON());
}
- else
- {
- Config.RemotePassword = null;
- Config.RemoteEntropy = null;
- }
- Config.RemoteDefault = true;
- VerifyAndConnect(I);
}
}
- private void LocalLoginButton_Click(object sender, EventArgs e)
+ void LocalLoginButton_Click(object sender, EventArgs e)
{
Properties.Settings.Default.RemoteDefault = false;
VerifyAndConnect(new ServerInterface());
}
- void VerifyAndConnect(IServerInterface I)
+ ///
+ /// Attempts a connection on a given
+ ///
+ /// The to attempt a connection on
+ /// if the connection was made and authenticated, otherwise
+ bool VerifyAndConnect(IServerInterface I)
{
try
{
@@ -66,19 +132,20 @@ namespace TGS.ControlPanel
if (!res.HasFlag(ConnectivityLevel.Connected))
{
MessageBox.Show("Unable to connect to service! Error: " + error);
- return;
+ return false;
}
if (!res.HasFlag(ConnectivityLevel.Authenticated))
{
MessageBox.Show("Authentication error: Username/password/windows identity is not authorized! Ensure you are a system administrator or in the correct Windows group on the service machine.");
- return;
+ return false;
}
if (I.VersionMismatch(out error) && MessageBox.Show(error, "Warning", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
- return;
+ return true;
new InstanceSelector(I).Show();
Close();
+ return true;
}
catch
{
@@ -87,14 +154,26 @@ namespace TGS.ControlPanel
}
}
- private void SavePasswordCheckBox_CheckedChanged(object sender, EventArgs e)
+ void SavePasswordCheckBox_CheckedChanged(object sender, EventArgs e)
{
- if (!SavePasswordCheckBox.Checked)
+ if (!updatingFields && !SavePasswordCheckBox.Checked && currentLoginInfo != null)
{
- var Config = Properties.Settings.Default;
- Config.RemotePassword = null;
- Config.RemoteEntropy = null;
+ currentLoginInfo = null;
+ PasswordTextBox.Text = "";
}
}
+
+ ///
+ /// Removes the selected item from
+ ///
+ /// The sender of the event
+ /// The
+ void DeleteLoginButton_Click(object sender, EventArgs e)
+ {
+ //make sure we're trying to delete a real item
+ if (IPComboBox.SelectedItem as RemoteLoginInfo == null)
+ return;
+ IPComboBox.Items.RemoveAt(IPComboBox.SelectedIndex);
+ }
}
}
diff --git a/TGS.ControlPanel/Properties/Settings.Designer.cs b/TGS.ControlPanel/Properties/Settings.Designer.cs
index 50131930ce..391f1eca5b 100644
--- a/TGS.ControlPanel/Properties/Settings.Designer.cs
+++ b/TGS.ControlPanel/Properties/Settings.Designer.cs
@@ -73,37 +73,12 @@ namespace TGS.ControlPanel.Properties {
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string RemoteIP {
+ public global::System.Collections.Specialized.StringCollection RemoteLoginInfo {
get {
- return ((string)(this["RemoteIP"]));
+ return ((global::System.Collections.Specialized.StringCollection)(this["RemoteLoginInfo"]));
}
set {
- this["RemoteIP"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string RemoteUsername {
- get {
- return ((string)(this["RemoteUsername"]));
- }
- set {
- this["RemoteUsername"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("38607")]
- public ushort RemotePort {
- get {
- return ((ushort)(this["RemotePort"]));
- }
- set {
- this["RemotePort"] = value;
+ this["RemoteLoginInfo"] = value;
}
}
@@ -119,30 +94,6 @@ namespace TGS.ControlPanel.Properties {
}
}
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string RemotePassword {
- get {
- return ((string)(this["RemotePassword"]));
- }
- set {
- this["RemotePassword"] = value;
- }
- }
-
- [global::System.Configuration.UserScopedSettingAttribute()]
- [global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
- [global::System.Configuration.DefaultSettingValueAttribute("")]
- public string RemoteEntropy {
- get {
- return ((string)(this["RemoteEntropy"]));
- }
- set {
- this["RemoteEntropy"] = value;
- }
- }
-
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
diff --git a/TGS.ControlPanel/Properties/Settings.settings b/TGS.ControlPanel/Properties/Settings.settings
index 2a1efd2454..f2be0bac77 100644
--- a/TGS.ControlPanel/Properties/Settings.settings
+++ b/TGS.ControlPanel/Properties/Settings.settings
@@ -14,24 +14,12 @@
0
-
+
-
-
-
-
- 38607
-
False
-
-
-
-
-
-
diff --git a/TGS.ControlPanel/ServerOpForm.cs b/TGS.ControlPanel/ServerOpForm.cs
index d3843c7c2b..c8aba31166 100644
--- a/TGS.ControlPanel/ServerOpForm.cs
+++ b/TGS.ControlPanel/ServerOpForm.cs
@@ -8,10 +8,9 @@ namespace TGS.ControlPanel
/// Used to provide an ATP function for calls into an
///
#if !DEBUG
- abstract class ServerOpForm : Form
-#else
- class ServerOpForm : Form
+ abstract
#endif
+ class ServerOpForm : Form
{
///
/// Used to wrap calls in a non-blocking fashion while disabling the and enabling the wait cursor
diff --git a/TGS.Interface/RemoteLoginInfo.cs b/TGS.Interface/RemoteLoginInfo.cs
new file mode 100644
index 0000000000..abdd76c4ee
--- /dev/null
+++ b/TGS.Interface/RemoteLoginInfo.cs
@@ -0,0 +1,133 @@
+using System;
+using System.Collections.Generic;
+using System.Web.Script.Serialization;
+
+namespace TGS.Interface
+{
+ ///
+ /// Information representing a remote server connection
+ ///
+ public sealed class RemoteLoginInfo : IEquatable
+ {
+ ///
+ /// Used for serialization
+ ///
+ const string EntropyFormatter = "{0}Entropy";
+
+ ///
+ /// The IP address or URL of the target server
+ ///
+ public string IP { get { return _ip; } }
+ ///
+ /// The port to connect to the target server
+ ///
+ public ushort Port { get { return _port; } }
+ ///
+ /// A Windows username for the target server
+ ///
+ public string Username { get { return _username; } }
+ ///
+ /// The Windows password for
+ ///
+ public string Password { internal get; set; }
+ ///
+ /// Check if the has been initialized with a
+ ///
+ [ScriptIgnore]
+ public bool HasPassword { get { return !String.IsNullOrWhiteSpace(Password); } }
+
+ ///
+ /// Backing field for
+ ///
+ readonly string _ip;
+ ///
+ /// Backing field for
+ ///
+ readonly ushort _port;
+ ///
+ /// Backing field for
+ ///
+ readonly string _username;
+
+ ///
+ /// Construct a
+ ///
+ /// The value for
+ /// The value for
+ /// The value for
+ /// The value for
+ public RemoteLoginInfo(string ip, ushort port, string username, string password)
+ {
+ if (String.IsNullOrWhiteSpace(ip))
+ throw new InvalidOperationException("ip must be set!");
+ _ip = ip;
+ if (port == 0)
+ throw new InvalidOperationException("port may not be 0!");
+ _port = port;
+ if (String.IsNullOrWhiteSpace(username))
+ throw new InvalidOperationException("username must be set!");
+ _username = username;
+ Password = password;
+ }
+
+ ///
+ /// Construct a from JSON
+ ///
+ /// The result of a call to
+ public RemoteLoginInfo(string json)
+ {
+ var dic = new JavaScriptSerializer().Deserialize>(json);
+ var ip = (string)dic[nameof(IP)];
+ if (String.IsNullOrWhiteSpace(ip))
+ throw new InvalidOperationException("ip must be set!");
+ _ip = ip;
+ var port = (ushort)(int)dic[nameof(Port)];
+ if (port == 0)
+ throw new InvalidOperationException("port may not be 0!");
+ _port = port;
+ var username = (string)dic[nameof(Username)];
+ if (String.IsNullOrWhiteSpace(username))
+ throw new InvalidOperationException("username must be set!");
+ _username = username;
+ if(dic.ContainsKey(nameof(Password)))
+ Password = Helpers.DecryptData((string)dic[nameof(Password)], (string)dic[String.Format(EntropyFormatter, nameof(Password))]);
+ }
+
+ ///
+ /// Returns
+ ///
+ ///
+ public override string ToString()
+ {
+ return IP;
+ }
+
+ ///
+ /// Checks if another matches one
+ ///
+ /// Another
+ /// if and have the same , , and
+ public bool Equals(RemoteLoginInfo other)
+ {
+ return other != null && IP == other.IP && Port == other.Port && Username == other.Username;
+ }
+
+ ///
+ /// Returns a JSON representation of the with the encrypted
+ ///
+ /// A JSON representation of the
+ public string ToJSON()
+ {
+ //serialize it to a dic first so we can store the entropy
+ var serializer = new JavaScriptSerializer();
+ var raw = serializer.Serialize(this);
+ var dic = serializer.Deserialize>(raw);
+ if (HasPassword)
+ {
+ dic.Add(nameof(Password), Helpers.EncryptData(Password, out string entropy));
+ dic.Add(String.Format(EntropyFormatter, nameof(Password)), entropy);
+ }
+ return serializer.Serialize(dic);
+ }
+ }
+}
diff --git a/TGS.Interface/ServerInterface.cs b/TGS.Interface/ServerInterface.cs
index 833b9c5574..142e08357d 100644
--- a/TGS.Interface/ServerInterface.cs
+++ b/TGS.Interface/ServerInterface.cs
@@ -1,6 +1,5 @@
using System;
using System.Collections.Generic;
-using System.Diagnostics;
using System.Linq;
using System.Net;
using System.Net.Security;
@@ -27,14 +26,9 @@ namespace TGS.Interface
string InstanceName { get; }
///
- /// If this is set, we will try and connect to an HTTPS server running at this address
+ /// The for the . Is for local connections
///
- string HTTPSURL { get; }
-
- ///
- /// The port used to connect to the
- ///
- ushort HTTPSPort { get; }
+ RemoteLoginInfo LoginInfo { get; }
///
/// Checks if the is setup for a remote connection
@@ -151,30 +145,12 @@ namespace TGS.Interface
public string InstanceName { get; private set; }
///
- /// If this is set, we will try and connect to an HTTPS server running at this address
+ /// Backing field for
///
- readonly string _HTTPSURL;
+ readonly RemoteLoginInfo _loginInfo;
///
- public string HTTPSURL { get { return _HTTPSURL; } }
-
- ///
- /// The port used to connect to the
- ///
- readonly ushort _HTTPSPort;
-
- ///
- public ushort HTTPSPort { get { return _HTTPSPort; } }
-
- ///
- /// Username for remote operations
- ///
- readonly string HTTPSUsername;
-
- ///
- /// Password for remote operations
- ///
- readonly string HTTPSPassword;
+ public RemoteLoginInfo LoginInfo { get { return _loginInfo; } }
///
/// Associated list of open s keyed by type name. A in this list may close or fault at any time. Must be locked before being accessed
@@ -237,24 +213,14 @@ namespace TGS.Interface
///
/// Construct an for a remote connection
///
- /// The address of the remote server
- /// The port the remote server runs on
- /// Windows account username for the remote server
- /// Windows account password for the remote server
- public ServerInterface(string address, ushort port, string username, string password)
+ /// The for a remote connection
+ public ServerInterface(RemoteLoginInfo loginInfo)
{
- _HTTPSURL = address;
- _HTTPSPort = port;
- HTTPSUsername = username;
- HTTPSPassword = password;
+ if (!loginInfo.HasPassword)
+ throw new InvalidOperationException("password must be set on loginInfo!");
+ _loginInfo = loginInfo;
}
- ///
- /// Constructs an that connects to the same as some
- ///
- /// Another to copy settings from
- public ServerInterface(ServerInterface other) : this(other.HTTPSURL, other.HTTPSPort, other.HTTPSUsername, other.HTTPSPassword) { }
-
///
public ConnectivityLevel ConnectToInstance(string instanceName = null, bool skipChecks = false)
{
@@ -297,7 +263,7 @@ namespace TGS.Interface
}
///
- public bool IsRemoteConnection { get { return HTTPSURL != null; } }
+ public bool IsRemoteConnection { get { return LoginInfo != null; } }
///
/// Closes all s stored in and clears it
@@ -436,12 +402,13 @@ namespace TGS.Interface
binding.Security.Transport.ClientCredentialType = HttpClientCredentialType.None;
binding.Security.Mode = requireAuth ? SecurityMode.TransportWithMessageCredential : SecurityMode.Transport; //do not require auth for a connectivity check
binding.Security.Message.ClientCredentialType = requireAuth ? MessageCredentialType.UserName : MessageCredentialType.None;
- var address = new EndpointAddress(String.Format("https://{0}:{1}/{2}/{3}", HTTPSURL, HTTPSPort, accessPath, InterfaceName));
+ var url = String.Format("https://{0}:{1}/{2}/{3}", LoginInfo.IP, LoginInfo.Port, accessPath, InterfaceName);
+ var address = new EndpointAddress(url);
var res = new ChannelFactory(binding, address);
if (requireAuth)
{
- res.Credentials.UserName.UserName = HTTPSUsername;
- res.Credentials.UserName.Password = HTTPSPassword;
+ res.Credentials.UserName.UserName = LoginInfo.Username;
+ res.Credentials.UserName.Password = LoginInfo.Password;
res.Credentials.Windows.AllowedImpersonationLevel = TokenImpersonationLevel.Impersonation;
}
return res;
@@ -460,7 +427,7 @@ namespace TGS.Interface
{
GetComponentImpl(false).VerifyConnection();
}
- catch (CommunicationException e)
+ catch (Exception e)
{
error = e.ToString();
return ConnectivityLevel.None;
diff --git a/TGS.Interface/TGS.Interface.csproj b/TGS.Interface/TGS.Interface.csproj
index fa07f5838f..7fcfc32cbb 100644
--- a/TGS.Interface/TGS.Interface.csproj
+++ b/TGS.Interface/TGS.Interface.csproj
@@ -65,6 +65,7 @@
+
diff --git a/TGS.Tests/ServiceInterface/TestInterface.cs b/TGS.Tests/ServiceInterface/TestInterface.cs
index cd4f55ac9d..79552086ef 100644
--- a/TGS.Tests/ServiceInterface/TestInterface.cs
+++ b/TGS.Tests/ServiceInterface/TestInterface.cs
@@ -52,7 +52,7 @@ namespace TGS.Interface.Tests
/// The created
ServerInterface CreateFakeRemoteInterface()
{
- return new ServerInterface("some.fake.url.420", 34752, "user", "password");
+ return new ServerInterface(new RemoteLoginInfo("some.fake.url.420", 34752, "user", "password"));
}
///
@@ -77,9 +77,11 @@ namespace TGS.Interface.Tests
public void TestCopyRemoteInterface()
{
var first = CreateFakeRemoteInterface();
- var second = new ServerInterface(first);
- Assert.AreEqual(first.HTTPSURL, second.HTTPSURL);
- Assert.AreEqual(first.HTTPSPort, second.HTTPSPort);
+ var second = new ServerInterface(first.LoginInfo);
+ Assert.AreEqual(first.LoginInfo.IP, second.LoginInfo.IP);
+ Assert.AreEqual(first.LoginInfo.Port, second.LoginInfo.Port);
+ Assert.AreEqual(first.LoginInfo.Username, second.LoginInfo.Username);
+ Assert.AreEqual(first.LoginInfo.Password, second.LoginInfo.Password);
Assert.IsTrue(second.IsRemoteConnection);
}