From 791a1f8b165caf73cec06e28d551392682301452 Mon Sep 17 00:00:00 2001 From: Daniel Szoke Date: Wed, 29 Nov 2023 11:50:34 +0100 Subject: [PATCH] feat(api): Validate `monitors run` command's `--timezone` argument (#1847) The `sentry-cli monitors run` command's `--timezone` argument will now be validated against a list of valid IANA time zone database identifiers. If the user provides a `--timezone` argument, which does not match a valid IANA time zone identifier, the command will fail with an error. Previously, the command would appear to run successfully, but the monitor upsert would silently fail in the Sentry backend, since the backend rejects monitor upserts that have an invalid timezone string. Fixes GH-1845 --- Cargo.lock | 122 ++++++++++++++++++++++++----------- Cargo.toml | 3 +- src/commands/monitors/run.rs | 11 +++- 3 files changed, 96 insertions(+), 40 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c898fa3657..c92406d676 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,6 +59,12 @@ dependencies = [ "memchr", ] +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + [[package]] name = "android_system_properties" version = "0.1.5" @@ -293,18 +299,39 @@ checksum = "1a48563284b67c003ba0fb7243c87fab68885e1532c605704228a80238512e31" [[package]] name = "chrono" -version = "0.4.23" +version = "0.4.31" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" +checksum = "7f2c685bad3eb3d45a01354cedb7d5faa66194d1d58ba6e267a8de788f79db38" dependencies = [ + "android-tzdata", "iana-time-zone", "js-sys", - "num-integer", "num-traits", "serde", - "time 0.1.45", "wasm-bindgen", - "winapi 0.3.9", + "windows-targets 0.48.5", +] + +[[package]] +name = "chrono-tz" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e23185c0e21df6ed832a12e2bda87c7d1def6842881fb634a8511ced741b0d76" +dependencies = [ + "chrono", + "chrono-tz-build", + "phf", +] + +[[package]] +name = "chrono-tz-build" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "433e39f13c9a060046954e0592a8d0a4bcb1040125cbf91cb8ee58964cfb350f" +dependencies = [ + "parse-zoneinfo", + "phf", + "phf_codegen", ] [[package]] @@ -884,7 +911,7 @@ checksum = "c05aeb6a22b8f62540c194aac980f2115af067bfe15a0734d7277a768d396b31" dependencies = [ "cfg-if", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", ] [[package]] @@ -1476,16 +1503,6 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "61807f77802ff30975e01f4f071c8ba10c022052f98b3294119f3e615d13e5be" -[[package]] -name = "num-integer" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" -dependencies = [ - "autocfg", - "num-traits", -] - [[package]] name = "num-traits" version = "0.2.15" @@ -1642,6 +1659,15 @@ dependencies = [ "windows-sys 0.42.0", ] +[[package]] +name = "parse-zoneinfo" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" +dependencies = [ + "regex", +] + [[package]] name = "password-hash" version = "0.4.2" @@ -1746,6 +1772,35 @@ dependencies = [ "sha2", ] +[[package]] +name = "phf" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ade2d8b8f33c7333b51bcf0428d37e217e9f32192ae4772156f65063b8ce03dc" +dependencies = [ + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_codegen" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" +dependencies = [ + "phf_generator", + "phf_shared 0.11.2", +] + +[[package]] +name = "phf_generator" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48e4cc64c2ad9ebe670cb8fd69dd50ae301650392e81c05f9bfcb2d5bdbc24b0" +dependencies = [ + "phf_shared 0.11.2", + "rand", +] + [[package]] name = "phf_shared" version = "0.10.0" @@ -1755,6 +1810,15 @@ dependencies = [ "siphasher", ] +[[package]] +name = "phf_shared" +version = "0.11.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" +dependencies = [ + "siphasher", +] + [[package]] name = "pin-project-lite" version = "0.2.9" @@ -1784,7 +1848,7 @@ dependencies = [ "line-wrap", "quick-xml", "serde", - "time 0.3.17", + "time", ] [[package]] @@ -2220,6 +2284,7 @@ dependencies = [ "bytecount", "chardet", "chrono", + "chrono-tz", "clap", "clap_complete", "console", @@ -2320,7 +2385,7 @@ dependencies = [ "serde", "serde_json", "thiserror", - "time 0.3.17", + "time", "url", "uuid", ] @@ -2521,7 +2586,7 @@ dependencies = [ "new_debug_unreachable", "once_cell", "parking_lot", - "phf_shared", + "phf_shared 0.10.0", "precomputed-hash", "serde", ] @@ -2733,17 +2798,6 @@ dependencies = [ "once_cell", ] -[[package]] -name = "time" -version = "0.1.45" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" -dependencies = [ - "libc", - "wasi 0.10.0+wasi-snapshot-preview1", - "winapi 0.3.9", -] - [[package]] name = "time" version = "0.3.17" @@ -2990,12 +3044,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "wasi" -version = "0.10.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" - [[package]] name = "wasi" version = "0.11.0+wasi-snapshot-preview1" @@ -3308,7 +3356,7 @@ dependencies = [ "hmac", "pbkdf2", "sha1", - "time 0.3.17", + "time", "zstd", ] diff --git a/Cargo.toml b/Cargo.toml index 2f84ebf60d..d39a768a4a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -14,7 +14,7 @@ backtrace = "0.3.67" brotli2 = "0.3.2" bytecount = "0.6.3" chardet = "0.2.4" -chrono = { version = "0.4.23", features = ["serde"] } +chrono = { version = "0.4.31", features = ["serde"] } clap = { version = "4.1.6", default-features = false, features = [ "std", "suggestions", @@ -77,6 +77,7 @@ which = "4.4.0" zip = "0.6.4" data-encoding = "2.3.3" magic_string = "0.3.4" +chrono-tz = "0.8.4" [dev-dependencies] insta = { version = "1.26.0", features = ["redactions", "yaml"] } diff --git a/src/commands/monitors/run.rs b/src/commands/monitors/run.rs index 10e1e7e3f2..d0ea829eea 100644 --- a/src/commands/monitors/run.rs +++ b/src/commands/monitors/run.rs @@ -1,3 +1,4 @@ +use chrono_tz::Tz; use log::warn; use std::process; use std::time::{Duration, Instant}; @@ -73,10 +74,16 @@ pub fn make_command(command: Command) -> Command { .arg( Arg::new("timezone") .long("timezone") + .value_parser(|value: &str| { + value.parse::().map_err(|err| { + err + "\n\tSee here for a list of valid timezone strings: \ + https://en.wikipedia.org/wiki/List_of_tz_database_time_zones#List" + }) + }) .requires("schedule") .help( "A tz database string (e.g. \"Europe/Vienna\") representing the monitor's \ - execution schedule's timezone. Requires --schedule.", + execution schedule's timezone. Requires --schedule.", ), ) } @@ -202,7 +209,7 @@ fn parse_monitor_config_args(matches: &ArgMatches) -> Result