Send broadcast message when an API token is deleted

This commit is contained in:
2025-11-18 15:09:27 +01:00
parent b5832df746
commit 5c13cffe08
5 changed files with 27 additions and 9 deletions

View File

@@ -1,10 +1,12 @@
use crate::users::UserEmail; use crate::users::{APIToken, UserEmail};
pub type BroadcastSender = tokio::sync::broadcast::Sender<BroadcastMessage>; pub type BroadcastSender = tokio::sync::broadcast::Sender<BroadcastMessage>;
/// Broadcast messages /// Broadcast messages
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum BroadcastMessage { pub enum BroadcastMessage {
/// User is or has been disconnected /// User is or has been disconnected from Matrix
UserDisconnected(UserEmail), UserDisconnectedFromMatrix(UserEmail),
/// API token has been deleted
APITokenDeleted(APIToken),
} }

View File

@@ -1,4 +1,5 @@
use crate::app_config::AppConfig; use crate::app_config::AppConfig;
use crate::broadcast_messages::BroadcastSender;
use crate::controllers::{HttpFailure, HttpResult}; use crate::controllers::{HttpFailure, HttpResult};
use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod}; use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod};
use crate::extractors::matrix_client_extractor::MatrixClientExtractor; use crate::extractors::matrix_client_extractor::MatrixClientExtractor;
@@ -113,14 +114,18 @@ pub async fn auth_info(client: MatrixClientExtractor) -> HttpResult {
} }
/// Sign out user /// Sign out user
pub async fn sign_out(auth: AuthExtractor, session: MatrixGWSession) -> HttpResult { pub async fn sign_out(
auth: AuthExtractor,
session: MatrixGWSession,
tx: web::Data<BroadcastSender>,
) -> HttpResult {
match auth.method { match auth.method {
AuthenticatedMethod::Cookie => { AuthenticatedMethod::Cookie => {
session.unset_current_user()?; session.unset_current_user()?;
} }
AuthenticatedMethod::Token(token) => { AuthenticatedMethod::Token(token) => {
token.delete(&auth.user.email).await?; token.delete(&auth.user.email, &tx).await?;
} }
AuthenticatedMethod::Dev => { AuthenticatedMethod::Dev => {

View File

@@ -1,3 +1,4 @@
use crate::broadcast_messages::BroadcastSender;
use crate::controllers::HttpResult; use crate::controllers::HttpResult;
use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod}; use crate::extractors::auth_extractor::{AuthExtractor, AuthenticatedMethod};
use crate::users::{APIToken, APITokenID, BaseAPIToken}; use crate::users::{APIToken, APITokenID, BaseAPIToken};
@@ -41,8 +42,12 @@ pub struct TokenIDInPath {
} }
/// Delete an API access token /// Delete an API access token
pub async fn delete(auth: AuthExtractor, path: web::Path<TokenIDInPath>) -> HttpResult { pub async fn delete(
auth: AuthExtractor,
path: web::Path<TokenIDInPath>,
tx: web::Data<BroadcastSender>,
) -> HttpResult {
let token = APIToken::load(&auth.user.email, &path.id).await?; let token = APIToken::load(&auth.user.email, &path.id).await?;
token.delete(&auth.user.email).await?; token.delete(&auth.user.email, &tx).await?;
Ok(HttpResponse::Accepted().finish()) Ok(HttpResponse::Accepted().finish())
} }

View File

@@ -67,7 +67,7 @@ impl Actor for MatrixManagerActor {
} }
if let Err(e) = state if let Err(e) = state
.broadcast_sender .broadcast_sender
.send(BroadcastMessage::UserDisconnected(email)) .send(BroadcastMessage::UserDisconnectedFromMatrix(email))
{ {
log::warn!( log::warn!(
"Failed to notify that user has been disconnected from Matrix! {e}" "Failed to notify that user has been disconnected from Matrix! {e}"

View File

@@ -1,4 +1,5 @@
use crate::app_config::AppConfig; use crate::app_config::AppConfig;
use crate::broadcast_messages::{BroadcastMessage, BroadcastSender};
use crate::constants; use crate::constants;
use crate::controllers::server_controller::ServerConstraints; use crate::controllers::server_controller::ServerConstraints;
use crate::matrix_connection::matrix_client::EncryptionRecoveryState; use crate::matrix_connection::matrix_client::EncryptionRecoveryState;
@@ -246,9 +247,14 @@ impl APIToken {
} }
/// Delete this token /// Delete this token
pub async fn delete(self, email: &UserEmail) -> anyhow::Result<()> { pub async fn delete(self, email: &UserEmail, tx: &BroadcastSender) -> anyhow::Result<()> {
let token_file = AppConfig::get().user_api_token_metadata_file(email, &self.id); let token_file = AppConfig::get().user_api_token_metadata_file(email, &self.id);
std::fs::remove_file(&token_file).map_err(MatrixGWUserError::DeleteToken)?; std::fs::remove_file(&token_file).map_err(MatrixGWUserError::DeleteToken)?;
if let Err(e) = tx.send(BroadcastMessage::APITokenDeleted(self)) {
log::error!("Failed to notify API token deletion! {e}");
}
Ok(()) Ok(())
} }