Update to rust 2018 and improve some todo notes

This commit is contained in:
William Brown 2019-04-18 11:28:33 +10:00
parent af9ac8f662
commit 4ab377ec88
21 changed files with 387 additions and 328 deletions

View file

@ -5,8 +5,7 @@ name = "rsidm"
version = "0.1.0"
authors = ["William Brown <william@blackhats.net.au>"]
default-run = "rsidm_core"
#
# edition = "2018"
edition = "2018"
# We need three major binaries. The server itself, the unix client, and a cli

View file

@ -62,6 +62,24 @@ macro_rules! try_audit {
}
}
};
($audit:ident, $result:expr, $logFormat:expr) => {
match $result {
Ok(v) => v,
Err(e) => {
audit_log!($audit, $logFormat, e);
return Err(e);
}
}
};
($audit:ident, $result:expr) => {
match $result {
Ok(v) => v,
Err(e) => {
audit_log!($audit, "error -> {:?}", e);
return Err(e);
}
}
};
}
#[derive(Serialize, Deserialize)]
@ -143,7 +161,7 @@ impl AuditScope {
#[cfg(test)]
mod tests {
use super::AuditScope;
use crate::audit::AuditScope;
// Create and remove. Perhaps add some core details?
#[test]

View file

@ -7,10 +7,10 @@ use rusqlite::NO_PARAMS;
use serde_json;
// use uuid;
use audit::AuditScope;
use entry::{Entry, EntryCommitted, EntryNew, EntryValid};
use error::{ConsistencyError, OperationError};
use filter::{Filter, FilterValid};
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryNew, EntryValid};
use crate::error::{ConsistencyError, OperationError};
use crate::filter::{Filter, FilterValid};
mod idl;
mod mem_be;

View file

@ -5,6 +5,7 @@ pub struct Configuration {
pub db_path: String,
pub maximum_request: usize,
// db type later
pub secure_cookies: bool,
}
impl Configuration {
@ -14,8 +15,9 @@ impl Configuration {
threads: 8,
db_path: String::from(""),
maximum_request: 262144, // 256k
// log type
// log path
// log type
// log path
secure_cookies: true,
}
}
}

View file

@ -1,8 +1,8 @@
pub static PURGE_TIMEOUT: u64 = 3600;
pub static UUID_ADMIN: &'static str = "00000000-0000-0000-0000-000000000000";
pub static _UUID_ADMIN: &'static str = "00000000-0000-0000-0000-000000000000";
pub static UUID_ANONYMOUS: &'static str = "00000000-0000-0000-0000-ffffffffffff";
pub static _UUID_ANONYMOUS: &'static str = "00000000-0000-0000-0000-ffffffffffff";
pub static JSON_ANONYMOUS_V1: &'static str = r#"{
"valid": null,
"state": null,
@ -16,7 +16,7 @@ pub static JSON_ANONYMOUS_V1: &'static str = r#"{
}
}"#;
pub static UUID_SYSTEM_INFO: &'static str = "00000000-0000-0000-0000-ffffff000001";
pub static _UUID_SYSTEM_INFO: &'static str = "00000000-0000-0000-0000-ffffff000001";
pub static JSON_SYSTEM_INFO_V1: &'static str = r#"{
"valid": null,
"state": null,

View file

