Skip to content

Commit 95bc20e

Browse files
committed
When adding personal session, upsert devices synchronously
1 parent 42f6664 commit 95bc20e

File tree

1 file changed

+26
-8
lines changed
  • crates/handlers/src/admin/v1/personal_sessions

1 file changed

+26
-8
lines changed

crates/handlers/src/admin/v1/personal_sessions/add.rs

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,16 @@
33
// SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial
44
// Please see LICENSE files in the repository root for full details.
55

6+
use std::sync::Arc;
7+
68
use aide::{NoApi, OperationIo, transform::TransformOperation};
7-
use axum::{Json, response::IntoResponse};
9+
use anyhow::Context;
10+
use axum::{Json, extract::State, response::IntoResponse};
811
use chrono::Duration;
912
use hyper::StatusCode;
1013
use mas_axum_utils::record_error;
11-
use mas_data_model::{BoxRng, TokenType, personal::session::PersonalSessionOwner};
12-
use mas_storage::queue::{QueueJobRepositoryExt as _, SyncDevicesJob};
14+
use mas_data_model::{BoxRng, Device, TokenType, personal::session::PersonalSessionOwner};
15+
use mas_matrix::HomeserverConnection;
1316
use oauth2_types::scope::Scope;
1417
use schemars::JsonSchema;
1518
use serde::Deserialize;
@@ -99,6 +102,7 @@ pub async fn handler(
99102
..
100103
}: CallContext,
101104
NoApi(mut rng): NoApi<BoxRng>,
105+
NoApi(State(homeserver)): NoApi<State<Arc<dyn HomeserverConnection>>>,
102106
Json(params): Json<Request>,
103107
) -> Result<(StatusCode, Json<SingleResponse<PersonalSession>>), RouteError> {
104108
let owner = if let Some(user_id) = session.user_id {
@@ -145,12 +149,26 @@ pub async fn handler(
145149
)
146150
.await?;
147151

152+
// If the session has a device, we should add those to the homeserver now
148153
if session.has_device() {
149-
// If the session has a device, then we are now
150-
// creating a device and should schedule a device sync.
151-
repo.queue_job()
152-
.schedule_job(&mut rng, &clock, SyncDevicesJob::new(&actor_user))
153-
.await?;
154+
// Lock the user sync to make sure we don't get into a race condition
155+
repo.user().acquire_lock_for_sync(&actor_user).await?;
156+
157+
for scope in &*session.scope {
158+
if let Some(device) = Device::from_scope_token(scope) {
159+
// NOTE: We haven't relinquished the repo at this point,
160+
// so we are holding a transaction across the homeserver
161+
// operation.
162+
// This is suboptimal, but simpler.
163+
// Given this is an administrative endpoint, this is a tolerable
164+
// compromise for now.
165+
homeserver
166+
.upsert_device(&actor_user.username, device.as_str(), None)
167+
.await
168+
.context("Failed to provision device")
169+
.map_err(|e| RouteError::Internal(e.into()))?;
170+
}
171+
}
154172
}
155173

156174
repo.save().await?;

0 commit comments

Comments
 (0)