mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Update to rust 2018 and improve some todo notes
This commit is contained in:
parent
af9ac8f662
commit
4ab377ec88
|
@ -5,8 +5,7 @@ name = "rsidm"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
authors = ["William Brown <william@blackhats.net.au>"]
|
authors = ["William Brown <william@blackhats.net.au>"]
|
||||||
default-run = "rsidm_core"
|
default-run = "rsidm_core"
|
||||||
#
|
edition = "2018"
|
||||||
# edition = "2018"
|
|
||||||
|
|
||||||
|
|
||||||
# We need three major binaries. The server itself, the unix client, and a cli
|
# We need three major binaries. The server itself, the unix client, and a cli
|
||||||
|
|
|
@ -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)]
|
#[derive(Serialize, Deserialize)]
|
||||||
|
@ -143,7 +161,7 @@ impl AuditScope {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
|
|
||||||
// Create and remove. Perhaps add some core details?
|
// Create and remove. Perhaps add some core details?
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -7,10 +7,10 @@ use rusqlite::NO_PARAMS;
|
||||||
use serde_json;
|
use serde_json;
|
||||||
// use uuid;
|
// use uuid;
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use entry::{Entry, EntryCommitted, EntryNew, EntryValid};
|
use crate::entry::{Entry, EntryCommitted, EntryNew, EntryValid};
|
||||||
use error::{ConsistencyError, OperationError};
|
use crate::error::{ConsistencyError, OperationError};
|
||||||
use filter::{Filter, FilterValid};
|
use crate::filter::{Filter, FilterValid};
|
||||||
|
|
||||||
mod idl;
|
mod idl;
|
||||||
mod mem_be;
|
mod mem_be;
|
||||||
|
|
|
@ -5,6 +5,7 @@ pub struct Configuration {
|
||||||
pub db_path: String,
|
pub db_path: String,
|
||||||
pub maximum_request: usize,
|
pub maximum_request: usize,
|
||||||
// db type later
|
// db type later
|
||||||
|
pub secure_cookies: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Configuration {
|
impl Configuration {
|
||||||
|
@ -14,8 +15,9 @@ impl Configuration {
|
||||||
threads: 8,
|
threads: 8,
|
||||||
db_path: String::from(""),
|
db_path: String::from(""),
|
||||||
maximum_request: 262144, // 256k
|
maximum_request: 262144, // 256k
|
||||||
// log type
|
// log type
|
||||||
// log path
|
// log path
|
||||||
|
secure_cookies: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
pub static PURGE_TIMEOUT: u64 = 3600;
|
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#"{
|
pub static JSON_ANONYMOUS_V1: &'static str = r#"{
|
||||||
"valid": null,
|
"valid": null,
|
||||||
"state": 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#"{
|
pub static JSON_SYSTEM_INFO_V1: &'static str = r#"{
|
||||||
"valid": null,
|
"valid": null,
|
||||||
"state": null,
|
"state": null,
|
||||||
|
|
|
@ -8,13 +8,13 @@ use actix_web::{
|
||||||
use bytes::BytesMut;
|
use bytes::BytesMut;
|
||||||
use futures::{future, Future, Stream};
|
use futures::{future, Future, Stream};
|
||||||
|
|
||||||
use super::config::Configuration;
|
use crate::config::Configuration;
|
||||||
|
|
||||||
// SearchResult
|
// SearchResult
|
||||||
use super::interval::IntervalActor;
|
use crate::interval::IntervalActor;
|
||||||
use super::log;
|
use crate::log;
|
||||||
use super::proto_v1::{AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest};
|
use crate::proto_v1::{AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, SearchRequest};
|
||||||
use super::proto_v1_actors::QueryServerV1;
|
use crate::proto_v1_actors::QueryServerV1;
|
||||||
|
|
||||||
struct AppState {
|
struct AppState {
|
||||||
qe: actix::Addr<QueryServerV1>,
|
qe: actix::Addr<QueryServerV1>,
|
||||||
|
@ -205,10 +205,12 @@ pub fn create_server_core(config: Configuration) {
|
||||||
let server_addr =
|
let server_addr =
|
||||||
match QueryServerV1::start(log_addr.clone(), config.db_path.as_str(), config.threads) {
|
match QueryServerV1::start(log_addr.clone(), config.db_path.as_str(), config.threads) {
|
||||||
Ok(addr) => addr,
|
Ok(addr) => addr,
|
||||||
Err(_e) => {
|
Err(e) => {
|
||||||
// Oh shiiiiiiii
|
println!(
|
||||||
// TODO: Handle this properly.
|
"An unknown failure in startup has occured - exiting -> {:?}",
|
||||||
unimplemented!()
|
e
|
||||||
|
);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -217,6 +219,7 @@ pub fn create_server_core(config: Configuration) {
|
||||||
|
|
||||||
// Copy the max size
|
// Copy the max size
|
||||||
let max_size = config.maximum_request;
|
let max_size = config.maximum_request;
|
||||||
|
let secure_cookies = config.secure_cookies;
|
||||||
|
|
||||||
// start the web server
|
// start the web server
|
||||||
actix_web::server::new(move || {
|
actix_web::server::new(move || {
|
||||||
|
@ -238,8 +241,7 @@ pub fn create_server_core(config: Configuration) {
|
||||||
.http_only(true)
|
.http_only(true)
|
||||||
.name("rsidm-session")
|
.name("rsidm-session")
|
||||||
// This forces https only
|
// This forces https only
|
||||||
// TODO: Make this a config value
|
.secure(secure_cookies),
|
||||||
.secure(false),
|
|
||||||
))
|
))
|
||||||
// .resource("/", |r| r.f(index))
|
// .resource("/", |r| r.f(index))
|
||||||
// curl --header ...?
|
// curl --header ...?
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
// use serde_json::{Error, Value};
|
// use serde_json::{Error, Value};
|
||||||
use super::proto_v1::Entry as ProtoEntry;
|
use crate::audit::AuditScope;
|
||||||
use audit::AuditScope;
|
use crate::error::{OperationError, SchemaError};
|
||||||
use error::{OperationError, SchemaError};
|
use crate::filter::{Filter, FilterValid};
|
||||||
use filter::{Filter, FilterValid};
|
use crate::modify::{Modify, ModifyInvalid, ModifyList, ModifyValid};
|
||||||
use modify::{Modify, ModifyInvalid, ModifyList, ModifyValid};
|
use crate::proto_v1::Entry as ProtoEntry;
|
||||||
use schema::{SchemaAttribute, SchemaClass, SchemaReadTransaction};
|
use crate::schema::{SchemaAttribute, SchemaClass, SchemaReadTransaction};
|
||||||
use server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
||||||
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
|
use std::collections::btree_map::{Iter as BTreeIter, IterMut as BTreeIterMut};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
@ -478,7 +478,7 @@ impl<STATE> Entry<EntryValid, STATE> {
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
Filter::AndNot(f) => !self.entry_match_no_index(f),
|
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?
|
// TODO: Is there a better way to not need to match the phantom?
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -746,8 +746,8 @@ struct User {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Entry, EntryInvalid, EntryNew};
|
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
||||||
use modify::{Modify, ModifyList};
|
use crate::modify::{Modify, ModifyList};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
|
@ -1,15 +1,19 @@
|
||||||
use super::filter::{Filter, FilterInvalid};
|
use crate::audit::AuditScope;
|
||||||
use super::proto_v1::Entry as ProtoEntry;
|
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
|
||||||
use super::proto_v1::{
|
use crate::filter::{Filter, FilterInvalid};
|
||||||
|
use crate::proto_v1::Entry as ProtoEntry;
|
||||||
|
use crate::proto_v1::{
|
||||||
AuthRequest, AuthResponse, AuthStatus, CreateRequest, DeleteRequest, ModifyRequest,
|
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 error::OperationError;
|
use crate::error::OperationError;
|
||||||
use modify::{ModifyInvalid, ModifyList};
|
use crate::modify::{ModifyInvalid, ModifyList};
|
||||||
use server::{QueryServerTransaction, QueryServerWriteTransaction};
|
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
|
||||||
|
|
||||||
|
// Only used for internal tests
|
||||||
|
#[cfg(test)]
|
||||||
|
use crate::proto_v1::SearchRecycledRequest;
|
||||||
|
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
|
@ -89,6 +93,7 @@ impl SearchEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub fn from_rec_request(
|
pub fn from_rec_request(
|
||||||
audit: &mut AuditScope,
|
audit: &mut AuditScope,
|
||||||
request: SearchRecycledRequest,
|
request: SearchRecycledRequest,
|
||||||
|
@ -103,6 +108,7 @@ impl SearchEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
pub fn new_rec_impersonate(filter: Filter<FilterInvalid>) -> Self {
|
pub fn new_rec_impersonate(filter: Filter<FilterInvalid>) -> Self {
|
||||||
SearchEvent {
|
SearchEvent {
|
||||||
internal: false,
|
internal: false,
|
||||||
|
@ -110,6 +116,7 @@ impl SearchEvent {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
/* Impersonate an external request */
|
/* Impersonate an external request */
|
||||||
pub fn new_ext_impersonate(filter: Filter<FilterInvalid>) -> Self {
|
pub fn new_ext_impersonate(filter: Filter<FilterInvalid>) -> Self {
|
||||||
SearchEvent {
|
SearchEvent {
|
||||||
|
|
|
@ -2,13 +2,12 @@
|
||||||
// in parallel map/reduce style, or directly on a single
|
// in parallel map/reduce style, or directly on a single
|
||||||
// entry to assert it matches.
|
// entry to assert it matches.
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::BackendReadTransaction;
|
use crate::error::{OperationError, SchemaError};
|
||||||
use error::{OperationError, SchemaError};
|
use crate::proto_v1::Filter as ProtoFilter;
|
||||||
use proto_v1::Filter as ProtoFilter;
|
use crate::schema::SchemaReadTransaction;
|
||||||
use schema::SchemaReadTransaction;
|
use crate::server::{
|
||||||
use server::{
|
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
||||||
QueryServer, QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
|
||||||
};
|
};
|
||||||
use std::cmp::{Ordering, PartialOrd};
|
use std::cmp::{Ordering, PartialOrd};
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
@ -30,7 +29,7 @@ pub enum Filter<VALID> {
|
||||||
Or(Vec<Filter<VALID>>),
|
Or(Vec<Filter<VALID>>),
|
||||||
And(Vec<Filter<VALID>>),
|
And(Vec<Filter<VALID>>),
|
||||||
AndNot(Box<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
|
// 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::Or(l) => Filter::Or(l.iter().map(|f| f.invalidate()).collect()),
|
||||||
Filter::And(l) => Filter::And(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::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?
|
// TODO: Is there a better way to not need to match the phantom?
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -253,7 +252,7 @@ impl Clone for Filter<FilterValid> {
|
||||||
Filter::Or(l) => Filter::Or(l.clone()),
|
Filter::Or(l) => Filter::Or(l.clone()),
|
||||||
Filter::And(l) => Filter::And(l.clone()),
|
Filter::And(l) => Filter::And(l.clone()),
|
||||||
Filter::AndNot(l) => Filter::AndNot(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?
|
// TODO: Is there a better way to not need to match the phantom?
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -271,7 +270,7 @@ impl Clone for Filter<FilterInvalid> {
|
||||||
Filter::Or(l) => Filter::Or(l.clone()),
|
Filter::Or(l) => Filter::Or(l.clone()),
|
||||||
Filter::And(l) => Filter::And(l.clone()),
|
Filter::And(l) => Filter::And(l.clone()),
|
||||||
Filter::AndNot(l) => Filter::AndNot(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?
|
// TODO: Is there a better way to not need to match the phantom?
|
||||||
unimplemented!()
|
unimplemented!()
|
||||||
}
|
}
|
||||||
|
@ -323,8 +322,8 @@ impl PartialOrd for Filter<FilterValid> {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::{Filter, FilterInvalid};
|
use crate::entry::{Entry, EntryNew, EntryValid};
|
||||||
use entry::{Entry, EntryNew, EntryValid};
|
use crate::filter::{Filter, FilterInvalid};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::cmp::{Ordering, PartialOrd};
|
use std::cmp::{Ordering, PartialOrd};
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
use constants::PURGE_TIMEOUT;
|
use crate::constants::PURGE_TIMEOUT;
|
||||||
use event::{PurgeRecycledEvent, PurgeTombstoneEvent};
|
use crate::event::{PurgeRecycledEvent, PurgeTombstoneEvent};
|
||||||
use proto_v1_actors::QueryServerV1;
|
use crate::proto_v1_actors::QueryServerV1;
|
||||||
// use server::QueryServer;
|
|
||||||
|
|
||||||
pub struct IntervalActor {
|
pub struct IntervalActor {
|
||||||
// Store any addresses we require
|
// Store any addresses we require
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
#![feature(try_from)]
|
|
||||||
|
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
extern crate serde_json;
|
extern crate serde_json;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
|
|
||||||
use super::audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
|
|
||||||
// Helper for internal logging.
|
// Helper for internal logging.
|
||||||
// Should only be used at startup/shutdown
|
// Should only be used at startup/shutdown
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! log_event {
|
macro_rules! log_event {
|
||||||
($log_addr:expr, $($arg:tt)*) => ({
|
($log_addr:expr, $($arg:tt)*) => ({
|
||||||
use log::LogEvent;
|
use crate::log::LogEvent;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
$log_addr.do_send(
|
$log_addr.do_send(
|
||||||
LogEvent {
|
LogEvent {
|
||||||
|
|
|
@ -1,10 +1,10 @@
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use proto_v1::Modify as ProtoModify;
|
use crate::proto_v1::Modify as ProtoModify;
|
||||||
use proto_v1::ModifyList as ProtoModifyList;
|
use crate::proto_v1::ModifyList as ProtoModifyList;
|
||||||
|
|
||||||
use error::{OperationError, SchemaError};
|
use crate::error::{OperationError, SchemaError};
|
||||||
use schema::{SchemaAttribute, SchemaReadTransaction};
|
use crate::schema::SchemaReadTransaction;
|
||||||
use server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
||||||
|
|
||||||
// Should this be std?
|
// Should this be std?
|
||||||
use std::slice;
|
use std::slice;
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
use plugins::Plugin;
|
use crate::plugins::Plugin;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::{BackendReadTransaction, BackendWriteTransaction};
|
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
||||||
use entry::{Entry, EntryInvalid, EntryNew};
|
use crate::error::{ConsistencyError, OperationError};
|
||||||
use error::{ConsistencyError, OperationError};
|
use crate::event::CreateEvent;
|
||||||
use event::CreateEvent;
|
use crate::filter::{Filter, FilterInvalid};
|
||||||
use filter::Filter;
|
use crate::server::{
|
||||||
use schema::SchemaWriteTransaction;
|
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
||||||
use server::{QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction};
|
};
|
||||||
|
|
||||||
// TO FINISH
|
// TO FINISH
|
||||||
/*
|
/*
|
||||||
|
@ -51,7 +51,7 @@ impl Plugin for Base {
|
||||||
|
|
||||||
// if they don't have uuid, create it.
|
// if they don't have uuid, create it.
|
||||||
// TODO: get_ava should have a str version for effeciency?
|
// 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) => {
|
Some(u) => {
|
||||||
// Actually check we have a value, could be empty array ...
|
// Actually check we have a value, could be empty array ...
|
||||||
// TODO: Should this be left to schema to assert the value?
|
// TODO: Should this be left to schema to assert the value?
|
||||||
|
@ -60,42 +60,31 @@ impl Plugin for Base {
|
||||||
return Err(OperationError::Plugin);
|
return Err(OperationError::Plugin);
|
||||||
};
|
};
|
||||||
|
|
||||||
let v = match u.first() {
|
// Schema of the value v, is checked in the filter generation. Neat!
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// This could actually fail, so we probably need to handle
|
// Should this be forgiving and just generate the UUID?
|
||||||
// this better ....
|
// NO! If you tried to specify it, but didn't give it, then you made
|
||||||
// TODO: Make this a SCHEMA check, not a manual one.
|
// a mistake and your intent is unknown.
|
||||||
//
|
try_audit!(
|
||||||
match Uuid::parse_str(v.as_str()) {
|
au,
|
||||||
Ok(up) => up,
|
u.first().ok_or(OperationError::Plugin).map(|v| v.clone())
|
||||||
Err(_) => {
|
)
|
||||||
audit_log!(
|
|
||||||
au,
|
|
||||||
"Entry contains invalid Base content, rejecting out of principle."
|
|
||||||
);
|
|
||||||
return Err(OperationError::Plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => Uuid::new_v4(),
|
None => Uuid::new_v4().to_hyphenated().to_string(),
|
||||||
};
|
};
|
||||||
|
|
||||||
// Make it a string, so we can filter.
|
// Make it a string, so we can filter.
|
||||||
let str_uuid = format!("{}", c_uuid);
|
|
||||||
|
|
||||||
let mut au_qs = AuditScope::new("qs_exist");
|
let mut au_qs = AuditScope::new("qs_exist");
|
||||||
|
|
||||||
// We need to clone to the filter because it owns the content
|
// 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);
|
au.append_scope(au_qs);
|
||||||
// end the scope for the be operation.
|
// 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", c_uuid);
|
||||||
audit_log!(au, "Setting UUID {} to entry", str_uuid);
|
let ava_uuid: Vec<String> = vec![c_uuid];
|
||||||
let ava_uuid: Vec<String> = vec![str_uuid];
|
|
||||||
|
|
||||||
entry.set_avas(name_uuid, ava_uuid);
|
entry.set_avas(name_uuid, ava_uuid);
|
||||||
audit_log!(au, "Final entry state: {:?}", entry);
|
audit_log!(au, "Final entry state: {:?}", entry);
|
||||||
|
@ -135,16 +123,14 @@ impl Plugin for Base {
|
||||||
|
|
||||||
// Search for class = *
|
// Search for class = *
|
||||||
let entries = match qs.internal_search(au, Filter::Pres("class".to_string())) {
|
let entries = match qs.internal_search(au, Filter::Pres("class".to_string())) {
|
||||||
Ok(r) => r,
|
Ok(v) => v,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
// try_audit?
|
audit_log!(au, "Internal Search Failure: {:?}", e);
|
||||||
// TODO: So here, should be returning the oper error? That makes the errors
|
|
||||||
// recursive, so what is correct?
|
|
||||||
return vec![Err(ConsistencyError::QueryServerSearchFailure)];
|
return vec![Err(ConsistencyError::QueryServerSearchFailure)];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut r_uniq = entries
|
let r_uniq = entries
|
||||||
.iter()
|
.iter()
|
||||||
// do an exists checks on the uuid
|
// do an exists checks on the uuid
|
||||||
.map(|e| {
|
.map(|e| {
|
||||||
|
@ -202,39 +188,18 @@ impl Plugin for Base {
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
use plugins::Plugin;
|
use crate::plugins::Plugin;
|
||||||
use plugins::base::Base;
|
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::Backend;
|
use crate::be::Backend;
|
||||||
use entry::{Entry, EntryInvalid, EntryNew};
|
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
||||||
use event::CreateEvent;
|
use crate::error::OperationError;
|
||||||
use schema::Schema;
|
use crate::event::CreateEvent;
|
||||||
use server::{QueryServer, QueryServerWriteTransaction};
|
use crate::filter::Filter;
|
||||||
|
use crate::schema::Schema;
|
||||||
// Check empty create
|
use crate::server::QueryServerReadTransaction;
|
||||||
#[test]
|
use crate::server::{QueryServer, QueryServerWriteTransaction};
|
||||||
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);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
// check create where no uuid
|
// check create where no uuid
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -255,21 +220,18 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e];
|
let create = vec![e];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Ok(()),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
false,
|
||||||
false,
|
|au: &mut AuditScope, qs: &QueryServerWriteTransaction| {
|
||||||
|au: &mut AuditScope,
|
let cands = qs
|
||||||
qs: &QueryServerWriteTransaction,
|
.internal_search(au, Filter::Eq("name".to_string(), "testperson".to_string()))
|
||||||
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
|
.unwrap();
|
||||||
ce: &CreateEvent| {
|
let ue = cands.first().unwrap();
|
||||||
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();
|
|
||||||
assert!(ue.attribute_pres("uuid"));
|
assert!(ue.attribute_pres("uuid"));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -295,20 +257,14 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e.clone()];
|
let create = vec![e.clone()];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Err(OperationError::Plugin),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
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();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e.clone()];
|
let create = vec![e.clone()];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Err(OperationError::Plugin),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
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();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e.clone()];
|
let create = vec![e.clone()];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Ok(()),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
false,
|
||||||
false,
|
|au: &mut AuditScope, qs: &QueryServerWriteTransaction| {
|
||||||
|au: &mut AuditScope,
|
let cands = qs
|
||||||
qs: &QueryServerWriteTransaction,
|
.internal_search(au, Filter::Eq("name".to_string(), "testperson".to_string()))
|
||||||
cand: &mut Vec<Entry<EntryInvalid, EntryNew>>,
|
.unwrap();
|
||||||
ce: &CreateEvent| {
|
let ue = cands.first().unwrap();
|
||||||
let r = Base::pre_create(au, qs, cand, ce);
|
|
||||||
assert!(r.is_ok());
|
|
||||||
let ue = cand.first().unwrap();
|
|
||||||
assert!(ue.attribute_equality("uuid", "79724141-3603-4060-b6bb-35c72772611d"));
|
assert!(ue.attribute_equality("uuid", "79724141-3603-4060-b6bb-35c72772611d"));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
@ -407,20 +355,14 @@ mod tests {
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e.clone()];
|
let create = vec![e.clone()];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Err(OperationError::Plugin),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
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();
|
.unwrap();
|
||||||
|
|
||||||
let mut create = vec![e.clone()];
|
let create = vec![e.clone()];
|
||||||
let preload = vec![e];
|
let preload = vec![e];
|
||||||
|
|
||||||
run_pre_create_test!(
|
run_create_test!(
|
||||||
|
Err(OperationError::Plugin),
|
||||||
preload,
|
preload,
|
||||||
create,
|
create,
|
||||||
false,
|
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());
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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.
|
// Test helpers for all plugins.
|
||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! run_pre_create_test {
|
macro_rules! run_create_test {
|
||||||
(
|
(
|
||||||
$preload_entries:ident,
|
$expect:expr,
|
||||||
$create_entries:ident,
|
$preload_entries:ident,
|
||||||
$ident:ident,
|
$create_entries:ident,
|
||||||
$internal:ident,
|
$internal:ident,
|
||||||
$test_fn:expr
|
$check:expr
|
||||||
) => {{
|
) => {{
|
||||||
let mut au = AuditScope::new("run_pre_create_test");
|
let mut au = AuditScope::new("run_create_test");
|
||||||
audit_segment!(au, || {
|
audit_segment!(au, || {
|
||||||
// Create an in memory BE
|
let qs = setup_test!(&mut au, $preload_entries);
|
||||||
let be = Backend::new(&mut au, "").unwrap();
|
|
||||||
|
|
||||||
let schema_outer = Schema::new(&mut au).unwrap();
|
let ce = if $internal {
|
||||||
{
|
CreateEvent::new_internal($create_entries.clone())
|
||||||
let mut schema = schema_outer.write();
|
} else {
|
||||||
schema.bootstrap_core(&mut au).unwrap();
|
CreateEvent::from_vec($create_entries.clone())
|
||||||
schema.commit().unwrap();
|
};
|
||||||
}
|
|
||||||
let qs = QueryServer::new(be, Arc::new(schema_outer));
|
|
||||||
|
|
||||||
if !$preload_entries.is_empty() {
|
let mut au_test = AuditScope::new("create_test");
|
||||||
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 qs_write = qs.write();
|
let qs_write = qs.write();
|
||||||
audit_segment!(au_test, || $test_fn(
|
let r = qs_write.create(&mut au_test, &ce);
|
||||||
&mut au_test,
|
assert!(r == $expect);
|
||||||
&qs_write,
|
$check(&mut au_test, &qs_write);
|
||||||
&mut $create_entries,
|
r.map(|_| {
|
||||||
&ce,
|
assert!(qs_write.commit(&mut au_test).is_ok());
|
||||||
));
|
});
|
||||||
assert!(qs_write.commit(&mut au).is_ok());
|
|
||||||
}
|
}
|
||||||
// Make sure there are no errors.
|
// Make sure there are no errors.
|
||||||
assert!(qs.verify(&mut au_test).len() == 0);
|
assert!(qs.verify(&mut au_test).len() == 0);
|
||||||
|
@ -51,16 +65,81 @@ macro_rules! run_pre_create_test {
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
#[macro_export]
|
#[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_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]
|
let de = if $internal {
|
||||||
macro_rules! run_post_delete_test {
|
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);
|
||||||
|
}};
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::BackendReadTransaction;
|
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
|
||||||
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
|
use crate::error::{ConsistencyError, OperationError};
|
||||||
use error::{ConsistencyError, OperationError};
|
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
|
||||||
use event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
|
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
|
||||||
use schema::SchemaReadTransaction;
|
|
||||||
use server::{QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction};
|
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -86,7 +84,7 @@ 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 mut r = audit_segment!(audit_scope, || <($target_plugin)>::pre_create(
|
let r = audit_segment!(audit_scope, || <($target_plugin)>::pre_create(
|
||||||
&mut audit_scope,
|
&mut audit_scope,
|
||||||
$qs,
|
$qs,
|
||||||
$cand,
|
$cand,
|
||||||
|
@ -133,46 +131,46 @@ impl Plugins {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_post_create(
|
pub fn run_post_create(
|
||||||
au: &mut AuditScope,
|
_au: &mut AuditScope,
|
||||||
qs: &QueryServerWriteTransaction,
|
_qs: &QueryServerWriteTransaction,
|
||||||
cand: &Vec<Entry<EntryValid, EntryNew>>,
|
_cand: &Vec<Entry<EntryValid, EntryNew>>,
|
||||||
ce: &CreateEvent,
|
_ce: &CreateEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_pre_modify(
|
pub fn run_pre_modify(
|
||||||
au: &mut AuditScope,
|
_au: &mut AuditScope,
|
||||||
qs: &QueryServerWriteTransaction,
|
_qs: &QueryServerWriteTransaction,
|
||||||
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
|
_cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
|
||||||
me: &ModifyEvent,
|
_me: &ModifyEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_post_modify(
|
pub fn run_post_modify(
|
||||||
au: &mut AuditScope,
|
_au: &mut AuditScope,
|
||||||
qs: &QueryServerWriteTransaction,
|
_qs: &QueryServerWriteTransaction,
|
||||||
cand: &Vec<Entry<EntryValid, EntryCommitted>>,
|
_cand: &Vec<Entry<EntryValid, EntryCommitted>>,
|
||||||
me: &ModifyEvent,
|
_me: &ModifyEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_pre_delete(
|
pub fn run_pre_delete(
|
||||||
au: &mut AuditScope,
|
_au: &mut AuditScope,
|
||||||
qs: &QueryServerWriteTransaction,
|
_qs: &QueryServerWriteTransaction,
|
||||||
cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
|
_cand: &mut Vec<Entry<EntryInvalid, EntryCommitted>>,
|
||||||
de: &DeleteEvent,
|
_de: &DeleteEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_post_delete(
|
pub fn run_post_delete(
|
||||||
au: &mut AuditScope,
|
_au: &mut AuditScope,
|
||||||
qs: &QueryServerWriteTransaction,
|
_qs: &QueryServerWriteTransaction,
|
||||||
cand: &Vec<Entry<EntryValid, EntryCommitted>>,
|
_cand: &Vec<Entry<EntryValid, EntryCommitted>>,
|
||||||
de: &DeleteEvent,
|
_de: &DeleteEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,12 +9,12 @@
|
||||||
// when that is written, as they *both* manipulate and alter entry reference
|
// when that is written, as they *both* manipulate and alter entry reference
|
||||||
// data, so we should be careful not to step on each other.
|
// data, so we should be careful not to step on each other.
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use entry::{Entry, EntryCommitted, EntryNew, EntryValid};
|
use crate::entry::{Entry, EntryCommitted, EntryNew, EntryValid};
|
||||||
use error::OperationError;
|
use crate::error::OperationError;
|
||||||
use event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
|
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
|
||||||
use plugins::Plugin;
|
use crate::plugins::Plugin;
|
||||||
use server::QueryServerWriteTransaction;
|
use crate::server::QueryServerWriteTransaction;
|
||||||
|
|
||||||
pub struct ReferentialIntegrity;
|
pub struct ReferentialIntegrity;
|
||||||
|
|
||||||
|
@ -52,4 +52,26 @@ impl Plugin for ReferentialIntegrity {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[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
|
||||||
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// use super::entry::Entry;
|
// use super::entry::Entry;
|
||||||
// use super::filter::Filter;
|
// use super::filter::Filter;
|
||||||
|
use crate::error::OperationError;
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use error::OperationError;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
// These proto implementations are here because they have public definitions
|
// These proto implementations are here because they have public definitions
|
||||||
|
|
|
@ -1,20 +1,20 @@
|
||||||
use actix::prelude::*;
|
use actix::prelude::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::Backend;
|
use crate::be::Backend;
|
||||||
|
|
||||||
use error::OperationError;
|
use crate::error::OperationError;
|
||||||
use event::{
|
use crate::event::{
|
||||||
CreateEvent, DeleteEvent, ModifyEvent, OpResult, PurgeRecycledEvent, PurgeTombstoneEvent,
|
CreateEvent, DeleteEvent, ModifyEvent, OpResult, PurgeRecycledEvent, PurgeTombstoneEvent,
|
||||||
SearchEvent, SearchResult,
|
SearchEvent, SearchResult,
|
||||||
};
|
};
|
||||||
use log::EventLog;
|
use crate::log::EventLog;
|
||||||
use schema::{Schema, SchemaReadTransaction};
|
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,
|
AuthRequest, CreateRequest, DeleteRequest, ModifyRequest, OperationResponse, SearchRequest,
|
||||||
SearchResponse,
|
SearchResponse,
|
||||||
};
|
};
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use constants::*;
|
use crate::constants::*;
|
||||||
use error::{ConsistencyError, OperationError, SchemaError};
|
use crate::error::{ConsistencyError, OperationError, SchemaError};
|
||||||
use regex::Regex;
|
use regex::Regex;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
@ -1006,13 +1006,13 @@ impl Schema {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use constants::*;
|
use crate::constants::*;
|
||||||
use entry::{Entry, EntryInvalid, EntryNew, EntryValid};
|
use crate::entry::{Entry, EntryInvalid, EntryNew, EntryValid};
|
||||||
use error::{ConsistencyError, SchemaError};
|
use crate::error::{ConsistencyError, SchemaError};
|
||||||
use filter::{Filter, FilterValid};
|
use crate::filter::{Filter, FilterValid};
|
||||||
use schema::SchemaReadTransaction;
|
use crate::schema::SchemaReadTransaction;
|
||||||
use schema::{IndexType, Schema, SchemaAttribute, SyntaxType};
|
use crate::schema::{IndexType, Schema, SchemaAttribute, SyntaxType};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
|
@ -3,19 +3,21 @@
|
||||||
// use actix::prelude::*;
|
// use actix::prelude::*;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use be::{
|
use crate::be::{
|
||||||
Backend, BackendError, BackendReadTransaction, BackendTransaction, BackendWriteTransaction,
|
Backend, BackendError, BackendReadTransaction, BackendTransaction, BackendWriteTransaction,
|
||||||
};
|
};
|
||||||
|
|
||||||
use constants::{JSON_ANONYMOUS_V1, JSON_SYSTEM_INFO_V1};
|
use crate::constants::{JSON_ANONYMOUS_V1, JSON_SYSTEM_INFO_V1};
|
||||||
use entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
|
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntryValid};
|
||||||
use error::{ConsistencyError, OperationError, SchemaError};
|
use crate::error::{ConsistencyError, OperationError, SchemaError};
|
||||||
use event::{CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent};
|
use crate::event::{
|
||||||
use filter::{Filter, FilterInvalid};
|
CreateEvent, DeleteEvent, ExistsEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent,
|
||||||
use modify::{Modify, ModifyInvalid, ModifyList};
|
};
|
||||||
use plugins::Plugins;
|
use crate::filter::{Filter, FilterInvalid};
|
||||||
use schema::{
|
use crate::modify::{Modify, ModifyInvalid, ModifyList};
|
||||||
|
use crate::plugins::Plugins;
|
||||||
|
use crate::schema::{
|
||||||
Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction, SyntaxType,
|
Schema, SchemaReadTransaction, SchemaTransaction, SchemaWriteTransaction, SyntaxType,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -344,7 +346,7 @@ pub trait QueryServerReadTransaction {
|
||||||
}
|
}
|
||||||
|
|
||||||
// In the opposite direction, we can resolve values for presentation
|
// 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())
|
Ok(value.clone())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -939,7 +941,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
|
|
||||||
pub fn internal_exists_or_create(
|
pub fn internal_exists_or_create(
|
||||||
&self,
|
&self,
|
||||||
e: Entry<EntryValid, EntryNew>,
|
_e: Entry<EntryValid, EntryNew>,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
// If the thing exists, stop.
|
// If the thing exists, stop.
|
||||||
// if not, create from Entry.
|
// if not, create from Entry.
|
||||||
|
@ -1116,23 +1118,21 @@ mod tests {
|
||||||
*/
|
*/
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
use super::super::audit::AuditScope;
|
use crate::audit::AuditScope;
|
||||||
use super::super::be::Backend;
|
use crate::be::Backend;
|
||||||
use super::super::entry::{Entry, EntryInvalid, EntryNew};
|
use crate::entry::{Entry, EntryInvalid, EntryNew};
|
||||||
use super::super::error::{OperationError, SchemaError};
|
use crate::error::{OperationError, SchemaError};
|
||||||
use super::super::event::{
|
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent};
|
||||||
CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent,
|
use crate::filter::Filter;
|
||||||
};
|
use crate::modify::{Modify, ModifyList};
|
||||||
use super::super::filter::Filter;
|
use crate::proto_v1::Filter as ProtoFilter;
|
||||||
use super::super::modify::{Modify, ModifyList};
|
use crate::proto_v1::Modify as ProtoModify;
|
||||||
use super::super::proto_v1::Filter as ProtoFilter;
|
use crate::proto_v1::ModifyList as ProtoModifyList;
|
||||||
use super::super::proto_v1::Modify as ProtoModify;
|
use crate::proto_v1::{
|
||||||
use super::super::proto_v1::ModifyList as ProtoModifyList;
|
|
||||||
use super::super::proto_v1::{
|
|
||||||
DeleteRequest, ModifyRequest, ReviveRecycledRequest, SearchRecycledRequest, SearchRequest,
|
DeleteRequest, ModifyRequest, ReviveRecycledRequest, SearchRecycledRequest, SearchRequest,
|
||||||
};
|
};
|
||||||
use super::super::schema::Schema;
|
use crate::schema::Schema;
|
||||||
use super::super::server::{QueryServer, QueryServerReadTransaction};
|
use crate::server::{QueryServer, QueryServerReadTransaction};
|
||||||
|
|
||||||
macro_rules! run_test {
|
macro_rules! run_test {
|
||||||
($test_fn:expr) => {{
|
($test_fn:expr) => {{
|
||||||
|
|
Loading…
Reference in a new issue