feat(gateway): allow updating expiry of access authorization (#9973)

Resolves: #9966
This commit is contained in:
Thomas Eizinger
2025-07-23 17:25:36 +10:00
committed by GitHub
parent fafe2c43ea
commit ecb2bbc86b
4 changed files with 70 additions and 3 deletions

View File

@@ -300,6 +300,20 @@ impl GatewayState {
Ok(())
}
pub fn update_access_authorization_expiry(
&mut self,
client: ClientId,
resource: ResourceId,
expires_at: DateTime<Utc>,
) -> anyhow::Result<()> {
self.peers
.get_mut(&client)
.context("No peer state")?
.update_resource_expiry(resource, expires_at);
Ok(())
}
pub fn handle_domain_resolved(
&mut self,
req: ResolveDnsRequest,

View File

@@ -4,7 +4,10 @@ use crate::messages::{
GatewayResponse, IceCredentials, Interface, Key, Peer, Relay, RelaysPresence, ResolveRequest,
SecretKey,
};
use chrono::{DateTime, Utc, serde::ts_seconds_option};
use chrono::{
DateTime, Utc,
serde::{ts_seconds, ts_seconds_option},
};
use connlib_model::{ClientId, ResourceId};
use ip_network::IpNetwork;
use serde::{Deserialize, Serialize};
@@ -195,6 +198,7 @@ pub enum IngressMessages {
RelaysPresence(RelaysPresence),
ResourceUpdated(ResourceDescription),
AuthorizeFlow(AuthorizeFlow),
AccessAuthorizationExpiryUpdated(AccessAuthorizationExpiryUpdated),
}
#[derive(Debug, Deserialize, Clone)]
@@ -220,6 +224,14 @@ pub struct AuthorizeFlow {
pub expires_at: Option<DateTime<Utc>>,
}
#[derive(Debug, Deserialize, Clone)]
pub struct AccessAuthorizationExpiryUpdated {
pub client_id: ClientId,
pub resource_id: ResourceId,
#[serde(with = "ts_seconds")]
pub expires_at: DateTime<Utc>,
}
/// A client's ice candidate message.
#[derive(Debug, Serialize, Clone)]
pub struct ClientsIceCandidates {

View File

@@ -233,6 +233,28 @@ impl ClientOnGateway {
self.recalculate_filters();
}
pub(crate) fn update_resource_expiry(
&mut self,
resource: ResourceId,
new_expiry: DateTime<Utc>,
) {
let Some(resource) = self.resources.get_mut(&resource) else {
tracing::debug!(%resource, "Unknown resource");
return;
};
let new_expiry_rfc3339 = new_expiry.to_rfc3339();
let old_expiry = match resource {
ResourceOnGateway::Cidr { expires_at, .. } => expires_at.replace(new_expiry),
ResourceOnGateway::Dns { expires_at, .. } => expires_at.replace(new_expiry),
ResourceOnGateway::Internet { expires_at } => expires_at.replace(new_expiry),
};
tracing::info!(old = ?old_expiry.map(|e| e.to_rfc3339()), new = %new_expiry_rfc3339, "Updated resource expiry");
}
pub(crate) fn retain_authorizations(&mut self, authorization: BTreeSet<ResourceId>) {
for (resource, _) in self
.resources

View File

@@ -7,8 +7,8 @@ use firezone_bin_shared::TunDeviceManager;
use firezone_telemetry::{Telemetry, analytics};
use firezone_tunnel::messages::gateway::{
AllowAccess, ClientIceCandidates, ClientsIceCandidates, ConnectionReady, EgressMessages,
IngressMessages, InitGateway, RejectAccess, RequestConnection,
AccessAuthorizationExpiryUpdated, AllowAccess, ClientIceCandidates, ClientsIceCandidates,
ConnectionReady, EgressMessages, IngressMessages, InitGateway, RejectAccess, RequestConnection,
};
use firezone_tunnel::messages::{ConnectionAccepted, GatewayResponse, Interface, RelaysPresence};
use firezone_tunnel::{
@@ -448,6 +448,25 @@ impl Eventloop {
.state_mut()
.update_resource(resource_description);
}
phoenix_channel::Event::InboundMessage {
msg:
IngressMessages::AccessAuthorizationExpiryUpdated(
AccessAuthorizationExpiryUpdated {
client_id,
resource_id,
expires_at,
},
),
..
} => {
if let Err(e) = self.tunnel.state_mut().update_access_authorization_expiry(
client_id,
resource_id,
expires_at,
) {
tracing::warn!(%client_id, %resource_id, "Failed to update expiry of access authorization: {e:#}")
};
}
phoenix_channel::Event::ErrorResponse { topic, req_id, res } => {
tracing::warn!(%topic, %req_id, "Request failed: {res:?}");
}