From ef34dbe2df9a15becdf6b4eb4a53338fbd3d3888 Mon Sep 17 00:00:00 2001 From: Antoine Martin Date: Sat, 11 Sep 2021 19:31:40 +0200 Subject: [PATCH] bot: setup autojoin Currently broken on v0.4.0, unfortunately. Investigating. --- Cargo.lock | 445 ++++++++++++++++++++++++++++++----- Cargo.toml | 10 +- src/bot/handlers/autojoin.rs | 68 ++++++ src/bot/handlers/mod.rs | 1 + src/bot/mod.rs | 102 ++++++++ src/config.rs | 20 ++ src/main.rs | 35 ++- 7 files changed, 615 insertions(+), 66 deletions(-) create mode 100644 src/bot/handlers/autojoin.rs create mode 100644 src/bot/handlers/mod.rs create mode 100644 src/bot/mod.rs create mode 100644 src/config.rs diff --git a/Cargo.lock b/Cargo.lock index fdecfa4..cf34603 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -31,7 +31,7 @@ checksum = "9e8b47f52ea9bae42228d07ec09eb676433d7c4ed1ebdf0f1d1c29ed446f1ab8" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.2.1", + "cpufeatures", "ctr", "opaque-debug", ] @@ -61,6 +61,21 @@ dependencies = [ "version_check", ] +[[package]] +name = "ansi_term" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d52a9bb7ec0cf484c551830a7ce27bd20d67eac647e1befb56b0be4ee39a55d2" +dependencies = [ + "winapi", +] + +[[package]] +name = "anyhow" +version = "1.0.43" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28ae2b3dec75a406790005a200b1bd89785afc02517a00ca99ecfe093ee9e6cf" + [[package]] name = "assign" version = "1.1.1" @@ -87,6 +102,17 @@ dependencies = [ "autocfg", ] +[[package]] +name = "atty" +version = "0.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" +dependencies = [ + "hermit-abi", + "libc", + "winapi", +] + [[package]] name = "autocfg" version = "1.0.1" @@ -172,21 +198,21 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chacha20" -version = "0.7.1" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fee7ad89dc1128635074c268ee661f90c3f7e83d9fd12910608c36b47d6c3412" +checksum = "01b72a433d0cf2aef113ba70f62634c56fddb0f244e6377185c56a7cadbd8f91" dependencies = [ "cfg-if", "cipher", - "cpufeatures 0.1.5", + "cpufeatures", "zeroize", ] [[package]] name = "chacha20poly1305" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1580317203210c517b6d44794abfbe600698276db18127e37ad3e69bf5e848e5" +checksum = "3b84ed6d1d5f7aa9bdde921a5090e0ca4d934d250ea3b402a5fab3a994e28a2a" dependencies = [ "aead", "chacha20", @@ -201,6 +227,18 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "17cc5e6b5ab06331c33589842070416baa137e8b0eb912b008cfd4a78ada7919" +[[package]] +name = "chrono" +version = "0.4.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "670ad68c9088c2a963aaa298cb369688cf3f9465ce5e2d4ca10e6e0098a1ce73" +dependencies = [ + "libc", + "num-integer", + "num-traits", + "winapi", +] + [[package]] name = "cipher" version = "0.3.0" @@ -210,6 +248,37 @@ dependencies = [ "generic-array", ] +[[package]] +name = "clap" +version = "3.0.0-beta.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcd70aa5597dbc42f7217a543f9ef2768b2ef823ba29036072d30e1d88e98406" +dependencies = [ + "atty", + "bitflags", + "clap_derive", + "indexmap", + "lazy_static", + "os_str_bytes", + "strsim", + "termcolor", + "textwrap", + "vec_map", +] + +[[package]] +name = "clap_derive" +version = "3.0.0-beta.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b5bb0d655624a0b8770d1c178fb8ffcb1f91cc722cb08f451e3dc72465421ac" +dependencies = [ + "heck", + "proc-macro-error", + "proc-macro2 1.0.29", + "quote 1.0.9", + "syn 1.0.76", +] + [[package]] name = "cmake" version = "0.1.45" @@ -253,15 +322,6 @@ version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea221b5284a47e40033bf9b66f35f984ec0ea2931eb03505246cd27a963f981b" -[[package]] -name = "cpufeatures" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "66c99696f6c9dd7f35d486b9d04d7e6e202aa3e8c40d553f2fdf5e7e0c6a71ef" -dependencies = [ - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.1" @@ -400,6 +460,12 @@ version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "212d0f5754cb6769937f4501cc0e67f4f4483c8d2c3e1e922ee9edbe4ab4c7c0" +[[package]] +name = "dtoa" +version = "0.4.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" + [[package]] name = "ed25519" version = "1.2.0" @@ -438,6 +504,12 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "event-listener" +version = "2.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f7531096570974c3a9dcf9e4b8e1cede1ec26cf5046219fb3b9d897503b9be59" + [[package]] name = "fnv" version = "1.0.7" @@ -724,6 +796,15 @@ dependencies = [ "ahash", ] +[[package]] +name = "heck" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "hermit-abi" version = "0.1.19" @@ -937,6 +1018,12 @@ version = "0.2.101" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3cb00336871be5ed2c8ed44b60ae9959dc5b9f08539422ed43f09e34ecaeba21" +[[package]] +name = "linked-hash-map" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" + [[package]] name = "lock_api" version = "0.4.5" @@ -970,6 +1057,15 @@ version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3e2e65a1a2e43cfcb47a895c4c8b10d1f4a61097f9f254f183aee60cad9c651d" +[[package]] +name = "matchers" +version = "0.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f099785f7595cc4b4553a174ce30dd7589ef93391ff414dbb67f62392b9e0ce1" +dependencies = [ + "regex-automata", +] + [[package]] name = "matches" version = "0.1.9" @@ -978,9 +1074,9 @@ checksum = "a3e378b66a060d48947b590737b30a1be76706c8dd7b8ba0f2fe3989c68a853f" [[package]] name = "matrix-qrcode" -version = "0.1.0" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "292c022b5b3d2f6fe39095497b27f4ec5cbcc6e55d0b20c0c01b8bde07f3f419" +checksum = "4231739aa2ff90c6c55b07d7179c52b496622a86fc2f7e0431336d109ba7838d" dependencies = [ "base64", "byteorder", @@ -993,13 +1089,14 @@ dependencies = [ [[package]] name = "matrix-sdk" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b1a9dcccddd5d1e7b13304169021404015fd40a95f56bd895319e9447f7784e6" +checksum = "1119aaca5e48e4794ad19d981a6d69205d16b60a15c55cec46d6cb1a0725d579" dependencies = [ "backoff", "bytes", "dashmap", + "event-listener", "futures", "futures-timer", "http", @@ -1008,6 +1105,7 @@ dependencies = [ "mime", "reqwest", "ruma", + "serde", "serde_json", "thiserror", "tokio", @@ -1019,9 +1117,9 @@ dependencies = [ [[package]] name = "matrix-sdk-base" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "96e360288b4acb062e4cb3e2952d49b2a93e256438ec749bfffdef701bd0abd0" +checksum = "c9907a9d8ae3caf2c18ff1334e712947caab891ccbe167dea7d1790ab1047ab3" dependencies = [ "chacha20poly1305", "dashmap", @@ -1045,9 +1143,9 @@ dependencies = [ [[package]] name = "matrix-sdk-common" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f595bd52c35ce962ecf52875c5b659f3845cb00b35dd205c7ae62e2b7bdad38" +checksum = "d6a110018ac4df72a57f1c9d3976243c7c3ad7189f50aa7ca0032276c9c78519" dependencies = [ "async-trait", "futures", @@ -1062,9 +1160,9 @@ dependencies = [ [[package]] name = "matrix-sdk-crypto" -version = "0.3.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "207af21203f5d1787426dbb89c13dc791515448086f098c52ecb9bc591a5b621" +checksum = "1683b93a94890337f75fdc3b8630a633c974089a9b5f874b4b5771cf82336bad" dependencies = [ "aes", "aes-gcm", @@ -1231,9 +1329,9 @@ dependencies = [ [[package]] name = "olm-rs" -version = "1.0.1" +version = "2.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8962a1fc909accf520991dcda872888554ecf16320097e02d3bd9981844a24ae" +checksum = "33a5773f317476f5687fc8200fc0120d97b075c30c133a5b15ca558252743720" dependencies = [ "getrandom 0.2.3", "olm-sys", @@ -1296,6 +1394,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "os_str_bytes" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6acbef58a60fe69ab50510a55bc8cdd4d6cf2283d27ad338f54cb52747a9cf2d" + [[package]] name = "parking_lot" version = "0.11.2" @@ -1329,9 +1433,9 @@ checksum = "acbf547ad0c65e31259204bd90935776d1c693cec2f4ff7abb7a1bbbd40dfe58" [[package]] name = "pbkdf2" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d95f5254224e617595d2cc3cc73ff0a5eaf2637519e25f03388154e9378b6ffa" +checksum = "f05894bce6a1ba4be299d0c5f29563e08af2bc18bb7d48313113bed71e904739" dependencies = [ "crypto-mac", ] @@ -1409,7 +1513,7 @@ version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "048aeb476be11a4b6ca432ca569e375810de9294ae78f4774e78ea98a9246ede" dependencies = [ - "cpufeatures 0.2.1", + "cpufeatures", "opaque-debug", "universal-hash", ] @@ -1421,7 +1525,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8419d2b623c7c0896ff2d5d96e2cb4ede590fed28fcc34934f4c33c036e620a1" dependencies = [ "cfg-if", - "cpufeatures 0.2.1", + "cpufeatures", "opaque-debug", "universal-hash", ] @@ -1442,6 +1546,30 @@ dependencies = [ "toml", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2 1.0.29", + "quote 1.0.9", + "syn 1.0.76", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2 1.0.29", + "quote 1.0.9", + "version_check", +] + [[package]] name = "proc-macro-hack" version = "0.5.19" @@ -1476,7 +1604,15 @@ dependencies = [ name = "prololo-reborn" version = "0.1.0" dependencies = [ + "anyhow", + "clap", "matrix-sdk", + "serde", + "serde_yaml", + "tokio", + "tracing", + "tracing-subscriber", + "url", ] [[package]] @@ -1622,6 +1758,30 @@ dependencies = [ "bitflags", ] +[[package]] +name = "regex" +version = "1.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d07a8629359eb56f1e2fb1652bb04212c072a87ba68546a04065d525673ac461" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-automata" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" +dependencies = [ + "regex-syntax", +] + +[[package]] +name = "regex-syntax" +version = "0.6.25" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f497285884f3fcff424ffc933e56d7cbca511def0c9831a7f9b5f6153e3cc89b" + [[package]] name = "remove_dir_all" version = "0.5.3" @@ -1678,9 +1838,9 @@ dependencies = [ [[package]] name = "ruma" -version = "0.2.0" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a4acf77afac731e1fa133e6952d074af052f02d64909677a66619f52e758261" +checksum = "668031e3108d6a2cfbe6eca271d8698f4593440e71a44afdadcf67ce3cb93c1f" dependencies = [ "assign", "js_int", @@ -1697,9 +1857,9 @@ dependencies = [ [[package]] name = "ruma-api" -version = "0.17.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6473753f244f057181f975224aeaf5b4e2003f43f2a6279bf0b95f4e0126335" +checksum = "f5f1843792b6749ec1ece62595cf99ad30bf9589c96bb237515235e71da396ea" dependencies = [ "bytes", "http", @@ -1714,9 +1874,9 @@ dependencies = [ [[package]] name = "ruma-api-macros" -version = "0.17.1" +version = "0.18.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85286e2c65897079e7dcc120964cca47d5a3c23b7d1e9f730f533060919fedf7" +checksum = "7b18abda5cca94178d08b622bca042e1cbb5eb7d4ebf3a2a81590a3bb3c57008" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.29", @@ -1726,9 +1886,9 @@ dependencies = [ [[package]] name = "ruma-client-api" -version = "0.11.0" +version = "0.12.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b86eba1c6fce6dd5c7a17ed632515aa7d04bbe6fbaa74c1699fb72c9fcc2d3d" +checksum = "9568a222c12cf6220e751484ab78feec28071f85965113a5bb802936a2920ff0" dependencies = [ "assign", "bytes", @@ -1747,9 +1907,9 @@ dependencies = [ [[package]] name = "ruma-common" -version = "0.5.4" +version = "0.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "146a88f34b7a084d54eaf790aaf4c25f5d2366ca8f3d1f326985fa5d31d72595" +checksum = "41d5b7605f58dc0d9cf1848cc7f1af2bae4e4bcd1d2b7a87bbb9864c8a785b91" dependencies = [ "indexmap", "js_int", @@ -1763,9 +1923,9 @@ dependencies = [ [[package]] name = "ruma-events" -version = "0.23.3" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7da5f1472d60803e06744f83040a055948fd5bc1f4344d3e555ea378d0d6c96d" +checksum = "87801e1207cfebdee02e7997ebf181a1c9837260b78c1b8ce96b896a2bcb3763" dependencies = [ "indoc", "js_int", @@ -1775,13 +1935,14 @@ dependencies = [ "ruma-serde", "serde", "serde_json", + "thiserror", ] [[package]] name = "ruma-events-macros" -version = "0.23.3" +version = "0.24.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85929d84b29c4ce034bd1742e13d7ca25d885831f0185b73f7f9a9094296e1c4" +checksum = "5da4498845347de88adf1b7da4578e2ca7355ad4ce47b0976f6594bacf958660" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.29", @@ -1791,9 +1952,9 @@ dependencies = [ [[package]] name = "ruma-federation-api" -version = "0.2.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9d5206d4922c5dbd3b6faf2aaec9b5551fdf710ef73cc2145f13d0a5bb3945dc" +checksum = "fa3d1db1a064ab26484df6ef5d96c384fc053022004f34d96c3b4939e13dc204" dependencies = [ "js_int", "ruma-api", @@ -1807,9 +1968,9 @@ dependencies = [ [[package]] name = "ruma-identifiers" -version = "0.19.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9be9ce339ce206dd5eb5eb29b7ad1b964652d46345bc46f25d68105effc75f4b" +checksum = "cb417d091e8dd5a633e4e5998231a156049d7fcc221045cfdc0642eb72067732" dependencies = [ "paste", "ruma-identifiers-macros", @@ -1821,9 +1982,9 @@ dependencies = [ [[package]] name = "ruma-identifiers-macros" -version = "0.19.4" +version = "0.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e3c7bc7e132a84f8d03924cf63d3a37bd87ffee5c29fee69b9125d045c7e4020" +checksum = "c708edad7f605638f26c951cbad7501fbf28ab01009e5ca65ea5a2db74a882b1" dependencies = [ "quote 1.0.9", "ruma-identifiers-validation", @@ -1832,15 +1993,15 @@ dependencies = [ [[package]] name = "ruma-identifiers-validation" -version = "0.4.0" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8edeb165c4dcb8c93d1b7396b32fd5f52c5d9c7e7898ab87d772f824fe642f7c" +checksum = "42285e7fb5d5f2d5268e45bb683e36d5c6fd9fc1e11a4559ba3c3521f3bbb2cb" [[package]] name = "ruma-serde" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cd9cf55470945ce15641f331d0230bbab328cdf9aa5c3ec8aa20977b60553f15" +checksum = "8b2b22aae842e7ecda695e42b7b39d4558959d9d9a27acc2a16acf4f4f7f00c3" dependencies = [ "bytes", "form_urlencoded", @@ -1853,9 +2014,9 @@ dependencies = [ [[package]] name = "ruma-serde-macros" -version = "0.4.2" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6af6e7156da1a4b0bd4b13dbe8c5a725878595a7962345393b3f171c75bd7cc" +checksum = "243e9bef188b08f94c79bc2f8fd1eb307a9e636b2b8e4571acf8c7be16381d28" dependencies = [ "proc-macro-crate", "proc-macro2 1.0.29", @@ -1865,9 +2026,9 @@ dependencies = [ [[package]] name = "ruma-signatures" -version = "0.8.0" +version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5d83873429181c7747b42fce80d86be84d63fd178e83573472c93143643b7a67" +checksum = "4a4f64027165b59500162d10d435b1253898bf3ad4f5002cb0d56913fe7f76d7" dependencies = [ "base64", "ed25519-dalek", @@ -1883,13 +2044,12 @@ dependencies = [ [[package]] name = "ruma-state-res" -version = "0.2.0" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50be7be79f1036dfdacda38e94f334e99f845db2e414887eedb757d065a05594" +checksum = "518c1afbddfcc5ffac8818a5cf0902709e6eca11aca8f24f6479df6f0601f1ba" dependencies = [ "itertools", "js_int", - "maplit", "ruma-common", "ruma-events", "ruma-identifiers", @@ -2024,6 +2184,18 @@ dependencies = [ "serde", ] +[[package]] +name = "serde_yaml" +version = "0.8.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8c608a35705a5d3cdc9fbe403147647ff34b921f8e833e49306df898f9b20af" +dependencies = [ + "dtoa", + "indexmap", + "serde", + "yaml-rust", +] + [[package]] name = "sha1" version = "0.6.0" @@ -2038,11 +2210,29 @@ checksum = "9204c41a1597a8c5af23c82d1c921cb01ec0a4c59e07a9c7306062829a3903f3" dependencies = [ "block-buffer", "cfg-if", - "cpufeatures 0.2.1", + "cpufeatures", "digest", "opaque-debug", ] +[[package]] +name = "sharded-slab" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "740223c51853f3145fe7c90360d2d4232f2b62e3449489c207eccde818979982" +dependencies = [ + "lazy_static", +] + +[[package]] +name = "signal-hook-registry" +version = "1.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" +dependencies = [ + "libc", +] + [[package]] name = "signature" version = "1.3.1" @@ -2154,6 +2344,12 @@ version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "213701ba3370744dcd1a12960caa4843b3d68b4d1c0a5d575e0d65b2ee9d16c0" +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "subtle" version = "2.4.1" @@ -2208,6 +2404,24 @@ dependencies = [ "winapi", ] +[[package]] +name = "termcolor" +version = "1.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dfed899f0eb03f32ee8c6a0aabdb8a7949659e3466561fc0adf54e26d88c5f4" +dependencies = [ + "winapi-util", +] + +[[package]] +name = "textwrap" +version = "0.14.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0066c8d12af8b5acd21e00547c3797fde4e8677254a7ee429176ccebbe93dd80" +dependencies = [ + "unicode-width", +] + [[package]] name = "thiserror" version = "1.0.29" @@ -2228,6 +2442,15 @@ dependencies = [ "syn 1.0.76", ] +[[package]] +name = "thread_local" +version = "1.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8018d24e04c95ac8790716a5987d0fec4f8b27249ffa0f7d33f1369bdfb88cbd" +dependencies = [ + "once_cell", +] + [[package]] name = "tiff" version = "0.6.1" @@ -2303,10 +2526,26 @@ dependencies = [ "libc", "memchr", "mio", + "num_cpus", + "once_cell", + "parking_lot", "pin-project-lite", + "signal-hook-registry", + "tokio-macros", "winapi", ] +[[package]] +name = "tokio-macros" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "54473be61f4ebe4efd09cec9bd5d16fa51d70ea0192213d754d2d500457db110" +dependencies = [ + "proc-macro2 1.0.29", + "quote 1.0.9", + "syn 1.0.76", +] + [[package]] name = "tokio-native-tls" version = "0.3.0" @@ -2388,6 +2627,49 @@ dependencies = [ "tracing", ] +[[package]] +name = "tracing-log" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6923477a48e41c1951f1999ef8bb5a3023eb723ceadafe78ffb65dc366761e3" +dependencies = [ + "lazy_static", + "log", + "tracing-core", +] + +[[package]] +name = "tracing-serde" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fb65ea441fbb84f9f6748fd496cf7f63ec9af5bca94dd86456978d055e8eb28b" +dependencies = [ + "serde", + "tracing-core", +] + +[[package]] +name = "tracing-subscriber" +version = "0.2.20" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9cbe87a2fa7e35900ce5de20220a582a9483a7063811defce79d7cbd59d4cfe" +dependencies = [ + "ansi_term", + "chrono", + "lazy_static", + "matchers", + "regex", + "serde", + "serde_json", + "sharded-slab", + "smallvec", + "thread_local", + "tracing", + "tracing-core", + "tracing-log", + "tracing-serde", +] + [[package]] name = "try-lock" version = "0.2.3" @@ -2415,6 +2697,18 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b" + +[[package]] +name = "unicode-width" +version = "0.1.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" + [[package]] name = "unicode-xid" version = "0.1.0" @@ -2453,6 +2747,7 @@ dependencies = [ "idna", "matches", "percent-encoding", + "serde", ] [[package]] @@ -2471,6 +2766,12 @@ version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "vec_map" +version = "0.8.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" + [[package]] name = "version_check" version = "0.9.3" @@ -2605,6 +2906,15 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" +[[package]] +name = "winapi-util" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" +dependencies = [ + "winapi", +] + [[package]] name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" @@ -2620,6 +2930,15 @@ dependencies = [ "winapi", ] +[[package]] +name = "yaml-rust" +version = "0.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85" +dependencies = [ + "linked-hash-map", +] + [[package]] name = "zeroize" version = "1.4.1" diff --git a/Cargo.toml b/Cargo.toml index a45df7c..21ebd5a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,4 +6,12 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -matrix-sdk = "0.3.0" +anyhow = "1.0" +clap = "3.0.0-beta.4" +matrix-sdk = "0.4.0" +serde = "1.0" +serde_yaml = "0.8" +tokio = { version = "1.0", features = [ "full" ] } +tracing-subscriber = "0.2" +tracing = "0.1" +url = { version = "2.2", features = [ "serde" ] } diff --git a/src/bot/handlers/autojoin.rs b/src/bot/handlers/autojoin.rs new file mode 100644 index 0000000..00bd326 --- /dev/null +++ b/src/bot/handlers/autojoin.rs @@ -0,0 +1,68 @@ +use std::time::Duration; + +use matrix_sdk::{ + room::Room, + ruma::{ + events::{room::member::MemberEventContent, StrippedStateEvent}, + RoomId, + }, + Client, +}; +use tokio::time::sleep; +use tracing::{debug, error, info, warn}; + +pub async fn autojoin_authorized_rooms( + room_member: StrippedStateEvent, + client: Client, + room: Room, + authorized_rooms: Vec, +) { + if room_member.state_key != client.user_id().await.unwrap() { + return; + } + + if let Room::Invited(room) = room { + let room_id = room.room_id(); + let room_name = room + .display_name() + .await + .expect("couldn't get joined room name!"); + info!( + "Received invitation for room `{}`: `{}`", + room_id, room_name + ); + + if authorized_rooms.contains(room_id) { + warn!( + "Bot isn't authorized to join room `{}`, declining invitation", + room_id + ); + room.reject_invitation().await.unwrap(); + return; + } + + debug!("Autojoining room {}", room.room_id()); + let mut delay = 2; + + while let Err(err) = room.accept_invitation().await { + // retry autojoin due to synapse sending invites, before the + // invited user can join for more information see + // https://github.com/matrix-org/synapse/issues/4345 + warn!( + "Failed to join room {} ({:?}), retrying in {}s", + room.room_id(), + err, + delay + ); + + sleep(Duration::from_secs(delay)).await; + delay *= 2; + + if delay > 3600 { + error!("Can't join room {} ({:?})", room.room_id(), err); + break; + } + } + info!("Successfully joined room {}", room.room_id()); + } +} diff --git a/src/bot/handlers/mod.rs b/src/bot/handlers/mod.rs new file mode 100644 index 0000000..e676b34 --- /dev/null +++ b/src/bot/handlers/mod.rs @@ -0,0 +1 @@ +pub mod autojoin; diff --git a/src/bot/mod.rs b/src/bot/mod.rs new file mode 100644 index 0000000..8da7ecc --- /dev/null +++ b/src/bot/mod.rs @@ -0,0 +1,102 @@ +use std::{ + fs::File, + io::{BufReader, BufWriter}, +}; + +use matrix_sdk::{ + room::Room, + ruma::events::{room::member::MemberEventContent, StrippedStateEvent}, + Client, ClientConfig, Session, SyncSettings, +}; +use tracing::{debug, info}; + +use crate::config::ProloloConfig; + +mod handlers; +use handlers::autojoin::autojoin_authorized_rooms; + +pub struct Prololo { + client: Client, + config: ProloloConfig, +} + +impl Prololo { + /// Creates a new [`Prololo`] bot and builds a [`matrix_sdk::Client`] using the provided + /// [`Config`]. + /// + /// The [`Client`] is only initialized, not ready to be used yet. + pub fn new(config: ProloloConfig) -> anyhow::Result { + let client_config = ClientConfig::new().store_path(config.matrix_state_dir.join("store")); + let client = Client::new_with_config(config.matrix_homeserver.clone(), client_config)?; + + Ok(Self { client, config }) + } + + /// Loads session information from file, or creates it if no previous session is found. + /// + /// The bot is ready to run once this function has been called. + pub async fn init(&self) -> anyhow::Result<()> { + self.load_or_init_session().await?; + + let authorized_rooms = vec![self.config.matrix_room_id.clone()]; + + self.client + .register_event_handler({ + move |ev: StrippedStateEvent, client: Client, room: Room| { + let authorized_rooms = authorized_rooms.clone(); + debug!("handler!!!second"); + async move { autojoin_authorized_rooms(ev, client, room, authorized_rooms).await } + } + }) + .await; + + Ok(()) + } + + /// Start listening to Matrix events. + /// + /// [`Prololo::init`] **must** be called before this function, otherwise the [`Client`] isn't + /// logged in. + pub async fn run(&self) { + debug!("running..."); + self.client.sync(SyncSettings::default()).await + } + + /// This loads the session information from an existing file, and tries to login with it. If no such + /// file is found, then login using username and password, and save the new session information on + /// disk. + async fn load_or_init_session(&self) -> anyhow::Result<()> { + let session_file = self.config.matrix_state_dir.join("session.yaml"); + + if session_file.is_file() { + let reader = BufReader::new(File::open(session_file)?); + let session: Session = serde_yaml::from_reader(reader)?; + + self.client.restore_login(session.clone()).await?; + info!("Reused session: {}, {}", session.user_id, session.device_id); + } else { + let response = self + .client + .login( + &self.config.matrix_username, + &self.config.matrix_password, + None, + Some("autojoin bot"), + ) + .await?; + + info!("logged in as {}", self.config.matrix_username); + + let session = Session { + access_token: response.access_token, + user_id: response.user_id, + device_id: response.device_id, + }; + + let writer = BufWriter::new(File::create(session_file)?); + serde_yaml::to_writer(writer, &session)?; + } + + Ok(()) + } +} diff --git a/src/config.rs b/src/config.rs new file mode 100644 index 0000000..8970830 --- /dev/null +++ b/src/config.rs @@ -0,0 +1,20 @@ +use std::path::PathBuf; + +use matrix_sdk::ruma::RoomId; +use serde::Deserialize; +use url::Url; + +#[derive(Debug, Deserialize)] +pub struct ProloloConfig { + /// The URL for the homeserver we should connect to + pub matrix_homeserver: Url, + /// The bot's account username + pub matrix_username: String, + /// The bot's account password + pub matrix_password: String, + /// Path to a directory where the bot will store Matrix state and current session information. + pub matrix_state_dir: PathBuf, + /// ID of the Matrix room where the bot should post messages. The bot will only accept + /// invitations to this room. + pub matrix_room_id: RoomId, +} diff --git a/src/main.rs b/src/main.rs index e7a11a9..64dacf2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,3 +1,34 @@ -fn main() { - println!("Hello, world!"); +use std::fs::File; +use std::io::BufReader; +use std::path::PathBuf; + +use clap::Clap; + +mod bot; +use bot::Prololo; + +mod config; +use config::ProloloConfig; + +#[derive(Clap)] +#[clap(version = "0.1")] +struct Opts { + /// File where session information will be saved + #[clap(short, long, parse(from_os_str))] + config: PathBuf, +} + +#[tokio::main] +async fn main() -> anyhow::Result<()> { + tracing_subscriber::fmt::init(); + + let opts = Opts::parse(); + let config_file = opts.config; + let config: ProloloConfig = serde_yaml::from_reader(BufReader::new(File::open(config_file)?))?; + + let prololo = Prololo::new(config)?; + prololo.init().await?; + prololo.run().await; + + Ok(()) }