FIXUP server-actor handler notify-users
This commit is contained in:
parent
769a5515ea
commit
82b83bc265
1 changed files with 65 additions and 23 deletions
|
@ -1,39 +1,81 @@
|
|||
//
|
||||
use actix::prelude::*;
|
||||
use git_next_config::server::NotificationType;
|
||||
use git_next_config::server::{Notification, NotificationType};
|
||||
use git_next_repo_actor::messages::NotifyUser;
|
||||
use secrecy::ExposeSecret;
|
||||
use standardwebhooks::Webhook;
|
||||
use tracing::Instrument;
|
||||
|
||||
use crate::ServerActor;
|
||||
|
||||
impl Handler<NotifyUser> for ServerActor {
|
||||
type Result = ();
|
||||
|
||||
fn handle(&mut self, msg: NotifyUser, _ctx: &mut Self::Context) -> Self::Result {
|
||||
fn handle(&mut self, msg: NotifyUser, ctx: &mut Self::Context) -> Self::Result {
|
||||
let Some(server_config) = &self.server_config else {
|
||||
return;
|
||||
};
|
||||
let notification = &server_config.notification();
|
||||
match notification.r#type() {
|
||||
NotificationType::None => { /* do nothing */ }
|
||||
NotificationType::Webhook => {
|
||||
let message_id = format!("msg_{}", ulid::Ulid::new());
|
||||
let timestamp = time::OffsetDateTime::now_utc(); //.unix_timestamp().to_string();
|
||||
let payload = msg.as_json(timestamp).to_string();
|
||||
let timestamp = timestamp.unix_timestamp();
|
||||
let to_sign = format!("{message_id}.{timestamp}.{payload}");
|
||||
tracing::info!(?to_sign, "");
|
||||
let Some(webhook) = self.webhook.as_ref() else {
|
||||
tracing::warn!("Invalid notification configuration - can't sent notification");
|
||||
return;
|
||||
};
|
||||
#[allow(clippy::expect_used)]
|
||||
let signature = webhook
|
||||
.sign(&message_id, timestamp, payload.as_ref())
|
||||
.expect("signature");
|
||||
tracing::info!(?signature, "");
|
||||
// TODO: (#95) should notify user
|
||||
// send post to notification webhook url
|
||||
let notification_config = server_config.notification().clone();
|
||||
let net = self.net.clone();
|
||||
async move {
|
||||
match notification_config.r#type() {
|
||||
NotificationType::None => { /* do nothing */ }
|
||||
NotificationType::Webhook => send_webhook(msg, notification_config, net).await,
|
||||
}
|
||||
}
|
||||
.in_current_span()
|
||||
.into_actor(self)
|
||||
.wait(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
async fn send_webhook(
|
||||
msg: NotifyUser,
|
||||
notification_config: Notification,
|
||||
net: kxio::network::Network,
|
||||
) {
|
||||
let Some(webhook_config) = notification_config.webhook() else {
|
||||
tracing::warn!("Invalid notification configuration (config) - can't sent notification");
|
||||
return;
|
||||
};
|
||||
let Ok(webhook) = Webhook::new(webhook_config.secret().expose_secret()) else {
|
||||
tracing::warn!("Invalid notification configuration (signer) - can't sent notification");
|
||||
return;
|
||||
};
|
||||
do_send_webhook(msg, webhook, webhook_config, net).await;
|
||||
}
|
||||
|
||||
async fn do_send_webhook(
|
||||
msg: NotifyUser,
|
||||
webhook: Webhook,
|
||||
webhook_config: &git_next_config::server::OutboundWebhook,
|
||||
net: kxio::network::Network,
|
||||
) {
|
||||
let message_id = format!("msg_{}", ulid::Ulid::new());
|
||||
let timestamp = time::OffsetDateTime::now_utc();
|
||||
let payload = msg.as_json(timestamp);
|
||||
let timestamp = timestamp.unix_timestamp();
|
||||
let to_sign = format!("{message_id}.{timestamp}.{payload}");
|
||||
tracing::info!(?to_sign, "");
|
||||
#[allow(clippy::expect_used)]
|
||||
let signature = webhook
|
||||
.sign(&message_id, timestamp, payload.to_string().as_ref())
|
||||
.expect("signature");
|
||||
tracing::info!(?signature, "");
|
||||
let url = webhook_config.url();
|
||||
use kxio::network::{NetRequest, NetUrl, RequestBody, ResponseType};
|
||||
let net_url = NetUrl::new(url.to_string());
|
||||
let request = NetRequest::post(net_url)
|
||||
.body(RequestBody::Json(payload))
|
||||
.header("webhook-id", &message_id)
|
||||
.header("webhook-timestamp", ×tamp.to_string())
|
||||
.header("webhook-signature", &signature)
|
||||
.response_type(ResponseType::None)
|
||||
.build();
|
||||
net.post_json::<()>(request).await.map_or_else(
|
||||
|err| {
|
||||
tracing::warn!(?err, "sending webhook");
|
||||
},
|
||||
|_| (),
|
||||
);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue