From 3a2ad3d4f4147f683ac78acab88597433a1430a2 Mon Sep 17 00:00:00 2001 From: Jonni Liljamo Date: Sun, 4 May 2025 13:19:09 +0300 Subject: [PATCH] feat: optionally read tokens from files --- README.md | 8 ++++++++ src/config.rs | 20 ++++++++++++++++++++ src/service/gotify.rs | 3 ++- src/service/matrix.rs | 3 ++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 5078032..00b46a5 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,14 @@ A small API for relaying the same message to multiple services. The following example creates a notifier that sends a message to Gotify and Matrix. +### `token` fields +All `token` fields (service and notifier configs) can also be a path to a +file containing the token, e.g. `/run/secrets/canwa-matrix-token` + +canwa will check if the value is a path that exists and reads it if it is. +If the value is not a path, or it is a path that cannot be read, it will be +assumed a raw string token. + ### Example `canwa.toml` ```toml interface = "0.0.0.0" diff --git a/src/config.rs b/src/config.rs index 865393f..0d57d35 100644 --- a/src/config.rs +++ b/src/config.rs @@ -32,8 +32,28 @@ pub trait ServiceConfig { fn as_any(&self) -> &dyn std::any::Any; } +pub fn deserialize_token<'de, D>(deserializer: D) -> Result +where + D: serde::Deserializer<'de>, +{ + let token_or_path: String = serde::de::Deserialize::deserialize(deserializer)?; + // If the value exists as a path and we can read it, read the file. + let path = std::path::Path::new(&token_or_path); + if path.exists() { + match std::fs::read_to_string(path) { + Ok(token) => return Ok(token.trim().into()), + Err(err) => { + tracing::warn!(msg="token exists as a filesystem path, but could not be read, assuming raw token", %err) + } + } + } + // Assume raw token. + Ok(token_or_path) +} + #[derive(Clone, Deserialize)] pub struct NotifierConfig { + #[serde(deserialize_with = "deserialize_token")] pub token: String, pub services: Vec, } diff --git a/src/service/gotify.rs b/src/service/gotify.rs index fa44bfd..07fe2a7 100644 --- a/src/service/gotify.rs +++ b/src/service/gotify.rs @@ -8,13 +8,14 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; -use crate::config::ServiceConfig; +use crate::config::{ServiceConfig, deserialize_token}; use super::Service; #[derive(Clone, Deserialize, Serialize)] pub struct GotifyConfig { pub instance: String, + #[serde(deserialize_with = "deserialize_token")] pub token: String, } diff --git a/src/service/matrix.rs b/src/service/matrix.rs index 75c8059..d1d15d9 100644 --- a/src/service/matrix.rs +++ b/src/service/matrix.rs @@ -9,13 +9,14 @@ use async_trait::async_trait; use serde::{Deserialize, Serialize}; use serde_json::json; -use crate::config::ServiceConfig; +use crate::config::{ServiceConfig, deserialize_token}; use super::Service; #[derive(Clone, Deserialize, Serialize)] pub struct MatrixConfig { pub instance: String, + #[serde(deserialize_with = "deserialize_token")] pub token: String, pub room: String, } -- 2.44.1