Added state machine verification of modifylists

This commit is contained in:
William Brown 2019-03-12 15:40:19 +10:00
parent 658e409d90
commit 30505f8285
2 changed files with 54 additions and 31 deletions

View file

@ -82,15 +82,62 @@ impl ModifyList<ModifyInvalid> {
pub fn validate(&self,
schema: &SchemaReadTransaction,
) -> Result<ModifyList<ModifyValid>, SchemaError> {
// Check that all attributes exist in the schema
// Normalise them
let schema_attributes = schema.get_attributes();
let schema_name = schema_attributes
.get("name")
.expect("Critical: Core schema corrupt or missing. To initiate a core transfer, please deposit substitute core in receptacle.");
// Validate them
let res: Result<Vec<Modify>, _> = (&self.mods).into_iter()
.map(|m| {
match m {
Modify::Present(attr, value) => {
let attr_norm = schema_name.normalise_value(&attr);
match schema_attributes.get(&attr_norm) {
Some(schema_a) => {
let value_norm = schema_a.normalise_value(&value);
schema_a
.validate_value(&value_norm)
.map(|_| Modify::Present(attr_norm, value_norm))
}
None => Err(SchemaError::InvalidAttribute),
}
}
Modify::Removed(attr, value) => {
let attr_norm = schema_name.normalise_value(&attr);
match schema_attributes.get(&attr_norm) {
Some(schema_a) => {
let value_norm = schema_a.normalise_value(&value);
schema_a
.validate_value(&value_norm)
.map(|_| Modify::Removed(attr_norm, value_norm))
}
None => Err(SchemaError::InvalidAttribute),
}
}
Modify::Purged(attr) => {
let attr_norm = schema_name.normalise_value(&attr);
match schema_attributes.get(&attr_norm) {
Some(_attr_name) => {
Ok(Modify::Purged(attr_norm))
}
None => Err(SchemaError::InvalidAttribute),
}
}
}
})
.collect();
let valid_mods = match res {
Ok(v) => v,
Err(e) => return Err(e),
};
// Return new ModifyList!
unimplemented!()
Ok(ModifyList {
valid: ModifyValid,
mods: valid_mods,
})
}
}

View file

@ -357,32 +357,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
return plug_pre_res;
}
// TODO: Rework this to be better.
/*
let (norm_cand, invalid_cand): (
Vec<Result<Entry<EntryValid, EntryNew>, _>>,
Vec<Result<_, SchemaError>>,
) = candidates
.into_iter()
.map(|e| e.validate(&self.schema))
.partition(|e| e.is_ok());
for err in invalid_cand.iter() {
audit_log!(au, "Schema Violation: {:?}", err);
}
for err in invalid_cand.iter() {
return Err(OperationError::SchemaViolation(err.unwrap_err()));
}
let norm_cand: Vec<Entry<EntryValid, EntryNew>> = norm_cand
.into_iter()
.map(|e| match e {
Ok(v) => v,
Err(_) => panic!("Invalid data set state!!!"),
})
.collect();
*/
// NOTE: This is how you map from Vec<Result<T>> to Result<Vec<T>>
// remember, that you only get the first error and the iter terminates.
let res: Result<Vec<Entry<EntryValid, EntryNew>>, SchemaError> = candidates
.into_iter()