Skip to content

Commit

Permalink
Add absolute path resolution to FilesystemSource
Browse files Browse the repository at this point in the history
  • Loading branch information
GamePad64 committed Dec 18, 2024
1 parent 08d8750 commit fb9564a
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 19 deletions.
9 changes: 9 additions & 0 deletions notifico-template/src/source/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,16 @@ impl TemplateSource for FilesystemSource {
} else {
self.base_path.join(project_id.to_string())
};

// TODO: `file` can be absolute path, so it can "escape" template directory
// Ensure, that we are ok with this in server environments.
let template_path = base_path.join(file);

let base_path = std::path::absolute(template_path.clone())?
.parent()
.unwrap()
.to_path_buf();

let content = tokio::fs::read_to_string(template_path).await?;
let template: Descriptor =
toml::from_str(&content).map_err(|_| TemplaterError::InvalidTemplateFormat)?;
Expand All @@ -60,6 +68,7 @@ impl TemplateSource for FilesystemSource {
let content = match sel {
PartSelector::Inline(content) => content,
PartSelector::File { file } => {
// TODO: `file` can be absolute path, so it can "escape" template directory
tokio::fs::read_to_string(base_path.join(file)).await?
}
};
Expand Down
17 changes: 11 additions & 6 deletions notificox/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,22 @@ enum Command {
/// Recipient(s), can be an email, phone number, or any other unique identifier
/// in following format: "TYPE:VALUE"
contacts: Vec<String>,
/// Template object in JSON5 format (can be used without escaping)
/// Templating context in JSON5 format. These values will be passed to templating engine if '--template' option is provided.
/// If not provided, these values will be used as the template itself, bypassing the templating engine.
#[arg(short, long, default_value = "{}")]
context: String,
/// Template object in JSON5 format OR template file location.
/// The location can be relative to '--template-dir' or absolute path.
/// Template file should be in TOML format.
/// Can be used multiple times to send multiple messages with different templates.
#[arg(short, long)]
template: Vec<String>,
#[arg(long, default_value_os_t = DEFAULT_TEMPLATE_DIR.get().unwrap().clone(), env = "NOTIFICO_TEMPLATE_DIR")]
template_dir: PathBuf,
/// Attachment file(s) to be attached to the notification.
/// These attachments will be attached will be attached to the first message sent.
#[arg(short, long)]
attach: Vec<String>,
#[arg(short, long)]
context: Option<String>,
},
/// Send an event to remote Notifico Ingest API
SendEvent {
Expand Down Expand Up @@ -214,9 +221,7 @@ async fn main() {
contacts,
};

let context: EventContext = context
.map(|context| json5::from_str(&context).unwrap())
.unwrap_or_default();
let context: EventContext = json5::from_str(&context).unwrap();

let process_event_request = ProcessEventRequest {
id: Uuid::nil(),
Expand Down
28 changes: 15 additions & 13 deletions transports/notifico-pushover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ impl SimpleTransport for PushoverTransport {
priority: None,
sound: None,
timestamp: None,
title: Some(content.title),
title: content.title,
ttl: None,
url: None,
url_title: None,
Expand All @@ -106,19 +106,21 @@ impl SimpleTransport for PushoverTransport {
.get_attachment(&message.attachments[0])
.await?;

let form = reqwest::multipart::Form::new()
let mut form = reqwest::multipart::Form::new()
.text("token", credential.token.clone())
.text("user", contact.user.clone())
.text("message", content.body)
.text("html", "1")
.text("title", content.title)
.part(
"attachment",
reqwest::multipart::Part::stream(attach.file)
.file_name(attach.file_name.clone())
.mime_str(attach.mime_type.as_ref())
.unwrap(),
);
.text("html", "1");
if let Some(title) = content.title {
form = form.text("title", title);
}
form = form.part(
"attachment",
reqwest::multipart::Part::stream(attach.file)
.file_name(attach.file_name.clone())
.mime_str(attach.mime_type.as_ref())
.unwrap(),
);
self.client
.post(API_URL)
.multipart(form)
Expand Down Expand Up @@ -158,7 +160,7 @@ impl TypedContact for PushoverContact {
#[derive(Serialize, Deserialize, Clone)]
pub struct PushoverMessage {
pub body: String,
pub title: String,
pub title: Option<String>,
}

impl TryFrom<RenderedTemplate> for PushoverMessage {
Expand All @@ -167,7 +169,7 @@ impl TryFrom<RenderedTemplate> for PushoverMessage {
fn try_from(value: RenderedTemplate) -> Result<Self, Self::Error> {
Ok(Self {
body: value.get("body")?.to_string(),
title: value.get("title")?.to_string(),
title: value.0.get("title").cloned(),
})
}
}
3 changes: 3 additions & 0 deletions transports/notifico-smtp/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -148,17 +148,20 @@ impl EmailTransport {
}
}

// multipart/mixed
let mut mp_mixed = MultiPart::mixed().build();
if rendered.body_html.is_empty() {
mp_mixed = mp_mixed.singlepart(SinglePart::plain(rendered.body))
} else {
// multipart/alternative
let mut mp_alternative = MultiPart::alternative().build();
if attachments_inline.is_empty() {
mp_alternative = mp_alternative.singlepart(SinglePart::plain(rendered.body));
mp_alternative = mp_alternative.singlepart(SinglePart::html(rendered.body_html));
} else {
mp_alternative = mp_alternative.singlepart(SinglePart::plain(rendered.body));

// multipart/related
let mut mp_related = MultiPart::related().build();
mp_related = mp_related.singlepart(SinglePart::html(rendered.body_html));
for mut attachment in attachments_inline {
Expand Down

0 comments on commit fb9564a

Please sign in to comment.