This commit is contained in:
William Brown 2018-12-29 21:01:38 +10:00
parent db024258f2
commit 8c97a08b74
5 changed files with 59 additions and 39 deletions

View file

@ -1,7 +1,7 @@
use actix::prelude::*; use actix::prelude::*;
use std::fmt;
use std::time::Duration; use std::time::Duration;
use std::time::SystemTime; use std::time::SystemTime;
use std::fmt;
use chrono::offset::Utc; use chrono::offset::Utc;
use chrono::DateTime; use chrono::DateTime;

View file

@ -55,24 +55,20 @@ impl Filter {
// Go through the filter components and check them in the entry. // Go through the filter components and check them in the entry.
// This is recursive!!!! // This is recursive!!!!
match self { match self {
Filter::Eq(attr, value) => { Filter::Eq(attr, value) => e.attribute_equality(attr.as_str(), value.as_str()),
e.attribute_equality(attr.as_str(), value.as_str()) Filter::Sub(attr, subvalue) => e.attribute_substring(attr.as_str(), subvalue.as_str()),
}
Filter::Sub(attr, subvalue) => {
e.attribute_substring(attr.as_str(), subvalue.as_str())
}
Filter::Pres(attr) => { Filter::Pres(attr) => {
// Given attr, is is present in the entry? // Given attr, is is present in the entry?
e.attribute_pres(attr.as_str()) e.attribute_pres(attr.as_str())
} }
Filter::Or(_) => { Filter::Or(_) => {
unimplemented!(); unimplemented!();
} }
Filter::And(_) => { Filter::And(_) => {
unimplemented!(); unimplemented!();
} }
Filter::Not(_) => { Filter::Not(_) => {
unimplemented!(); unimplemented!();
} }
} }
} }

View file

@ -49,7 +49,7 @@ trait Plugin {
} }
} }
pub struct Plugins{} pub struct Plugins {}
macro_rules! run_pre_create_plugin { macro_rules! run_pre_create_plugin {
( (
@ -61,14 +61,16 @@ macro_rules! run_pre_create_plugin {
$target_plugin:ty $target_plugin:ty
) => {{ ) => {{
let mut audit_scope = AuditScope::new(<($target_plugin)>::id()); let mut audit_scope = AuditScope::new(<($target_plugin)>::id());
let r = audit_segment!(audit_scope, || { let r = audit_segment!(audit_scope, || <($target_plugin)>::pre_create(
<($target_plugin)>::pre_create( $be,
$be, &mut audit_scope, $cand, $ce, $schema &mut audit_scope,
) $cand,
}); $ce,
$schema
));
$au.append_scope(audit_scope); $au.append_scope(audit_scope);
r r
}} }};
} }
impl Plugins { impl Plugins {
@ -80,16 +82,13 @@ impl Plugins {
schema: &Schema, schema: &Schema,
) -> Result<(), OperationError> { ) -> Result<(), OperationError> {
audit_segment!(audit_plugin_pre, || { audit_segment!(audit_plugin_pre, || {
// map chain? // map chain?
let uuid_res = run_pre_create_plugin!(be, au, cand, ce, schema, uuid::UUID); let uuid_res = run_pre_create_plugin!(be, au, cand, ce, schema, uuid::UUID);
// TODO, actually return the right thing ... // TODO, actually return the right thing ...
uuid_res uuid_res
}) })
} }
} }
// We should define the order that plugins should run // We should define the order that plugins should run

View file

