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

Commit ac38f4d

Browse files
sxlijinDanielleHuisman
authored andcommitted
feat: add organization memberships
1 parent 2841e19 commit ac38f4d

8 files changed

Lines changed: 1035 additions & 0 deletions

src/user_management/operations.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,11 @@ mod authenticate_with_password;
66
mod authenticate_with_refresh_token;
77
mod authenticate_with_totp;
88
mod create_magic_auth;
9+
mod create_organization_membership;
910
mod create_password_reset;
1011
mod create_user;
12+
mod deactivate_organization_membership;
13+
mod delete_organization_membership;
1114
mod delete_user;
1215
mod enroll_auth_factor;
1316
mod find_invitation_by_token;
@@ -18,16 +21,20 @@ mod get_jwks;
1821
mod get_jwks_url;
1922
mod get_logout_url;
2023
mod get_magic_auth;
24+
mod get_organization_membership;
2125
mod get_password_reset;
2226
mod get_user;
2327
mod get_user_by_external_id;
2428
mod get_user_identities;
2529
mod list_auth_factors;
2630
mod list_invitations;
31+
mod list_organization_memberships;
2732
mod list_users;
33+
mod reactivate_organization_membership;
2834
mod reset_password;
2935
mod revoke_invitation;
3036
mod send_invitation;
37+
mod update_organization_membership;
3138
mod update_user;
3239

