mirror of
https://git.asonix.dog/asonix/pict-rs
synced 2024-12-22 19:31:35 +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,
|
store: &S,
|
||||||
alias: &Alias,
|
alias: &Alias,
|
||||||
) -> Result<Details, Error> {
|
) -> 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?;
|
let details = repo.details(&identifier).await?;
|
||||||
|
|
||||||
if let Some(details) = details {
|
if let Some(details) = details {
|
||||||
|
@ -573,7 +576,13 @@ async fn process_details<R: FullRepo, S: Store>(
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let (_, alias, thumbnail_path, _) = prepare_process(query, ext.as_str())?;
|
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
|
let identifier = repo
|
||||||
.variant_identifier::<S::Identifier>(hash, thumbnail_path.to_string_lossy().to_string())
|
.variant_identifier::<S::Identifier>(hash, thumbnail_path.to_string_lossy().to_string())
|
||||||
.await?
|
.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 (format, alias, thumbnail_path, thumbnail_args) = prepare_process(query, ext.as_str())?;
|
||||||
|
|
||||||
let path_string = thumbnail_path.to_string_lossy().to_string();
|
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
|
let identifier_opt = repo
|
||||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
.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 (format, alias, thumbnail_path, _) = prepare_process(query, ext.as_str())?;
|
||||||
|
|
||||||
let path_string = thumbnail_path.to_string_lossy().to_string();
|
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
|
let identifier_opt = repo
|
||||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
||||||
.await?;
|
.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 (target_format, source, process_path, process_args) = prepare_process(query, ext.as_str())?;
|
||||||
|
|
||||||
let path_string = process_path.to_string_lossy().to_string();
|
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
|
let identifier_opt = repo
|
||||||
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
.variant_identifier::<S::Identifier>(hash.clone(), path_string)
|
||||||
.await?;
|
.await?;
|
||||||
|
@ -764,7 +785,11 @@ async fn serve<R: FullRepo, S: Store + 'static>(
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let alias = alias.into_inner();
|
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?;
|
let details = ensure_details(&repo, &store, &alias).await?;
|
||||||
|
|
||||||
|
@ -780,7 +805,10 @@ async fn serve_head<R: FullRepo, S: Store + 'static>(
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let alias = alias.into_inner();
|
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?;
|
let details = ensure_details(&repo, &store, &alias).await?;
|
||||||
|
|
||||||
|
@ -932,7 +960,11 @@ async fn purge<R: FullRepo>(
|
||||||
let alias = query.into_inner().alias;
|
let alias = query.into_inner().alias;
|
||||||
let aliases = repo.aliases_from_alias(&alias).await?;
|
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?;
|
queue::cleanup_hash(&repo, hash).await?;
|
||||||
|
|
||||||
Ok(HttpResponse::Ok().json(&serde_json::json!({
|
Ok(HttpResponse::Ok().json(&serde_json::json!({
|
||||||
|
@ -961,7 +993,12 @@ async fn identifier<R: FullRepo, S: Store>(
|
||||||
repo: web::Data<R>,
|
repo: web::Data<R>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
let alias = query.into_inner().alias;
|
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!({
|
Ok(HttpResponse::Ok().json(&serde_json::json!({
|
||||||
"msg": "ok",
|
"msg": "ok",
|
||||||
|
|
|
@ -127,9 +127,13 @@ where
|
||||||
return Err(UploadError::InvalidToken.into());
|
return Err(UploadError::InvalidToken.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
let hash = repo.hash(&alias).await?;
|
|
||||||
|
|
||||||
AliasRepo::cleanup(repo, &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?;
|
repo.remove_alias(hash.clone(), &alias).await?;
|
||||||
|
|
||||||
if repo.aliases(hash.clone()).await?.is_empty() {
|
if repo.aliases(hash.clone()).await?.is_empty() {
|
||||||
|
|
|
@ -125,7 +125,10 @@ async fn generate<R: FullRepo, S: Store + 'static>(
|
||||||
process_path: PathBuf,
|
process_path: PathBuf,
|
||||||
process_args: Vec<String>,
|
process_args: Vec<String>,
|
||||||
) -> Result<(), Error> {
|
) -> 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 path_string = process_path.to_string_lossy().to_string();
|
||||||
let identifier_opt = repo
|
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>(
|
async fn identifier_from_alias<I: Identifier + 'static>(
|
||||||
&self,
|
&self,
|
||||||
alias: &Alias,
|
alias: &Alias,
|
||||||
) -> Result<I, StoreError> {
|
) -> Result<Option<I>, StoreError> {
|
||||||
let hash = self.hash(alias).await?;
|
let Some(hash) = self.hash(alias).await? else {
|
||||||
self.identifier(hash).await
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
self.identifier(hash).await.map(Some)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
async fn aliases_from_alias(&self, alias: &Alias) -> Result<Vec<Alias>, RepoError> {
|
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
|
self.aliases(hash).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,7 +108,10 @@ pub(crate) trait FullRepo:
|
||||||
&self,
|
&self,
|
||||||
alias: &Alias,
|
alias: &Alias,
|
||||||
) -> Result<Option<I>, StoreError> {
|
) -> 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?;
|
let identifier = self.identifier::<I>(hash.clone()).await?;
|
||||||
|
|
||||||
match self.details(&identifier).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 delete_token(&self, alias: &Alias) -> Result<DeleteToken, RepoError>;
|
||||||
|
|
||||||
async fn relate_hash(&self, alias: &Alias, hash: Self::Bytes) -> Result<(), 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>;
|
async fn cleanup(&self, alias: &Alias) -> Result<(), RepoError>;
|
||||||
}
|
}
|
||||||
|
@ -441,7 +450,7 @@ where
|
||||||
T::relate_hash(self, alias, hash).await
|
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
|
T::hash(self, alias).await
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -729,13 +729,12 @@ impl AliasRepo for SledRepo {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(level = "trace", skip(self))]
|
#[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 key = alias.to_bytes();
|
||||||
|
|
||||||
let opt = b!(self.alias_hashes, alias_hashes.get(key));
|
let opt = b!(self.alias_hashes, alias_hashes.get(key));
|
||||||
|
|
||||||
opt.ok_or(SledError::Missing("alias -> hash"))
|
Ok(opt)
|
||||||
.map_err(RepoError::from)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tracing::instrument(skip(self))]
|
#[tracing::instrument(skip(self))]
|
||||||
|
|
Loading…
Reference in a new issue