From 2f757fa231278bad984764d268460475fc326fca Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Fri, 7 Jul 2023 16:40:58 +0200 Subject: [PATCH 01/11] WIP --- src/commands/login.rs | 4 +- src/commands/mod.rs | 11 +++--- src/config.rs | 90 ++++++++++++++++++++++++++++++++++++++----- 3 files changed, 89 insertions(+), 16 deletions(-) diff --git a/src/commands/login.rs b/src/commands/login.rs index d66b00691c..ba7dfacef0 100644 --- a/src/commands/login.rs +++ b/src/commands/login.rs @@ -20,7 +20,7 @@ pub fn make_command(command: Command) -> Command { fn update_config(config: &Config, token: &str) -> Result<()> { let mut new_cfg = config.clone(); - new_cfg.set_auth(Auth::Token(token.to_string())); + new_cfg.set_auth(Auth::Token(token.to_string()))?; new_cfg.save()?; Ok(()) } @@ -65,7 +65,7 @@ pub fn execute(matches: &ArgMatches) -> Result<()> { }; let test_cfg = config.make_copy(|cfg| { - cfg.set_auth(Auth::Token(token.to_string())); + cfg.set_auth(Auth::Token(token.to_string()))?; Ok(()) })?; match Api::with_config(test_cfg).get_auth_info() { diff --git a/src/commands/mod.rs b/src/commands/mod.rs index d089028774..df204da9ac 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -97,6 +97,11 @@ fn preexecute_hooks() -> Result { } fn configure_args(config: &mut Config, matches: &ArgMatches) -> Result<()> { + bail!("Test"); + if let Some(auth_token) = matches.get_one::("auth_token") { + config.set_auth(Auth::Token(auth_token.to_owned()))?; + } + if let Some(url) = matches.get_one::("url") { config.set_base_url(url); } @@ -107,11 +112,7 @@ fn configure_args(config: &mut Config, matches: &ArgMatches) -> Result<()> { } if let Some(api_key) = matches.get_one::("api_key") { - config.set_auth(Auth::Key(api_key.to_owned())); - } - - if let Some(auth_token) = matches.get_one::("auth_token") { - config.set_auth(Auth::Token(auth_token.to_owned())); + config.set_auth(Auth::Key(api_key.to_owned()))?; } if let Some(level_str) = matches.get_one::("log_level") { diff --git a/src/config.rs b/src/config.rs index f7fb623ebb..73dc16b04c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -13,6 +13,7 @@ use lazy_static::lazy_static; use log::{debug, info, set_max_level, warn}; use parking_lot::Mutex; use sentry::types::Dsn; +use serde::Deserialize; use crate::constants::DEFAULT_MAX_DIF_ITEM_SIZE; use crate::constants::DEFAULT_MAX_DIF_UPLOAD_SIZE; @@ -26,6 +27,25 @@ pub enum Auth { Token(String), } +#[derive(Debug, Clone, Deserialize, PartialEq, Eq)] +struct TokenData { + org: String, + url: String, +} + +fn decode_token_data(token: &str) -> Result> { + const ORG_TOKEN_PREFIX: &str = "sntrys_"; + + let Some(rest) = token.strip_prefix(ORG_TOKEN_PREFIX) else { + return Ok(None); + }; + let Some((encoded, _)) = rest.split_once('_') else { + bail!("missing trailing _"); + }; + let json = data_encoding::BASE64.decode(encoded.as_bytes())?; + Ok(serde_json::from_slice(&json)?) +} + lazy_static! { static ref CONFIG: Mutex>> = Mutex::new(None); } @@ -40,6 +60,7 @@ pub struct Config { cached_headers: Option>, cached_log_level: log::LevelFilter, cached_vcs_remote: String, + token_embedded_data: Option, } impl Config { @@ -60,6 +81,7 @@ impl Config { cached_log_level: get_default_log_level(&ini), cached_vcs_remote: get_default_vcs_remote(&ini), ini, + token_embedded_data: None, }) } @@ -139,13 +161,14 @@ impl Config { } /// Updates the auth info - pub fn set_auth(&mut self, auth: Auth) { + pub fn set_auth(&mut self, auth: Auth) -> Result<()> { self.cached_auth = Some(auth); self.ini.delete_from(Some("auth"), "api_key"); self.ini.delete_from(Some("auth"), "token"); match self.cached_auth { Some(Auth::Token(ref val)) => { + self.token_embedded_data = decode_token_data(val)?; self.ini .set_to(Some("auth"), "token".into(), val.to_string()); } @@ -155,6 +178,8 @@ impl Config { } None => {} } + + Ok(()) } /// Returns the base url (without trailing slashes) @@ -171,6 +196,16 @@ impl Config { /// Sets the URL pub fn set_base_url(&mut self, url: &str) { + if let Some(ref org_token) = self.token_embedded_data { + if url != org_token.url { + warn!( + "Two different url values supplied: `{}` (from token), `{url}`. Proceeding with `{}`.", + org_token.url, + org_token.url, + ); + return; + } + } self.cached_base_url = url.to_owned(); self.ini .set_to(Some("defaults"), "url".into(), self.cached_base_url.clone()); @@ -273,16 +308,34 @@ impl Config { /// Given a match object from clap, this returns the org from it. pub fn get_org(&self, matches: &ArgMatches) -> Result { - matches + let org_from_token = self.token_embedded_data.as_ref().map(|t| &t.org); + + let org_from_cli = matches .get_one::("org") .cloned() - .or_else(|| env::var("SENTRY_ORG").ok()) - .or_else(|| { - self.ini - .get_from(Some("defaults"), "org") - .map(str::to_owned) - }) - .ok_or_else(|| format_err!("An organization slug is required (provide with --org)")) + .or_else(|| env::var("SENTRY_ORG").ok()); + + match (org_from_token, org_from_cli) { + (None, None) => self + .ini + .get_from(Some("defaults"), "org") + .map(str::to_owned) + .ok_or_else(|| { + format_err!("An organization slug is required (provide with --org)") + }), + (None, Some(org)) => Ok(org), + (Some(org), None) => Ok(org.to_string()), + (Some(org1), Some(org2)) => { + if *org1 == org2 { + Ok(org2) + } else { + warn!( + "Two different org values supplied: `{org1}` (from token), `{org2}`. Proceeding with `{org1}`." + ); + Ok(org1.to_string()) + } + } + } } /// Given a match object from clap, this returns the release from it. @@ -574,6 +627,7 @@ impl Clone for Config { cached_headers: self.cached_headers.clone(), cached_log_level: self.cached_log_level, cached_vcs_remote: self.cached_vcs_remote.clone(), + token_embedded_data: self.token_embedded_data.clone(), } } } @@ -641,3 +695,21 @@ fn get_default_vcs_remote(ini: &Ini) -> String { "origin".to_string() } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_decode_org_token() { + let token = "sntrys_eyJpYXQiOjE2ODg3MzYxNjAuODMzNSwidXJsIjoiaHR0cHM6Ly9zZW50cnkuaW8iLCJyZWdpb25fdXJsIjoiaHR0cHM6Ly91cy5zZW50cnkuaW8iLCJvcmciOiJmcmFuY2VzY29zLW9yZ2FuaXphdGlvbiJ9_CJtUZXhud0T6ZFdsMxyvEg6uN4es96sCMNwnkVj1"; + + assert_eq!( + decode_token_data(token).unwrap().unwrap(), + TokenData { + org: "francescos-organization".to_string(), + url: "https://sentry.io".to_string(), + } + ); + } +} From fca27b62b6345c5642e1a376e28aecc2fd681789 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Fri, 7 Jul 2023 19:40:33 +0200 Subject: [PATCH 02/11] WIP --- src/commands/mod.rs | 3 +-- src/config.rs | 42 ++++++++++++++++++++++-------------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index df204da9ac..14a44c0142 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -97,13 +97,12 @@ fn preexecute_hooks() -> Result { } fn configure_args(config: &mut Config, matches: &ArgMatches) -> Result<()> { - bail!("Test"); if let Some(auth_token) = matches.get_one::("auth_token") { config.set_auth(Auth::Token(auth_token.to_owned()))?; } if let Some(url) = matches.get_one::("url") { - config.set_base_url(url); + config.set_base_url(url)?; } if let Some(headers) = matches.get_many::("headers") { diff --git a/src/config.rs b/src/config.rs index 73dc16b04c..73d4c0918d 100644 --- a/src/config.rs +++ b/src/config.rs @@ -33,17 +33,21 @@ struct TokenData { url: String, } -fn decode_token_data(token: &str) -> Result> { - const ORG_TOKEN_PREFIX: &str = "sntrys_"; +impl TokenData { + fn decode(token: &str) -> Result> { + const ORG_TOKEN_PREFIX: &str = "sntrys_"; - let Some(rest) = token.strip_prefix(ORG_TOKEN_PREFIX) else { + let Some(rest) = token.strip_prefix(ORG_TOKEN_PREFIX) else { return Ok(None); }; - let Some((encoded, _)) = rest.split_once('_') else { + let Some((encoded, _)) = rest.split_once('_') else { bail!("missing trailing _"); }; - let json = data_encoding::BASE64.decode(encoded.as_bytes())?; - Ok(serde_json::from_slice(&json)?) + let json = data_encoding::BASE64 + .decode(encoded.as_bytes()) + .context("invalid base64 data")?; + Ok(serde_json::from_slice(&json)?) + } } lazy_static! { @@ -168,7 +172,7 @@ impl Config { self.ini.delete_from(Some("auth"), "token"); match self.cached_auth { Some(Auth::Token(ref val)) => { - self.token_embedded_data = decode_token_data(val)?; + self.token_embedded_data = TokenData::decode(val)?; self.ini .set_to(Some("auth"), "token".into(), val.to_string()); } @@ -195,20 +199,19 @@ impl Config { } /// Sets the URL - pub fn set_base_url(&mut self, url: &str) { + pub fn set_base_url(&mut self, url: &str) -> Result<()> { if let Some(ref org_token) = self.token_embedded_data { if url != org_token.url { - warn!( - "Two different url values supplied: `{}` (from token), `{url}`. Proceeding with `{}`.", - org_token.url, + bail!( + "Two different url values supplied: `{}` (from token), `{url}`.", org_token.url, ); - return; } } self.cached_base_url = url.to_owned(); self.ini .set_to(Some("defaults"), "url".into(), self.cached_base_url.clone()); + Ok(()) } /// Sets headers that should be attached to all requests @@ -329,10 +332,9 @@ impl Config { if *org1 == org2 { Ok(org2) } else { - warn!( - "Two different org values supplied: `{org1}` (from token), `{org2}`. Proceeding with `{org1}`." - ); - Ok(org1.to_string()) + Err(format_err!( + "Two different org values supplied: `{org1}` (from token), `{org2}`." + )) } } } @@ -701,13 +703,13 @@ mod tests { use super::*; #[test] - fn test_decode_org_token() { - let token = "sntrys_eyJpYXQiOjE2ODg3MzYxNjAuODMzNSwidXJsIjoiaHR0cHM6Ly9zZW50cnkuaW8iLCJyZWdpb25fdXJsIjoiaHR0cHM6Ly91cy5zZW50cnkuaW8iLCJvcmciOiJmcmFuY2VzY29zLW9yZ2FuaXphdGlvbiJ9_CJtUZXhud0T6ZFdsMxyvEg6uN4es96sCMNwnkVj1"; + fn test_decode_token_data() { + let token = "sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_foobarthisdoesntmatter"; assert_eq!( - decode_token_data(token).unwrap().unwrap(), + TokenData::decode(token).unwrap().unwrap(), TokenData { - org: "francescos-organization".to_string(), + org: "test-org".to_string(), url: "https://sentry.io".to_string(), } ); From aef4ba7adba2a1062ad43c839ff9ee3c478b76f4 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 12:35:26 +0200 Subject: [PATCH 03/11] WIP --- src/config.rs | 38 ++++++++++++++++++++++++++++++-------- 1 file changed, 30 insertions(+), 8 deletions(-) diff --git a/src/config.rs b/src/config.rs index 73d4c0918d..02e09f42e7 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,7 +64,7 @@ pub struct Config { cached_headers: Option>, cached_log_level: log::LevelFilter, cached_vcs_remote: String, - token_embedded_data: Option, + cached_token_data: Option, } impl Config { @@ -76,16 +76,37 @@ impl Config { /// Creates Config based on provided config file. pub fn from_file(filename: PathBuf, ini: Ini) -> Result { + let auth = get_default_auth(&ini); + let token_embedded_data = match auth { + Some(Auth::Token(ref token)) => { + TokenData::decode(token).context("Failed to parse org auth token {token}")? + } + _ => None, + }; + + let mut url = get_default_url(&ini); + + if let Some(ref token_embedded_data) = token_embedded_data { + if url == DEFAULT_URL { + url = token_embedded_data.url.clone(); + } else if url != token_embedded_data.url { + bail!( + "Two different url values supplied: `{}` (from token), `{url}`.", + token_embedded_data.url, + ); + } + } + Ok(Config { filename, process_bound: false, - cached_auth: get_default_auth(&ini), - cached_base_url: get_default_url(&ini), + cached_auth: auth, + cached_base_url: url, cached_headers: get_default_headers(&ini), cached_log_level: get_default_log_level(&ini), cached_vcs_remote: get_default_vcs_remote(&ini), ini, - token_embedded_data: None, + cached_token_data: token_embedded_data, }) } @@ -172,7 +193,8 @@ impl Config { self.ini.delete_from(Some("auth"), "token"); match self.cached_auth { Some(Auth::Token(ref val)) => { - self.token_embedded_data = TokenData::decode(val)?; + self.cached_token_data = + TokenData::decode(val).context("Failed to parse org auth token {token}")?; self.ini .set_to(Some("auth"), "token".into(), val.to_string()); } @@ -200,7 +222,7 @@ impl Config { /// Sets the URL pub fn set_base_url(&mut self, url: &str) -> Result<()> { - if let Some(ref org_token) = self.token_embedded_data { + if let Some(ref org_token) = self.cached_token_data { if url != org_token.url { bail!( "Two different url values supplied: `{}` (from token), `{url}`.", @@ -311,7 +333,7 @@ impl Config { /// Given a match object from clap, this returns the org from it. pub fn get_org(&self, matches: &ArgMatches) -> Result { - let org_from_token = self.token_embedded_data.as_ref().map(|t| &t.org); + let org_from_token = self.cached_token_data.as_ref().map(|t| &t.org); let org_from_cli = matches .get_one::("org") @@ -629,7 +651,7 @@ impl Clone for Config { cached_headers: self.cached_headers.clone(), cached_log_level: self.cached_log_level, cached_vcs_remote: self.cached_vcs_remote.clone(), - token_embedded_data: self.token_embedded_data.clone(), + cached_token_data: self.cached_token_data.clone(), } } } From 392b722c26676e242de460f93209488cb484603c Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 13:13:47 +0200 Subject: [PATCH 04/11] documentation --- src/config.rs | 22 ++++++++++++++++++---- 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/src/config.rs b/src/config.rs index 02e09f42e7..a63c2d296b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -27,25 +27,39 @@ pub enum Auth { Token(String), } +/// Data parsed from an "org auth token". #[derive(Debug, Clone, Deserialize, PartialEq, Eq)] struct TokenData { + /// An org slug. org: String, + /// A base Sentry URL. url: String, } impl TokenData { + /// Attempt to extract data from an "org auth token". + /// + /// Org auth tokens start with `sntrys` and contain BASE64-encoded + /// data between two underscores. + /// + /// Attempting to decode a valid org auth token results in `Ok(Some(data))`. + /// Attempting to decode an org auth token that contains invalid data returns an error. + /// Attempting to decode any other token returns Ok(None). fn decode(token: &str) -> Result> { const ORG_TOKEN_PREFIX: &str = "sntrys_"; let Some(rest) = token.strip_prefix(ORG_TOKEN_PREFIX) else { - return Ok(None); - }; + return Ok(None); + }; + let Some((encoded, _)) = rest.split_once('_') else { - bail!("missing trailing _"); - }; + bail!("no closing _"); + }; + let json = data_encoding::BASE64 .decode(encoded.as_bytes()) .context("invalid base64 data")?; + Ok(serde_json::from_slice(&json)?) } } From 9f87cad3dc7fbd1bb1cb7f6d7f8892475ed92bf3 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 13:18:42 +0200 Subject: [PATCH 05/11] minor ref --- src/commands/mod.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/commands/mod.rs b/src/commands/mod.rs index 14a44c0142..9335a25472 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -97,6 +97,10 @@ fn preexecute_hooks() -> Result { } fn configure_args(config: &mut Config, matches: &ArgMatches) -> Result<()> { + if let Some(api_key) = matches.get_one::("api_key") { + config.set_auth(Auth::Key(api_key.to_owned()))?; + } + if let Some(auth_token) = matches.get_one::("auth_token") { config.set_auth(Auth::Token(auth_token.to_owned()))?; } @@ -110,10 +114,6 @@ fn configure_args(config: &mut Config, matches: &ArgMatches) -> Result<()> { config.set_headers(headers); } - if let Some(api_key) = matches.get_one::("api_key") { - config.set_auth(Auth::Key(api_key.to_owned()))?; - } - if let Some(level_str) = matches.get_one::("log_level") { match level_str.parse() { Ok(level) => { From 87a0fc6c9de453528cf8773dbb561a47afdb75c3 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 18:01:33 +0200 Subject: [PATCH 06/11] Add tests --- .../integration/_cases/org_tokens/org-mismatch.trycmd | 6 ++++++ .../integration/_cases/org_tokens/url-mismatch.trycmd | 6 ++++++ tests/integration/mod.rs | 1 + tests/integration/org_tokens.rs | 11 +++++++++++ 4 files changed, 24 insertions(+) create mode 100644 tests/integration/_cases/org_tokens/org-mismatch.trycmd create mode 100644 tests/integration/_cases/org_tokens/url-mismatch.trycmd create mode 100644 tests/integration/org_tokens.rs diff --git a/tests/integration/_cases/org_tokens/org-mismatch.trycmd b/tests/integration/_cases/org_tokens/org-mismatch.trycmd new file mode 100644 index 0000000000..15ec4812dc --- /dev/null +++ b/tests/integration/_cases/org_tokens/org-mismatch.trycmd @@ -0,0 +1,6 @@ +``` +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --org sentry sourcemaps upload test_path +? failed +error: Two different url values supplied: `https://sentry.io` (from token), `http://example.com`. + +``` diff --git a/tests/integration/_cases/org_tokens/url-mismatch.trycmd b/tests/integration/_cases/org_tokens/url-mismatch.trycmd new file mode 100644 index 0000000000..5d854e479f --- /dev/null +++ b/tests/integration/_cases/org_tokens/url-mismatch.trycmd @@ -0,0 +1,6 @@ +``` +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --url http://exaample.com sourcemaps upload test_path +? failed +error: Two different url values supplied: `https://sentry.io` (from token), `http://example.com`. + +``` diff --git a/tests/integration/mod.rs b/tests/integration/mod.rs index c6afeaca21..5df0c40b5f 100644 --- a/tests/integration/mod.rs +++ b/tests/integration/mod.rs @@ -6,6 +6,7 @@ mod help; mod info; mod login; mod monitors; +mod org_tokens; mod organizations; mod projects; mod releases; diff --git a/tests/integration/org_tokens.rs b/tests/integration/org_tokens.rs new file mode 100644 index 0000000000..df056485bc --- /dev/null +++ b/tests/integration/org_tokens.rs @@ -0,0 +1,11 @@ +use crate::integration::register_test; + +#[test] +fn org_token_url_mismatch() { + register_test("org_tokens/url-mismatch.trycmd"); +} + +#[test] +fn org_token_org_mismatch() { + register_test("org_tokens/org-mismatch.trycmd"); +} From 273980099bd2388112233eea3d7dd7aed28aa033 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 18:19:17 +0200 Subject: [PATCH 07/11] Fix tests --- tests/integration/_cases/org_tokens/org-mismatch.trycmd | 7 +++++-- tests/integration/_cases/org_tokens/url-mismatch.trycmd | 5 ++++- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/tests/integration/_cases/org_tokens/org-mismatch.trycmd b/tests/integration/_cases/org_tokens/org-mismatch.trycmd index 15ec4812dc..445b6114ac 100644 --- a/tests/integration/_cases/org_tokens/org-mismatch.trycmd +++ b/tests/integration/_cases/org_tokens/org-mismatch.trycmd @@ -1,6 +1,9 @@ ``` -$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --org sentry sourcemaps upload test_path +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ sourcemaps upload --org sentry test_path ? failed -error: Two different url values supplied: `https://sentry.io` (from token), `http://example.com`. +error: Two different org values supplied: `test-org` (from token), `sentry`. + +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 5d854e479f..ba6a8a5a2b 100644 --- a/tests/integration/_cases/org_tokens/url-mismatch.trycmd +++ b/tests/integration/_cases/org_tokens/url-mismatch.trycmd @@ -1,6 +1,9 @@ ``` $ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --url http://exaample.com sourcemaps upload test_path ? failed -error: Two different url values supplied: `https://sentry.io` (from token), `http://example.com`. +error: Two different url values supplied: `https://sentry.io` (from token), `http://exaample.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. ``` From 650b5c181a86d7a096c16ddc144cc3a9cc53559e Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Mon, 10 Jul 2023 18:33:12 +0200 Subject: [PATCH 08/11] Add tests for matching org/url --- tests/integration/_cases/org_tokens/org-match.trycmd | 11 +++++++++++ tests/integration/_cases/org_tokens/url-match.trycmd | 11 +++++++++++ tests/integration/org_tokens.rs | 10 ++++++++++ 3 files changed, 32 insertions(+) create mode 100644 tests/integration/_cases/org_tokens/org-match.trycmd create mode 100644 tests/integration/_cases/org_tokens/url-match.trycmd diff --git a/tests/integration/_cases/org_tokens/org-match.trycmd b/tests/integration/_cases/org_tokens/org-match.trycmd new file mode 100644 index 0000000000..de254f8d77 --- /dev/null +++ b/tests/integration/_cases/org_tokens/org-match.trycmd @@ -0,0 +1,11 @@ +``` +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ sourcemaps upload --org test-org +? failed +error: the following required arguments were not provided: + ... + +Usage: sentry-cli[EXE] sourcemaps upload --org ... + +For more information, try '--help'. + +``` diff --git a/tests/integration/_cases/org_tokens/url-match.trycmd b/tests/integration/_cases/org_tokens/url-match.trycmd new file mode 100644 index 0000000000..b711f8142f --- /dev/null +++ b/tests/integration/_cases/org_tokens/url-match.trycmd @@ -0,0 +1,11 @@ +``` +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --url http://sentry.io sourcemaps upload +? failed +error: the following required arguments were not provided: + ... + +Usage: sentry-cli[EXE] sourcemaps upload ... + +For more information, try '--help'. + +``` diff --git a/tests/integration/org_tokens.rs b/tests/integration/org_tokens.rs index df056485bc..fedc616838 100644 --- a/tests/integration/org_tokens.rs +++ b/tests/integration/org_tokens.rs @@ -9,3 +9,13 @@ fn org_token_url_mismatch() { fn org_token_org_mismatch() { register_test("org_tokens/org-mismatch.trycmd"); } + +#[test] +fn org_token_url_match() { + register_test("org_tokens/url-match.trycmd"); +} + +#[test] +fn org_token_org_match() { + register_test("org_tokens/org-match.trycmd"); +} From 6430bdf5479b8d66a78eedbd103cb48ecbc88892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20Og=C3=B3rek?= Date: Tue, 11 Jul 2023 10:34:14 +0200 Subject: [PATCH 09/11] Skip empty SENTRY_ORG when comparing with org_token and use distinctive data in tests --- src/config.rs | 22 ++++++++++--------- .../_cases/org_tokens/org-match.trycmd | 2 +- .../_cases/org_tokens/org-mismatch.trycmd | 4 ++-- .../_cases/org_tokens/url-match.trycmd | 2 +- .../_cases/org_tokens/url-mismatch.trycmd | 4 ++-- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/config.rs b/src/config.rs index a63c2d296b..774b216196 100644 --- a/src/config.rs +++ b/src/config.rs @@ -101,7 +101,7 @@ impl Config { let mut url = get_default_url(&ini); if let Some(ref token_embedded_data) = token_embedded_data { - if url == DEFAULT_URL { + if url == DEFAULT_URL || url.is_empty() { url = token_embedded_data.url.clone(); } else if url != token_embedded_data.url { bail!( @@ -362,16 +362,18 @@ impl Config { .ok_or_else(|| { format_err!("An organization slug is required (provide with --org)") }), - (None, Some(org)) => Ok(org), - (Some(org), None) => Ok(org.to_string()), - (Some(org1), Some(org2)) => { - if *org1 == org2 { - Ok(org2) - } else { - Err(format_err!( - "Two different org values supplied: `{org1}` (from token), `{org2}`." - )) + (None, Some(cli_org)) => Ok(cli_org), + (Some(token_org), None) => Ok(token_org.to_string()), + (Some(token_org), Some(cli_org)) => { + if cli_org.is_empty() { + return Ok(token_org.to_owned()); + } + if cli_org != *token_org { + return Err(format_err!( + "Two different org values supplied: `{token_org}` (from token), `{cli_org}`." + )); } + Ok(cli_org) } } } diff --git a/tests/integration/_cases/org_tokens/org-match.trycmd b/tests/integration/_cases/org_tokens/org-match.trycmd index de254f8d77..4f002ba198 100644 --- a/tests/integration/_cases/org_tokens/org-match.trycmd +++ b/tests/integration/_cases/org_tokens/org-match.trycmd @@ -1,5 +1,5 @@ ``` -$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ sourcemaps upload --org test-org +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS10b2tlbml6ZWQuaW8iLCJvcmciOiJ0ZXN0LW9yZy10b2tlbml6ZWQifQ==_ sourcemaps upload --org test-org ? failed error: the following required arguments were not provided: ... diff --git a/tests/integration/_cases/org_tokens/org-mismatch.trycmd b/tests/integration/_cases/org_tokens/org-mismatch.trycmd index 445b6114ac..79ce77f76d 100644 --- a/tests/integration/_cases/org_tokens/org-mismatch.trycmd +++ b/tests/integration/_cases/org_tokens/org-mismatch.trycmd @@ -1,7 +1,7 @@ ``` -$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ sourcemaps upload --org sentry test_path +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS10b2tlbml6ZWQuaW8iLCJvcmciOiJ0ZXN0LW9yZy10b2tlbml6ZWQifQ==_ sourcemaps upload --org sentry test_path ? failed -error: Two different org values supplied: `test-org` (from token), `sentry`. +error: Two different org values supplied: `test-org-tokenized` (from token), `sentry`. 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-match.trycmd b/tests/integration/_cases/org_tokens/url-match.trycmd index b711f8142f..9d65a29a1d 100644 --- a/tests/integration/_cases/org_tokens/url-match.trycmd +++ b/tests/integration/_cases/org_tokens/url-match.trycmd @@ -1,5 +1,5 @@ ``` -$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --url http://sentry.io sourcemaps upload +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS10b2tlbml6ZWQuaW8iLCJvcmciOiJ0ZXN0LW9yZy10b2tlbml6ZWQifQ==_ --url http://sentry.io sourcemaps upload ? failed error: the following required arguments were not provided: ... diff --git a/tests/integration/_cases/org_tokens/url-mismatch.trycmd b/tests/integration/_cases/org_tokens/url-mismatch.trycmd index ba6a8a5a2b..bb1dcc6e90 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 sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS5pbyIsIm9yZyI6InRlc3Qtb3JnIn0=_ --url http://exaample.com sourcemaps upload test_path +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS10b2tlbml6ZWQuaW8iLCJvcmciOiJ0ZXN0LW9yZy10b2tlbml6ZWQifQ==_ --url http://example.com sourcemaps upload test_path ? failed -error: Two different url values supplied: `https://sentry.io` (from token), `http://exaample.com`. +error: Two different url values supplied: `https://sentry-tokenized.io` (from token), `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. From 51a34232859dac56323937b6add70c7327b0e9f7 Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Tue, 11 Jul 2023 11:28:47 +0200 Subject: [PATCH 10/11] Actually pick up URL from org token --- src/config.rs | 5 +++++ tests/integration/_cases/org_tokens/url-works.trycmd | 12 ++++++++++++ tests/integration/org_tokens.rs | 5 +++++ 3 files changed, 22 insertions(+) create mode 100644 tests/integration/_cases/org_tokens/url-works.trycmd diff --git a/src/config.rs b/src/config.rs index 774b216196..f10bddf58f 100644 --- a/src/config.rs +++ b/src/config.rs @@ -209,6 +209,11 @@ impl Config { Some(Auth::Token(ref val)) => { self.cached_token_data = TokenData::decode(val).context("Failed to parse org auth token {token}")?; + + if let Some(ref data) = self.cached_token_data { + self.cached_base_url = data.url.clone(); + } + self.ini .set_to(Some("auth"), "token".into(), val.to_string()); } diff --git a/tests/integration/_cases/org_tokens/url-works.trycmd b/tests/integration/_cases/org_tokens/url-works.trycmd new file mode 100644 index 0000000000..981e114134 --- /dev/null +++ b/tests/integration/_cases/org_tokens/url-works.trycmd @@ -0,0 +1,12 @@ +``` +$ sentry-cli --auth-token sntrys_eyJ1cmwiOiJodHRwczovL3NlbnRyeS10b2tlbml6ZWQuaW8iLCJvcmciOiJ0ZXN0LW9yZy10b2tlbml6ZWQifQ==_ info +? failed +Sentry Server: https://sentry-tokenized.io +Default Organization: wat-org +Default Project: wat-project + +Authentication Info: + Method: Auth Token + (failure on authentication: API request failed) + +``` diff --git a/tests/integration/org_tokens.rs b/tests/integration/org_tokens.rs index fedc616838..1c05451004 100644 --- a/tests/integration/org_tokens.rs +++ b/tests/integration/org_tokens.rs @@ -19,3 +19,8 @@ fn org_token_url_match() { fn org_token_org_match() { register_test("org_tokens/org-match.trycmd"); } + +#[test] +fn org_token_url_works() { + register_test("org_tokens/url-works.trycmd"); +} From 52aa00108ccfa407f2f956e9a72f5822162e365c Mon Sep 17 00:00:00 2001 From: Sebastian Zivota Date: Tue, 11 Jul 2023 12:54:21 +0200 Subject: [PATCH 11/11] changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index f01ad552eb..f875a3a72d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,12 @@ "You know what they say. Fool me once, strike one, but fool me twice... strike three." — Michael Scott +## Unreleased + +### Various fixes and improvements + +- feat: The server URL and org slug can now be extracted from Org Auth Tokens (#1673) + ## 2.19.4 ### Various fixes and improvements