diff --git a/src/config.rs b/src/config.rs index f70d093a0d..5111ef309c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -45,6 +45,26 @@ pub struct Config { cached_token_data: Option, } +fn get_url_validation_error(default_url: &str, region_url: &str, token_url: &str) -> String { + match (region_url, token_url) { + ("", "") => format!("An unexpected error occurred when validating the URL."), + (region_url, token_url) + if token_url != region_url && region_url != "" && token_url != "" => + { + format!( + "The provided URL does not match any of the URLs on the authentication token. \ + Expected: `{token_url}` or `{region_url}`, Received: `{default_url}`." + ) + } + ("", url) | (url, _) => { + format!( + "The provided URL does not match the URL on the authentication token. \ + Expected: `{url}`, Received: `{default_url}`." + ) + } + } +} + impl Config { /// Loads the CLI config from the default location and returns it. pub fn from_cli_config() -> Result { @@ -66,13 +86,20 @@ impl Config { .map(|td| td.url.as_str()) .unwrap_or_default(); - let url = match (default_url.as_str(), token_url) { - (_, "") => default_url, - _ if default_url == token_url => default_url, - (DEFAULT_URL | "", _) => String::from(token_url), - _ => bail!( - "Two different url values supplied: `{token_url}` (from token), `{default_url}`." - ), + let region_url = token_embedded_data + .as_ref() + .map(|td| td.region_url.as_str()) + .unwrap_or_default(); + + let url = match (default_url.as_str(), token_url, region_url) { + (_, "", "") => default_url, + _ if default_url == token_url || default_url == region_url => default_url, + (DEFAULT_URL | "", _, _) => String::from(token_url), + _ => bail!(get_url_validation_error( + &default_url, + region_url, + token_url + )), }; Ok(Config { @@ -210,8 +237,14 @@ impl Config { .map(|td| td.url.as_str()) .unwrap_or_default(); - if !token_url.is_empty() && url != token_url { - bail!("Two different url values supplied: `{token_url}` (from token), `{url}`."); + let region_url = self + .cached_token_data + .as_ref() + .map(|td| td.region_url.as_str()) + .unwrap_or_default(); + + if !token_url.is_empty() && url != token_url && url != region_url { + bail!(get_url_validation_error(url, region_url, token_url)) } self.cached_base_url = url.to_owned(); diff --git a/src/utils/auth_token/org_auth_token.rs b/src/utils/auth_token/org_auth_token.rs index b6ff0e7455..3489881cec 100644 --- a/src/utils/auth_token/org_auth_token.rs +++ b/src/utils/auth_token/org_auth_token.rs @@ -16,7 +16,7 @@ pub struct OrgAuthToken { #[allow(dead_code)] // Otherwise, we get a warning about unused fields pub struct AuthTokenPayload { iat: f64, - region_url: String, + pub region_url: String, pub org: String, // URL may be missing from some old auth tokens, see getsentry/sentry#57123 diff --git a/tests/integration/_cases/org_tokens/url-match.trycmd b/tests/integration/_cases/org_tokens/url-match.trycmd index 6b09576016..12cdecf96b 100644 --- a/tests/integration/_cases/org_tokens/url-match.trycmd +++ b/tests/integration/_cases/org_tokens/url-match.trycmd @@ -1,11 +1,9 @@ ``` -$ sentry-cli --auth-token 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 --url http://localhost:8000 sourcemaps upload +$ sentry-cli --auth-token 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 --url http://localhost:8000 sourcemaps upload --org nomatch test_path ? failed -error: the following required arguments were not provided: - ... +error: Two different org values supplied: `sentry` (from token), `nomatch`. -Usage: sentry-cli[EXE] sourcemaps upload ... - -For more information, try '--help'. +Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. +Please attach the full debug log to all bug reports. ``` diff --git a/tests/integration/_cases/org_tokens/url-mismatch-with-matching-region.trycmd b/tests/integration/_cases/org_tokens/url-mismatch-with-matching-region.trycmd new file mode 100644 index 0000000000..01b24bb11f --- /dev/null +++ b/tests/integration/_cases/org_tokens/url-mismatch-with-matching-region.trycmd @@ -0,0 +1,9 @@ +``` +$ sentry-cli --auth-token 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 --url http://example.com sourcemaps upload test_path +? failed +error: The provided URL does not match the URL on the authentication token. Expected: `http://localhost:8000`, Received: `http://example.com`. + +Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. +Please attach the full debug log to all bug reports. + +``` diff --git a/tests/integration/_cases/org_tokens/url-mismatch.trycmd b/tests/integration/_cases/org_tokens/url-mismatch.trycmd index 6009f05c9a..3ea78d8b62 100644 --- a/tests/integration/_cases/org_tokens/url-mismatch.trycmd +++ b/tests/integration/_cases/org_tokens/url-mismatch.trycmd @@ -1,7 +1,7 @@ ``` -$ sentry-cli --auth-token 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 --url http://example.com sourcemaps upload test_path +$ sentry-cli --auth-token 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 --url http://example.com sourcemaps upload test_path ? failed -error: Two different url values supplied: `http://localhost:8000` (from token), `http://example.com`. +error: The provided URL does not match any of the URLs on the authentication token. Expected: `http://localhost:8000` or `http://region.localhost:8000`, Received: `http://example.com`. Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. Please attach the full debug log to all bug reports. diff --git a/tests/integration/_cases/org_tokens/url-region-match.trycmd b/tests/integration/_cases/org_tokens/url-region-match.trycmd new file mode 100644 index 0000000000..945e22165a --- /dev/null +++ b/tests/integration/_cases/org_tokens/url-region-match.trycmd @@ -0,0 +1,9 @@ +``` +$ sentry-cli --auth-token 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 --url http://region.localhost:8000 sourcemaps upload --org nomatch test_path +? failed +error: Two different org values supplied: `sentry` (from token), `nomatch`. + +Add --log-level=[info|debug] or export SENTRY_LOG_LEVEL=[info|debug] to see more output. +Please attach the full debug log to all bug reports. + +``` diff --git a/tests/integration/org_tokens.rs b/tests/integration/org_tokens.rs index 41b70f4d1b..dbdc502af0 100644 --- a/tests/integration/org_tokens.rs +++ b/tests/integration/org_tokens.rs @@ -15,6 +15,16 @@ fn org_token_url_match() { register_test("org_tokens/url-match.trycmd"); } +#[test] +fn org_token_region_url_match() { + register_test("org_tokens/url-region-match.trycmd"); +} + +#[test] +fn org_token_url_mismatch_with_matching_region_url() { + register_test("org_tokens/url-mismatch-with-matching-region.trycmd"); +} + #[test] fn org_token_org_match() { register_test("org_tokens/org-match.trycmd");