Remove path repetition
This commit is contained in:
parent
2536f09cd7
commit
2a7a19fdf0
10 changed files with 65 additions and 149 deletions
|
|
@ -11,3 +11,19 @@ pub mod put_file_manifest;
|
|||
mod utils;
|
||||
pub mod vault_snapshot;
|
||||
pub mod websocket;
|
||||
|
||||
use serde::{Deserialize, Deserializer};
|
||||
|
||||
use crate::{app_state::database::models::VaultId, utils::normalize_vault_id::normalize_vault_id};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct VaultPath(pub VaultId);
|
||||
|
||||
impl<'de> Deserialize<'de> for VaultPath {
|
||||
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
|
||||
where
|
||||
D: Deserializer<'de>,
|
||||
{
|
||||
normalize_vault_id(deserializer).map(Self)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,21 +5,12 @@ use axum::{
|
|||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{EventBatch, VaultId},
|
||||
},
|
||||
app_state::{AppState, database::models::EventBatch},
|
||||
errors::{SyncServerError, client_error, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct EventsPath {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct EventsQuery {
|
||||
pub after: i64,
|
||||
|
|
@ -27,13 +18,13 @@ pub struct EventsQuery {
|
|||
|
||||
#[axum::debug_handler]
|
||||
pub async fn events(
|
||||
Path(path): Path<EventsPath>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
Query(query): Query<EventsQuery>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<EventBatch>, SyncServerError> {
|
||||
debug!(
|
||||
"Fetching events after `{}` for vault `{}`",
|
||||
query.after, path.vault_id
|
||||
query.after, vault_id
|
||||
);
|
||||
|
||||
if query.after < 0 {
|
||||
|
|
@ -42,7 +33,7 @@ pub async fn events(
|
|||
|
||||
state
|
||||
.database
|
||||
.events_after(&path.vault_id, query.after)
|
||||
.events_after(&vault_id, query.after)
|
||||
.await
|
||||
.map(Json)
|
||||
.map_err(server_error)
|
||||
|
|
|
|||
|
|
@ -4,33 +4,23 @@ use axum::{
|
|||
extract::{Path, State},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{DocumentId, VaultId, VaultUpdateId},
|
||||
database::models::{DocumentId, VaultUpdateId},
|
||||
},
|
||||
errors::{SyncServerError, not_found_error, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchDocumentVersionContentPathParams {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
|
||||
document_id: DocumentId,
|
||||
vault_update_id: VaultUpdateId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn fetch_document_version_content(
|
||||
Path(FetchDocumentVersionContentPathParams {
|
||||
vault_id,
|
||||
document_id,
|
||||
vault_update_id,
|
||||
}): Path<FetchDocumentVersionContentPathParams>,
|
||||
Path((VaultPath(vault_id), document_id, vault_update_id)): Path<(
|
||||
VaultPath,
|
||||
DocumentId,
|
||||
VaultUpdateId,
|
||||
)>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Bytes, SyncServerError> {
|
||||
debug!(
|
||||
|
|
|
|||
|
|
@ -4,31 +4,19 @@ use axum::{
|
|||
extract::{Path, State},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{DocumentId, DocumentVersion, VaultId},
|
||||
database::models::{DocumentId, DocumentVersion},
|
||||
},
|
||||
errors::{SyncServerError, not_found_error, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct FetchLatestDocumentVersionPathParams {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
|
||||
document_id: DocumentId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn fetch_latest_document_version(
|
||||
Path(FetchLatestDocumentVersionPathParams {
|
||||
vault_id,
|
||||
document_id,
|
||||
}): Path<FetchLatestDocumentVersionPathParams>,
|
||||
Path((VaultPath(vault_id), document_id)): Path<(VaultPath, DocumentId)>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<DocumentVersion>, SyncServerError> {
|
||||
debug!("Fetching latest document version for document `{document_id}` in vault `{vault_id}`");
|
||||
|
|
|
|||
|
|
@ -3,36 +3,26 @@ use axum::{
|
|||
extract::{Path, State},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::{
|
||||
Database,
|
||||
models::{FileManifest, VaultId},
|
||||
},
|
||||
database::{Database, models::FileManifest},
|
||||
},
|
||||
errors::{SyncServerError, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct GetFileManifestPath {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn get_file_manifest(
|
||||
Path(path): Path<GetFileManifestPath>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<FileManifest>, SyncServerError> {
|
||||
debug!("Fetching file manifest for vault `{}`", path.vault_id);
|
||||
debug!("Fetching file manifest for vault `{vault_id}`");
|
||||
|
||||
let mut transaction = state
|
||||
.database
|
||||
.create_readonly_transaction(&path.vault_id)
|
||||
.create_readonly_transaction(&vault_id)
|
||||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
|
|
|
|||
|
|
@ -7,26 +7,15 @@ use axum_extra::{
|
|||
headers::{Authorization, authorization::Bearer},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::server::{auth::auth, responses::PingResponse};
|
||||
use crate::{
|
||||
app_state::{AppState, database::models::VaultId},
|
||||
consts::SUPPORTED_API_VERSION,
|
||||
errors::SyncServerError,
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PingPathParams {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
use crate::{app_state::AppState, consts::SUPPORTED_API_VERSION, errors::SyncServerError};
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn ping(
|
||||
maybe_auth_header: Option<TypedHeader<Authorization<Bearer>>>,
|
||||
Path(PingPathParams { vault_id }): Path<PingPathParams>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<PingResponse>, SyncServerError> {
|
||||
debug!("Pinging vault `{vault_id}`");
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
use super::utils::find_already_processed_event;
|
||||
use super::{VaultPath, utils::find_already_processed_event};
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
|
|
@ -14,7 +14,6 @@ use crate::{
|
|||
requests::{PushContent, PutFileContent},
|
||||
responses::DocumentUpdateResponse,
|
||||
},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
use anyhow::anyhow;
|
||||
use axum::{
|
||||
|
|
@ -25,37 +24,26 @@ use axum_extra::TypedHeader;
|
|||
use base64::{Engine as _, engine::general_purpose::STANDARD};
|
||||
use log::debug;
|
||||
use reconcile_text::{BuiltinTokenizer, EditedText, NumberOrText};
|
||||
use serde::Deserialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PutFileContentPath {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
document_id: DocumentId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn put_file_content(
|
||||
Path(path): Path<PutFileContentPath>,
|
||||
Path((VaultPath(vault_id), document_id)): Path<(VaultPath, DocumentId)>,
|
||||
Extension(user): Extension<User>,
|
||||
TypedHeader(device): TypedHeader<DeviceIdHeader>,
|
||||
State(state): State<AppState>,
|
||||
Json(push): Json<PutFileContent>,
|
||||
) -> Result<Json<DocumentUpdateResponse>, SyncServerError> {
|
||||
debug!(
|
||||
"Pushing document `{}` in vault `{}`",
|
||||
path.document_id, path.vault_id
|
||||
);
|
||||
debug!("Pushing document `{}` in vault `{}`", document_id, vault_id);
|
||||
|
||||
let fingerprint = Sha256::digest(
|
||||
serde_json::to_vec(&("content", path.document_id, &push))
|
||||
serde_json::to_vec(&("content", document_id, &push))
|
||||
.map_err(|error| server_error(error.into()))?,
|
||||
);
|
||||
|
||||
let mut tx = state
|
||||
.database
|
||||
.create_write_transaction(&path.vault_id)
|
||||
.create_write_transaction(&vault_id)
|
||||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
|
|
@ -74,7 +62,7 @@ pub async fn put_file_content(
|
|||
|
||||
let parent = state
|
||||
.database
|
||||
.get_latest_document_version(&path.vault_id, &path.document_id, Some(&mut tx))
|
||||
.get_latest_document_version(&vault_id, &document_id, Some(&mut tx))
|
||||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
|
|
@ -87,7 +75,7 @@ pub async fn put_file_content(
|
|||
} else if push.parent_version_id.is_some() {
|
||||
return Err(not_found_error(anyhow!(
|
||||
"Document {} does not exist",
|
||||
path.document_id
|
||||
document_id
|
||||
)));
|
||||
}
|
||||
|
||||
|
|
@ -123,7 +111,7 @@ pub async fn put_file_content(
|
|||
vault_update_id: Database::allocate_event(&mut tx, push.request_id, &fingerprint)
|
||||
.await
|
||||
.map_err(server_error)?,
|
||||
document_id: path.document_id,
|
||||
document_id,
|
||||
content,
|
||||
updated_date: chrono::Utc::now(),
|
||||
user_id: user.name,
|
||||
|
|
@ -152,10 +140,7 @@ pub async fn put_file_content(
|
|||
.await
|
||||
.map_err(|error| server_error(error.into()))?;
|
||||
|
||||
state
|
||||
.broadcasts
|
||||
.notify_about_vault_update(path.vault_id)
|
||||
.await;
|
||||
state.broadcasts.notify_about_vault_update(vault_id).await;
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
|
@ -185,10 +170,7 @@ mod tests {
|
|||
push: PutFileContent,
|
||||
) -> Result<DocumentUpdateResponse, SyncServerError> {
|
||||
put_file_content(
|
||||
Path(PutFileContentPath {
|
||||
vault_id: vault.clone(),
|
||||
document_id,
|
||||
}),
|
||||
Path((VaultPath(vault.clone()), document_id)),
|
||||
Extension(User {
|
||||
name: user_id,
|
||||
token: String::new(),
|
||||
|
|
|
|||
|
|
@ -4,36 +4,28 @@ use axum::{
|
|||
extract::{Path, State},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
use super::utils::find_already_processed_event;
|
||||
use super::{VaultPath, utils::find_already_processed_event};
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::{
|
||||
Database,
|
||||
models::{EventRecord, FileManifest, VaultEvent, VaultId},
|
||||
models::{EventRecord, FileManifest, VaultEvent},
|
||||
},
|
||||
},
|
||||
errors::{SyncServerError, client_error, server_error},
|
||||
server::{requests::PushFileManifest, responses::FileManifestUpdateResponse},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct PutFileManifestPath {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn put_file_manifest(
|
||||
Path(path): Path<PutFileManifestPath>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
State(state): State<AppState>,
|
||||
Json(push): Json<PushFileManifest>,
|
||||
) -> Result<Json<FileManifestUpdateResponse>, SyncServerError> {
|
||||
debug!("Pushing file manifest for vault `{}`", path.vault_id);
|
||||
debug!("Pushing file manifest for vault `{vault_id}`");
|
||||
|
||||
// BTreeMap canonicalizes file manifest entries for request fingerprinting.
|
||||
let fingerprint = Sha256::digest(
|
||||
|
|
@ -43,7 +35,7 @@ pub async fn put_file_manifest(
|
|||
|
||||
let mut tx = state
|
||||
.database
|
||||
.create_write_transaction(&path.vault_id)
|
||||
.create_write_transaction(&vault_id)
|
||||
.await
|
||||
.map_err(server_error)?;
|
||||
|
||||
|
|
@ -73,7 +65,7 @@ pub async fn put_file_manifest(
|
|||
for id in push.entries.keys() {
|
||||
if state
|
||||
.database
|
||||
.get_latest_document_version(&path.vault_id, id, Some(&mut tx))
|
||||
.get_latest_document_version(&vault_id, id, Some(&mut tx))
|
||||
.await
|
||||
.map_err(server_error)?
|
||||
.is_none()
|
||||
|
|
@ -113,10 +105,7 @@ pub async fn put_file_manifest(
|
|||
.await
|
||||
.map_err(|error| server_error(error.into()))?;
|
||||
|
||||
state
|
||||
.broadcasts
|
||||
.notify_about_vault_update(path.vault_id)
|
||||
.await;
|
||||
state.broadcasts.notify_about_vault_update(vault_id).await;
|
||||
|
||||
Ok(Json(response))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,33 +3,23 @@ use axum::{
|
|||
extract::{Path, State},
|
||||
};
|
||||
use log::debug;
|
||||
use serde::Deserialize;
|
||||
|
||||
use super::VaultPath;
|
||||
use crate::{
|
||||
app_state::{
|
||||
AppState,
|
||||
database::models::{VaultId, VaultSnapshot},
|
||||
},
|
||||
app_state::{AppState, database::models::VaultSnapshot},
|
||||
errors::{SyncServerError, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct VaultSnapshotPath {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn vault_snapshot(
|
||||
Path(path): Path<VaultSnapshotPath>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Json<VaultSnapshot>, SyncServerError> {
|
||||
debug!("Fetching vault snapshot for vault `{}`", path.vault_id);
|
||||
debug!("Fetching vault snapshot for vault `{vault_id}`");
|
||||
|
||||
state
|
||||
.database
|
||||
.vault_snapshot(&path.vault_id)
|
||||
.vault_snapshot(&vault_id)
|
||||
.await
|
||||
.map(Json)
|
||||
.map_err(server_error)
|
||||
|
|
|
|||
|
|
@ -9,7 +9,6 @@ use crate::{
|
|||
},
|
||||
},
|
||||
errors::{SyncServerError, client_error, server_error},
|
||||
utils::normalize_vault_id::normalize_vault_id,
|
||||
};
|
||||
use axum::{
|
||||
extract::{
|
||||
|
|
@ -20,29 +19,21 @@ use axum::{
|
|||
};
|
||||
use futures::StreamExt;
|
||||
use log::{debug, info};
|
||||
use serde::Deserialize;
|
||||
use std::time::Duration;
|
||||
use tokio::sync::broadcast::error::RecvError;
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub struct WebSocketPathParams {
|
||||
#[serde(deserialize_with = "normalize_vault_id")]
|
||||
vault_id: VaultId,
|
||||
}
|
||||
use super::VaultPath;
|
||||
|
||||
#[axum::debug_handler]
|
||||
pub async fn websocket_handler(
|
||||
ws: WebSocketUpgrade,
|
||||
Path(path): Path<WebSocketPathParams>,
|
||||
Path(VaultPath(vault_id)): Path<VaultPath>,
|
||||
State(state): State<AppState>,
|
||||
) -> Result<Response, SyncServerError> {
|
||||
debug!(
|
||||
"Upgrading WebSocket connection for vault `{}`",
|
||||
path.vault_id
|
||||
);
|
||||
debug!("Upgrading WebSocket connection for vault `{vault_id}`");
|
||||
|
||||
Ok(ws.on_upgrade(move |socket| async move {
|
||||
if let Err(error) = websocket(state, socket, path.vault_id).await {
|
||||
if let Err(error) = websocket(state, socket, vault_id).await {
|
||||
debug!("WebSocket disconnected: {error}");
|
||||
}
|
||||
}))
|
||||
|
|
|
|||
Loading…
Reference in a new issue