mirror of
https://github.com/telemt/telemt.git
synced 2026-10-31 04:50:35 +03:00
Proxy Shared User Drafts
This commit is contained in:
@@ -89,11 +89,6 @@ impl WebProcessRuntime {
|
||||
.record_rejection(WebRejectionReason::ConfigDisabled);
|
||||
return Err(ManagerError::Closed);
|
||||
}
|
||||
if !generation.proxy_shared.is_user_enabled(&profile.user) {
|
||||
self.telemetry
|
||||
.record_rejection(WebRejectionReason::UserDisabled);
|
||||
return Err(ManagerError::Closed);
|
||||
}
|
||||
let _operator_admission = self.try_operator_admission()?;
|
||||
let now = Instant::now();
|
||||
let mut state = self.state.lock();
|
||||
@@ -146,12 +141,25 @@ impl WebProcessRuntime {
|
||||
.record_rejection(WebRejectionReason::BootstrapCapacity);
|
||||
return Err(ManagerError::Limit);
|
||||
};
|
||||
let Some(mut user_publication) = generation
|
||||
.proxy_shared
|
||||
.claim_authenticated_user(&profile.user, profile.credential_id)
|
||||
else {
|
||||
self.telemetry
|
||||
.record_rejection(WebRejectionReason::UserDisabled);
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
let Some(user_registration) = user_publication.take_registration() else {
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
let trace_session_id = self.trace.next_session_id();
|
||||
let bridge_diagnostics_enabled = config.web.debug.bridge_diagnostics_enabled();
|
||||
let (user_agent, user_agent_id) = bounded_user_agent(user_agent);
|
||||
let issued_profile = Arc::clone(&profile);
|
||||
state.bootstraps.insert(
|
||||
hash,
|
||||
Bootstrap {
|
||||
user_registration,
|
||||
expires_at: now + Duration::from_secs(config.web.timeouts.bootstrap_lifetime_secs),
|
||||
issued_at: now,
|
||||
issuance_ip: client_ip,
|
||||
@@ -186,11 +194,7 @@ impl WebProcessRuntime {
|
||||
},
|
||||
);
|
||||
*state.bootstraps_per_ip.entry(client_ip).or_insert(0) += 1;
|
||||
let profile = state
|
||||
.bootstraps
|
||||
.get(&hash)
|
||||
.map(|entry| Arc::clone(&entry.profile))
|
||||
.ok_or(ManagerError::Closed)?;
|
||||
user_publication.commit();
|
||||
drop(state);
|
||||
if recovery {
|
||||
self.telemetry
|
||||
@@ -202,7 +206,7 @@ impl WebProcessRuntime {
|
||||
Some(client_ip),
|
||||
crate::web::trace::TraceIdentity::from_optional_profile(
|
||||
Some(trace_session_id),
|
||||
&profile,
|
||||
&issued_profile,
|
||||
),
|
||||
crate::web::trace::TraceLifecycleEvent::BridgeIssued,
|
||||
None,
|
||||
@@ -216,7 +220,7 @@ impl WebProcessRuntime {
|
||||
self.trace.record_profile_lifecycle(
|
||||
client_ip,
|
||||
Some(trace_session_id),
|
||||
&profile,
|
||||
&issued_profile,
|
||||
crate::web::trace::TraceLifecycleEvent::BridgeIssued,
|
||||
None,
|
||||
None,
|
||||
|
||||
@@ -30,14 +30,17 @@ pub(crate) struct WebShutdownDrain {
|
||||
}
|
||||
|
||||
impl WebProcessRuntime {
|
||||
/// Applies learning policy before publishing one new runtime generation.
|
||||
/// Applies issuance and learning policy before publishing one new generation.
|
||||
pub(crate) fn activate_generation(
|
||||
&self,
|
||||
generation: Arc<RuntimeGeneration>,
|
||||
) -> Arc<RuntimeGeneration> {
|
||||
let config = generation.config();
|
||||
let (replaced, detached) = {
|
||||
// Manager state precedes learning in the request-path lock order.
|
||||
let mut state = self.state.lock();
|
||||
let mut learning = self.learning.lock();
|
||||
state.apply_issuance_policy(generation.id, config.web.enabled);
|
||||
let outcome = learning.apply_policy(
|
||||
Instant::now(),
|
||||
generation.id,
|
||||
|
||||
@@ -69,7 +69,10 @@ impl WebProcessRuntime {
|
||||
let Some(entry) = state.bootstraps.get(&bootstrap_hash) else {
|
||||
return Err(ManagerError::Authentication);
|
||||
};
|
||||
if entry.profile.host != host || now > entry.expires_at {
|
||||
if entry.profile.host != host
|
||||
|| now > entry.expires_at
|
||||
|| entry.user_registration.is_cancelled()
|
||||
{
|
||||
return Err(ManagerError::Authentication);
|
||||
}
|
||||
if entry.used {
|
||||
@@ -301,6 +304,15 @@ impl WebProcessRuntime {
|
||||
return Err(ManagerError::Protocol);
|
||||
};
|
||||
let _operator_admission = self.try_operator_admission()?;
|
||||
let Some(mut user_publication) = generation
|
||||
.proxy_shared
|
||||
.claim_authenticated_user(&profile.user, profile.credential_id)
|
||||
else {
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
let Some(user_registration) = user_publication.take_registration() else {
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
if !admit_initial(self, &mut state, now, client_ip, profile_key, &profile) {
|
||||
return Err(ManagerError::Limit);
|
||||
}
|
||||
@@ -338,6 +350,7 @@ impl WebProcessRuntime {
|
||||
recovery,
|
||||
self.limits.clone(),
|
||||
issued_timeouts.clone(),
|
||||
Some(user_registration),
|
||||
);
|
||||
state.sessions.insert(session_hash, Arc::clone(&session));
|
||||
*state.sessions_per_ip.entry(client_ip).or_insert(0) += 1;
|
||||
@@ -402,6 +415,7 @@ impl WebProcessRuntime {
|
||||
user_agent_id,
|
||||
},
|
||||
);
|
||||
user_publication.commit();
|
||||
drop(state);
|
||||
self.telemetry
|
||||
.record_carrier_selection(carrier, learning_disposition);
|
||||
|
||||
@@ -43,14 +43,24 @@ impl WebProcessRuntime {
|
||||
if !valid
|
||||
|| state.closed
|
||||
|| !state.issuance_enabled
|
||||
|| !generation
|
||||
.proxy_shared
|
||||
.is_user_enabled(&replacement.profile.user)
|
||||
{
|
||||
drop(state);
|
||||
self.cancel_replacement(bootstrap_hash, &replacement.old_session);
|
||||
return Err(ManagerError::Closed);
|
||||
}
|
||||
let Some(mut user_publication) = generation.proxy_shared.claim_authenticated_user(
|
||||
&replacement.profile.user,
|
||||
replacement.profile.credential_id,
|
||||
) else {
|
||||
drop(state);
|
||||
self.cancel_replacement(bootstrap_hash, &replacement.old_session);
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
let Some(user_registration) = user_publication.take_registration() else {
|
||||
drop(state);
|
||||
self.cancel_replacement(bootstrap_hash, &replacement.old_session);
|
||||
return Err(ManagerError::Closed);
|
||||
};
|
||||
let Some((session_token, session_hash)) = new_unique_token(&generation, &state) else {
|
||||
self.record_limit_hit();
|
||||
self.telemetry
|
||||
@@ -86,6 +96,7 @@ impl WebProcessRuntime {
|
||||
replacement.recovery,
|
||||
self.limits.clone(),
|
||||
replacement.old_session.timeouts().clone(),
|
||||
Some(user_registration),
|
||||
);
|
||||
let Some(supersede) = replacement.old_session.prepare_carrier_supersede() else {
|
||||
drop(state);
|
||||
@@ -146,6 +157,7 @@ impl WebProcessRuntime {
|
||||
index.bootstrap_hash = bootstrap_hash;
|
||||
index.attempt = replacement.attempt;
|
||||
}
|
||||
user_publication.commit();
|
||||
let identity = session.trace_identity();
|
||||
let old_identity = replacement.old_session.trace_identity();
|
||||
drop(state);
|
||||
|
||||
@@ -10,6 +10,7 @@ use zeroize::Zeroizing;
|
||||
use super::{CarrierRequest, ProfileKey, TOKEN_BYTES, TokenHash};
|
||||
use crate::config::{WebCarrier, WebRuntimeConfig, WebRuntimeProfile, WebTimeoutsConfig};
|
||||
use crate::maestro::generation::RuntimeGeneration;
|
||||
use crate::proxy::user_admission::UserSessionRegistration;
|
||||
use crate::web::session::WebSession;
|
||||
use crate::web::telemetry::WebCarrierSelectionDisposition;
|
||||
|
||||
@@ -34,6 +35,8 @@ impl CarrierChainPhase {
|
||||
|
||||
/// One issued bootstrap and optional idempotent session-creation replay state.
|
||||
pub(super) struct Bootstrap {
|
||||
/// User authority ownership retained for the credential lifetime.
|
||||
pub(super) user_registration: UserSessionRegistration,
|
||||
/// Credential and replay-state expiry deadline.
|
||||
pub(super) expires_at: Instant,
|
||||
/// Stable ordering point used for bounded eviction.
|
||||
@@ -273,6 +276,7 @@ pub(super) fn matching_profile(
|
||||
profile.host == expected.host
|
||||
&& profile.public_addr == expected.public_addr
|
||||
&& profile.user == expected.user
|
||||
&& profile.credential_id == expected.credential_id
|
||||
&& profile.secret_mode == expected.secret_mode
|
||||
&& profile.carrier == expected.carrier
|
||||
&& profile.carrier_negotiation_enabled == expected.carrier_negotiation_enabled
|
||||
|
||||
Reference in New Issue
Block a user