Skip to content
This repository was archived by the owner on May 13, 2026. It is now read-only.

Commit a0fe2b6

Browse files
feat(user-management): add update user
1 parent 4d2f772 commit a0fe2b6

2 files changed

Lines changed: 187 additions & 0 deletions

File tree

src/user_management/operations.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ mod get_user_identities;
1919
mod list_auth_factors;
2020
mod list_users;
2121
mod reset_password;
22+
mod update_user;
2223

2324
pub use authenticate_with_code::*;
2425
pub use authenticate_with_email_verification::*;
@@ -41,3 +42,4 @@ pub use get_user_identities::*;
4142
pub use list_auth_factors::*;
4243
pub use list_users::*;
4344
pub use reset_password::*;
45+
pub use update_user::*;
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
use async_trait::async_trait;
2+
use serde::Serialize;
3+
use thiserror::Error;
4+
5+
use crate::user_management::{PasswordParams, User, UserId, UserManagement};
6+
use crate::{Metadata, ResponseExt, WorkOsError, WorkOsResult};
7+
8+
/// The parameters for [`UpdateUser`].
9+
#[derive(Debug, Serialize)]
10+
pub struct UpdateUserParams<'a> {
11+
/// The ID of the user passed in the URL.
12+
#[serde(skip_serializing)]
13+
pub user_id: &'a UserId,
14+
15+
/// The user's first name.
16+
pub first_name: Option<&'a str>,
17+
18+
/// The user's last name.
19+
pub last_name: Option<&'a str>,
20+
21+
/// The user's email address.
22+
pub email: Option<&'a str>,
23+
24+
/// Whether the user's email address was previously verified.
25+
pub email_verified: Option<bool>,
26+
27+
/// The password to set for the user.
28+
#[serde(flatten)]
29+
pub password: Option<&'a PasswordParams<'a>>,
30+
31+
/// The external ID of the user.
32+
pub external_id: Option<&'a str>,
33+
34+
/// Object containing metadata key/value pairs associated with the user.
35+
pub metadata: Option<Metadata>,
36+
}
37+
38+
/// An error returned from [`UpdateUser`].
39+
#[derive(Debug, Error)]
40+
pub enum UpdateUserError {}
41+
42+
impl From<UpdateUserError> for WorkOsError<UpdateUserError> {
43+
fn from(err: UpdateUserError) -> Self {
44+
Self::Operation(err)
45+
}
46+
}
47+
48+
/// [WorkOS Docs: Update a user](https://workos.com/docs/reference/user-management/user/update)
49+
#[async_trait]
50+
pub trait UpdateUser {
51+
/// Update a [`User`].
52+
///
53+
/// [WorkOS Docs: Update a user](https://workos.com/docs/reference/user-management/user/update)
54+
///
55+
/// # Examples
56+
///
57+
/// ```
58+
/// use std::collections::HashMap;
59+
///
60+
/// # use workos_sdk::WorkOsResult;
61+
/// # use workos_sdk::user_management::*;
62+
/// use workos_sdk::{ApiKey, Metadata, WorkOs};
63+
///
64+
/// # async fn run() -> WorkOsResult<(), UpdateUserError> {
65+
/// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789"));
66+
///
67+
/// let user = workos
68+
/// .user_management()
69+
/// .update_user(&UpdateUserParams {
70+
/// user_id: &UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5"),
71+
/// first_name: Some("Marcelina"),
72+
/// last_name: Some("Davis"),
73+
/// email: None,
74+
/// email_verified: Some(true),
75+
/// password: None,
76+
/// external_id: Some("2fe01467-f7ea-4dd2-8b79-c2b4f56d0191"),
77+
/// metadata: Some(Metadata(HashMap::from([(
78+
/// "language".to_string(),
79+
/// "en".to_string(),
80+
/// )]))),
81+
/// })
82+
/// .await?;
83+
/// # Ok(())
84+
/// # }
85+
/// ```
86+
async fn update_user(
87+
&self,
88+
params: &UpdateUserParams<'_>,
89+
) -> WorkOsResult<User, UpdateUserError>;
90+
}
91+
92+
#[async_trait]
93+
impl UpdateUser for UserManagement<'_> {
94+
async fn update_user(
95+
&self,
96+
params: &UpdateUserParams<'_>,
97+
) -> WorkOsResult<User, UpdateUserError> {
98+
let url = self
99+
.workos
100+
.base_url()
101+
.join(&format!("/user_management/{id}", id = params.user_id))?;
102+
let user = self
103+
.workos
104+
.client()
105+
.put(url)
106+
.bearer_auth(self.workos.key())
107+
.json(&params)
108+
.send()
109+
.await?
110+
.handle_unauthorized_or_generic_error()?
111+
.json::<User>()
112+
.await?;
113+
114+
Ok(user)
115+
}
116+
}
117+
118+
#[cfg(test)]
119+
mod test {
120+
use std::collections::HashMap;
121+
122+
use serde_json::json;
123+
use tokio;
124+
125+
use crate::user_management::UserId;
126+
use crate::{ApiKey, WorkOs};
127+
128+
use super::*;
129+
130+
#[tokio::test]
131+
async fn it_calls_the_update_user_endpoint() {
132+
let mut server = mockito::Server::new_async().await;
133+
134+
let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789"))
135+
.base_url(&server.url())
136+
.unwrap()
137+
.build();
138+
139+
server
140+
.mock("PUT", "/user_management/user_01E4ZCR3C56J083X43JQXF3JK5")
141+
.match_header("Authorization", "Bearer sk_example_123456789")
142+
.with_status(200)
143+
.with_body(
144+
json!({
145+
"object": "user",
146+
"id": "user_01E4ZCR3C56J083X43JQXF3JK5",
147+
"email": "marcelina.davis@example.com",
148+
"first_name": "Marcelina",
149+
"last_name": "Davis",
150+
"email_verified": true,
151+
"profile_picture_url": "https://workoscdn.com/images/v1/123abc",
152+
"external_id": "2fe01467-f7ea-4dd2-8b79-c2b4f56d0191",
153+
"metadata": {
154+
"language": "en"
155+
},
156+
"last_sign_in_at": "2021-06-25T19:07:33.155Z",
157+
"created_at": "2021-06-25T19:07:33.155Z",
158+
"updated_at": "2021-06-25T19:07:33.155Z"
159+
})
160+
.to_string(),
161+
)
162+
.create_async()
163+
.await;
164+
165+
let user = workos
166+
.user_management()
167+
.update_user(&UpdateUserParams {
168+
user_id: &UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5"),
169+
first_name: Some("Marcelina"),
170+
last_name: Some("Davis"),
171+
email: None,
172+
email_verified: Some(true),
173+
password: None,
174+
external_id: Some("2fe01467-f7ea-4dd2-8b79-c2b4f56d0191"),
175+
metadata: Some(Metadata(HashMap::from([(
176+
"language".to_string(),
177+
"en".to_string(),
178+
)]))),
179+
})
180+
.await
181+
.unwrap();
182+
183+
assert_eq!(user.id, UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5"))
184+
}
185+
}

0 commit comments

Comments
 (0)