Skip to content

Commit 972c50d

Browse files
committed
Require "erase" key in deactivation request body
If body is absent, treat "erase" as true. If body is present, require "erase" to be present in the body.
1 parent d2c708f commit 972c50d

File tree

2 files changed

+63
-6
lines changed

2 files changed

+63
-6
lines changed

crates/handlers/src/admin/v1/users/deactivate.rs

Lines changed: 62 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,12 @@ pub struct Request {
5959
erase: bool,
6060
}
6161

62+
impl Default for Request {
63+
fn default() -> Self {
64+
Self { erase: true }
65+
}
66+
}
67+
6268
pub fn doc(operation: TransformOperation) -> TransformOperation {
6369
operation
6470
.id("deactivateUser")
@@ -86,8 +92,9 @@ pub async fn handler(
8692
}: CallContext,
8793
NoApi(mut rng): NoApi<BoxRng>,
8894
id: UlidPathParam,
89-
Json(params): Json<Request>,
95+
body: Option<Json<Request>>,
9096
) -> Result<Json<SingleResponse<User>>, RouteError> {
97+
let Json(params) = body.unwrap_or_default();
9198
let id = *id;
9299
let mut user = repo
93100
.user()
@@ -125,8 +132,7 @@ mod tests {
125132

126133
use crate::test_utils::{RequestBuilderExt, ResponseExt, TestState, setup};
127134

128-
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
129-
async fn test_deactivate_user(pool: PgPool) {
135+
async fn test_deactivate_user_helper(pool: PgPool, erase: Option<bool>) {
130136
setup();
131137
let mut state = TestState::from_pool(pool.clone()).await.unwrap();
132138
let token = state.token_with_scope("urn:mas:admin").await;
@@ -140,8 +146,13 @@ mod tests {
140146
repo.save().await.unwrap();
141147

142148
let request = Request::post(format!("/api/admin/v1/users/{}/deactivate", user.id))
143-
.bearer(&token)
144-
.empty();
149+
.bearer(&token);
150+
let request = match erase {
151+
None => request.empty(),
152+
Some(erase) => request.json(serde_json::json!({
153+
"erase": erase,
154+
})),
155+
};
145156
let response = state.request(request).await;
146157
response.assert_status(StatusCode::OK);
147158
let body: serde_json::Value = response.json();
@@ -161,6 +172,52 @@ mod tests {
161172
.await
162173
.expect("Deactivation job to be scheduled");
163174
assert_eq!(job["user_id"], serde_json::json!(user.id));
175+
assert_eq!(job["hs_erase"], serde_json::json!(erase.unwrap_or(true)));
176+
}
177+
178+
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
179+
async fn test_deactivate_user(pool: PgPool) {
180+
test_deactivate_user_helper(pool, Option::None).await;
181+
}
182+
183+
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
184+
async fn test_deactivate_user_with_explicit_erase(pool: PgPool) {
185+
test_deactivate_user_helper(pool, Option::Some(true)).await;
186+
}
187+
188+
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
189+
async fn test_deactivate_user_without_erase(pool: PgPool) {
190+
test_deactivate_user_helper(pool, Option::Some(false)).await;
191+
}
192+
193+
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]
194+
async fn test_deactivate_user_missing_erase(pool: PgPool) {
195+
setup();
196+
let mut state = TestState::from_pool(pool.clone()).await.unwrap();
197+
let token = state.token_with_scope("urn:mas:admin").await;
198+
199+
let mut repo = state.repository().await.unwrap();
200+
let user = repo
201+
.user()
202+
.add(&mut state.rng(), &state.clock, "alice".to_owned())
203+
.await
204+
.unwrap();
205+
repo.save().await.unwrap();
206+
207+
let request = Request::post(format!("/api/admin/v1/users/{}/deactivate", user.id))
208+
.bearer(&token)
209+
.json(serde_json::json!({}));
210+
let response = state.request(request).await;
211+
response.assert_status(StatusCode::UNPROCESSABLE_ENTITY);
212+
213+
// It should have not scheduled a deactivation job for the user
214+
let count: i64 = sqlx::query_scalar(
215+
"SELECT COUNT(1) FROM queue_jobs WHERE queue_name = 'deactivate-user'",
216+
)
217+
.fetch_one(&pool)
218+
.await
219+
.unwrap();
220+
assert_eq!(count, 0);
164221
}
165222

166223
#[sqlx::test(migrator = "mas_storage_pg::MIGRATOR")]

docs/api/spec.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1367,7 +1367,7 @@
13671367
}
13681368
}
13691369
},
1370-
"required": true
1370+
"required": false
13711371
},
13721372
"responses": {
13731373
"200": {

0 commit comments

Comments
 (0)