Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion App/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ public App()

services.AddSingleton<IDispatcherQueueManager>(_ => this);
services.AddSingleton<IDefaultNotificationHandler>(_ => this);
services.AddSingleton<ISettingsManager<CoderConnectSettings>, SettingsManager<CoderConnectSettings>>();
services.AddSingleton<ICredentialBackend>(_ =>
new WindowsCredentialBackend(WindowsCredentialBackend.CoderCredentialsTargetName));
services.AddSingleton<ICredentialManager, CredentialManager>();
Expand Down Expand Up @@ -120,7 +121,6 @@ public App()
// FileSyncListMainPage is created by FileSyncListWindow.
services.AddTransient<FileSyncListWindow>();

services.AddSingleton<ISettingsManager<CoderConnectSettings>, SettingsManager<CoderConnectSettings>>();
services.AddSingleton<IStartupManager, StartupManager>();
// SettingsWindow views and view models
services.AddTransient<SettingsViewModel>();
Expand Down
13 changes: 11 additions & 2 deletions App/Models/Settings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,11 @@ public class CoderConnectSettings : ISettings<CoderConnectSettings>
/// </summary>
public bool ConnectOnLaunch { get; set; }

/// <summary>
/// When this is true Coder Connect will not attempt to protect against Tailscale loopback issues.
/// </summary>
public bool DisableTailscaleLoopProtection { get; set; }

/// <summary>
/// CoderConnect current settings version. Increment this when the settings schema changes.
/// In future iterations we will be able to handle migrations when the user has
Expand All @@ -46,17 +51,21 @@ public CoderConnectSettings()
Version = VERSION;

ConnectOnLaunch = false;

DisableTailscaleLoopProtection = false;
}

public CoderConnectSettings(int? version, bool connectOnLaunch)
public CoderConnectSettings(int? version, bool connectOnLaunch, bool disableTailscaleLoopProtection)
{
Version = version ?? VERSION;

ConnectOnLaunch = connectOnLaunch;

DisableTailscaleLoopProtection = disableTailscaleLoopProtection;
}

public CoderConnectSettings Clone()
{
return new CoderConnectSettings(Version, ConnectOnLaunch);
return new CoderConnectSettings(Version, ConnectOnLaunch, DisableTailscaleLoopProtection);
}
}
9 changes: 8 additions & 1 deletion App/Services/RpcController.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,16 +69,18 @@ public interface IRpcController : IAsyncDisposable
public class RpcController : IRpcController
{
private readonly ICredentialManager _credentialManager;
private readonly ISettingsManager<CoderConnectSettings> _settingsManager;

private readonly RaiiSemaphoreSlim _operationLock = new(1, 1);
private Speaker<ClientMessage, ServiceMessage>? _speaker;

private readonly RaiiSemaphoreSlim _stateLock = new(1, 1);
private readonly RpcModel _state = new();

public RpcController(ICredentialManager credentialManager)
public RpcController(ICredentialManager credentialManager, ISettingsManager<CoderConnectSettings> settingsManager)
{
_credentialManager = credentialManager;
_settingsManager = settingsManager;
}

public event EventHandler<RpcModel>? StateChanged;
Expand Down Expand Up @@ -156,6 +158,11 @@ public async Task StartVpn(CancellationToken ct = default)
using var _ = await AcquireOperationLockNowAsync();
AssertRpcConnected();

var coderConnectSettings = await _settingsManager.Read();
var disableTailscaleLoopProtection = coderConnectSettings.DisableTailscaleLoopProtection;
Debug.WriteLine(
$"Starting VPN with DisableTailscaleLoopProtection={disableTailscaleLoopProtection}");

var credentials = _credentialManager.GetCachedCredentials();
if (credentials.State != CredentialState.Valid)
throw new RpcOperationException(
Expand Down
21 changes: 20 additions & 1 deletion App/ViewModels/SettingsViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ public partial class SettingsViewModel : ObservableObject
[ObservableProperty]
public partial bool ConnectOnLaunch { get; set; }

[ObservableProperty]
public partial bool DisableTailscaleLoopProtection { get; set; }

[ObservableProperty]
public partial bool StartOnLoginDisabled { get; set; }

Expand All @@ -31,6 +34,7 @@ public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager<Cod
_connectSettings = settingsManager.Read().GetAwaiter().GetResult();
StartOnLogin = startupManager.IsEnabled();
ConnectOnLaunch = _connectSettings.ConnectOnLaunch;
DisableTailscaleLoopProtection = _connectSettings.DisableTailscaleLoopProtection;

// Various policies can disable the "Start on login" option.
// We disable the option in the UI if the policy is set.
Expand All @@ -43,6 +47,21 @@ public SettingsViewModel(ILogger<SettingsViewModel> logger, ISettingsManager<Cod
}
}

partial void OnDisableTailscaleLoopProtectionChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue)
return;
try
{
_connectSettings.DisableTailscaleLoopProtection = DisableTailscaleLoopProtection;
_connectSettingsManager.Write(_connectSettings);
}
catch (Exception ex)
{
_logger.LogError($"Error saving Coder Connect {nameof(DisableTailscaleLoopProtection)} settings: {ex.Message}");
}
}

partial void OnConnectOnLaunchChanged(bool oldValue, bool newValue)
{
if (oldValue == newValue)
Expand All @@ -54,7 +73,7 @@ partial void OnConnectOnLaunchChanged(bool oldValue, bool newValue)
}
catch (Exception ex)
{
_logger.LogError($"Error saving Coder Connect settings: {ex.Message}");
_logger.LogError($"Error saving Coder Connect {nameof(ConnectOnLaunch)} settings: {ex.Message}");
}
}

Expand Down
6 changes: 6 additions & 0 deletions App/Views/Pages/SettingsMainPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,12 @@
>
<ToggleSwitch IsOn="{x:Bind ViewModel.ConnectOnLaunch, Mode=TwoWay}" />
</controls:SettingsCard>
<controls:SettingsCard Description="This setting controls whether Coder Connect should bypass VPN loop preventation mechanism. Turn this ON only when dealing with a Coder deployment behind a corporate VPN."
Header="Disable corporate VPN loop protection"
HeaderIcon="{ui:FontIcon Glyph=&#xE8AF;}"
>
<ToggleSwitch IsOn="{x:Bind ViewModel.DisableTailscaleLoopProtection, Mode=TwoWay}" />
</controls:SettingsCard>
</StackPanel>
</Grid>
</ScrollViewer>
Expand Down
4 changes: 2 additions & 2 deletions App/Views/SettingsWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
xmlns:winuiex="using:WinUIEx"
mc:Ignorable="d"
Title="Coder Settings"
Width="600" Height="350"
MinWidth="600" MinHeight="350">
Width="600" Height="450"
MinWidth="600" MinHeight="450">

<Window.SystemBackdrop>
<MicaBackdrop/>
Expand Down
Loading