cargo fmt

This commit is contained in:
William Brown 2019-01-29 17:17:28 +10:00
parent 66e087787a
commit 63e600d49e
9 changed files with 252 additions and 213 deletions

View file

@ -8,7 +8,7 @@ use serde_json;
// use uuid;
use audit::AuditScope;
use entry::{Entry, EntryValid, EntryNew, EntryCommitted};
use entry::{Entry, EntryCommitted, EntryNew, EntryValid};
use filter::Filter;
mod idl;
@ -53,7 +53,11 @@ pub trait BackendReadTransaction {
fn get_conn(&self) -> &r2d2::PooledConnection<r2d2_sqlite::SqliteConnectionManager>;
// Take filter, and AuditScope ref?
fn search(&self, au: &mut AuditScope, filt: &Filter) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, BackendError> {
fn search(
&self,
au: &mut AuditScope,
filt: &Filter,
) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, BackendError> {
// Do things
// Alloc a vec for the entries.
// FIXME: Make this actually a good size for the result set ...
@ -97,7 +101,8 @@ pub trait BackendReadTransaction {
.iter()
.filter_map(|id_ent| {
// TODO: Should we do better than unwrap?
let mut e: Entry<EntryValid, EntryCommitted> = serde_json::from_str(id_ent.data.as_str()).unwrap();
let mut e: Entry<EntryValid, EntryCommitted> =
serde_json::from_str(id_ent.data.as_str()).unwrap();
e.id = Some(id_ent.id);
if e.entry_match_no_index(&filt) {
Some(e)
@ -206,10 +211,14 @@ impl BackendWriteTransaction {
}
fn get_id2entry_max_id(&self) -> i64 {
let mut stmt = self.conn.prepare("SELECT MAX(id) as id_max FROM id2entry").unwrap();
let mut stmt = self
.conn
.prepare("SELECT MAX(id) as id_max FROM id2entry")
.unwrap();
assert!(stmt.exists(NO_PARAMS).unwrap());
let i: Option<i64> = stmt.query_row(NO_PARAMS, |row| row.get(0))
let i: Option<i64> = stmt
.query_row(NO_PARAMS, |row| row.get(0))
.expect("failed to execute");
match i {
Some(e) => e,
@ -217,7 +226,11 @@ impl BackendWriteTransaction {
}
}
pub fn create(&self, au: &mut AuditScope, entries: &Vec<Entry<EntryValid, EntryNew>>) -> Result<(), BackendError> {
pub fn create(
&self,
au: &mut AuditScope,
entries: &Vec<Entry<EntryValid, EntryNew>>,
) -> Result<(), BackendError> {
audit_segment!(au, || {
// Start be audit timer
@ -273,7 +286,11 @@ impl BackendWriteTransaction {
})
}
pub fn modify(&self, au: &mut AuditScope, entries: &Vec<Entry<EntryValid, EntryCommitted>>) -> Result<(), BackendError> {
pub fn modify(
&self,
au: &mut AuditScope,
entries: &Vec<Entry<EntryValid, EntryCommitted>>,
) -> Result<(), BackendError> {
if entries.is_empty() {
// TODO: Better error
return Err(BackendError::EmptyRequest);
@ -291,7 +308,7 @@ impl BackendWriteTransaction {
data: serde_json::to_string(&e).unwrap(),
})
}
None => None
None => None,
}
})
.collect();
@ -307,20 +324,25 @@ impl BackendWriteTransaction {
// Now, given the list of id's, update them
{
// TODO: ACTUALLY HANDLE THIS ERROR WILLIAM YOU LAZY SHIT.
let mut stmt = self.conn.prepare("UPDATE id2entry SET data = :data WHERE id = :id").unwrap();
let mut stmt = self
.conn
.prepare("UPDATE id2entry SET data = :data WHERE id = :id")
.unwrap();
ser_entries.iter().for_each(|ser_ent| {
stmt.execute_named(&[
(":id", &ser_ent.id),
(":data", &ser_ent.data),
]).unwrap();
stmt.execute_named(&[(":id", &ser_ent.id), (":data", &ser_ent.data)])
.unwrap();
});
}
Ok(())
}
pub fn delete(&self, au: &mut AuditScope, entries: &Vec<Entry<EntryValid, EntryCommitted>>) -> Result<(), BackendError> {
pub fn delete(
&self,
au: &mut AuditScope,
entries: &Vec<Entry<EntryValid, EntryCommitted>>,
) -> Result<(), BackendError> {
// Perform a search for the entries --> This is a problem for the caller
if entries.is_empty() {
@ -329,11 +351,7 @@ impl BackendWriteTransaction {
}
// Assert the Id's exist on the entry.
let id_list: Vec<i64> = entries.iter()
.filter_map(|entry| {
entry.id
})
.collect();
let id_list: Vec<i64> = entries.iter().filter_map(|entry| entry.id).collect();
// Simple: If the list of id's is not the same as the input list, we are missing id's
// TODO: This check won't be needed once I rebuild the entry state types.
@ -348,7 +366,10 @@ impl BackendWriteTransaction {
// probably okay with this.
// TODO: ACTUALLY HANDLE THIS ERROR WILLIAM YOU LAZY SHIT.
let mut stmt = self.conn.prepare("DELETE FROM id2entry WHERE id = :id").unwrap();
let mut stmt = self
.conn
.prepare("DELETE FROM id2entry WHERE id = :id")
.unwrap();
id_list.iter().for_each(|id| {
stmt.execute(&[id]).unwrap();
@ -532,7 +553,7 @@ mod tests {
extern crate tokio;
use super::super::audit::AuditScope;
use super::super::entry::{Entry, EntryInvalid, EntryValid, EntryNew, EntryCommitted};
use super::super::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use super::super::filter::Filter;
use super::{
Backend, BackendError, BackendReadTransaction, BackendTransaction, BackendWriteTransaction,
@ -560,7 +581,7 @@ mod tests {
let filt = ei.filter_from_attrs(&vec![String::from("userid")]).unwrap();
let entries = $be.search($audit, &filt).unwrap();
entries.first().is_some()
}}
}};
}
macro_rules! entry_attr_pres {
@ -569,12 +590,10 @@ mod tests {
let filt = ei.filter_from_attrs(&vec![String::from("userid")]).unwrap();
let entries = $be.search($audit, &filt).unwrap();
match entries.first() {
Some(ent) => {
ent.attribute_pres($attr)
Some(ent) => ent.attribute_pres($attr),
None => false,
}
None => false
}
}}
}};
}
#[test]
@ -625,7 +644,9 @@ mod tests {
assert!(entry_exists!(audit, be, e2));
// You need to now retrieve the entries back out to get the entry id's
let mut results = be.search(audit, &Filter::Pres(String::from("userid"))).unwrap();
let mut results = be
.search(audit, &Filter::Pres(String::from("userid")))
.unwrap();
// Get these out to usable entries.
let r1 = results.remove(0);
@ -689,9 +710,10 @@ mod tests {
assert!(entry_exists!(audit, be, e2));
assert!(entry_exists!(audit, be, e3));
// You need to now retrieve the entries back out to get the entry id's
let mut results = be.search(audit, &Filter::Pres(String::from("userid"))).unwrap();
let mut results = be
.search(audit, &Filter::Pres(String::from("userid")))
.unwrap();
// Get these out to usable entries.
let r1 = results.remove(0);
@ -727,7 +749,6 @@ mod tests {
// delete none (no entries left)
// see fn delete for why this is ok, not err
assert!(be.delete(audit, &vec![r2.clone(), r3.clone()]).is_ok());
});
}
}

View file

@ -1,14 +1,14 @@
// use serde_json::{Error, Value};
use super::proto_v1::Entry as ProtoEntry;
use error::SchemaError;
use filter::Filter;
use modify::{Modify, ModifyList};
use schema::{SchemaAttribute, SchemaClass, SchemaReadTransaction};
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
use std::collections::BTreeMap;
use std::collections::HashMap;
use std::slice::Iter as SliceIter;
use modify::{Modify, ModifyList};
use schema::{SchemaReadTransaction, SchemaAttribute, SchemaClass};
use error::SchemaError;
use std::iter::ExactSizeIterator;
use std::slice::Iter as SliceIter;
// make a trait entry for everything to adhere to?
// * How to get indexs out?
@ -175,10 +175,18 @@ impl Entry<EntryInvalid, EntryNew> {
}
impl<STATE> Entry<EntryInvalid, STATE> {
pub fn validate(self, schema: &SchemaReadTransaction) -> Result<Entry<EntryValid, STATE>, SchemaError> {
pub fn validate(
self,
schema: &SchemaReadTransaction,
) -> Result<Entry<EntryValid, STATE>, SchemaError> {
// We need to clone before we start, as well be mutating content.
// We destructure:
let Entry { valid, state, id, attrs } = self;
let Entry {
valid,
state,
id,
attrs,
} = self;
let schema_classes = schema.get_classes();
let schema_attributes = schema.get_attributes();
@ -232,20 +240,16 @@ impl<STATE> Entry<EntryInvalid, STATE> {
{
// First, check we have class on the object ....
if !ne.attribute_pres("class") {
return Err(SchemaError::InvalidClass)
return Err(SchemaError::InvalidClass);
}
let entry_classes = ne.classes();
let entry_classes_size = entry_classes.len();
let classes: HashMap<String, &SchemaClass> = entry_classes
.filter_map(|c| {
match schema_classes.get(c) {
Some(cls) => {
Some((c.clone(), cls))
}
.filter_map(|c| match schema_classes.get(c) {
Some(cls) => Some((c.clone(), cls)),
None => None,
}
})
.collect();
@ -253,7 +257,6 @@ impl<STATE> Entry<EntryInvalid, STATE> {
return Err(SchemaError::InvalidClass);
};
let extensible = classes.contains_key("extensibleobject");
// What this is really doing is taking a set of classes, and building an
@ -287,9 +290,7 @@ impl<STATE> Entry<EntryInvalid, STATE> {
for (attr_name, _attr) in must {
let avas = ne.get_ava(&attr_name);
if avas.is_none() {
return Err(SchemaError::MissingMustAttribute(
String::from(attr_name)
));
return Err(SchemaError::MissingMustAttribute(String::from(attr_name)));
}
}
@ -304,7 +305,7 @@ impl<STATE> Entry<EntryInvalid, STATE> {
// We have to destructure here to make type checker happy
match r {
Ok(_) => {}
Err(e) => return Err(e)
Err(e) => return Err(e),
}
}
None => {
@ -322,7 +323,8 @@ impl<STATE> Entry<EntryInvalid, STATE> {
}
impl<VALID, STATE> Clone for Entry<VALID, STATE>
where VALID: Copy,
where
VALID: Copy,
STATE: Copy,
{
// Dirty modifiable state. Works on any other state to dirty them.
@ -381,7 +383,7 @@ impl<STATE> Entry<EntryValid, STATE> {
valid: EntryInvalid,
state: self.state,
id: self.id,
attrs: self.attrs
attrs: self.attrs,
}
}
@ -390,7 +392,7 @@ impl<STATE> Entry<EntryValid, STATE> {
valid: self.valid,
state: EntryCommitted,
id: self.id,
attrs: self.attrs
attrs: self.attrs,
}
}
@ -400,34 +402,28 @@ impl<STATE> Entry<EntryValid, STATE> {
// This is recursive!!!!
match filter {
Filter::Eq(attr, value) => self.attribute_equality(attr.as_str(), value.as_str()),
Filter::Sub(attr, subvalue) => self.attribute_substring(attr.as_str(), subvalue.as_str()),
Filter::Sub(attr, subvalue) => {
self.attribute_substring(attr.as_str(), subvalue.as_str())
}
Filter::Pres(attr) => {
// Given attr, is is present in the entry?
self.attribute_pres(attr.as_str())
}
Filter::Or(l) => {
l.iter()
.fold(false, |acc, f| {
Filter::Or(l) => l.iter().fold(false, |acc, f| {
if acc {
acc
} else {
self.entry_match_no_index(f)
}
})
}
Filter::And(l) => {
l.iter()
.fold(true, |acc, f| {
}),
Filter::And(l) => l.iter().fold(true, |acc, f| {
if acc {
self.entry_match_no_index(f)
} else {
acc
}
})
}
Filter::Not(f) => {
!self.entry_match_no_index(f)
}
}),
Filter::Not(f) => !self.entry_match_no_index(f),
}
}
@ -473,8 +469,7 @@ impl<STATE> Entry<EntryValid, STATE> {
}
}
pub fn gen_modlist_assert(&self, schema: &SchemaReadTransaction) -> Result<ModifyList, ()>
{
pub fn gen_modlist_assert(&self, schema: &SchemaReadTransaction) -> Result<ModifyList, ()> {
// Create a modlist from this entry. We make this assuming we want the entry
// to have this one as a subset of values. This means if we have single
// values, we'll replace, if they are multivalue, we present them.
@ -490,9 +485,7 @@ impl<STATE> Entry<EntryValid, STATE> {
mods.push_mod(Modify::Purged(k.clone()));
}
}
Err(e) => {
return Err(())
}
Err(e) => return Err(()),
}
for v in vs {
mods.push_mod(Modify::Present(k.clone(), v.clone()));
@ -535,7 +528,11 @@ impl<VALID, STATE> Entry<VALID, STATE> {
// Get the class vec, if any?
// How do we indicate "empty?"
// FIXME: Actually handle this error ...
let v = self.attrs.get("class").map(|c| c.len()).expect("INVALID STATE, NO CLASS FOUND");
let v = self
.attrs
.get("class")
.map(|c| c.len())
.expect("INVALID STATE, NO CLASS FOUND");
let c = self.attrs.get("class").map(|c| c.iter());
EntryClasses { size: v, inner: c }
}
@ -548,7 +545,8 @@ impl<VALID, STATE> Entry<VALID, STATE> {
}
impl<STATE> Entry<EntryInvalid, STATE>
where STATE: Copy,
where
STATE: Copy,
{
// This should always work? It's only on validate that we'll build
// a list of syntax violations ...
@ -589,8 +587,7 @@ impl<STATE> Entry<EntryInvalid, STATE>
v.remove(idx);
}
// It does not exist, move on.
Err(_) => {
}
Err(_) => {}
}
});
}
@ -618,8 +615,7 @@ impl<STATE> Entry<EntryInvalid, STATE>
// This is effectively clone-and-transform
// clone the entry
let mut ne: Entry<EntryInvalid, STATE> =
Entry {
let mut ne: Entry<EntryInvalid, STATE> = Entry {
valid: self.valid,
state: self.state,
id: self.id,
@ -629,15 +625,9 @@ impl<STATE> Entry<EntryInvalid, STATE>
// mutate
for modify in modlist.mods.iter() {
match modify {
Modify::Present(a, v) => {
ne.add_ava(a.clone(), v.clone())
}
Modify::Removed(a, v) => {
ne.remove_ava(a, v)
}
Modify::Purged(a) => {
ne.purge_ava(a)
}
Modify::Present(a, v) => ne.add_ava(a.clone(), v.clone()),
Modify::Removed(a, v) => ne.remove_ava(a, v),
Modify::Purged(a) => ne.purge_ava(a),
}
}
@ -745,16 +735,16 @@ mod tests {
let mut e: Entry<EntryInvalid, EntryNew> = Entry::new();
e.add_ava(String::from("userid"), String::from("william"));
let mods = ModifyList::new_list(vec![
Modify::Present(String::from("attr"), String::from("value")),
]);
let mods = ModifyList::new_list(vec![Modify::Present(
String::from("attr"),
String::from("value"),
)]);
let ne = e.apply_modlist(&mods).unwrap();
// Assert the changes are there
assert!(ne.attribute_equality("attr", "value"));
// Assert present for multivalue
// Assert purge on single/multi/empty value
// Assert removed on value that exists and doesn't exist

View file

@ -2,7 +2,7 @@ use super::filter::Filter;
use super::proto_v1::Entry as ProtoEntry;
use super::proto_v1::{CreateRequest, Response, SearchRequest, SearchResponse};
use actix::prelude::*;
use entry::{Entry, EntryInvalid, EntryNew, EntryValid, EntryCommitted};
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use error::OperationError;
use modify::ModifyList;
@ -185,4 +185,3 @@ impl ModifyEvent {
}
}
}

View file

@ -2,8 +2,8 @@
// in parallel map/reduce style, or directly on a single
// entry to assert it matches.
use std::cmp::{Ordering, PartialOrd};
use regex::Regex;
use std::cmp::{Ordering, PartialOrd};
// Perhaps make these json serialisable. Certainly would make parsing
// simpler ...
@ -102,7 +102,7 @@ impl PartialOrd for Filter {
#[cfg(test)]
mod tests {
use super::Filter;
use entry::{Entry, EntryValid, EntryNew};
use entry::{Entry, EntryNew, EntryValid};
use serde_json;
use std::cmp::{Ordering, PartialOrd};
@ -199,14 +199,17 @@ mod tests {
#[test]
fn test_or_entry_filter() {
let e: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"userid": ["william"],
"uidNumber": ["1000"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let f_t1a = Filter::Or(vec![
Filter::Eq(String::from("userid"), String::from("william")),
@ -235,14 +238,17 @@ mod tests {
#[test]
fn test_and_entry_filter() {
let e: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"userid": ["william"],
"uidNumber": ["1000"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let f_t1a = Filter::And(vec![
Filter::Eq(String::from("userid"), String::from("william")),
@ -271,64 +277,80 @@ mod tests {
#[test]
fn test_not_entry_filter() {
let e1: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e1: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"userid": ["william"],
"uidNumber": ["1000"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let f_t1a = Filter::Not(Box::new(
Filter::Eq(String::from("userid"), String::from("alice")),
));
let f_t1a = Filter::Not(Box::new(Filter::Eq(
String::from("userid"),
String::from("alice"),
)));
assert!(e1.entry_match_no_index(&f_t1a));
let f_t2a = Filter::Not(Box::new(
Filter::Eq(String::from("userid"), String::from("william")),
));
let f_t2a = Filter::Not(Box::new(Filter::Eq(
String::from("userid"),
String::from("william"),
)));
assert!(!e1.entry_match_no_index(&f_t2a));
}
#[test]
fn test_nested_entry_filter() {
let e1: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e1: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"class": ["person"],
"uidNumber": ["1000"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let e2: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e2: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"class": ["person"],
"uidNumber": ["1001"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let e3: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e3: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"class": ["person"],
"uidNumber": ["1002"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let e4: Entry<EntryValid, EntryNew> = serde_json::from_str(r#"{
let e4: Entry<EntryValid, EntryNew> = serde_json::from_str(
r#"{
"valid": null,
"state": null,
"attrs": {
"class": ["group"],
"uidNumber": ["1000"]
}
}"#).unwrap();
}"#,
)
.unwrap();
let f_t1a = Filter::And(vec![
Filter::Eq(String::from("class"), String::from("person")),

View file

@ -39,10 +39,10 @@ mod constants;
mod entry;
mod event;
mod identity;
mod modify;
mod plugins;
mod schema;
mod server;
mod modify;
pub mod config;
pub mod core;

View file

@ -133,7 +133,7 @@ mod tests {
use audit::AuditScope;
use be::{Backend, BackendWriteTransaction};
use entry::{Entry, EntryValid, EntryInvalid, EntryNew};
use entry::{Entry, EntryInvalid, EntryNew, EntryValid};
use event::CreateEvent;
use schema::{Schema, SchemaWriteTransaction};

View file

@ -75,3 +75,23 @@ impl CreateRequest {
//
// On loginSuccess, we send a cookie, and that allows the token to be
// generated. The cookie can be shared between servers.
// Request auth for identity X
pub struct AuthRequest {}
// Respond with the list of auth types and nonce, etc.
pub struct AuthResponse {}
// Provide responses
pub struct AuthProvide {}
// After authprovide, we can move to AuthResponse (for more)
// or below ...
// Go away.
// Provide reason?
pub struct AuthDenied {}
// Welcome friend.
// On success provide entry "self", for group assertions?
pub struct AuthSuccess {}

View file

@ -5,11 +5,11 @@ use super::error::SchemaError;
use super::filter::Filter;
use std::collections::HashMap;
// Apparently this is nightly only?
use modify::ModifyList;
use regex::Regex;
use std::convert::TryFrom;
use std::str::FromStr;
use uuid::Uuid;
use modify::ModifyList;
use concread::cowcell::{CowCell, CowCellReadTxn, CowCellWriteTxn};
@ -917,9 +917,7 @@ impl SchemaInner {
}
})
}
Filter::Not(filter) => {
self.validate_filter(filter)
}
Filter::Not(filter) => self.validate_filter(filter),
}
}
@ -932,9 +930,7 @@ impl SchemaInner {
fn is_multivalue(&self, attr_name: &str) -> Result<bool, SchemaError> {
match self.attributes.get(attr_name) {
Some(a_schema) => {
Ok(a_schema.multivalue)
}
Some(a_schema) => Ok(a_schema.multivalue),
None => {
return Err(SchemaError::InvalidAttribute);
}
@ -1009,7 +1005,7 @@ impl Schema {
mod tests {
use super::super::audit::AuditScope;
use super::super::constants::*;
use super::super::entry::{Entry, EntryValid, EntryInvalid, EntryNew};
use super::super::entry::{Entry, EntryInvalid, EntryNew, EntryValid};
use super::super::error::SchemaError;
use super::super::filter::Filter;
use super::{IndexType, Schema, SchemaAttribute, SchemaClass, SyntaxType};
@ -1238,10 +1234,7 @@ mod tests {
)
.unwrap();
assert_eq!(
e_no_class.validate(&schema),
Err(SchemaError::InvalidClass)
);
assert_eq!(e_no_class.validate(&schema), Err(SchemaError::InvalidClass));
let e_bad_class: Entry<EntryInvalid, EntryNew> = serde_json::from_str(
r#"{

View file

@ -10,15 +10,16 @@ use be::{
};
use constants::{JSON_ANONYMOUS_V1, JSON_SYSTEM_INFO_V1};
use entry::{Entry, EntryNew, EntryCommitted, EntryValid, EntryInvalid};
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use error::{OperationError, SchemaError};
use event::{CreateEvent, ExistsEvent, OpResult, SearchEvent, SearchResult, DeleteEvent, ModifyEvent};
use event::{
CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, OpResult, SearchEvent, SearchResult,
};
use filter::Filter;
use log::EventLog;
use plugins::Plugins;
use schema::{Schema, SchemaTransaction, SchemaReadTransaction, SchemaWriteTransaction};
use modify::ModifyList;
use plugins::Plugins;
use schema::{Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction};
pub fn start(log: actix::Addr<EventLog>, path: &str, threads: usize) -> actix::Addr<QueryServer> {
let mut audit = AuditScope::new("server_start");
@ -89,7 +90,11 @@ pub trait QueryServerReadTransaction {
fn get_be_txn(&self) -> &Self::BackendTransactionType;
fn search(&self, au: &mut AuditScope, se: &SearchEvent) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, OperationError> {
fn search(
&self,
au: &mut AuditScope,
se: &SearchEvent,
) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, 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
@ -141,8 +146,11 @@ pub trait QueryServerReadTransaction {
res
}
fn internal_search(&self, audit: &mut AuditScope, filter: Filter) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, OperationError> {
fn internal_search(
&self,
audit: &mut AuditScope,
filter: Filter,
) -> Result<Vec<Entry<EntryValid, EntryCommitted>>, OperationError> {
let mut audit_int = AuditScope::new("internal_search");
let se = SearchEvent::new_internal(filter);
let res = self.search(&mut audit_int, &se);
@ -240,7 +248,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
// based on request size in the frontend?
// Copy the entries to a writeable form.
let mut candidates: Vec<Entry<EntryInvalid, EntryNew>> = ce.entries.iter().map(|er| er.clone()).collect();
let mut candidates: Vec<Entry<EntryInvalid, EntryNew>> =
ce.entries.iter().map(|er| er.clone()).collect();
// run any pre plugins, giving them the list of mutable candidates.
// pre-plugins are defined here in their correct order of calling!
@ -261,15 +270,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
return plug_pre_res;
}
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()
});
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);
@ -279,14 +286,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
return Err(OperationError::SchemaViolation);
}
let norm_cand: Vec<Entry<EntryValid, EntryNew>> = norm_cand.into_iter()
.map(|e| {
match e {
let norm_cand: Vec<Entry<EntryValid, EntryNew>> = norm_cand
.into_iter()
.map(|e| match e {
Ok(v) => v,
Err(_) => {
panic!("Invalid data set state!!!")
}
}
Err(_) => panic!("Invalid data set state!!!"),
})
.collect();
@ -319,7 +323,6 @@ impl<'a> QueryServerWriteTransaction<'a> {
res
}
pub fn delete(&self, au: &mut AuditScope, ce: &DeleteEvent) -> Result<(), OperationError> {
unimplemented!()
}
@ -340,19 +343,17 @@ impl<'a> QueryServerWriteTransaction<'a> {
};
if pre_candidates.len() == 0 {
return Err(OperationError::NoMatchingEntries)
return Err(OperationError::NoMatchingEntries);
};
// Clone a set of writeables.
// Apply the modlist -> Remember, we have a set of origs
// and the new modified ents.
let mut candidates: Vec<Entry<EntryInvalid, EntryCommitted>> = pre_candidates.into_iter()
let mut candidates: Vec<Entry<EntryInvalid, EntryCommitted>> = pre_candidates
.into_iter()
.map(|er| {
// TODO: Deal with this properly william
er
.invalidate()
.apply_modlist(&me.modlist)
.unwrap()
er.invalidate().apply_modlist(&me.modlist).unwrap()
})
.collect();
@ -364,15 +365,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
// FIXME: This normalisation COPIES everything, which may be
// slow.
let (norm_cand, invalid_cand):
(Vec<Result<Entry<EntryValid, EntryCommitted>, _>>,
Vec<Result<_, SchemaError>>) = candidates.into_iter()
.map(|e| {
e.validate(&self.schema)
})
.partition(|e| {
e.is_ok()
});
let (norm_cand, invalid_cand): (
Vec<Result<Entry<EntryValid, EntryCommitted>, _>>,
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);
@ -382,14 +381,11 @@ impl<'a> QueryServerWriteTransaction<'a> {
return Err(OperationError::SchemaViolation);
}
let norm_cand: Vec<Entry<EntryValid, EntryCommitted>> = norm_cand.into_iter()
.map(|e| {
match e {
let norm_cand: Vec<Entry<EntryValid, EntryCommitted>> = norm_cand
.into_iter()
.map(|e| match e {
Ok(v) => v,
Err(_) => {
panic!("Invalid data set state!!!")
}
}
Err(_) => panic!("Invalid data set state!!!"),
})
.collect();
@ -442,7 +438,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
pub fn internal_delete(
&self,
audit: &mut AuditScope,
filter: Filter
filter: Filter,
) -> Result<(), OperationError> {
let mut audit_int = AuditScope::new("internal_delete");
let de = DeleteEvent::new_internal(filter);
@ -455,7 +451,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
&self,
audit: &mut AuditScope,
filter: Filter,
modlist: ModifyList
modlist: ModifyList,
) -> Result<(), OperationError> {
let mut audit_int = AuditScope::new("internal_modify");
let me = ModifyEvent::new_internal(filter, modlist);
@ -470,7 +466,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
// and markers. They act as though they have the highest level privilege
// IE there are no access control checks.
pub fn internal_exists_or_create(&self, e: Entry<EntryValid, EntryNew>) -> Result<(), OperationError> {
pub fn internal_exists_or_create(
&self,
e: Entry<EntryValid, EntryNew>,
) -> Result<(), OperationError> {
// If the thing exists, stop.
// if not, create from Entry.
unimplemented!()
@ -549,9 +548,6 @@ impl<'a> QueryServerWriteTransaction<'a> {
self.internal_create(audit, vec![e.invalidate()])
} else if results.len() == 1 {
// it exists. To guarantee content exactly as is, we compare if it's identical.
audit_log!(audit, "LEFT -> {:?}", &e);
audit_log!(audit, "RIGHT -> {:?}", &results[0]);
if !e.compare(&results[0]) {
self.internal_delete(audit, filt);
self.internal_create(audit, vec![e.invalidate()]);
@ -715,7 +711,7 @@ mod tests {
use super::super::audit::AuditScope;
use super::super::be::{Backend, BackendTransaction};
use super::super::entry::{Entry, EntryNew, EntryCommitted, EntryValid, EntryInvalid};
use super::super::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use super::super::event::{CreateEvent, SearchEvent};
use super::super::filter::Filter;
use super::super::log;
@ -791,9 +787,7 @@ mod tests {
println!("--> {:?}", r2);
assert!(r2.len() == 1);
let expected = unsafe {
vec![e.to_valid_committed()]
};
let expected = unsafe { vec![e.to_valid_committed()] };
assert_eq!(r2, expected);