@ -8,13 +8,13 @@ use actix_web::{
use bytes::BytesMut;
use futures::{future, Future, Stream};
use super::config::Configuration;
use crate::config::Configuration;
// SearchResult
use super::interval::IntervalActor;
use super::log;
use super::proto_v1::{AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest};
use super::proto_v1_actors::QueryServerV1;
use crate::interval::IntervalActor;
use crate::log;
use crate::proto_v1::{AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest};
use crate::proto_v1_actors::QueryServerV1;
struct AppState {
qe: actix::Addr<QueryServerV1>,
@ -205,10 +205,12 @@ pub fn create_server_core(config: Configuration) {
let server_addr =
match QueryServerV1::start(log_addr.clone(), config.db_path.as_str(), config.threads) {
Ok(addr) => addr,
Err(_e) => {
// Oh shiiiiiiii
// TODO: Handle this properly.
unimplemented!()
Err(e) => {
println!(
"An unknown failure in startup has occured - exiting -> {:?}",
e
);
return;
}
};
@ -217,6 +219,7 @@ pub fn create_server_core(config: Configuration) {
// Copy the max size
let max_size = config.maximum_request;
let secure_cookies = config.secure_cookies;
// start the web server
actix_web::server::new(move || {
@ -238,8 +241,7 @@ pub fn create_server_core(config: Configuration) {
.http_only(true)
.name("rsidm-session")
// This forces https only
// TODO: Make this a config value
.secure(false),
.secure(secure_cookies),
))
// .resource("/", |r| r.f(index))
// curl --header ...?

View file

@ -1,11 +1,11 @@
// use serde_json::{Error, Value};
use super::proto_v1::Entry as ProtoEntry;
use audit::AuditScope;
use error::{OperationError, SchemaError};
use filter::{Filter, FilterValid};
use modify::{Modify, ModifyInvalid, ModifyList, ModifyValid};
use schema::{SchemaAttribute, SchemaClass, SchemaReadTransaction};
use server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::audit::AuditScope;
use crate::error::{OperationError, SchemaError};
use crate::filter::{Filter, FilterValid};
use crate::modify::{Modify, ModifyInvalid, ModifyList, ModifyValid};
use crate::proto_v1::Entry as ProtoEntry;
use crate::schema::{SchemaAttribute, SchemaClass, SchemaReadTransaction};
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
use std::collections::BTreeMap;
use std::collections::HashMap;
@ -478,7 +478,7 @@ impl<STATE> Entry<EntryValid, STATE> {
}
}),
Filter::AndNot(f) => !self.entry_match_no_index(f),
Filter::invalid(_) => {
Filter::Invalid(_) => {
// TODO: Is there a better way to not need to match the phantom?
unimplemented!()
}
@ -746,8 +746,8 @@ struct User {
#[cfg(test)]
mod tests {
use super::{Entry, EntryInvalid, EntryNew};
use modify::{Modify, ModifyList};
use crate::entry::{Entry, EntryInvalid, EntryNew};
use crate::modify::{Modify, ModifyList};
use serde_json;
#[test]

View file

@ -1,15 +1,19 @@
use super::filter::{Filter, FilterInvalid};
use super::proto_v1::Entry as ProtoEntry;
use super::proto_v1::{
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use crate::filter::{Filter, FilterInvalid};
use crate::proto_v1::Entry as ProtoEntry;
use crate::proto_v1::{
AuthRequest, AuthResponse, AuthStatus, CreateRequest, DeleteRequest, ModifyRequest,
OperationResponse, ReviveRecycledRequest, SearchRecycledRequest, SearchRequest, SearchResponse,
OperationResponse, ReviveRecycledRequest, SearchRequest, SearchResponse,
};
use audit::AuditScope;
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
// use error::OperationError;
use error::OperationError;
use modify::{ModifyInvalid, ModifyList};
use server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::error::OperationError;
use crate::modify::{ModifyInvalid, ModifyList};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
// Only used for internal tests
#[cfg(test)]
use crate::proto_v1::SearchRecycledRequest;
use actix::prelude::*;
@ -89,6 +93,7 @@ impl SearchEvent {
}
}
#[cfg(test)]
pub fn from_rec_request(
audit: &mut AuditScope,
request: SearchRecycledRequest,
@ -103,6 +108,7 @@ impl SearchEvent {
}
}
#[cfg(test)]
pub fn new_rec_impersonate(filter: Filter<FilterInvalid>) -> Self {
SearchEvent {
internal: false,
@ -110,6 +116,7 @@ impl SearchEvent {
}
}
#[cfg(test)]
/* Impersonate an external request */
pub fn new_ext_impersonate(filter: Filter<FilterInvalid>) -> Self {
SearchEvent {

View file

@ -2,13 +2,12 @@
// in parallel map/reduce style, or directly on a single
// entry to assert it matches.
use audit::AuditScope;
use be::BackendReadTransaction;
use error::{OperationError, SchemaError};
use proto_v1::Filter as ProtoFilter;
use schema::SchemaReadTransaction;
use server::{
QueryServer, QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
use crate::audit::AuditScope;
use crate::error::{OperationError, SchemaError};
use crate::proto_v1::Filter as ProtoFilter;
use crate::schema::SchemaReadTransaction;
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use std::cmp::{Ordering, PartialOrd};
use std::marker::PhantomData;
@ -30,7 +29,7 @@ pub enum Filter<VALID> {
Or(Vec<Filter<VALID>>),
And(Vec<Filter<VALID>>),
AndNot(Box<Filter<VALID>>),
invalid(PhantomData<VALID>),
Invalid(PhantomData<VALID>),
}
// Change this so you have RawFilter and Filter. RawFilter is the "builder", and then
@ -64,7 +63,7 @@ impl Filter<FilterValid> {
Filter::Or(l) => Filter::Or(l.iter().map(|f| f.invalidate()).collect()),
Filter::And(l) => Filter::And(l.iter().map(|f| f.invalidate()).collect()),
Filter::AndNot(l) => Filter::AndNot(Box::new(l.invalidate())),
Filter::invalid(_) => {
Filter::Invalid(_) => {
// TODO: Is there a better way to not need to match the phantom?
unimplemented!()
}
@ -253,7 +252,7 @@ impl Clone for Filter<FilterValid> {
Filter::Or(l) => Filter::Or(l.clone()),
Filter::And(l) => Filter::And(l.clone()),
Filter::AndNot(l) => Filter::AndNot(l.clone()),
Filter::invalid(_) => {
Filter::Invalid(_) => {
// TODO: Is there a better way to not need to match the phantom?
unimplemented!()
}
@ -271,7 +270,7 @@ impl Clone for Filter<FilterInvalid> {
Filter::Or(l) => Filter::Or(l.clone()),
Filter::And(l) => Filter::And(l.clone()),
Filter::AndNot(l) => Filter::AndNot(l.clone()),
Filter::invalid(_) => {
Filter::Invalid(_) => {
// TODO: Is there a better way to not need to match the phantom?
unimplemented!()
}
@ -323,8 +322,8 @@ impl PartialOrd for Filter<FilterValid> {
#[cfg(test)]
mod tests {
use super::{Filter, FilterInvalid};
use entry::{Entry, EntryNew, EntryValid};
use crate::entry::{Entry, EntryNew, EntryValid};
use crate::filter::{Filter, FilterInvalid};
use serde_json;
use std::cmp::{Ordering, PartialOrd};

View file

@ -1,10 +1,9 @@
use actix::prelude::*;
use std::time::Duration;
use constants::PURGE_TIMEOUT;
use event::{PurgeRecycledEvent, PurgeTombstoneEvent};
use proto_v1_actors::QueryServerV1;
// use server::QueryServer;
use crate::constants::PURGE_TIMEOUT;
use crate::event::{PurgeRecycledEvent, PurgeTombstoneEvent};
use crate::proto_v1_actors::QueryServerV1;
pub struct IntervalActor {
// Store any addresses we require

View file

@ -1,5 +1,3 @@
#![feature(try_from)]
extern crate serde;
extern crate serde_json;
#[macro_use]

View file

@ -1,13 +1,13 @@
use actix::prelude::*;
use super::audit::AuditScope;
use crate::audit::AuditScope;
// Helper for internal logging.
// Should only be used at startup/shutdown
#[macro_export]
macro_rules! log_event {
($log_addr:expr, $($arg:tt)*) => ({
use log::LogEvent;
use crate::log::LogEvent;
use std::fmt;
$log_addr.do_send(
LogEvent {

View file

@ -1,10 +1,10 @@
use audit::AuditScope;
use proto_v1::Modify as ProtoModify;
use proto_v1::ModifyList as ProtoModifyList;
use crate::audit::AuditScope;
use crate::proto_v1::Modify as ProtoModify;
use crate::proto_v1::ModifyList as ProtoModifyList;
use error::{OperationError, SchemaError};
use schema::{SchemaAttribute, SchemaReadTransaction};
use server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::error::{OperationError, SchemaError};
use crate::schema::SchemaReadTransaction;
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
// Should this be std?
use std::slice;

View file

@ -1,14 +1,14 @@
use plugins::Plugin;
use crate::plugins::Plugin;
use uuid::Uuid;
use audit::AuditScope;
use be::{BackendReadTransaction, BackendWriteTransaction};
use entry::{Entry, EntryInvalid, EntryNew};
use error::{ConsistencyError, OperationError};
use event::CreateEvent;
use filter::Filter;
use schema::SchemaWriteTransaction;
use server::{QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction};
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryInvalid, EntryNew};
use crate::error::{ConsistencyError, OperationError};
use crate::event::CreateEvent;
use crate::filter::{Filter, FilterInvalid};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
// TO FINISH
/*
@ -51,7 +51,7 @@ impl Plugin for Base {
// if they don't have uuid, create it.
// TODO: get_ava should have a str version for effeciency?
let mut c_uuid = match entry.get_ava(&name_uuid) {
let c_uuid: String = match entry.get_ava(&name_uuid) {
Some(u) => {
// Actually check we have a value, could be empty array ...
// TODO: Should this be left to schema to assert the value?
@ -60,42 +60,31 @@ impl Plugin for Base {
return Err(OperationError::Plugin);
};
let v = match u.first() {
Some(v) => v,
None => {
// TODO: Should this be forgiving and just generate the UUID?
audit_log!(au, "Entry defines uuid attr, but no value.");
return Err(OperationError::Plugin);
}
};
// Schema of the value v, is checked in the filter generation. Neat!
// This could actually fail, so we probably need to handle
// this better ....
// TODO: Make this a SCHEMA check, not a manual one.
//
match Uuid::parse_str(v.as_str()) {
Ok(up) => up,
Err(_) => {
audit_log!(
au,
"Entry contains invalid Base content, rejecting out of principle."
);
return Err(OperationError::Plugin);
}
}
// Should this be forgiving and just generate the UUID?
// NO! If you tried to specify it, but didn't give it, then you made
// a mistake and your intent is unknown.
try_audit!(
au,
u.first().ok_or(OperationError::Plugin).map(|v| v.clone())
)
}
None => Uuid::new_v4(),
None => Uuid::new_v4().to_hyphenated().to_string(),
};
// Make it a string, so we can filter.
let str_uuid = format!("{}", c_uuid);
let mut au_qs = AuditScope::new("qs_exist");
// We need to clone to the filter because it owns the content
let filt = Filter::Eq(name_uuid.clone(), str_uuid.clone());
// Now, str_uuid could we invalid, but the filter validation step here will check
// that for us *and* if we fails, we return because the value was not valid. If it
// works, great, we can check for duplication.
let filt_in: Filter<FilterInvalid> = Filter::Eq(name_uuid.clone(), c_uuid.clone());
// let schema_ro = qs.get_schema();
// let filt = try_audit!(au, filt_in.validate(schema_ro));
let r = qs.internal_exists(&mut au_qs, filt);
let r = qs.internal_exists(&mut au_qs, filt_in);
au.append_scope(au_qs);
// end the scope for the be operation.
@ -113,9 +102,8 @@ impl Plugin for Base {
}
}
let str_uuid = format!("{}", c_uuid);
audit_log!(au, "Setting UUID {} to entry", str_uuid);
let ava_uuid: Vec<String> = vec![str_uuid];
audit_log!(au, "Setting UUID {} to entry", c_uuid);
let ava_uuid: Vec<String> = vec![c_uuid];
entry.set_avas(name_uuid, ava_uuid);
audit_log!(au, "Final entry state: {:?}", entry);
@ -135,16 +123,14 @@ impl Plugin for Base {
// Search for class = *
let entries = match qs.internal_search(au, Filter::Pres("class".to_string())) {
Ok(r) => r,
Ok(v) => v,
Err(e) => {
// try_audit?
// TODO: So here, should be returning the oper error? That makes the errors
// recursive, so what is correct?
audit_log!(au, "Internal Search Failure: {:?}", e);
return vec![Err(ConsistencyError::QueryServerSearchFailure)];
}
};
let mut r_uniq = entries
let r_uniq = entries
.iter()
// do an exists checks on the uuid
.map(|e| {
@ -202,39 +188,18 @@ impl Plugin for Base {
#[cfg(test)]
mod tests {
#[macro_use]
use plugins::Plugin;
use plugins::base::Base;
use crate::plugins::Plugin;
use std::sync::Arc;
use audit::AuditScope;
use be::Backend;
use entry::{Entry, EntryInvalid, EntryNew};
use event::CreateEvent;
use schema::Schema;
use server::{QueryServer, QueryServerWriteTransaction};
// Check empty create
#[test]
fn test_pre_create_empty() {
let preload: Vec<Entry<EntryInvalid, EntryNew>> = Vec::new();
let mut create: Vec<Entry<EntryInvalid, EntryNew>> = Vec::new();
run_pre_create_test!(
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_ok());
// Nothing should have changed.
assert!(cand.len() == 0);
}
);
}
use crate::audit::AuditScope;
use crate::be::Backend;
use crate::entry::{Entry, EntryInvalid, EntryNew};
use crate::error::OperationError;
use crate::event::CreateEvent;
use crate::filter::Filter;
use crate::schema::Schema;
use crate::server::QueryServerReadTransaction;
use crate::server::{QueryServer, QueryServerWriteTransaction};
// check create where no uuid
#[test]
@ -255,21 +220,18 @@ mod tests {
)
.unwrap();
let mut create = vec![e];
let create = vec![e];
run_pre_create_test!(
run_create_test!(
Ok(()),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_ok());
// Assert that the entry contains the attr "uuid" now.
let ue = cand.first().unwrap();
|au: &mut AuditScope, qs: &QueryServerWriteTransaction| {
let cands = qs
.internal_search(au, Filter::Eq("name".to_string(), "testperson".to_string()))
.unwrap();
let ue = cands.first().unwrap();
assert!(ue.attribute_pres("uuid"));
}
);
@ -295,20 +257,14 @@ mod tests {
)
.unwrap();
let mut create = vec![e.clone()];
let create = vec![e.clone()];
run_pre_create_test!(
run_create_test!(
Err(OperationError::Plugin),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_err());
}
|_, _| {}
);
}
@ -332,20 +288,14 @@ mod tests {
)
.unwrap();
let mut create = vec![e.clone()];
let create = vec![e.clone()];
run_pre_create_test!(
run_create_test!(
Err(OperationError::Plugin),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_err());
}
|_, _| {}
);
}
@ -369,20 +319,18 @@ mod tests {
)
.unwrap();
let mut create = vec![e.clone()];
let create = vec![e.clone()];
run_pre_create_test!(
run_create_test!(
Ok(()),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_ok());
let ue = cand.first().unwrap();
|au: &mut AuditScope, qs: &QueryServerWriteTransaction| {
let cands = qs
.internal_search(au, Filter::Eq("name".to_string(), "testperson".to_string()))
.unwrap();
let ue = cands.first().unwrap();
assert!(ue.attribute_equality("uuid", "79724141-3603-4060-b6bb-35c72772611d"));
}
);
@ -407,20 +355,14 @@ mod tests {
)
.unwrap();
let mut create = vec![e.clone()];
let create = vec![e.clone()];
run_pre_create_test!(
run_create_test!(
Err(OperationError::Plugin),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_err());
}
|_, _| {}
);
}
@ -442,21 +384,15 @@ mod tests {
)
.unwrap();
let mut create = vec![e.clone()];
let create = vec![e.clone()];
let preload = vec![e];
run_pre_create_test!(
run_create_test!(
Err(OperationError::Plugin),
preload,
create,
false,
false,
|au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
ce: &CreateEvent| {
let r = Base::pre_create(au, qs, cand, ce);
assert!(r.is_err());
}
|_, _| {}
);
}

View file

@ -1,45 +1,59 @@
#[macro_escape]
// #[macro_escape]
macro_rules! setup_test {
(
$au:expr,
$preload_entries:ident
) => {{
// Create an in memory BE
let be = Backend::new($au, "").unwrap();
let schema_outer = Schema::new($au).unwrap();
{
let mut schema = schema_outer.write();
schema.bootstrap_core($au).unwrap();
schema.commit().unwrap();
}
let qs = QueryServer::new(be, Arc::new(schema_outer));
if !$preload_entries.is_empty() {
let qs_write = qs.write();
qs_write.internal_create($au, $preload_entries);
assert!(qs_write.commit($au).is_ok());
}
qs
}};
}
// Test helpers for all plugins.
#[macro_export]
macro_rules! run_pre_create_test {
macro_rules! run_create_test {
(
$preload_entries:ident,
$create_entries:ident,
$ident:ident,
$internal:ident,
$test_fn:expr
) => {{
let mut au = AuditScope::new("run_pre_create_test");
$expect:expr,
$preload_entries:ident,
$create_entries:ident,
$internal:ident,
$check:expr
) => {{
let mut au = AuditScope::new("run_create_test");
audit_segment!(au, || {
// Create an in memory BE
let be = Backend::new(&mut au, "").unwrap();
let qs = setup_test!(&mut au, $preload_entries);
let schema_outer = Schema::new(&mut au).unwrap();
{
let mut schema = schema_outer.write();
schema.bootstrap_core(&mut au).unwrap();
schema.commit().unwrap();
}
let qs = QueryServer::new(be, Arc::new(schema_outer));
let ce = if $internal {
CreateEvent::new_internal($create_entries.clone())
} else {
CreateEvent::from_vec($create_entries.clone())
};
if !$preload_entries.is_empty() {
let qs_write = qs.write();
qs_write.internal_create(&mut au, $preload_entries);
assert!(qs_write.commit(&mut au).is_ok());
}
let ce = CreateEvent::from_vec($create_entries.clone());
let mut au_test = AuditScope::new("pre_create_test");
let mut au_test = AuditScope::new("create_test");
{
let qs_write = qs.write();
audit_segment!(au_test, || $test_fn(
&mut au_test,
&qs_write,
&mut $create_entries,
&ce,
));
assert!(qs_write.commit(&mut au).is_ok());
let r = qs_write.create(&mut au_test, &ce);
assert!(r == $expect);
$check(&mut au_test, &qs_write);
r.map(|_| {
assert!(qs_write.commit(&mut au_test).is_ok());
});
}
// Make sure there are no errors.
assert!(qs.verify(&mut au_test).len() == 0);
@ -51,16 +65,81 @@ macro_rules! run_pre_create_test {
}};
}
/*
#[macro_export]
macro_rules! run_post_create_test {
macro_rules! run_modify_test {
(
$expect:expr,
$preload_entries:ident,
$modify_filter:ident,
$modify_list:ident,
$internal:ident,
$check:expr
) => {{
let mut au = AuditScope::new("run_modify_test");
audit_segment!(au, || {
let qs = setup_test!(&mut au, $preload_entries);
let me = if $internal {
ModifyEvent::new_internal($)
} else {
ModifyEvent::from_filter($modify_entries.clone())
};
let mut au_test = AuditScope::new("modify_test");
{
let qs_write = qs.write();
let r = qs_write.modify(&mut au_test, &me);
$check(&mut au_test, &qs_write);
assert!(r == $expect);
r.map(|_| {
assert!(qs_write.commit(&mut au_test).is_ok());
});
}
// Make sure there are no errors.
assert!(qs.verify(&mut au_test).len() == 0);
au.append_scope(au_test);
});
// Dump the raw audit log.
println!("{}", au);
}};
}
#[macro_export]
macro_rules! run_post_modify_test {
}
macro_rules! run_delete_test {
(
$expect:expr,
$preload_entries:ident,
$delete_filter:ident,
$internal:ident,
$check:expr
) => {{
let mut au = AuditScope::new("run_delete_test");
audit_segment!(au, || {
let qs = setup_test!(&mut au, $preload_entries);
#[macro_export]
macro_rules! run_post_delete_test {
let de = if $internal {
DeleteEvent::new_internal($delete_filter.clone())
} else {
DeleteEvent::from_filter($delete_filter.clone())
};
let mut au_test = AuditScope::new("delete_test");
{
let qs_write = qs.write();
let r = qs_write.delete(&mut au_test, &de);
$check(&mut au_test, &qs_write);
assert!(r == $expect);
r.map(|_| {
assert!(qs_write.commit(&mut au_test).is_ok());
});
}
// Make sure there are no errors.
assert!(qs.verify(&mut au_test).len() == 0);
au.append_scope(au_test);
});
// Dump the raw audit log.
println!("{}", au);
}};
}
*/

View file

@ -1,10 +1,8 @@
use audit::AuditScope;
use be::BackendReadTransaction;
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use error::{ConsistencyError, OperationError};
use event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
use schema::SchemaReadTransaction;
use server::{QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction};
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use crate::error::{ConsistencyError, OperationError};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
#[macro_use]
mod macros;
@ -86,7 +84,7 @@ macro_rules! run_pre_create_plugin {
$target_plugin:ty
) => {{
let mut audit_scope = AuditScope::new(<($target_plugin)>::id());
let mut r = audit_segment!(audit_scope, || <($target_plugin)>::pre_create(
let r = audit_segment!(audit_scope, || <($target_plugin)>::pre_create(
&mut audit_scope,
$qs,
$cand,
@ -133,46 +131,46 @@ impl Plugins {
}
pub fn run_post_create(
au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &Vec<Entry<EntryValid, EntryNew>>,
ce: &CreateEvent,
_au: &mut AuditScope,
_qs: &QueryServerWriteTransaction,
_cand: &Vec<Entry<EntryValid, EntryNew>>,
_ce: &CreateEvent,
) -> Result<(), OperationError> {
Ok(())
}
pub fn run_pre_modify(
au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
me: &ModifyEvent,
_au: &mut AuditScope,
_qs: &QueryServerWriteTransaction,
_cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
_me: &ModifyEvent,
) -> Result<(), OperationError> {
Ok(())
}
pub fn run_post_modify(
au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &Vec<Entry<EntryValid, EntryCommitted>>,
me: &ModifyEvent,
_au: &mut AuditScope,
_qs: &QueryServerWriteTransaction,
_cand: &Vec<Entry<EntryValid, EntryCommitted>>,
_me: &ModifyEvent,
) -> Result<(), OperationError> {
Ok(())
}
pub fn run_pre_delete(
au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
de: &DeleteEvent,
_au: &mut AuditScope,
_qs: &QueryServerWriteTransaction,
_cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
_de: &DeleteEvent,
) -> Result<(), OperationError> {
Ok(())
}
pub fn run_post_delete(
au: &mut AuditScope,
qs: &QueryServerWriteTransaction,
cand: &Vec<Entry<EntryValid, EntryCommitted>>,
de: &DeleteEvent,
_au: &mut AuditScope,
_qs: &QueryServerWriteTransaction,
_cand: &Vec<Entry<EntryValid, EntryCommitted>>,
_de: &DeleteEvent,
) -> Result<(), OperationError> {
Ok(())
}

View file

@ -9,12 +9,12 @@
// when that is written, as they *both* manipulate and alter entry reference
// data, so we should be careful not to step on each other.
use audit::AuditScope;
use entry::{Entry, EntryCommitted, EntryNew, EntryValid};
use error::OperationError;
use event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
use plugins::Plugin;
use server::QueryServerWriteTransaction;
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryNew, EntryValid};
use crate::error::OperationError;
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::plugins::Plugin;
use crate::server::QueryServerWriteTransaction;
pub struct ReferentialIntegrity;
@ -52,4 +52,26 @@ impl Plugin for ReferentialIntegrity {
}
#[cfg(test)]
mod tests {}
mod tests {
// The create references a uuid that doesn't exist - reject
// The create references a uuid that does exist - validate
// The create references itself - allow
// The create reference a different object - allow
// Modify references a different object - allow
// Modify reference something that doesn't exist - must be rejected
// Modify removes an entry that something else pointed to. - must remove ref in other
// Modify removes the reference to an entry - doesn't need a test
// Modify adds reference to self - allow
// Delete of something that is referenced - must remove ref in other (unless would make inconsistent)
// Delete of something that holds references - doesn't need a test
}

View file

@ -1,7 +1,7 @@
// use super::entry::Entry;
// use super::filter::Filter;
use crate::error::OperationError;
use actix::prelude::*;
use error::OperationError;
use std::collections::BTreeMap;
// These proto implementations are here because they have public definitions

View file

@ -1,20 +1,20 @@
use actix::prelude::*;
use std::sync::Arc;
use audit::AuditScope;
use be::Backend;
use crate::audit::AuditScope;
use crate::be::Backend;
use error::OperationError;
use event::{
use crate::error::OperationError;
use crate::event::{
CreateEvent, DeleteEvent, ModifyEvent, OpResult, PurgeRecycledEvent, PurgeTombstoneEvent,
SearchEvent, SearchResult,
};
use log::EventLog;
use schema::{Schema, SchemaReadTransaction};
use crate::log::EventLog;
use crate::schema::{Schema, SchemaReadTransaction};
use server::{QueryServer, QueryServerReadTransaction};
use crate::server::{QueryServer, QueryServerReadTransaction};
use proto_v1::{
use crate::proto_v1::{
AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, OperationResponse, SearchRequest,
SearchResponse,
};

View file

@ -1,6 +1,6 @@
use audit::AuditScope;
use constants::*;
use error::{ConsistencyError, OperationError, SchemaError};
use crate::audit::AuditScope;
use crate::constants::*;
use crate::error::{ConsistencyError, OperationError, SchemaError};
use regex::Regex;
use std::collections::HashMap;
use std::convert::TryFrom;
@ -1006,13 +1006,13 @@ impl Schema {
#[cfg(test)]
mod tests {
use audit::AuditScope;
use constants::*;
use entry::{Entry, EntryInvalid, EntryNew, EntryValid};
use error::{ConsistencyError, SchemaError};
use filter::{Filter, FilterValid};
use schema::SchemaReadTransaction;
use schema::{IndexType, Schema, SchemaAttribute, SyntaxType};
use crate::audit::AuditScope;
use crate::constants::*;
use crate::entry::{Entry, EntryInvalid, EntryNew, EntryValid};
use crate::error::{ConsistencyError, SchemaError};
use crate::filter::{Filter, FilterValid};
use crate::schema::SchemaReadTransaction;
use crate::schema::{IndexType, Schema, SchemaAttribute, SyntaxType};
use serde_json;
use std::convert::TryFrom;
use uuid::Uuid;

View file

@ -3,19 +3,21 @@
// use actix::prelude::*;
use std::sync::Arc;
use audit::AuditScope;
use be::{
use crate::audit::AuditScope;
use crate::be::{
Backend, BackendError, BackendReadTransaction, BackendTransaction, BackendWriteTransaction,
};
use constants::{JSON_ANONYMOUS_V1, JSON_SYSTEM_INFO_V1};
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use error::{ConsistencyError, OperationError, SchemaError};
use event::{CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent};
use filter::{Filter, FilterInvalid};
use modify::{Modify, ModifyInvalid, ModifyList};
use plugins::Plugins;
use schema::{
use crate::constants::{JSON_ANONYMOUS_V1, JSON_SYSTEM_INFO_V1};
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
use crate::error::{ConsistencyError, OperationError, SchemaError};
use crate::event::{
CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent,
};
use crate::filter::{Filter, FilterInvalid};
use crate::modify::{Modify, ModifyInvalid, ModifyList};
use crate::plugins::Plugins;
use crate::schema::{
Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction, SyntaxType,
};
@ -344,7 +346,7 @@ pub trait QueryServerReadTransaction {
}
// In the opposite direction, we can resolve values for presentation
fn resolve_value(&self, attr: &String, value: &String) -> Result<String, OperationError> {
fn resolve_value(&self, _attr: &String, value: &String) -> Result<String, OperationError> {
Ok(value.clone())
}
}
@ -939,7 +941,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
pub fn internal_exists_or_create(
&self,
e: Entry<EntryValid, EntryNew>,
_e: Entry<EntryValid, EntryNew>,
) -> Result<(), OperationError> {
// If the thing exists, stop.
// if not, create from Entry.
@ -1116,23 +1118,21 @@ mod tests {
*/
use std::sync::Arc;
use super::super::audit::AuditScope;
use super::super::be::Backend;
use super::super::entry::{Entry, EntryInvalid, EntryNew};
use super::super::error::{OperationError, SchemaError};
use super::super::event::{
CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent,
};
use super::super::filter::Filter;
use super::super::modify::{Modify, ModifyList};
use super::super::proto_v1::Filter as ProtoFilter;
use super::super::proto_v1::Modify as ProtoModify;
use super::super::proto_v1::ModifyList as ProtoModifyList;
use super::super::proto_v1::{
use crate::audit::AuditScope;
use crate::be::Backend;
use crate::entry::{Entry, EntryInvalid, EntryNew};
use crate::error::{OperationError, SchemaError};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent};
use crate::filter::Filter;
use crate::modify::{Modify, ModifyList};
use crate::proto_v1::Filter as ProtoFilter;
use crate::proto_v1::Modify as ProtoModify;
use crate::proto_v1::ModifyList as ProtoModifyList;
use crate::proto_v1::{
DeleteRequest, ModifyRequest, ReviveRecycledRequest, SearchRecycledRequest, SearchRequest,
};
use super::super::schema::Schema;
use super::super::server::{QueryServer, QueryServerReadTransaction};
use crate::schema::Schema;
use crate::server::{QueryServer, QueryServerReadTransaction};
macro_rules! run_test {
($test_fn:expr) => {{