SCIM: a suspended account's open sessions end, and no credential it holds still works (SCIM-52)
The push router records which account each subscription belongs to, and a new Revoke event drops every subscription the account holds, so its IMAP IDLE, JMAP event streams and WebSockets on this node end. Other users' subscriptions to its shared mailboxes stay. Test 28 now checks an open IDLE is ended, and that the account's password over HTTP and its own API key, both already cached, are refused on the next request.
This commit is contained in:
@@ -43,6 +43,11 @@ pub enum PushEvent {
|
||||
account_id: u32,
|
||||
broadcast: bool,
|
||||
},
|
||||
// inbuxa: SCIM-52: ends the push subscriptions the account itself holds
|
||||
// (IMAP IDLE, JMAP event streams and WebSockets) on this node
|
||||
Revoke {
|
||||
account_id: u32,
|
||||
},
|
||||
Stop,
|
||||
}
|
||||
|
||||
|
||||
@@ -691,6 +691,18 @@ pub async fn replace(
|
||||
external_id,
|
||||
);
|
||||
if active_change.is_some() {
|
||||
// SCIM-52: sessions the account has open are ended
|
||||
if !active {
|
||||
let _ = ctx
|
||||
.server
|
||||
.inner
|
||||
.ipc
|
||||
.push_tx
|
||||
.send(common::ipc::PushEvent::Revoke {
|
||||
account_id: id.document_id(),
|
||||
})
|
||||
.await;
|
||||
}
|
||||
audit(
|
||||
ctx,
|
||||
if active {
|
||||
|
||||
@@ -49,6 +49,7 @@ pub fn spawn_push_router(inner: Arc<Inner>, mut change_rx: mpsc::Receiver<PushEv
|
||||
types,
|
||||
tx,
|
||||
} => {
|
||||
let owner = account_ids.first().copied().unwrap_or(u32::MAX);
|
||||
for account_id in account_ids {
|
||||
subscribers
|
||||
.entry(account_id)
|
||||
@@ -57,10 +58,22 @@ pub fn spawn_push_router(inner: Arc<Inner>, mut change_rx: mpsc::Receiver<PushEv
|
||||
.push(IpcSubscriber {
|
||||
types,
|
||||
tx: tx.clone(),
|
||||
owner,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// inbuxa: SCIM-52: dropping every sender closes the session's
|
||||
// channel, which ends it
|
||||
PushEvent::Revoke { account_id } => {
|
||||
for subscriber_list in subscribers.values_mut() {
|
||||
subscriber_list
|
||||
.ipc
|
||||
.retain(|subscriber| subscriber.owner != account_id);
|
||||
}
|
||||
purge_needed = true;
|
||||
}
|
||||
|
||||
PushEvent::PushServerRegister { activate, expired } => {
|
||||
for account_id in activate {
|
||||
subscribers.entry(account_id).or_default().is_push = true;
|
||||
|
||||
@@ -28,6 +28,8 @@ const SEND_TIMEOUT: Duration = Duration::from_millis(500);
|
||||
struct IpcSubscriber {
|
||||
types: Bitmap<DataType>,
|
||||
tx: mpsc::Sender<PushNotification>,
|
||||
// inbuxa: SCIM-52: the account whose session subscribed
|
||||
owner: u32,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
||||
Reference in New Issue
Block a user