3340
pub use accept_invitation::*;
@@ -38,8 +45,11 @@ pub use authenticate_with_password::*;
3845
pub use authenticate_with_refresh_token::*;
3946
pub use authenticate_with_totp::*;
4047
pub use create_magic_auth::*;
48+
pub use create_organization_membership::*;
4149
pub use create_password_reset::*;
4250
pub use create_user::*;
51+
pub use deactivate_organization_membership::*;
52+
pub use delete_organization_membership::*;
4353
pub use delete_user::*;
4454
pub use enroll_auth_factor::*;
4555
pub use find_invitation_by_token::*;
@@ -50,14 +60,18 @@ pub use get_jwks::*;
5060
pub use get_jwks_url::*;
5161
pub use get_logout_url::*;
5262
pub use get_magic_auth::*;
63+
pub use get_organization_membership::*;
5364
pub use get_password_reset::*;
5465
pub use get_user::*;
5566
pub use get_user_by_external_id::*;
5667
pub use get_user_identities::*;
5768
pub use list_auth_factors::*;
5869
pub use list_invitations::*;
70+
pub use list_organization_memberships::*;
5971
pub use list_users::*;
72+
pub use reactivate_organization_membership::*;
6073
pub use reset_password::*;
6174
pub use revoke_invitation::*;
6275
pub use send_invitation::*;
76+
pub use update_organization_membership::*;
6377
pub use update_user::*;
Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
use async_trait::async_trait;
2+
use serde::Serialize;
3+
use thiserror::Error;
4+
5+
use crate::organizations::OrganizationId;
6+
use crate::user_management::{OrganizationMembership, UserId, UserManagement};
7+
use crate::{ResponseExt, WorkOsError, WorkOsResult};
8+
9+
/// Parameters for the [`CreateOrganizationMembership`] function.
10+
#[derive(Debug, Serialize)]
11+
pub struct CreateOrganizationMembershipParams<'a> {
12+
/// The ID of the user to create a membership for.
13+
pub user_id: &'a UserId,
14+
15+
/// The ID of the organization to create a membership for.
16+
pub organization_id: &'a OrganizationId,
17+
18+
/// The slug of the role to assign to the user.
19+
#[serde(skip_serializing_if = "Option::is_none")]
20+
pub role_slug: Option<&'a str>,
21+
}
22+
23+
/// An error returned from [`CreateOrganizationMembership`].
24+
#[derive(Debug, Error)]
25+
pub enum CreateOrganizationMembershipError {}
26+
27+
impl From<CreateOrganizationMembershipError> for WorkOsError<CreateOrganizationMembershipError> {
28+
fn from(err: CreateOrganizationMembershipError) -> Self {
29+
Self::Operation(err)
30+
}
31+
}
32+
33+
/// [WorkOS Docs: Create Organization Membership](https://workos.com/docs/reference/authkit/organization-membership#create-organization-membership)
34+
#[async_trait]
35+
pub trait CreateOrganizationMembership {
36+
/// Creates an [`OrganizationMembership`].
37+
///
38+
/// [WorkOS Docs: Create Organization Membership](https://workos.com/docs/reference/authkit/organization-membership#create-organization-membership)
39+
///
40+
/// # Examples
41+
///
42+
/// ```
43+
/// # use workos_sdk::WorkOsResult;
44+
/// # use workos_sdk::user_management::*;
45+
/// use workos_sdk::{ApiKey, WorkOs};
46+
///
47+
/// # async fn run() -> WorkOsResult<(), CreateOrganizationMembershipError> {
48+
/// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789"));
49+
///
50+
/// let organization_membership = workos
51+
/// .user_management()
52+
/// .create_organization_membership(&CreateOrganizationMembershipParams {
53+
/// user_id: &UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5"),
54+
/// organization_id: &OrganizationId::from("org_01EHZNVPK3SFK441A1RGBFSHRT"),
55+
/// role_slug: Some("admin"),
56+
/// })
57+
/// .await?;
58+
/// # Ok(())
59+
/// # }
60+
/// ```
61+
async fn create_organization_membership(
62+
&self,
63+
params: &CreateOrganizationMembershipParams<'_>,
64+
) -> WorkOsResult<OrganizationMembership, CreateOrganizationMembershipError>;
65+
}
66+
67+
#[async_trait]
68+
impl CreateOrganizationMembership for UserManagement<'_> {
69+
async fn create_organization_membership(
70+
&self,
71+
params: &CreateOrganizationMembershipParams<'_>,
72+
) -> WorkOsResult<OrganizationMembership, CreateOrganizationMembershipError> {
73+
let url = self.workos.base_url().join("/user_management/organization_memberships")?;
74+
75+
let organization_membership = self
76+
.workos
77+
.client()
78+
.post(url)
79+
.bearer_auth(self.workos.key())
80+
.json(&params)
81+
.send()
82+
.await?
83+
.handle_unauthorized_or_generic_error()?
84+
.json::<OrganizationMembership>()
85+
.await?;
86+
87+
Ok(organization_membership)
88+
}
89+
}
90+
91+
#[cfg(test)]
92+
mod test {
93+
use serde_json::json;
94+
use tokio;
95+
96+
use crate::user_management::OrganizationMembershipId;
97+
use crate::{ApiKey, WorkOs};
98+
99+
use super::*;
100+
101+
#[tokio::test]
102+
async fn it_calls_the_create_organization_membership_endpoint() {
103+
let mut server = mockito::Server::new_async().await;
104+
105+
let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789"))
106+
.base_url(&server.url())
107+
.unwrap()
108+
.build();
109+
110+
server
111+
.mock("POST", "/user_management/organization_memberships")
112+
.match_header("Authorization", "Bearer sk_example_123456789")
113+
.match_body(mockito::Matcher::Json(json!({
114+
"user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
115+
"organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT",
116+
"role_slug": "admin"
117+
})))
118+
.with_status(201)
119+
.with_body(
120+
json!({
121+
"object": "organization_membership",
122+
"id": "om_01E4ZCR3C56J083X43JQXF3JK5",
123+
"user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
124+
"organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT",
125+
"role": {
126+
"slug": "admin"
127+
},
128+
"status": "active",
129+
"created_at": "2021-06-25T19:07:33.155Z",
130+
"updated_at": "2021-06-25T19:07:33.155Z"
131+
})
132+
.to_string(),
133+
)
134+
.create_async()
135+
.await;
136+
137+
let organization_membership = workos
138+
.user_management()
139+
.create_organization_membership(&CreateOrganizationMembershipParams {
140+
user_id: &UserId::from("user_01E4ZCR3C56J083X43JQXF3JK5"),
141+
organization_id: &OrganizationId::from("org_01EHZNVPK3SFK441A1RGBFSHRT"),
142+
role_slug: Some("admin"),
143+
})
144+
.await
145+
.unwrap();
146+
147+
assert_eq!(
148+
organization_membership.id,
149+
OrganizationMembershipId::from("om_01E4ZCR3C56J083X43JQXF3JK5")
150+
);
151+
}
152+
}
Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
use async_trait::async_trait;
2+
use thiserror::Error;
3+
4+
use crate::user_management::{OrganizationMembership, OrganizationMembershipId, UserManagement};
5+
use crate::{ResponseExt, WorkOsError, WorkOsResult};
6+
7+
/// An error returned from [`DeactivateOrganizationMembership`].
8+
#[derive(Debug, Error)]
9+
pub enum DeactivateOrganizationMembershipError {}
10+
11+
impl From<DeactivateOrganizationMembershipError> for WorkOsError<DeactivateOrganizationMembershipError> {
12+
fn from(err: DeactivateOrganizationMembershipError) -> Self {
13+
Self::Operation(err)
14+
}
15+
}
16+
17+
/// [WorkOS Docs: Deactivate Organization Membership](https://workos.com/docs/reference/authkit/organization-membership#deactivate-organization-membership)
18+
#[async_trait]
19+
pub trait DeactivateOrganizationMembership {
20+
/// Deactivates an [`OrganizationMembership`].
21+
///
22+
/// [WorkOS Docs: Deactivate Organization Membership](https://workos.com/docs/reference/authkit/organization-membership#deactivate-organization-membership)
23+
///
24+
/// # Examples
25+
///
26+
/// ```
27+
/// # use workos_sdk::WorkOsResult;
28+
/// # use workos_sdk::user_management::*;
29+
/// use workos_sdk::{ApiKey, WorkOs};
30+
///
31+
/// # async fn run() -> WorkOsResult<(), DeactivateOrganizationMembershipError> {
32+
/// let workos = WorkOs::new(&ApiKey::from("sk_example_123456789"));
33+
///
34+
/// let organization_membership = workos
35+
/// .user_management()
36+
/// .deactivate_organization_membership(&OrganizationMembershipId::from("om_01E4ZCR3C56J083X43JQXF3JK5"))
37+
/// .await?;
38+
/// # Ok(())
39+
/// # }
40+
/// ```
41+
async fn deactivate_organization_membership(
42+
&self,
43+
organization_membership_id: &OrganizationMembershipId,
44+
) -> WorkOsResult<OrganizationMembership, DeactivateOrganizationMembershipError>;
45+
}
46+
47+
#[async_trait]
48+
impl DeactivateOrganizationMembership for UserManagement<'_> {
49+
async fn deactivate_organization_membership(
50+
&self,
51+
organization_membership_id: &OrganizationMembershipId,
52+
) -> WorkOsResult<OrganizationMembership, DeactivateOrganizationMembershipError> {
53+
let url = self
54+
.workos
55+
.base_url()
56+
.join(&format!("/user_management/organization_memberships/{}/deactivate", organization_membership_id))?;
57+
58+
let organization_membership = self
59+
.workos
60+
.client()
61+
.put(url)
62+
.bearer_auth(self.workos.key())
63+
.send()
64+
.await?
65+
.handle_unauthorized_or_generic_error()?
66+
.json::<OrganizationMembership>()
67+
.await?;
68+
69+
Ok(organization_membership)
70+
}
71+
}
72+
73+
#[cfg(test)]
74+
mod test {
75+
use serde_json::json;
76+
use tokio;
77+
78+
use crate::user_management::{OrganizationMembershipId, OrganizationMembershipStatus};
79+
use crate::{ApiKey, WorkOs};
80+
81+
use super::*;
82+
83+
#[tokio::test]
84+
async fn it_calls_the_deactivate_organization_membership_endpoint() {
85+
let mut server = mockito::Server::new_async().await;
86+
87+
let workos = WorkOs::builder(&ApiKey::from("sk_example_123456789"))
88+
.base_url(&server.url())
89+
.unwrap()
90+
.build();
91+
92+
server
93+
.mock("PUT", "/user_management/organization_memberships/om_01E4ZCR3C56J083X43JQXF3JK5/deactivate")
94+
.match_header("Authorization", "Bearer sk_example_123456789")
95+
.with_status(200)
96+
.with_body(
97+
json!({
98+
"object": "organization_membership",
99+
"id": "om_01E4ZCR3C56J083X43JQXF3JK5",
100+
"user_id": "user_01E4ZCR3C56J083X43JQXF3JK5",
101+
"organization_id": "org_01EHZNVPK3SFK441A1RGBFSHRT",
102+
"role": {
103+
"slug": "admin"
104+
},
105+
"status": "inactive",
106+
"created_at": "2021-06-25T19:07:33.155Z",
107+
"updated_at": "2021-06-25T19:07:33.155Z"
108+
})
109+
.to_string(),
110+
)
111+
.create_async()
112+
.await;
113+
114+
let organization_membership = workos
115+
.user_management()
116+
.deactivate_organization_membership(&OrganizationMembershipId::from("om_01E4ZCR3C56J083X43JQXF3JK5"))
117+
.await
118+
.unwrap();
119+
120+
assert_eq!(
121+
organization_membership.id,
122+
OrganizationMembershipId::from("om_01E4ZCR3C56J083X43JQXF3JK5")
123+
);
124+
assert_eq!(organization_membership.status, OrganizationMembershipStatus::Inactive);
125+
}
126+
}

0 commit comments

Comments
 (0)