From 772b72bbbce4e22b59c5d8acf67824604a6a0368 Mon Sep 17 00:00:00 2001 From: Matheus Zaniolo Date: Wed, 22 Apr 2026 14:25:30 +0200 Subject: [PATCH 1/5] feat!: Add org_id to list_user_metadata --- src/v2/users/mod.rs | 3 ++- tests/e2e.rs | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/src/v2/users/mod.rs b/src/v2/users/mod.rs index 92fc8f1..5583d27 100644 --- a/src/v2/users/mod.rs +++ b/src/v2/users/mod.rs @@ -634,12 +634,13 @@ impl Zitadel { user_id: &str, params: Option, queries: Option>, + org_id: Option, ) -> Result> + Send> { Ok(PaginationHandler::new( self.clone(), (params, queries), self.make_url(&format!("/management/v1/users/{user_id}/metadata/_search"))?, - None, // TODO: Breaking change -> possibility to add org_id to function args + org_id, )) } } diff --git a/tests/e2e.rs b/tests/e2e.rs index 03a9426..5c995f9 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -1071,6 +1071,7 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { &id, None, Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), + None, )?; let res_metadata: Vec<_> = stream @@ -1107,6 +1108,7 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { &id, None, Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), + None, )? .count() .await == 0 From bf9a6b57baabab7e861af81b09f34e5f794c0320 Mon Sep 17 00:00:00 2001 From: Matheus Zaniolo Date: Wed, 22 Apr 2026 15:01:47 +0200 Subject: [PATCH 2/5] feat!: Add org_id to list_users --- src/v2/users/mod.rs | 3 ++- tests/e2e.rs | 11 ++++++----- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/v2/users/mod.rs b/src/v2/users/mod.rs index 5583d27..62758f5 100644 --- a/src/v2/users/mod.rs +++ b/src/v2/users/mod.rs @@ -170,12 +170,13 @@ impl Zitadel { params: Option, sorting: Option, queries: Option>, + org_id: Option, ) -> Result> + Send> { Ok(PaginationHandler::new( self.clone(), (params, sorting, queries), self.make_url("v2/users")?, - None, + org_id, )) } diff --git a/tests/e2e.rs b/tests/e2e.rs index 5c995f9..f6ed9ea 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -73,7 +73,7 @@ async fn tear_down(zitadel: &Zitadel) { let queries = Some(vec![SearchQuery::new().with_type_query(TypeQuery::new(Userv2Type::Human))]); zitadel - .list_users(None, None, queries) + .list_users(None, None, queries, None) .expect("Error getting the list of users for tear down") .try_for_each(|user| async move { tracing::info!("user: {user:?}"); @@ -499,7 +499,8 @@ async fn test_e2e_create_organization() -> Result<()> { Some(vec![ SearchQuery::new() .with_last_name_query(LastNameQuery::new("Adminmann".to_owned())) - ]) + ]), + None, )? .count() .await, @@ -816,7 +817,7 @@ async fn test_e2e_list_human_users() -> Result<()> { Some(vec![SearchQuery::new().with_last_name_query(LastNameQuery::new("Doe".to_owned()))]); let pagination_params = Some(PaginationParams::DEFAULT.with_asc(true).with_page_size(5)); - let stream = zitadel.list_users(pagination_params, None, queries)?; + let stream = zitadel.list_users(pagination_params, None, queries, None)?; let res_user_emails: Vec<_> = stream .and_then(|user| { @@ -962,14 +963,14 @@ async fn test_e2e_delete_user() -> Result<()> { let pagination_params = Some(PaginationParams::DEFAULT.with_asc(true)); assert_eq!( - zitadel.list_users(pagination_params.clone(), None, queries.clone())?.count().await, + zitadel.list_users(pagination_params.clone(), None, queries.clone(), None)?.count().await, 2 ); zitadel.delete_user(&id).await?; let user_count = zitadel - .list_users(pagination_params, None, queries)? + .list_users(pagination_params, None, queries, None)? .inspect_ok(|user| { let user_name = user .human() From 2e8d60dba2598ff7f3a0f5907275c14bd45a5d82 Mon Sep 17 00:00:00 2001 From: Matheus Zaniolo Date: Wed, 22 Apr 2026 15:29:38 +0200 Subject: [PATCH 3/5] feat!: Add org_id to user metadata functions --- src/v2/users/mod.rs | 14 +++++++++++++- tests/e2e.rs | 9 +++++---- 2 files changed, 18 insertions(+), 5 deletions(-) diff --git a/src/v2/users/mod.rs b/src/v2/users/mod.rs index 62758f5..f95054a 100644 --- a/src/v2/users/mod.rs +++ b/src/v2/users/mod.rs @@ -575,10 +575,16 @@ impl Zitadel { Ok(self.send_request(request).await?) } /// Remove a metadata object from a user with a specific key - pub async fn delete_user_metadata(&self, user_id: &str, key: &str) -> Result
{ + pub async fn delete_user_metadata( + &self, + user_id: &str, + key: &str, + org_id: Option, + ) -> Result
{ let request = self .client .delete(self.make_url(&format!("/management/v1/users/{user_id}/metadata/{key}"))?) + .chain_opt(org_id, |req, org_id| req.header(HEADER_ZITADEL_ORGANIZATION_ID, org_id)) .build()?; Ok(self.send_request(request).await?) @@ -590,10 +596,12 @@ impl Zitadel { user_id: &str, key: &str, value: &str, + org_id: Option, ) -> Result { let request = self .client .post(self.make_url(&format!("/management/v1/users/{user_id}/metadata/{key}"))?) + .chain_opt(org_id, |req, org_id| req.header(HEADER_ZITADEL_ORGANIZATION_ID, org_id)) .json(&serde_json::json!({"value": BASE64_STANDARD.encode(value)})) .build()?; @@ -605,10 +613,12 @@ impl Zitadel { &self, user_id: &str, body: Vec, + org_id: Option, ) -> Result
{ let request = self .client .post(self.make_url(&format!("/management/v1/users/{user_id}/metadata/_bulk"))?) + .chain_opt(org_id, |req, org_id| req.header(HEADER_ZITADEL_ORGANIZATION_ID, org_id)) .json(&serde_json::json!({"metadata": body})) .build()?; @@ -619,10 +629,12 @@ impl Zitadel { &self, user_id: &str, body: Vec, + org_id: Option, ) -> Result
{ let request = self .client .delete(self.make_url(&format!("/management/v1/users/{user_id}/metadata/_bulk"))?) + .chain_opt(org_id, |req, org_id| req.header(HEADER_ZITADEL_ORGANIZATION_ID, org_id)) .json(&serde_json::json!({"keys": body})) .build()?; diff --git a/tests/e2e.rs b/tests/e2e.rs index f6ed9ea..9bc536f 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -1011,7 +1011,7 @@ async fn test_e2e_user_metadata() -> Result<()> { .cloned() .expect("Couldn't get the user id from response"); - zitadel.set_user_metadata(&id, metadata[1].0, metadata[1].1).await?; + zitadel.set_user_metadata(&id, metadata[1].0, metadata[1].1, None).await?; for (query_key, expected_value) in &metadata { let ret = zitadel.get_user_metadata(&id, query_key, None).await?; @@ -1023,11 +1023,11 @@ async fn test_e2e_user_metadata() -> Result<()> { assert_eq!(*expected_value, value); } - zitadel.delete_user_metadata(&id, metadata[1].0).await?; + zitadel.delete_user_metadata(&id, metadata[1].0, None).await?; assert!(zitadel.get_user_metadata(&id, metadata[1].0, None).await.is_err()); let updated_value = "new_value"; - zitadel.set_user_metadata(&id, metadata[0].0, updated_value).await?; + zitadel.set_user_metadata(&id, metadata[0].0, updated_value, None).await?; let ret = zitadel.get_user_metadata(&id, metadata[0].0, None).await?; let value = ret @@ -1066,7 +1066,7 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { .cloned() .expect("Couldn't get the user id from response"); - zitadel.set_user_metadata_bulk(&id, metadata.clone()).await?; + zitadel.set_user_metadata_bulk(&id, metadata.clone(), None).await?; let stream = zitadel.list_user_metadata( &id, @@ -1100,6 +1100,7 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { .delete_user_metadata_bulk( &id, metadata.iter().map(|metadata| metadata.key().clone()).collect(), + None, ) .await?; From 286dcd1e6bc2da528eba066c6a70e1e53e79a1ad Mon Sep 17 00:00:00 2001 From: Matheus Zaniolo Date: Thu, 23 Apr 2026 11:37:56 +0200 Subject: [PATCH 4/5] refactor!: Change org_id param order --- src/v2/users/mod.rs | 7 ++++--- tests/e2e.rs | 16 ++++++++-------- 2 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/v2/users/mod.rs b/src/v2/users/mod.rs index f95054a..d6478a2 100644 --- a/src/v2/users/mod.rs +++ b/src/v2/users/mod.rs @@ -137,13 +137,14 @@ impl Zitadel { pub fn list_idp_links( &self, user_id: &str, + org_id: Option, params: Option, ) -> Result> + Send> { Ok(PaginationHandler::new( self.clone(), params, self.make_url(&format!("v2/users/{user_id}/links/_search"))?, - None, // Endpoint does not support org_id + org_id, )) } /// List passkeys of an user @@ -167,10 +168,10 @@ impl Zitadel { /// [Docs](https://zitadel.com/docs/apis/resources/user_service_v2/user-service-list-users) pub fn list_users( &self, + org_id: Option, params: Option, sorting: Option, queries: Option>, - org_id: Option, ) -> Result> + Send> { Ok(PaginationHandler::new( self.clone(), @@ -645,9 +646,9 @@ impl Zitadel { pub fn list_user_metadata( &self, user_id: &str, + org_id: Option, params: Option, queries: Option>, - org_id: Option, ) -> Result> + Send> { Ok(PaginationHandler::new( self.clone(), diff --git a/tests/e2e.rs b/tests/e2e.rs index 9bc536f..5b33845 100644 --- a/tests/e2e.rs +++ b/tests/e2e.rs @@ -73,7 +73,7 @@ async fn tear_down(zitadel: &Zitadel) { let queries = Some(vec![SearchQuery::new().with_type_query(TypeQuery::new(Userv2Type::Human))]); zitadel - .list_users(None, None, queries, None) + .list_users(None, None, None, queries) .expect("Error getting the list of users for tear down") .try_for_each(|user| async move { tracing::info!("user: {user:?}"); @@ -494,13 +494,13 @@ async fn test_e2e_create_organization() -> Result<()> { assert_eq!( zitadel .list_users( + None, None, None, Some(vec![ SearchQuery::new() .with_last_name_query(LastNameQuery::new("Adminmann".to_owned())) ]), - None, )? .count() .await, @@ -817,7 +817,7 @@ async fn test_e2e_list_human_users() -> Result<()> { Some(vec![SearchQuery::new().with_last_name_query(LastNameQuery::new("Doe".to_owned()))]); let pagination_params = Some(PaginationParams::DEFAULT.with_asc(true).with_page_size(5)); - let stream = zitadel.list_users(pagination_params, None, queries, None)?; + let stream = zitadel.list_users(None, pagination_params, None, queries)?; let res_user_emails: Vec<_> = stream .and_then(|user| { @@ -855,7 +855,7 @@ async fn test_e2e_list_idp_links() -> Result<()> { let id = ret.user_id().expect("Couldn't get the user id from response"); let pagination_params = Some(PaginationParams::DEFAULT.with_asc(true)); - let stream = zitadel.list_idp_links(id, pagination_params)?; + let stream = zitadel.list_idp_links(id, None, pagination_params)?; assert_eq!(stream.count().await, idp_links.len()); @@ -963,14 +963,14 @@ async fn test_e2e_delete_user() -> Result<()> { let pagination_params = Some(PaginationParams::DEFAULT.with_asc(true)); assert_eq!( - zitadel.list_users(pagination_params.clone(), None, queries.clone(), None)?.count().await, + zitadel.list_users(None, pagination_params.clone(), None, queries.clone())?.count().await, 2 ); zitadel.delete_user(&id).await?; let user_count = zitadel - .list_users(pagination_params, None, queries, None)? + .list_users(None, pagination_params, None, queries)? .inspect_ok(|user| { let user_name = user .human() @@ -1071,8 +1071,8 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { let stream = zitadel.list_user_metadata( &id, None, - Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), None, + Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), )?; let res_metadata: Vec<_> = stream @@ -1109,8 +1109,8 @@ async fn test_e2e_user_metadata_bulk() -> Result<()> { .list_user_metadata( &id, None, - Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), None, + Some(vec![KeyQuery::new("key".to_owned()).with_method(TextQueryMethod::Contains)]), )? .count() .await == 0 From 29e9fe61be0d4239b1ebd58f4087be0189383472 Mon Sep 17 00:00:00 2001 From: Matheus Zaniolo Date: Thu, 23 Apr 2026 11:38:46 +0200 Subject: [PATCH 5/5] release: v0.12.0 --- CHANGELOG.md | 12 ++++++++++++ Cargo.lock | 2 +- Cargo.toml | 2 +- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 04a93db..378397a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,18 @@ SPDX-License-Identifier: Apache-2.0 All notable changes to this project will be documented in this file. +## [0.12.0] - 2026-04-23 + +### Features + +- [**breaking**] Add org_id to list_user_metadata +- [**breaking**] Add org_id to list_users +- [**breaking**] Add org_id to user metadata functions + +### Refactor + +- [**breaking**] Change org_id param order + ## [0.11.1] - 2026-04-20 ### Bug Fixes diff --git a/Cargo.lock b/Cargo.lock index 20fef1c..7385da5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -734,7 +734,7 @@ dependencies = [ [[package]] name = "famedly-zitadel-rust-client" -version = "0.11.1" +version = "0.12.0" dependencies = [ "anyhow", "anyhow_ext", diff --git a/Cargo.toml b/Cargo.toml index 85d2390..4a4753e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,7 +5,7 @@ [package] name = "famedly-zitadel-rust-client" description = "HTTP client for Zitadel IdP built by Famedly" -version = "0.11.1" +version = "0.12.0" authors = [] edition = "2024" resolver = "2"