tokens and more

This commit is contained in:
Mateusz Gruszczyński
2026-08-01 00:15:37 +02:00
parent 6c5232ccc5
commit 1401054c71
18 changed files with 1966 additions and 285 deletions
+34 -17
View File
@@ -26,6 +26,9 @@ enum PadServerMessage {
Pong {
nonce: u64,
},
Diagnostics {
diagnostics: ConnectionDiagnostics,
},
Error {
message: String,
},
@@ -41,11 +44,19 @@ pub async fn upgrade_pad(
return (StatusCode::FORBIDDEN, "Invalid WebSocket origin").into_response();
}
let account_token = crate::security::session_token(&headers).map(str::to_owned);
let resource_token = crate::security::resource_token(&headers, "pad", &slug)
.map(str::to_owned);
let resource_token = crate::security::resource_token(&headers, "pad", &slug).map(str::to_owned);
let client_key = crate::security::client_key(&headers);
let client_context = RequestClientContext::from_headers(&headers, &client_key);
ws.on_upgrade(move |socket| {
handle_pad_socket(socket, state, slug, account_token, resource_token, client_key)
handle_pad_socket(
socket,
state,
slug,
account_token,
resource_token,
client_key,
client_context,
)
})
}
async fn handle_pad_socket(
@@ -55,6 +66,7 @@ async fn handle_pad_socket(
cookie_session_token: Option<String>,
cookie_access_token: Option<String>,
client_key: String,
client_context: RequestClientContext,
) {
info!(%slug, "pad websocket connected");
let Some(pad) = db::find_pad(&state.db, &slug).await.ok().flatten() else {
@@ -68,7 +80,7 @@ async fn handle_pad_socket(
.await;
return;
};
let (password, access_token, nickname, guest_id, color) =
let (password, access_token, nickname, guest_id, color, client_diagnostics) =
match socket.recv().await {
Some(Ok(Message::Text(text))) => match serde_json::from_str::<ClientMessage>(&text) {
Ok(ClientMessage::Authenticate {
@@ -77,12 +89,14 @@ async fn handle_pad_socket(
nickname,
guest_id,
color,
diagnostics,
}) => (
password,
access_token,
clean_nickname(nickname),
clean_guest_id(guest_id),
clean_color(color),
diagnostics,
),
_ => {
let _ = send_pad(
@@ -132,13 +146,7 @@ async fn handle_pad_socket(
)
.await;
let anonymous_token_ok = permission.is_none()
&& anonymous_access_from_tokens(
&state,
"pad",
&slug,
access_token.as_deref(),
)
.await;
&& anonymous_access_from_tokens(&state, "pad", &slug, access_token.as_deref()).await;
let password_limit_key = format!("resource-password:{client_key}:pad:{slug}");
let password_attempted = password
.as_deref()
@@ -157,9 +165,7 @@ async fn handle_pad_socket(
let _ = send_pad(
&mut socket,
&PadServerMessage::Error {
message: format!(
"Too many password attempts. Try again in {seconds} seconds."
),
message: format!("Too many password attempts. Try again in {seconds} seconds."),
},
)
.await;
@@ -172,9 +178,7 @@ async fn handle_pad_socket(
let _ = send_pad(
&mut socket,
&PadServerMessage::Error {
message: format!(
"Too many password attempts. Try again in {seconds} seconds."
),
message: format!("Too many password attempts. Try again in {seconds} seconds."),
},
)
.await;
@@ -239,6 +243,19 @@ async fn handle_pad_socket(
let _ = channel.send(RoomEvent::Presence(users));
let mut last_chat = Instant::now() - Duration::from_secs(1);
let (mut sender, mut receiver) = socket.split();
if send_pad_split(
&mut sender,
&PadServerMessage::Diagnostics {
diagnostics: connection_diagnostics(connection_id, &client_context, client_diagnostics),
},
)
.await
.is_err()
{
let users = state.leave_room(&room_key, connection_id).await;
let _ = channel.send(RoomEvent::Presence(users));
return;
}
loop {
tokio::select! {
incoming=receiver.next()=>match incoming{