diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b4ed73..72019c2 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -36,6 +36,7 @@ jobs: profile: minimal toolchain: stable override: true + - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 with: command: check @@ -52,6 +53,7 @@ jobs: toolchain: stable override: true - run: rustup component add clippy + - run: rustup component add rustfmt - uses: actions-rs/cargo@v1 with: command: clippy @@ -67,6 +69,7 @@ jobs: profile: minimal toolchain: stable override: true + - run: rustup component add rustfmt - name: Run tests env: FIREBASE_PROJECT_ID: ${{ secrets.FIREBASE_PROJECT_ID }} diff --git a/src/auth/mod.rs b/src/auth/mod.rs index 203fd27..502b684 100644 --- a/src/auth/mod.rs +++ b/src/auth/mod.rs @@ -573,6 +573,44 @@ impl FirebaseAuthClient { /// # Ok(()) /// # } /// ``` + /// + /// Disable a user: + /// + /// ``` + /// # #[tokio::main] + /// # async fn main() -> Result<(), fireplace::error::FirebaseError> { + /// # let auth_client = fireplace::auth::test_helpers::initialise()?; + /// use fireplace::auth::models::{NewUser, UpdateUserValues}; + /// use ulid::Ulid; + /// + /// let user_id = auth_client + /// .create_user(NewUser { + /// display_name: Some("Test User".to_string()), + /// email: format!("{}@example.com", Ulid::new()), + /// password: Ulid::new().to_string(), + /// }) + /// .await?; + /// + /// // Disable the user + /// auth_client + /// .update_user(&user_id, UpdateUserValues::new().disabled(true)) + /// .await?; + /// + /// // Verify the user is disabled + /// let user = auth_client.get_user(&user_id).await?.unwrap(); + /// assert_eq!(user.disabled, Some(true)); + /// + /// // Re-enable the user + /// auth_client + /// .update_user(&user_id, UpdateUserValues::new().disabled(false)) + /// .await?; + /// + /// // Verify the user is enabled again + /// let user = auth_client.get_user(&user_id).await?.unwrap(); + /// assert_eq!(user.disabled, Some(false)); + /// # Ok(()) + /// # } + /// ``` #[tracing::instrument(name = "Update user", skip_all, fields(user_id = %user_id.as_ref()))] pub async fn update_user( &self, diff --git a/src/auth/models/update_user.rs b/src/auth/models/update_user.rs index 9163293..f399bad 100644 --- a/src/auth/models/update_user.rs +++ b/src/auth/models/update_user.rs @@ -6,6 +6,7 @@ pub struct UpdateUserValues { display_name: Option>, email: Option, password: Option, + disabled: Option, } impl UpdateUserValues { @@ -31,6 +32,12 @@ impl UpdateUserValues { self.password = Some(password.into()); self } + + /// Enable or disable the user. + pub fn disabled(mut self, disabled: bool) -> Self { + self.disabled = Some(disabled); + self + } } #[derive(Serialize)] @@ -45,6 +52,8 @@ pub(crate) struct UpdateUserBody<'a> { password: Option, #[serde(skip_serializing_if = "Vec::is_empty")] delete_attribute: Vec<&'static str>, + #[serde(skip_serializing_if = "Option::is_none")] + disable_user: Option, } impl<'a> UpdateUserBody<'a> { @@ -63,6 +72,11 @@ impl<'a> UpdateUserBody<'a> { email: values.email, password: values.password, delete_attribute, + // The `disabled` field is internally renamed to `disableUser`. See the Firebase Node + // Admin SDK implementation for reference: + // - https://github.com/firebase/firebase-admin-node/blob/137a0d9312b0b45b69f6a5111081420729d8eaeb/src/auth/auth-api-request.ts#L480-L486 + // - https://github.com/firebase/firebase-admin-node/blob/137a0d9312b0b45b69f6a5111081420729d8eaeb/src/auth/auth-api-request.ts#L1468-L1472 + disable_user: values.disabled, } } }