feat: added live updates for checking in
This commit is contained in:
parent
f284cf47eb
commit
e103fa9f28
@ -12,6 +12,7 @@ pub enum Error {
|
|||||||
Rustls(rustls::Error),
|
Rustls(rustls::Error),
|
||||||
Rcgen(rcgen::Error),
|
Rcgen(rcgen::Error),
|
||||||
WebPki(rustls::client::VerifierBuilderError),
|
WebPki(rustls::client::VerifierBuilderError),
|
||||||
|
TokioSend,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl std::fmt::Display for Error {
|
impl std::fmt::Display for Error {
|
||||||
@ -38,6 +39,9 @@ impl std::fmt::Display for Error {
|
|||||||
Error::WebPki(err) => {
|
Error::WebPki(err) => {
|
||||||
write!(f, "webpki error: {err:?}")
|
write!(f, "webpki error: {err:?}")
|
||||||
}
|
}
|
||||||
|
Error::TokioSend => {
|
||||||
|
write!(f, "tokio broadcast error")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -105,3 +109,9 @@ impl From<rustls::client::VerifierBuilderError> for Error {
|
|||||||
Self::WebPki(err)
|
Self::WebPki(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<T> From<tokio::sync::broadcast::error::SendError<T>> for Error {
|
||||||
|
fn from(_: tokio::sync::broadcast::error::SendError<T>) -> Self {
|
||||||
|
Self::TokioSend
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@ -107,9 +107,7 @@ pub async fn start_listener(
|
|||||||
.fetch_one(&db)
|
.fetch_one(&db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
let sender = broadcast::Sender::new(128);
|
let app = router::get_router(db, beacon_event_broadcast.clone());
|
||||||
|
|
||||||
let app = router::get_router(db, sender.clone());
|
|
||||||
|
|
||||||
let ca_cert = rustls::pki_types::CertificateDer::from(listener.certificate.clone());
|
let ca_cert = rustls::pki_types::CertificateDer::from(listener.certificate.clone());
|
||||||
|
|
||||||
@ -182,7 +180,7 @@ pub async fn start_listener(
|
|||||||
));
|
));
|
||||||
};
|
};
|
||||||
|
|
||||||
blm_handle.insert(listener_id, BeaconListenerHandle { join_handle, events_broadcast: sender });
|
blm_handle.insert(listener_id, BeaconListenerHandle { join_handle, events_broadcast: beacon_event_broadcast });
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -76,6 +76,8 @@ pub async fn handle_checkin(
|
|||||||
|
|
||||||
let current_beacon_reg = match current_beacon_reg {
|
let current_beacon_reg = match current_beacon_reg {
|
||||||
Some(rec) => {
|
Some(rec) => {
|
||||||
|
state.event_publisher.send(BeaconEvent::Checkin(reg.beacon_id.clone()))?;
|
||||||
|
|
||||||
parse_db_config(rec)
|
parse_db_config(rec)
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
@ -111,6 +113,8 @@ pub async fn handle_checkin(
|
|||||||
.fetch_one(&state.db)
|
.fetch_one(&state.db)
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
|
state.event_publisher.send(BeaconEvent::NewBeacon(reg.beacon_id.clone()))?;
|
||||||
|
|
||||||
parse_db_config(rec)
|
parse_db_config(rec)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use leptos::{either::Either, prelude::*};
|
use leptos::{either::Either, prelude::*};
|
||||||
|
use leptos_router::components::A;
|
||||||
#[cfg(feature = "hydrate")]
|
#[cfg(feature = "hydrate")]
|
||||||
use leptos_use::use_websocket;
|
use leptos_use::use_websocket;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
@ -62,7 +63,7 @@ pub struct CurrentBeaconInstance {
|
|||||||
unsafe impl Send for CurrentBeaconInstance {}
|
unsafe impl Send for CurrentBeaconInstance {}
|
||||||
unsafe impl Send for SidebarEvents {}
|
unsafe impl Send for SidebarEvents {}
|
||||||
|
|
||||||
#[derive(Clone, Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub enum SidebarEvents {
|
pub enum SidebarEvents {
|
||||||
BeaconList(Vec<CurrentBeaconInstance>),
|
BeaconList(Vec<CurrentBeaconInstance>),
|
||||||
NewBeacon(CurrentBeaconInstance),
|
NewBeacon(CurrentBeaconInstance),
|
||||||
@ -99,6 +100,8 @@ pub fn BeaconSidebar() -> impl IntoView {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
leptos::logging::log!("Received message: {m:?}");
|
||||||
|
|
||||||
match m {
|
match m {
|
||||||
SidebarEvents::BeaconList(bs) => {
|
SidebarEvents::BeaconList(bs) => {
|
||||||
let mut bs = bs.to_vec();
|
let mut bs = bs.to_vec();
|
||||||
@ -125,6 +128,7 @@ pub fn BeaconSidebar() -> impl IntoView {
|
|||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
if let Some(ref mut b) = bs.iter_mut().find(|b| b.beacon_id == *bid) {
|
if let Some(ref mut b) = bs.iter_mut().find(|b| b.beacon_id == *bid) {
|
||||||
|
leptos::logging::log!("Found beacon to check in");
|
||||||
b.last_checkin = chrono::Utc::now();
|
b.last_checkin = chrono::Utc::now();
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
@ -163,10 +167,6 @@ pub fn BeaconSidebar() -> impl IntoView {
|
|||||||
let partitions = move || -> Vec<BeaconPartition> {
|
let partitions = move || -> Vec<BeaconPartition> {
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
|
|
||||||
leptos::logging::log!(
|
|
||||||
"There are {:?} beacons",
|
|
||||||
current_beacons.read().as_ref().map(Vec::len)
|
|
||||||
);
|
|
||||||
let sm = sort_method.read();
|
let sm = sort_method.read();
|
||||||
let search_regex = Regex::new(&*search_input.read());
|
let search_regex = Regex::new(&*search_input.read());
|
||||||
let str_match_search = {
|
let str_match_search = {
|
||||||
@ -558,23 +558,26 @@ pub fn BeaconSidebar() -> impl IntoView {
|
|||||||
|
|
||||||
<For
|
<For
|
||||||
each={
|
each={
|
||||||
let beacons = Arc::clone(&partition.beacons);
|
move || (partition.beacons)()
|
||||||
move || (beacons)()
|
|
||||||
}
|
}
|
||||||
key=|b| b.beacon_id.clone()
|
key=|b| (b.beacon_id.clone(), b.last_checkin)
|
||||||
let:beacon
|
let:beacon
|
||||||
>
|
>
|
||||||
<div class="beacon-instance">
|
<div class="beacon-instance">
|
||||||
<div class="beacon-instance-id">
|
<div class="beacon-instance-id">
|
||||||
{match &*beacon.nickname {
|
{match &*beacon.nickname {
|
||||||
"" => Either::Left(view! {
|
"" => Either::Left(view! {
|
||||||
<span>{beacon.beacon_id.clone()}</span>
|
<A href=format!("/beacons/beacon/{}", &beacon.beacon_id)>
|
||||||
|
<span>{beacon.beacon_id.clone()}</span>
|
||||||
|
</A>
|
||||||
}),
|
}),
|
||||||
nick => {
|
nick => {
|
||||||
let nick = nick.to_string();
|
let nick = nick.to_string();
|
||||||
Either::Right(view! {
|
Either::Right(view! {
|
||||||
{nick}
|
<A href=format!("/beacons/beacon/{}", &beacon.beacon_id)>
|
||||||
<span>"(" {beacon.beacon_id.clone()} ")"</span>
|
{nick}
|
||||||
|
<span>"(" {beacon.beacon_id.clone()} ")"</span>
|
||||||
|
</A>
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
|
|||||||
@ -430,8 +430,35 @@ async fn handle_listener_events(
|
|||||||
let mut event_receiver = state.beacon_event_broadcast.subscribe();
|
let mut event_receiver = state.beacon_event_broadcast.subscribe();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
|
use sparse_handler::BeaconEvent;
|
||||||
|
|
||||||
let event = event_receiver.recv().await;
|
let event = event_receiver.recv().await;
|
||||||
|
|
||||||
|
match event {
|
||||||
|
Ok(BeaconEvent::Checkin(bid)) => {
|
||||||
|
socket.send(ws::Message::Text(serde_json::to_string(&SidebarEvents::Checkin(bid.clone()))?)).await?;
|
||||||
|
}
|
||||||
|
Ok(BeaconEvent::NewBeacon(bid)) => {
|
||||||
|
let beacons = sqlx::query!(
|
||||||
|
"SELECT template_id, peer_ip, nickname, cwd, operating_system, beacon_userent, hostname, config_id FROM beacon_instance
|
||||||
|
WHERE beacon_id = ?",
|
||||||
|
bid
|
||||||
|
)
|
||||||
|
.fetch_one(&state.db)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
let category_ids = sqlx::query!(
|
||||||
|
"SELECT category_id FROM beacon_category_assignment
|
||||||
|
WHERE beacon_id = ?",
|
||||||
|
bid
|
||||||
|
)
|
||||||
|
.fetch_one(&state.db)
|
||||||
|
.await?;
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
tracing::warn!("Unable to handle general event: {e:?}");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -66,7 +66,11 @@ aside.beacons {
|
|||||||
color: yellow;
|
color: yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
.beacon-instance-id {
|
.beacon-instance-id a {
|
||||||
|
text-decoration: none;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user