diff --git a/Cargo.toml b/Cargo.toml index 0ffe8fd..288bc61 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,7 +9,7 @@ license = "AGPL-3.0+" [dependencies] clap = { version = "4.5", features = [ "cargo" ] } forgejo-hooks = "*" -gitlab = { version = "0.1706", optional = true } +gitlab = "0.1706" hyper = { version = "1.6", default-features = false, features = [ "http1", "server" ] } hyper-util = { version = "0.1", features = [ "tokio" ] } http-body-util = "0.1" @@ -19,21 +19,16 @@ tokio = { version = "1", default-features = false, features = [ "rt", "net", "sy pretty_env_logger = "0.5" serde = { version = "1.0", features = [ "derive" ] } serde_json = "1.0" -toml = "1.1" -xmpp = { git = "https://gitlab.com/xmppftw/xmpp-rs", branch = "feat-openssl-vendored", default-features = false, features = [ "serde", "starttls", "rustls-native-certs", "aws_lc_rs" ] } -hmac = "0.13" -sha2 = "0.11" +toml = "0.9" +xmpp = { git = "https://gitlab.com/xmpp-rs/xmpp-rs", branch = "xmpp-join-resync", default-features = false, features = [ "serde", "starttls", "rustls-native-certs", "aws_lc_rs" ] } +hmac = "0.12" +sha2 = "0.10" hex = "0.4" camino = { version = "1.2", features = ["serde1"] } chrono = { version = "0.4", default-features = false } -[build-dependencies] -git2 = "0.20" - [patch.crates-io] forgejo-hooks = { path = "forgejo-hooks" } [features] -gitlab = [ "dep:gitlab" ] syntax-highlighting = ["xmpp/syntax-highlighting"] -vendored-openssl = [ "xmpp/vendored-openssl", "git2/vendored-openssl" ] diff --git a/README.md b/README.md index b3ba21b..5109c74 100644 --- a/README.md +++ b/README.md @@ -7,12 +7,6 @@ be somewhat of a testbed for xmpp-rs features. Originally based on tokio-webhook2muc. -# Cross-compile musl - -``` -cross build --release --target x86_64-unknown-linux-musl --features vendored-openssl -``` - ## License AGPL-3.0-or-later. See the LICENSE file. diff --git a/build.rs b/build.rs deleted file mode 100644 index da0edcf..0000000 --- a/build.rs +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2026-2099 The crate authors. -// -// This program is free software: you can redistribute it and/or modify it -// under the terms of the GNU Affero General Public License as published by the -// Free Software Foundation, either version 3 of the License, or (at your -// option) any later version. -// -// This program is distributed in the hope that it will be useful, but WITHOUT -// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -// FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License -// for more details. -// -// You should have received a copy of the GNU Affero General Public License -// along with this program. If not, see . - -use std::env; -use std::fs; -use std::path::Path; - -use git2::Repository; - -fn main() { - let oid = { - match Repository::open(".") { - Ok(repo) => { - let head = repo.head().unwrap(); - format!("{}", repo.refname_to_id(head.name().unwrap()).unwrap()) - } - Err(e) => { - println!("cargo::warning={}", e); - String::new() - } - } - }; - - let out_dir = env::var_os("OUT_DIR").unwrap(); - let dest_path = Path::new(&out_dir).join("GIT_COMMIT"); - fs::write(&dest_path, oid).unwrap(); - - println!("cargo::rerun-if-changed=build.rs"); -} diff --git a/config.sample.toml b/config.sample.toml deleted file mode 100644 index 5fed1de..0000000 --- a/config.sample.toml +++ /dev/null @@ -1,8 +0,0 @@ -admins = [ "foo@localhost" ] -jid = "bar@localhost" -password = "bonjourxmpp" - -rooms = [ "room@muc.localhost" ] -secret = "bonjourforgejo" - -addr = "[::1]:5225" diff --git a/src/bot.rs b/src/bot.rs index 4d09ffa..deec1ff 100644 --- a/src/bot.rs +++ b/src/bot.rs @@ -14,7 +14,6 @@ // along with this program. If not, see . use crate::Error; -use crate::config::Config; use crate::hooks::{Hook, IssueAction, MergeRequestAction, format_hook}; use chrono::{TimeDelta, Utc}; @@ -24,28 +23,34 @@ use xmpp::jid::{BareJid, Jid, ResourcePart}; use xmpp::parsers::message::MessageType; use xmpp::{ Agent, ClientBuilder, ClientFeature, ClientType, Config as AgentConfig, Event, RoomNick, - message::send::{MessageSettings, RawMessageSettings}, - muc::room::JoinRoomSettings, + message::send::RawMessageSettings, muc::room::JoinRoomSettings, }; pub struct XmppClient { is_online: bool, agent: Agent, + rooms: Vec, nickname: ResourcePart, - config: Config, + admins: Vec, /// Keep around messages we've sent recently so we're able to prevent spamming the same type of /// messages recent_hooks: Vec, } impl XmppClient { - pub fn new(jid: BareJid, password: &str, nickname: ResourcePart, config: Config) -> XmppClient { - let agent_config = AgentConfig { + pub fn new( + jid: BareJid, + password: &str, + rooms: Vec, + nickname: ResourcePart, + admins: Vec, + ) -> XmppClient { + let config = AgentConfig { bookmarks_autojoin: false, ..AgentConfig::default() }; let agent = ClientBuilder::new(jid, password) - .set_config(agent_config) + .set_config(config) .set_client(ClientType::Bot, "xmpp-rs") .set_website("https://gitlab.com/xmpp-rs/xmpp-rs") .set_default_nick(&nickname) @@ -55,8 +60,9 @@ impl XmppClient { XmppClient { is_online: false, agent, + rooms, nickname, - config, + admins, recent_hooks: Vec::new(), } } @@ -67,7 +73,7 @@ impl XmppClient { Event::Online => { self.is_online = true; debug!("XMPP Online"); - for room in &self.config.rooms { + for room in &self.rooms { self.agent .join_room(JoinRoomSettings { nick: Some(RoomNick::from_resource_ref(self.nickname.as_ref())), @@ -77,43 +83,20 @@ impl XmppClient { } } Event::ChatMessage(_id, bare, message, _timeinfo) => { - if !self.config.admins.contains(&bare) { + if !self.admins.contains(&bare) { debug!("Received chat message from {}, not in admins", bare); continue; } debug!("Received chat message from {}: {}", bare, message); - match message.as_str() { - "rejoin" => { - for room in &self.config.rooms { - self.agent - .join_room(JoinRoomSettings { - nick: Some(RoomNick::from_resource_ref( - self.nickname.as_ref(), - )), - force_resync: true, - ..JoinRoomSettings::new(room.clone()) - }) - .await - } - } - "version" => { + if message == "rejoin" { + for room in &self.rooms { self.agent - .send_message(MessageSettings { - recipient: bare, - message: self.config.version.unwrap_or("No version specified."), - lang: Some("en"), - }) - .await - } - _ => { - let message = "Help:\nrejoin: Re-join all rooms.\nversion: Display software version."; - self.agent - .send_message(MessageSettings { - recipient: bare, - message, - lang: Some("en"), + .join_room(JoinRoomSettings { + nick: Some(RoomNick::from_resource_ref(self.nickname.as_ref())), + force_resync: true, + ..JoinRoomSettings::new(room.clone()) }) .await } @@ -226,7 +209,7 @@ impl XmppClient { } if let Some(display) = format_hook(&wh) { debug!("Hook: {}", display); - for room in &self.config.rooms { + for room in &self.rooms { self.agent .send_raw_message(RawMessageSettings { recipient: Jid::from(room.clone()), diff --git a/src/config.rs b/src/config.rs index f5b7f5c..81a8e82 100644 --- a/src/config.rs +++ b/src/config.rs @@ -23,15 +23,7 @@ use xmpp::jid::{BareJid, ResourcePart}; use crate::error::Error; -const MAYBE_VERSION: &'static str = include_str!(concat!(env!("OUT_DIR"), "/GIT_COMMIT")); -const fn version() -> Option<&'static str> { - match MAYBE_VERSION { - v if v.is_empty() => None, - v => Some(v), - } -} - -#[derive(Debug, Clone, Serialize, Deserialize)] +#[derive(Debug, Serialize, Deserialize)] pub struct Config { /// Accounts trusted for admin tasks #[serde(default = "Vec::new")] @@ -58,11 +50,6 @@ pub struct Config { /// HTTP Webhook listening address and port, e.g., 127.0.0.1:1234 or [::1]:1234 #[serde(default = "Config::default_addr")] pub addr: SocketAddr, - - /// Software version - #[serde(skip)] - #[serde(default = "version")] - pub version: Option<&'static str>, } impl Config { diff --git a/src/hooks/forgejo.rs b/src/hooks/forgejo.rs index 47b9bad..9a32686 100644 --- a/src/hooks/forgejo.rs +++ b/src/hooks/forgejo.rs @@ -38,11 +38,7 @@ impl From for Issue { action: Some(other.action.into()), title: other.issue.title, author: User { - name: other - .comment - .as_ref() - .map(|c| c.user.login.clone()) - .unwrap_or(other.issue.user.login), + name: other.issue.user.login, }, repository: Repository { name: other.repository.name, @@ -64,11 +60,7 @@ impl From for Note { merge_request: None, snippet: false, author: User { - name: other - .comment - .as_ref() - .map(|c| c.user.login.clone()) - .unwrap_or(other.issue.user.login), + name: other.issue.user.login, }, repository: Repository { name: other.repository.name, @@ -77,7 +69,6 @@ impl From for Note { .comment .map(|c| c.html_url) .unwrap_or(other.issue.html_url), - is_update: other.action == FjIssueAction::Edited, } } } diff --git a/src/hooks/mod.rs b/src/hooks/mod.rs index 3a2fce3..8fcd544 100644 --- a/src/hooks/mod.rs +++ b/src/hooks/mod.rs @@ -14,12 +14,11 @@ // along with this program. If not, see . mod forgejo; -#[cfg(feature = "gitlab")] mod gitlab; mod types; pub use crate::hooks::forgejo::ForgejoHook; -#[cfg(feature = "gitlab")] +#[allow(deprecated)] pub use crate::hooks::gitlab::GitlabHook; pub use crate::hooks::types::Hook; pub use crate::hooks::types::{IssueAction, MergeRequestAction, WikiAction}; @@ -109,26 +108,19 @@ pub fn format_hook(hook: &Hook) -> Option { if note.snippet { return None; } - - let updated_fmt = if note.is_update { - "updated comment" - } else { - "commented" - }; - if let Some(commit) = ¬e.commit { format!( - "[{}] {} {updated_fmt} on commit {:?} <{}>", + "[{}] {} commented on commit {:?} <{}>", note.repository.name, note.author.name, commit.ref_, commit.url, ) } else if let Some(issue) = ¬e.issue { format!( - "[{}] {} {updated_fmt} on issue {}: {} <{}>", + "[{}] {} commented on issue {}: {} <{}>", note.repository.name, note.author.name, issue.id, issue.title, note.url, ) } else if let Some(mr) = ¬e.merge_request { format!( - "[{}] {} {updated_fmt} on merge request {}: {} <{}>", + "[{}] {} commented on merge request {}: {} <{}>", note.repository.name, note.author.name, mr.id, mr.title, note.url, ) } else { diff --git a/src/hooks/types.rs b/src/hooks/types.rs index b828ebe..6525fe2 100644 --- a/src/hooks/types.rs +++ b/src/hooks/types.rs @@ -116,7 +116,6 @@ pub struct Note { pub repository: Repository, pub author: User, pub url: String, - pub is_update: bool, } #[derive(Debug, Clone, PartialEq)] diff --git a/src/main.rs b/src/main.rs index 8f2f0a3..e9c22d6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -56,10 +56,11 @@ async fn main() -> Result<(), Error> { let (value_tx, value_rx) = mpsc::unbounded_channel::(); let mut bot = XmppClient::new( - config.jid.clone(), + config.jid, config.password.as_str(), - config.nickname.clone(), - config.clone(), + config.rooms, + config.nickname, + config.admins, ); let xmpp_handle = tokio::task::spawn(async move { diff --git a/src/web.rs b/src/web.rs index 3dc01f2..50fbc0d 100644 --- a/src/web.rs +++ b/src/web.rs @@ -14,7 +14,7 @@ // along with this program. If not, see . use crate::error::Error; -#[cfg(feature = "gitlab")] +#[allow(deprecated)] use crate::hooks::GitlabHook; use crate::hooks::{ForgejoHook, Hook}; @@ -22,7 +22,7 @@ use std::convert::Infallible; use std::io::Read; use bytes::{Buf, Bytes}; -use hmac::{Hmac, KeyInit, Mac}; +use hmac::{Hmac, Mac}; use http_body_util::{BodyExt, Full}; use hyper::{Method, Request, Response, body::Incoming, header}; use log::{debug, error, trace}; @@ -62,7 +62,6 @@ async fn hooks_inner(req: Request, secret: &str) -> Result