@ -9,6 +9,14 @@ use event::CreateEvent;
use filter::Filter; use filter::Filter;
use schema::Schema; use schema::Schema;
// TO FINISH
/*
Add UUID type
Add base system class to all incoming objects (so we can add our values)
Add normalisation step
Add filter normaliser to search.
*/
pub struct UUID {} pub struct UUID {}
impl Plugin for UUID { impl Plugin for UUID {
@ -41,27 +49,30 @@ impl Plugin for UUID {
Some(u) => { Some(u) => {
// Actually check we have a value, could be empty array ... // Actually check we have a value, could be empty array ...
if u.len() > 1 { if u.len() > 1 {
audit_log!(au, "Entry defines uuid attr, but multiple values."); audit_log!(au, "Entry defines uuid attr, but multiple values.");
return Err(OperationError::Plugin) return Err(OperationError::Plugin);
}; };
let v = match u.first() { let v = match u.first() {
Some(v) => v, Some(v) => v,
None => { None => {
audit_log!(au, "Entry defines uuid attr, but no value."); audit_log!(au, "Entry defines uuid attr, but no value.");
return Err(OperationError::Plugin) return Err(OperationError::Plugin);
} }
}; };
// This could actually fail, so we probably need to handle // This could actually fail, so we probably need to handle
// this better .... // this better ....
// TODO: Make this a SCHEMA check, not a manual one. // TODO: Make this a SCHEMA check, not a manual one.
// //
match Uuid::parse_str(v.as_str()) { match Uuid::parse_str(v.as_str()) {
Ok(up) => up, Ok(up) => up,
Err(_) => { Err(_) => {
audit_log!(au, "Entry contains invalid UUID content, rejecting out of principle."); audit_log!(
return Err(OperationError::Plugin) au,
"Entry contains invalid UUID content, rejecting out of principle."
);
return Err(OperationError::Plugin);
} }
} }
} }
@ -90,7 +101,7 @@ impl Plugin for UUID {
} }
Err(e) => { Err(e) => {
audit_log!(au, "Backend error occured checking UUID existance."); audit_log!(au, "Backend error occured checking UUID existance.");
return Err(OperationError::Plugin) return Err(OperationError::Plugin);
} }
} }
@ -131,11 +142,8 @@ mod tests {
let mut be = Backend::new(&mut au, ""); let mut be = Backend::new(&mut au, "");
// TODO: Preload entries here! // TODO: Preload entries here!
if ! $preload_entries.is_empty() { if !$preload_entries.is_empty() {
assert!(be.create( assert!(be.create(&mut au, &$preload_entries).is_ok());
&mut au,
&$preload_entries
).is_ok());
}; };
let ce = CreateEvent::from_vec($create_entries.clone()); let ce = CreateEvent::from_vec($create_entries.clone());
@ -292,7 +300,6 @@ mod tests {
); );
} }
// check create where provided uuid is valid. It should be unchanged. // check create where provided uuid is valid. It should be unchanged.
#[test] #[test]
fn test_pre_create_uuid_valid() { fn test_pre_create_uuid_valid() {

View file

@ -73,6 +73,16 @@ impl QueryServer {
au: &mut AuditScope, au: &mut AuditScope,
se: &SearchEvent, se: &SearchEvent,
) -> Result<Vec<Entry>, OperationError> { ) -> Result<Vec<Entry>, OperationError> {
// TODO: Validate the filter
// This is an important security step because it prevents us from
// performing un-indexed searches on attr's that don't exist in the
// server. This is why ExtensibleObject can only take schema that
// exists in the server, not arbitrary attr names.
// TODO: Normalise the filter
// TODO: Pre-search plugins
let mut audit_be = AuditScope::new("backend_search"); let mut audit_be = AuditScope::new("backend_search");
let res = self let res = self
.be .be
@ -81,7 +91,11 @@ impl QueryServer {
.map_err(|_| OperationError::Backend); .map_err(|_| OperationError::Backend);
au.append_scope(audit_be); au.append_scope(audit_be);
// TODO: We'll add ACI later // TODO: Post-search plugins
// TODO: We'll add ACI here. I think ACI should transform from
// internal -> proto entries since we have to anyway ...
// alternately, we can just clone again ...
res res
} }
@ -96,9 +110,7 @@ impl QueryServer {
// based on request size in the frontend? // based on request size in the frontend?
// Copy the entries to a writeable form. // Copy the entries to a writeable form.
let mut candidates: Vec<Entry> = ce.entries.iter() let mut candidates: Vec<Entry> = ce.entries.iter().map(|er| er.clone()).collect();
.map(|er| er.clone())
.collect();
// Start a txn // Start a txn
@ -107,7 +119,13 @@ impl QueryServer {
// I have no intent to make these dynamic or configurable. // I have no intent to make these dynamic or configurable.
let mut audit_plugin_pre = AuditScope::new("plugin_pre_create"); let mut audit_plugin_pre = AuditScope::new("plugin_pre_create");
let plug_pre_res = Plugins::run_pre_create(&mut self.be, &mut audit_plugin_pre, &mut candidates, ce, &self.schema); let plug_pre_res = Plugins::run_pre_create(
&mut self.be,
&mut audit_plugin_pre,
&mut candidates,
ce,
&self.schema,
);
au.append_scope(audit_plugin_pre); au.append_scope(audit_plugin_pre);
if plug_pre_res.is_err() { if plug_pre_res.is_err() {