refactor(connlib): explicitly enable/disable Internet Resource (#10507)

Instead of the generic "disable any kind of resource"-functionality that
connlib currently exposes, we now provide an API to only enable /
disable the Internet Resource. This is a lot simpler to deal with and
reason about than the previous system, especially when it comes to the
proptests. Those need to model connlib's behaviour correctly across its
entire API surface which makes them unnecessarily complex if we only
ever use the `set_disabled_resources` API with a single resource.

In preparation for #4789, I want to extend the proptests to cover
traffic filters (#7126). This will make them a fair bit more
complicated, so any prior removal of complexity is appreciated.

Simplifying the implementation here is also a good starting point to fix
#10255. Not implicitly enabling the Internet Resource when it gets added
should be quite simple after this change.

Finally, resolving #8885 should also be quite easy. We just need to
store the state of the Internet Resource once per API URL instead of
globally.

Resolves: #8404

---------

Signed-off-by: Thomas Eizinger <thomas@eizinger.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Thomas Eizinger
2025-10-07 00:26:07 +00:00
committed by GitHub
parent 4ef827b611
commit 36dfee2c42
14 changed files with 184 additions and 252 deletions

View File

@@ -17,7 +17,7 @@ use futures::{
stream::{self, BoxStream},
};
use secrecy::{ExposeSecret as _, SecretString};
use std::{collections::BTreeSet, ops::ControlFlow, path::PathBuf, task::Poll, time::Duration};
use std::{ops::ControlFlow, path::PathBuf, task::Poll, time::Duration};
use tokio::sync::{mpsc, oneshot};
use tokio_stream::wrappers::ReceiverStream;
use url::Url;
@@ -145,16 +145,6 @@ impl Status {
Status::TunnelReady { .. } | Status::WaitingForTunnel => true,
}
}
fn internet_resource(&self) -> Option<ResourceView> {
#[expect(clippy::wildcard_enum_match_arm)]
match self {
Status::TunnelReady { resources } => {
resources.iter().find(|r| r.is_internet_resource()).cloned()
}
_ => None,
}
}
}
enum EventloopTick {
@@ -761,20 +751,10 @@ impl<I: GuiIntegration> Controller<I> {
async fn update_disabled_resources(&mut self) -> Result<()> {
settings::save_general(&self.general_settings).await?;
let Some(internet_resource) = self.status.internet_resource() else {
return Ok(());
};
let state = self.general_settings.internet_resource_enabled();
let mut disabled_resources = BTreeSet::new();
if !self.general_settings.internet_resource_enabled() {
disabled_resources.insert(internet_resource.id());
}
self.send_ipc(&service::ClientMsg::SetDisabledResources(
disabled_resources,
))
.await?;
self.send_ipc(&service::ClientMsg::SetInternetResourceState(state))
.await?;
self.refresh_ui_state();
Ok(())

View File

@@ -5,7 +5,7 @@ use crate::{
use anyhow::{Context as _, Result, bail};
use atomicwrites::{AtomicFile, OverwriteBehavior};
use backoff::ExponentialBackoffBuilder;
use connlib_model::{ResourceId, ResourceView};
use connlib_model::ResourceView;
use firezone_bin_shared::{
DnsControlMethod, DnsController, TunDeviceManager,
device_id::{self, DeviceId},
@@ -24,7 +24,6 @@ use futures::{
use phoenix_channel::{DeviceInfo, LoginUrl, PhoenixChannel, get_user_agent};
use secrecy::{Secret, SecretString};
use std::{
collections::BTreeSet,
io::{self, Write},
mem,
pin::pin,
@@ -59,7 +58,7 @@ pub enum ClientMsg {
ApplyLogFilter {
directives: String,
},
SetDisabledResources(BTreeSet<ResourceId>),
SetInternetResourceState(bool),
StartTelemetry {
environment: String,
release: String,
@@ -555,14 +554,14 @@ impl<'a> Handler<'a> {
tracing::warn!(path = %path.display(), %directives, "Failed to write new log directives: {}", err_with_src(&e));
}
}
ClientMsg::SetDisabledResources(disabled_resources) => {
ClientMsg::SetInternetResourceState(state) => {
let Some(connlib) = self.session.as_connlib() else {
// At this point, the GUI has already saved the disabled Resources to disk, so it'll be correct on the next sign-in anyway.
tracing::debug!("Cannot set disabled resources if we're signed out");
// At this point, the GUI has already saved the state to disk, so it'll be correct on the next sign-in anyway.
tracing::debug!("Cannot enable/disable Internet Resource if we're signed out");
return Ok(());
};
connlib.set_disabled_resources(disabled_resources);
connlib.set_internet_resource_state(state);
}
ClientMsg::StartTelemetry {
environment,