mirror of
https://git.asonix.dog/asonix/pict-rs.git
synced 2024-11-25 02:51:17 +00:00
Explicitly handle cases of invalid aliases
This commit is contained in:
parent
d9c5ed20b9
commit
e7e4876908
5 changed files with 74 additions and 22 deletions
55
src/lib.rs
55
src/lib.rs
|
@ -105,7 +105,10 @@ async fn ensure_details<R: FullRepo, S: Store + 'static>(
|
|||
store: &S,
|
||||
alias: &Alias,
|
||||
) -> Result<Details, Error> {
|
||||
let identifier = repo.identifier_from_alias::<S::Identifier>(alias).await?;
|
||||
let Some(identifier) = repo.identifier_from_alias::<S::Identifier>(alias).await? else {
|
||||
return Err(UploadError::MissingAlias.into());
|
||||
};
|
||||
|
||||
let details = repo.details(&identifier).await?;
|
||||
|
||||
if let Some(details) = details {
|
||||
|
@ -573,7 +576,13 @@ async fn process_details<R: FullRepo, S: Store>(
|
|||
) -> Result<HttpResponse, Error> {
|
||||
let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str())?;
|
||||
|
||||
let hash = repo.hash(&alias).await?;
|
||||
let Some(hash) = repo.hash(&alias).await? else {
|
||||
// Invalid alias
|
||||
return Ok(HttpResponse::NotFound().json(&serde_json::json!({
|
||||
"msg": "No images associated with provided alias",
|
||||
})));
|
||||
};
|
||||
|
||||
let identifier = repo
|
||||
.variant_identifier::<S::Identifier>(hash, thumbnail_path.to_string_lossy().to_string())
|
||||
.await?
|
||||
|
@ -598,7 +607,11 @@ async fn process<R: FullRepo, S: Store + 'static>(
|
|||
let (format, alias, thumbnail_path, thumbnail_args) = prepare_process(query, ext.as_str())?;
|
||||
|
||||
let path_string = thumbnail_path.to_string_lossy().to_string();
|
||||
let hash = repo.hash(&alias).await?;
|
||||
let Some(hash) = repo.hash(&alias).await? else {
|
||||
// Invalid alias
|
||||
// TODO: placeholder 404 image
|
||||
return Ok(HttpResponse::NotFound().finish());
|
||||
};
|
||||
|
||||
let identifier_opt = repo
|
||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
||||
|
@ -685,7 +698,11 @@ async fn process_head<R: FullRepo, S: Store + 'static>(
|
|||
let (format, alias, thumbnail_path, _) = prepare_process(query, ext.as_str())?;
|
||||
|
||||
let path_string = thumbnail_path.to_string_lossy().to_string();
|
||||
let hash = repo.hash(&alias).await?;
|
||||
let Some(hash) = repo.hash(&alias).await? else {
|
||||
// Invalid alias
|
||||
return Ok(HttpResponse::NotFound().finish());
|
||||
};
|
||||
|
||||
let identifier_opt = repo
|
||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
||||
.await?;
|
||||
|
@ -726,7 +743,11 @@ async fn process_backgrounded<R: FullRepo, S: Store>(
|
|||
let (target_format, source, process_path, process_args) = prepare_process(query, ext.as_str())?;
|
||||
|
||||
let path_string = process_path.to_string_lossy().to_string();
|
||||
let hash = repo.hash(&source).await?;
|
||||
let Some(hash) = repo.hash(&source).await? else {
|
||||
// Invalid alias
|
||||
return Ok(HttpResponse::BadRequest().finish());
|
||||
};
|
||||
|
||||
let identifier_opt = repo
|
||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
||||
.await?;
|
||||
|
@ -764,7 +785,11 @@ async fn serve<R: FullRepo, S: Store + 'static>(
|
|||
) -> Result<HttpResponse, Error> {
|
||||
let alias = alias.into_inner();
|
||||
|
||||
let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?;
|
||||
let Some(identifier) = repo.identifier_from_alias::<S::Identifier>(&alias).await? else {
|
||||
// Invalid alias
|
||||
// TODO: placeholder 404 image
|
||||
return Ok(HttpResponse::NotFound().finish());
|
||||
};
|
||||
|
||||
let details = ensure_details(&repo, &store, &alias).await?;
|
||||
|
||||
|
@ -780,7 +805,10 @@ async fn serve_head<R: FullRepo, S: Store + 'static>(
|
|||
) -> Result<HttpResponse, Error> {
|
||||
let alias = alias.into_inner();
|
||||
|
||||
let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?;
|
||||
let Some(identifier) = repo.identifier_from_alias::<S::Identifier>(&alias).await? else {
|
||||
// Invalid alias
|
||||
return Ok(HttpResponse::NotFound().finish());
|
||||
};
|
||||
|
||||
let details = ensure_details(&repo, &store, &alias).await?;
|
||||
|
||||
|
@ -932,7 +960,11 @@ async fn purge<R: FullRepo>(
|
|||
let alias = query.into_inner().alias;
|
||||
let aliases = repo.aliases_from_alias(&alias).await?;
|
||||
|
||||
let hash = repo.hash(&alias).await?;
|
||||
let Some(hash) = repo.hash(&alias).await? else {
|
||||
return Ok(HttpResponse::BadRequest().json(&serde_json::json!({
|
||||
"msg": "No images associated with provided alias",
|
||||
})));
|
||||
};
|
||||
queue::cleanup_hash(&repo, hash).await?;
|
||||
|
||||
Ok(HttpResponse::Ok().json(&serde_json::json!({
|
||||
|
@ -961,7 +993,12 @@ async fn identifier<R: FullRepo, S: Store>(
|
|||
repo: web::Data<R>,
|
||||
) -> Result<HttpResponse, Error> {
|
||||
let alias = query.into_inner().alias;
|
||||
let identifier = repo.identifier_from_alias::<S::Identifier>(&alias).await?;
|
||||
let Some(identifier) = repo.identifier_from_alias::<S::Identifier>(&alias).await? else {
|
||||
// Invalid alias
|
||||
return Ok(HttpResponse::NotFound().json(serde_json::json!({
|
||||
"msg": "No identifiers associated with provided alias"
|
||||
})));
|
||||
};
|
||||
|
||||
Ok(HttpResponse::Ok().json(&serde_json::json!({
|
||||
"msg": "ok",
|
||||
|
|
|
@ -127,9 +127,13 @@ where
|
|||
return Err(UploadError::InvalidToken.into());
|
||||
}
|
||||
|
||||
let hash = repo.hash(&alias).await?;
|
||||
|
||||
AliasRepo::cleanup(repo, &alias).await?;
|
||||
|
||||
let Some(hash) = repo.hash(&alias).await? else {
|
||||
// hash doesn't exist, nothing to do
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
repo.remove_alias(hash.clone(), &alias).await?;
|
||||
|
||||
if repo.aliases(hash.clone()).await?.is_empty() {
|
||||
|
|
|
@ -125,7 +125,10 @@ async fn generate<R: FullRepo, S: Store + 'static>(
|
|||
process_path: PathBuf,
|
||||
process_args: Vec<String>,
|
||||
) -> Result<(), Error> {
|
||||
let hash = repo.hash(&source).await?;
|
||||
let Some(hash) = repo.hash(&source).await? else {
|
||||
// Nothing to do
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let path_string = process_path.to_string_lossy().to_string();
|
||||
let identifier_opt = repo
|
||||
|
|
23
src/repo.rs
23
src/repo.rs
|
@ -86,14 +86,20 @@ pub(crate) trait FullRepo:
|
|||
async fn identifier_from_alias<I: Identifier + 'static>(
|
||||
&self,
|
||||
alias: &Alias,
|
||||
) -> Result<I, StoreError> {
|
||||
let hash = self.hash(alias).await?;
|
||||
self.identifier(hash).await
|
||||
) -> Result<Option<I>, StoreError> {
|
||||
let Some(hash) = self.hash(alias).await? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
self.identifier(hash).await.map(Some)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
async fn aliases_from_alias(&self, alias: &Alias) -> Result<Vec<Alias>, RepoError> {
|
||||
let hash = self.hash(alias).await?;
|
||||
let Some(hash) = self.hash(alias).await? else {
|
||||
return Ok(vec![]);
|
||||
};
|
||||
|
||||
self.aliases(hash).await
|
||||
}
|
||||
|
||||
|
@ -102,7 +108,10 @@ pub(crate) trait FullRepo:
|
|||
&self,
|
||||
alias: &Alias,
|
||||
) -> Result<Option<I>, StoreError> {
|
||||
let hash = self.hash(alias).await?;
|
||||
let Some(hash) = self.hash(alias).await? else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
let identifier = self.identifier::<I>(hash.clone()).await?;
|
||||
|
||||
match self.details(&identifier).await? {
|
||||
|
@ -411,7 +420,7 @@ pub(crate) trait AliasRepo: BaseRepo {
|
|||
async fn delete_token(&self, alias: &Alias) -> Result<DeleteToken, RepoError>;
|
||||
|
||||
async fn relate_hash(&self, alias: &Alias, hash: Self::Bytes) -> Result<(), RepoError>;
|
||||
async fn hash(&self, alias: &Alias) -> Result<Self::Bytes, RepoError>;
|
||||
async fn hash(&self, alias: &Alias) -> Result<Option<Self::Bytes>, RepoError>;
|
||||
|
||||
async fn cleanup(&self, alias: &Alias) -> Result<(), RepoError>;
|
||||
}
|
||||
|
@ -441,7 +450,7 @@ where
|
|||
T::relate_hash(self, alias, hash).await
|
||||
}
|
||||
|
||||
async fn hash(&self, alias: &Alias) -> Result<Self::Bytes, RepoError> {
|
||||
async fn hash(&self, alias: &Alias) -> Result<Option<Self::Bytes>, RepoError> {
|
||||
T::hash(self, alias).await
|
||||
}
|
||||
|
||||
|
|
|
@ -729,13 +729,12 @@ impl AliasRepo for SledRepo {
|
|||
}
|
||||
|
||||
#[tracing::instrument(level = "trace", skip(self))]
|
||||
async fn hash(&self, alias: &Alias) -> Result<Self::Bytes, RepoError> {
|
||||
async fn hash(&self, alias: &Alias) -> Result<Option<Self::Bytes>, RepoError> {
|
||||
let key = alias.to_bytes();
|
||||
|
||||
let opt = b!(self.alias_hashes, alias_hashes.get(key));
|
||||
|
||||
opt.ok_or(SledError::Missing("alias -> hash"))
|
||||
.map_err(RepoError::from)
|
||||
Ok(opt)
|
||||
}
|
||||
|
||||
#[tracing::instrument(skip(self))]
|
||||
|
|
Loading…
Reference in a new issue