mirror of
https://github.com/tgstation/tgstation-server.git
synced 2026-08-30 16:39:21 +01:00
Clean up how connectivity level is determined
This commit is contained in:
@@ -1,5 +1,4 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Generic;
|
||||
using TGServiceInterface;
|
||||
using TGServiceInterface.Components;
|
||||
|
||||
@@ -14,7 +13,7 @@ namespace TGCommandLine
|
||||
}
|
||||
public override string GetHelpText()
|
||||
{
|
||||
return "Manage server service authentication";
|
||||
return "Manage instance authentication";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+11
-11
@@ -64,21 +64,21 @@ namespace TGCommandLine
|
||||
return Command.ExitCode.BadCommand;
|
||||
}
|
||||
|
||||
var res = currentInterface.VerifyConnection();
|
||||
if (res != null)
|
||||
var res = currentInterface.ConnectionStatus(out string error);
|
||||
if (!res.HasFlag(ConnectivityLevel.Connected))
|
||||
{
|
||||
Console.WriteLine("Unable to connect to service: " + res);
|
||||
Console.WriteLine("Unable to connect to service: " + error);
|
||||
Console.WriteLine("Remote connection usage: <-c/--connect> username:password@address:port");
|
||||
return Command.ExitCode.ConnectionError;
|
||||
}
|
||||
|
||||
if (!currentInterface.Authenticate())
|
||||
if (!res.HasFlag(ConnectivityLevel.Authenticated))
|
||||
{
|
||||
Console.WriteLine("Authentication error: Username/password/windows identity is not authorized!");
|
||||
return Command.ExitCode.ConnectionError;
|
||||
}
|
||||
|
||||
if (!SentVMMWarning && currentInterface.VersionMismatch(out string error))
|
||||
if (!SentVMMWarning && currentInterface.VersionMismatch(out error))
|
||||
{
|
||||
SentVMMWarning = true;
|
||||
Console.WriteLine(error);
|
||||
@@ -190,13 +190,13 @@ namespace TGCommandLine
|
||||
Console.Write("Enter password: ");
|
||||
var password = ReadLineSecure();
|
||||
ReplaceInterface(new Interface(address, port, username, password));
|
||||
var res = currentInterface.VerifyConnection();
|
||||
if (res != null)
|
||||
var res = currentInterface.ConnectionStatus(out string error);
|
||||
if (!res.HasFlag(ConnectivityLevel.Connected))
|
||||
{
|
||||
Console.WriteLine("Unable to connect: " + res);
|
||||
Console.WriteLine("Unable to connect: " + error);
|
||||
ReplaceInterface(new Interface());
|
||||
}
|
||||
else if (!currentInterface.Authenticate())
|
||||
else if (!res.HasFlag(ConnectivityLevel.Authenticated))
|
||||
{
|
||||
Console.WriteLine("Authentication error: Username/password/windows identity is not authorized! Returning to local mode...");
|
||||
ReplaceInterface(new Interface());
|
||||
@@ -204,10 +204,10 @@ namespace TGCommandLine
|
||||
else
|
||||
{
|
||||
Console.WriteLine("Connected remotely");
|
||||
if (currentInterface.VersionMismatch(out res))
|
||||
if (currentInterface.VersionMismatch(out error))
|
||||
{
|
||||
SentVMMWarning = true;
|
||||
Console.WriteLine(res);
|
||||
Console.WriteLine(error);
|
||||
}
|
||||
Console.WriteLine("Type 'disconnect' to return to local mode");
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace TGCommandLine
|
||||
public CLICommand(Interface I)
|
||||
{
|
||||
var tmp = new List<Command> { new UpdateCommand(), new TestmergeCommand(), new RepoCommand(), new BYONDCommand(), new DMCommand(), new DDCommand(), new ConfigCommand(), new IRCCommand(), new DiscordCommand(), new AutoUpdateCommand(), new SetAutoUpdateCommand() };
|
||||
if (I.VerifyConnection() == null && I.Authenticate() && I.AuthenticateAdmin())
|
||||
if (I.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator))
|
||||
tmp.Add(new AdminCommand());
|
||||
Children = tmp.ToArray();
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace TGControlPanel
|
||||
|
||||
bool CheckAdminWithWarning()
|
||||
{
|
||||
if (!Interface.AuthenticateAdmin())
|
||||
if (!Interface.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator))
|
||||
{
|
||||
MessageBox.Show("Only system administrators may use this command!");
|
||||
return false;
|
||||
|
||||
@@ -62,13 +62,13 @@ namespace TGControlPanel
|
||||
|
||||
void VerifyAndConnect(Interface I)
|
||||
{
|
||||
var res = I.VerifyConnection();
|
||||
if (res != null)
|
||||
var res = I.ConnectionStatus(out string error);
|
||||
if (!res.HasFlag(ConnectivityLevel.Connected))
|
||||
{
|
||||
MessageBox.Show("Unable to connect to service! Error: " + res);
|
||||
MessageBox.Show("Unable to connect to service! Error: " + error);
|
||||
return;
|
||||
}
|
||||
if (!I.Authenticate())
|
||||
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;
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace TGControlPanel
|
||||
|
||||
void InitStaticPage()
|
||||
{
|
||||
if(!Interface.AuthenticateAdmin())
|
||||
if(!Interface.ConnectToInstance().HasFlag(ConnectivityLevel.Administrator))
|
||||
RecreateStaticButton.Visible = false;
|
||||
BuildFileList();
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace TGServiceInterface
|
||||
parsedArgs.AddRange(args);
|
||||
parsedArgs.RemoveAt(0);
|
||||
using (var I = new Interface())
|
||||
if(I.ConnectToInstanceImpl(parsedArgs[0], true).HasFlag(InstanceConnectivity.Connected))
|
||||
if(I.ConnectToInstanceImpl(parsedArgs[0], true).HasFlag(ConnectivityLevel.Connected))
|
||||
I.GetComponent<ITGInterop>().InteropMessage(String.Join(" ", parsedArgs));
|
||||
}
|
||||
catch { }
|
||||
|
||||
@@ -3,10 +3,10 @@
|
||||
namespace TGServiceInterface
|
||||
{
|
||||
/// <summary>
|
||||
/// Description of the connectivity level to an <see cref="Components.ITGInstance"/>
|
||||
/// Description of the connectivity level to an <see cref="Components.ITGInstance"/> or the <see cref="Components.ITGSService"/>
|
||||
/// </summary>
|
||||
[Flags]
|
||||
public enum InstanceConnectivity
|
||||
public enum ConnectivityLevel
|
||||
{
|
||||
/// <summary>
|
||||
/// The connection could not be made, either a communication error occurred or the specified <see cref="Components.ITGInstance"/> does not exist
|
||||
|
||||
@@ -116,26 +116,30 @@ namespace TGServiceInterface
|
||||
/// Targets <paramref name="instanceName"/> as the instance to use with <see cref="GetComponent{T}"/>. Closes all connections to any previous instance
|
||||
/// </summary>
|
||||
/// <param name="instanceName">The name of the instance to connect to</param>
|
||||
/// <returns>The apporopriate <see cref="InstanceConnectivity"/> value</returns>
|
||||
public InstanceConnectivity ConnectToInstance(string instanceName)
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
public ConnectivityLevel ConnectToInstance(string instanceName = null)
|
||||
{
|
||||
if (instanceName == null)
|
||||
instanceName = InstanceName;
|
||||
return ConnectToInstanceImpl(instanceName, false);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Targets <paramref name="instanceName"/> as the instance to use with <see cref="GetComponent{T}"/>. Closes all connections to any previous instance
|
||||
/// Targets <paramref name="instanceName"/> as the instance to use with <see cref="GetComponent{T}"/>. Closes all connections to any previous instance. Sets <see cref="InstanceName"/>
|
||||
/// </summary>
|
||||
/// <param name="instanceName">The name of the instance to connect to</param>
|
||||
/// <param name="skipAuthChecks">If set to <see langword="true"/>, skips the connectivity and authentication checks and returns <see cref="InstanceConnectivity.Connected"/></param>
|
||||
/// <returns>The apporopriate <see cref="InstanceConnectivity"/> value</returns>
|
||||
internal InstanceConnectivity ConnectToInstanceImpl(string instanceName, bool skipAuthChecks) {
|
||||
if (VerifyConnection() != null)
|
||||
return InstanceConnectivity.None;
|
||||
/// <param name="skipAuthChecks">If set to <see langword="true"/>, skips the connectivity and authentication checks and returns <see cref="ConnectivityLevel.Connected"/></param>
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
internal ConnectivityLevel ConnectToInstanceImpl(string instanceName, bool skipAuthChecks)
|
||||
{
|
||||
if (!ConnectionStatus().HasFlag(ConnectivityLevel.Connected))
|
||||
return ConnectivityLevel.None;
|
||||
var prevInstance = InstanceName;
|
||||
CloseAllChannels();
|
||||
if (prevInstance != instanceName)
|
||||
CloseAllChannels();
|
||||
InstanceName = instanceName;
|
||||
if (skipAuthChecks)
|
||||
return InstanceConnectivity.Connected;
|
||||
return ConnectivityLevel.Connected;
|
||||
try
|
||||
{
|
||||
GetComponent<ITGConnectivity>().VerifyConnection();
|
||||
@@ -143,14 +147,24 @@ namespace TGServiceInterface
|
||||
catch
|
||||
{
|
||||
InstanceName = prevInstance;
|
||||
return InstanceConnectivity.None;
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetComponent<ITGInstance>().ServerDirectory();
|
||||
return InstanceConnectivity.Authenticated;
|
||||
} catch {
|
||||
return InstanceConnectivity.Connected;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ConnectivityLevel.Connected;
|
||||
}
|
||||
try
|
||||
{
|
||||
GetComponent<ITGAdministration>().GetCurrentAuthorizedGroup();
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return ConnectivityLevel.Authenticated;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -301,7 +315,7 @@ namespace TGServiceInterface
|
||||
/// <typeparam name="T">The component <see langword="interface"/> of the channel to be created</typeparam>
|
||||
/// <returns>The correct <see cref="ChannelFactory{TChannel}"/></returns>
|
||||
/// <exception cref="Exception">Thrown if <typeparamref name="T"/> isn't a valid component <see langword="interface"/></exception>
|
||||
public ChannelFactory<T> CreateChannel<T>(string instanceName)
|
||||
ChannelFactory<T> CreateChannel<T>(string instanceName)
|
||||
{
|
||||
var accessPath = instanceName == null ? ServiceInterfaceName : String.Format("{0}/{1}", InstanceInterfaceName, instanceName);
|
||||
|
||||
@@ -335,53 +349,51 @@ namespace TGServiceInterface
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the service is avaiable on the machine. Note that state can technically change at any time and any call to the service may throw an exception because it failed
|
||||
/// Used to test if the <see cref="ITGSService"/> is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
|
||||
/// </summary>
|
||||
/// <returns><see langword="null"/> on successful connection, error message <see cref="string"/> on failure</returns>
|
||||
public string VerifyConnection()
|
||||
public ConnectivityLevel ConnectionStatus()
|
||||
{
|
||||
return ConnectionStatus(out string unused);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to test if the <see cref="ITGSService"/> is avaiable on the target machine. Note that state can change at any time and any call into the may throw an exception because of communcation errors
|
||||
/// </summary>
|
||||
/// <param name="error">String of the error that prevented an elevated connectivity level</param>
|
||||
/// <returns>The apporopriate <see cref="ConnectivityLevel"/></returns>
|
||||
public ConnectivityLevel ConnectionStatus(out string error)
|
||||
{
|
||||
try
|
||||
{
|
||||
GetComponentImpl<ITGConnectivity>(false).VerifyConnection();
|
||||
return null;
|
||||
}
|
||||
catch (Exception e)
|
||||
catch (CommunicationException e)
|
||||
{
|
||||
return e.ToString();
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.None;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the supplied user's credentials have permission to use the service. Requires a successful prior call to <see cref="VerifyConnection"/>
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if credentials are valid, <see langword="false"/> otherwise</returns>
|
||||
public bool Authenticate()
|
||||
{
|
||||
var service = GetService();
|
||||
try
|
||||
{
|
||||
GetService().Version();
|
||||
return true;
|
||||
service.Version();
|
||||
}
|
||||
catch
|
||||
catch(Exception e)
|
||||
{
|
||||
return false;
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Connected;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current login can use <see cref="ITGAdministration"/>. Requires a successful prior call to <see cref="Authenticate"/>
|
||||
/// </summary>
|
||||
/// <returns><see langword="true"/> if the connection may use <see cref="ITGAdministration"/>, <see langword="false"/> otherwise</returns>
|
||||
public bool AuthenticateAdmin()
|
||||
{
|
||||
try
|
||||
{
|
||||
GetComponent<ITGAdministration>().GetCurrentAuthorizedGroup();
|
||||
return true;
|
||||
// TODO
|
||||
|
||||
error = null;
|
||||
return ConnectivityLevel.Administrator;
|
||||
}
|
||||
catch
|
||||
catch(Exception e)
|
||||
{
|
||||
return false;
|
||||
error = e.ToString();
|
||||
return ConnectivityLevel.Authenticated;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user