/* * SPDX-FileCopyrightText: 2020 Stalwart Labs LLC * * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-SEL */ use common::{Server, auth::AccessToken}; use groupware::{DestroyArchive, cache::GroupwareCache, calendar::CalendarEventNotification}; use http_proto::HttpSessionData; use jmap_proto::{ error::set::SetError, method::set::{SetRequest, SetResponse}, object::calendar_event_notification, request::IntoValid, types::state::State, }; use store::{ ValueKey, write::{AlignedBytes, Archive, BatchBuilder}, }; use trc::AddContext; use types::collection::{Collection, SyncCollection}; pub trait CalendarEventNotificationSet: Sync + Send { fn calendar_event_notification_set( &self, request: SetRequest<'_, calendar_event_notification::CalendarEventNotification>, access_token: &AccessToken, session: &HttpSessionData, ) -> impl Future< Output = trc::Result>, > + Send; } impl CalendarEventNotificationSet for Server { async fn calendar_event_notification_set( &self, mut request: SetRequest<'_, calendar_event_notification::CalendarEventNotification>, access_token: &AccessToken, _session: &HttpSessionData, ) -> trc::Result> { let account_id = request.account_id.document_id(); let cache = self .fetch_dav_resources( access_token.account_id(), account_id, SyncCollection::CalendarEventNotification, ) .await?; let mut response = SetResponse::from_request(&request, self.core.jmap.set_max_objects)?; let mut batch = BatchBuilder::new(); for (id, _) in request.unwrap_create() { response.not_created.append( id, SetError::forbidden().with_description("Cannot create event notifications."), ); } // Process updates for (id, _) in request.unwrap_update().into_valid() { response.not_updated.append( id, SetError::forbidden().with_description("Cannot update event notifications."), ); } // Process deletions for id in request.unwrap_destroy().into_valid() { let document_id = id.document_id(); if !cache.has_item_id(&document_id) { response.not_destroyed.append(id, SetError::not_found()); continue; }; let _event = if let Some(event) = self .store() .get_value::>(ValueKey::archive( account_id, Collection::CalendarEventNotification, document_id, )) .await? { event } else { response.not_destroyed.append(id, SetError::not_found()); continue; }; let event = _event .to_unarchived::() .caused_by(trc::location!())?; DestroyArchive(event) .delete( access_token.account_tenant_ids(), account_id, document_id, &mut batch, ) .caused_by(trc::location!())?; response.destroyed.push(id); } // Write changes if !batch.is_empty() { let change_id = self .commit_batch(batch) .await .and_then(|ids| ids.last_change_id(account_id)) .caused_by(trc::location!())?; response.new_state = State::Exact(change_id).into(); } Ok(response) } }