Always normalise vaultId and trim token

This commit is contained in:
Andras Schmelczer 2025-04-07 22:29:23 +01:00
parent 04a24d0b38
commit 74a8060246
No known key found for this signature in database
GPG key ID: FC8F2C3D3D1A718C
11 changed files with 44 additions and 10 deletions

View file

@ -15,6 +15,7 @@ use crate::{
app_state::{AppState, database::models::VaultId}, app_state::{AppState, database::models::VaultId},
config::user_config::{AllowListedVaults, User, VaultAccess}, config::user_config::{AllowListedVaults, User, VaultAccess},
errors::{SyncServerError, permission_denied_error, unauthenticated_error}, errors::{SyncServerError, permission_denied_error, unauthenticated_error},
utils::normalize::normalize_string,
}; };
pub async fn auth_middleware( pub async fn auth_middleware(
@ -24,12 +25,14 @@ pub async fn auth_middleware(
mut req: Request, mut req: Request,
next: Next, next: Next,
) -> Result<Response, SyncServerError> { ) -> Result<Response, SyncServerError> {
let token = auth_header.token(); let token = auth_header.token().trim();
let vault_id = path_params let vault_id = normalize_string(
.get("vault_id") path_params
.ok_or_else(|| unauthenticated_error(anyhow::anyhow!("Missing vault_id")))?; .get("vault_id")
.ok_or_else(|| unauthenticated_error(anyhow::anyhow!("Missing vault_id")))?,
);
let user = auth(&state, token, vault_id)?; let user = auth(&state, token, &vault_id)?;
req.extensions_mut().insert(user); req.extensions_mut().insert(user);

View file

@ -16,12 +16,13 @@ use crate::{
}, },
}, },
errors::{SyncServerError, client_error, server_error}, errors::{SyncServerError, client_error, server_error},
utils::sanitize_path, utils::{normalize::normalize, sanitize_path::sanitize_path},
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct CreateDocumentPathParams { pub struct CreateDocumentPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
} }

View file

@ -14,13 +14,15 @@ use crate::{
}, },
}, },
errors::{SyncServerError, server_error}, errors::{SyncServerError, server_error},
utils::sanitize_path, utils::{normalize::normalize, sanitize_path::sanitize_path},
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct DeleteDocumentPathParams { pub struct DeleteDocumentPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
document_id: DocumentId, document_id: DocumentId,
} }

View file

@ -10,12 +10,15 @@ use crate::{
database::models::{DocumentId, DocumentVersion, VaultId, VaultUpdateId}, database::models::{DocumentId, DocumentVersion, VaultId, VaultUpdateId},
}, },
errors::{SyncServerError, not_found_error, server_error}, errors::{SyncServerError, not_found_error, server_error},
utils::normalize::normalize,
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct FetchDocumentVersionPathParams { pub struct FetchDocumentVersionPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
document_id: DocumentId, document_id: DocumentId,
vault_update_id: VaultUpdateId, vault_update_id: VaultUpdateId,
} }

View file

@ -12,12 +12,15 @@ use crate::{
database::models::{DocumentId, VaultId, VaultUpdateId}, database::models::{DocumentId, VaultId, VaultUpdateId},
}, },
errors::{SyncServerError, not_found_error, server_error}, errors::{SyncServerError, not_found_error, server_error},
utils::normalize::normalize,
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct FetchDocumentVersionContentPathParams { pub struct FetchDocumentVersionContentPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
document_id: DocumentId, document_id: DocumentId,
vault_update_id: VaultUpdateId, vault_update_id: VaultUpdateId,
} }

View file

@ -10,12 +10,15 @@ use crate::{
database::models::{DocumentId, DocumentVersion, VaultId}, database::models::{DocumentId, DocumentVersion, VaultId},
}, },
errors::{SyncServerError, not_found_error, server_error}, errors::{SyncServerError, not_found_error, server_error},
utils::normalize::normalize,
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct FetchLatestDocumentVersionPathParams { pub struct FetchLatestDocumentVersionPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
document_id: DocumentId, document_id: DocumentId,
} }

View file

@ -10,11 +10,13 @@ use crate::{
database::models::{VaultId, VaultUpdateId}, database::models::{VaultId, VaultUpdateId},
}, },
errors::{SyncServerError, server_error}, errors::{SyncServerError, server_error},
utils::normalize::normalize,
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct FetchLatestDocumentsPathParams { pub struct FetchLatestDocumentsPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
} }

View file

@ -13,11 +13,13 @@ use super::{auth::auth, responses::PingResponse};
use crate::{ use crate::{
app_state::{AppState, database::models::VaultId}, app_state::{AppState, database::models::VaultId},
errors::SyncServerError, errors::SyncServerError,
utils::normalize::normalize,
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct PingPathParams { pub struct PingPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
} }

View file

@ -18,13 +18,15 @@ use crate::{
database::models::{DeviceId, DocumentId, StoredDocumentVersion, VaultId, VaultUpdateId}, database::models::{DeviceId, DocumentId, StoredDocumentVersion, VaultId, VaultUpdateId},
}, },
errors::{SyncServerError, client_error, not_found_error, server_error}, errors::{SyncServerError, client_error, not_found_error, server_error},
utils::{deduped_file_paths, sanitize_path}, utils::{dedup_paths::dedup_paths, normalize::normalize, sanitize_path::sanitize_path},
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct UpdateDocumentPathParams { pub struct UpdateDocumentPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
document_id: DocumentId, document_id: DocumentId,
} }
@ -171,7 +173,7 @@ async fn internal_update_document(
&& latest_version.relative_path != sanitized_relative_path && latest_version.relative_path != sanitized_relative_path
{ {
let mut new_relative_path = String::default(); let mut new_relative_path = String::default();
for candidate in deduped_file_paths(&sanitized_relative_path) { for candidate in dedup_paths(&sanitized_relative_path) {
if state if state
.database .database
.get_latest_document_by_path(&vault_id, &candidate, Some(&mut transaction)) .get_latest_document_by_path(&vault_id, &candidate, Some(&mut transaction))

View file

@ -21,11 +21,13 @@ use crate::{
database::models::{DeviceId, DocumentVersionWithoutContent, VaultId, VaultUpdateId}, database::models::{DeviceId, DocumentVersionWithoutContent, VaultId, VaultUpdateId},
}, },
errors::{SyncServerError, server_error, unauthenticated_error}, errors::{SyncServerError, server_error, unauthenticated_error},
utils::normalize::{normalize, normalize_string},
}; };
// This is required for aide to infer the path parameter types and names // This is required for aide to infer the path parameter types and names
#[derive(Deserialize, JsonSchema)] #[derive(Deserialize, JsonSchema)]
pub struct WebsocketPathParams { pub struct WebsocketPathParams {
#[serde(deserialize_with = "normalize")]
vault_id: VaultId, vault_id: VaultId,
} }
@ -81,7 +83,7 @@ async fn websocket(
.context("Failed to parse token") .context("Failed to parse token")
.map_err(server_error)?; .map_err(server_error)?;
auth(&state, &handshake.token, &vault_id)?; auth(&state, handshake.token.trim(), &normalize_string(&vault_id))?;
handshake handshake
} else { } else {

View file

@ -0,0 +1,11 @@
use serde::{Deserialize, Deserializer};
pub fn normalize<'de, D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
let s = String::deserialize(deserializer)?;
Ok(normalize_string(&s))
}
pub fn normalize_string(s: &str) -> String { s.trim().to_lowercase() }