fix(api): malformed entries aren't parsed as invariants during PUT

feat/type-attributes
Tomáš Mládek 2023-01-04 21:16:59 +01:00
parent d5f6a615ba
commit 89bca64d23
1 changed files with 45 additions and 30 deletions

View File

@ -324,12 +324,18 @@ pub async fn get_object(
}))) })))
} }
#[derive(Debug, Clone, Deserialize)]
pub struct InEntry {
pub entity: Option<Address>,
pub attribute: String,
pub value: EntryValue,
}
#[derive(Debug, Clone, Deserialize)] #[derive(Debug, Clone, Deserialize)]
#[serde(untagged)] #[serde(untagged)]
pub enum InEntry { pub enum PutInput {
Entry(Entry), Entry(InEntry),
EntryList(Vec<Entry>), EntryList(Vec<Entry>),
Invariant(InvariantEntry),
Address { entity: InAddress }, Address { entity: InAddress },
} }
@ -367,7 +373,7 @@ impl TryInto<Address> for InAddress {
pub async fn put_object( pub async fn put_object(
req: HttpRequest, req: HttpRequest,
state: web::Data<State>, state: web::Data<State>,
payload: Either<web::Json<InEntry>, Multipart>, payload: Either<web::Json<PutInput>, Multipart>,
) -> Result<HttpResponse, Error> { ) -> Result<HttpResponse, Error> {
check_auth(&req, &state)?; check_auth(&req, &state)?;
@ -379,15 +385,40 @@ pub async fn put_object(
debug!("PUTting {in_entry:?}"); debug!("PUTting {in_entry:?}");
match in_entry { match in_entry {
InEntry::Entry(entry) => Ok(web::block::<_, _, anyhow::Error>(move || { PutInput::Entry(in_entry) => {
Ok(( if let Some(entity) = in_entry.entity {
Some(connection.insert_entry(entry.clone())?), let entry = Entry {
Some(entry.entity), entity,
)) attribute: in_entry.attribute,
}) value: in_entry.value,
.await };
.map_err(ErrorInternalServerError)?),
InEntry::EntryList(entries) => { Ok(web::block::<_, _, anyhow::Error>(move || {
Ok((
Some(connection.insert_entry(entry.clone())?),
Some(entry.entity),
))
})
.await
.map_err(ErrorInternalServerError)?)
} else {
let invariant = Entry::try_from(&InvariantEntry {
attribute: in_entry.attribute,
value: in_entry.value,
})
.map_err(ErrorInternalServerError)?;
Ok(web::block::<_, _, anyhow::Error>(move || {
Ok((
Some(connection.insert_entry(invariant.clone())?),
Some(invariant.entity),
))
})
.await
.map_err(ErrorInternalServerError)?)
}
}
PutInput::EntryList(entries) => {
web::block(move || { web::block(move || {
connection.transaction::<_, anyhow::Error, _>(|| { connection.transaction::<_, anyhow::Error, _>(|| {
for entry in entries { for entry in entries {
@ -400,23 +431,7 @@ pub async fn put_object(
.map_err(ErrorInternalServerError)?; .map_err(ErrorInternalServerError)?;
Ok((None, None)) Ok((None, None))
} }
InEntry::Invariant(in_entry) => { PutInput::Address { entity: in_address } => {
let invariant = Entry::try_from(&InvariantEntry {
attribute: in_entry.attribute,
value: in_entry.value,
})
.map_err(ErrorInternalServerError)?;
Ok(web::block::<_, _, anyhow::Error>(move || {
Ok((
Some(connection.insert_entry(invariant.clone())?),
Some(invariant.entity),
))
})
.await
.map_err(ErrorInternalServerError)?)
}
InEntry::Address { entity: in_address } => {
let address = in_address.try_into().map_err(ErrorBadRequest)?; let address = in_address.try_into().map_err(ErrorBadRequest)?;
let label_entry = match &address { let label_entry = match &address {