62 idm qs cleanup (#419)

This commit is contained in:
Firstyear 2021-04-25 11:35:02 +10:00 committed by GitHub
parent 8da89613e3
commit 6f222f6408
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
30 changed files with 390 additions and 515 deletions

View file

@ -26,17 +26,15 @@ use std::cell::Cell;
use std::ops::DerefMut;
use uuid::Uuid;
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInit, EntryNew, EntryReduced, EntrySealed};
use crate::filter::{Filter, FilterValid, FilterValidResolved};
use crate::modify::Modify;
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::prelude::*;
use crate::value::PartialValue;
use crate::event::{
CreateEvent, DeleteEvent, Event, EventOrigin, EventOriginId, ModifyEvent, SearchEvent,
};
use smartstring::alias::String as AttrString;
// const ACP_RELATED_SEARCH_CACHE_MAX: usize = 2048;
// const ACP_RELATED_SEARCH_CACHE_LOCAL: usize = 16;
@ -1456,16 +1454,8 @@ mod tests {
AccessControlCreate, AccessControlDelete, AccessControlModify, AccessControlProfile,
AccessControlSearch, AccessControls, AccessControlsTransaction,
};
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInit, EntryNew, EntryReduced};
// use crate::server::QueryServerWriteTransaction;
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
// use crate::filter::Filter;
// use crate::proto_v1::Filter as ProtoFilter;
use crate::constants::{JSON_ADMIN_V1, JSON_ANONYMOUS_V1, JSON_TESTPERSON1, JSON_TESTPERSON2};
use crate::value::{PartialValue, Value};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
macro_rules! acp_from_entry_err {
(

View file

@ -2,7 +2,7 @@ use tokio::sync::mpsc::UnboundedSender as Sender;
use std::sync::Arc;
use crate::audit::AuditScope;
use crate::prelude::*;
use crate::event::{AuthEvent, AuthResult, SearchEvent, SearchResult, WhoamiResult};
use crate::idm::event::{
@ -15,7 +15,6 @@ use kanidm_proto::v1::{OperationError, RadiusAuthToken};
use crate::filter::{Filter, FilterInvalid};
use crate::idm::server::IdmServer;
use crate::ldap::{LdapBoundToken, LdapResponseState, LdapServer};
use crate::server::{QueryServer, QueryServerTransaction};
use kanidm_proto::v1::Entry as ProtoEntry;
use kanidm_proto::v1::{
@ -145,7 +144,6 @@ pub struct LdapRequestMessage {
pub struct QueryServerReadV1 {
log: Sender<AuditScope>,
log_level: Option<u32>,
qs: QueryServer,
idms: Arc<IdmServer>,
ldap: Arc<LdapServer>,
}
@ -154,7 +152,6 @@ impl QueryServerReadV1 {
pub fn new(
log: Sender<AuditScope>,
log_level: Option<u32>,
qs: QueryServer,
idms: Arc<IdmServer>,
ldap: Arc<LdapServer>,
) -> Self {
@ -162,7 +159,6 @@ impl QueryServerReadV1 {
QueryServerReadV1 {
log,
log_level,
qs,
idms,
ldap,
}
@ -171,17 +167,10 @@ impl QueryServerReadV1 {
pub fn start_static(
log: Sender<AuditScope>,
log_level: Option<u32>,
query_server: QueryServer,
idms: Arc<IdmServer>,
ldap: Arc<LdapServer>,
) -> &'static Self {
let x = Box::new(QueryServerReadV1::new(
log,
log_level,
query_server,
idms,
ldap,
));
let x = Box::new(QueryServerReadV1::new(log, log_level, idms, ldap));
let x_ref = Box::leak(x);
&(*x_ref)
@ -198,10 +187,10 @@ impl QueryServerReadV1 {
) -> Result<SearchResponse, OperationError> {
let mut audit = AuditScope::new("search", msg.eventid, self.log_level);
// Begin a read
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(&mut audit, "actors::v1_read::handle<SearchMessage>", || {
// Make an event from the request
let srch = match SearchEvent::from_message(&mut audit, &msg, &qs_read) {
let srch = match SearchEvent::from_message(&mut audit, &msg, &idms_prox_read.qs_read) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin search: {:?}", e);
@ -211,10 +200,9 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => {
SearchResult::new(&mut audit, &qs_read, &entries).map(|ok_sr| ok_sr.response())
}
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => SearchResult::new(&mut audit, &idms_prox_read.qs_read, &entries)
.map(|ok_sr| ok_sr.response()),
Err(e) => Err(e),
}
});
@ -232,7 +220,7 @@ impl QueryServerReadV1 {
// the credentials provided is sufficient to say if someone is
// "authenticated" or not.
let mut audit = AuditScope::new("auth", msg.eventid, self.log_level);
let mut idm_write = self.idms.write_async().await;
let mut idm_auth = self.idms.auth_async().await;
// let res = lperf_op_segment!(&mut audit, "actors::v1_read::handle<AuthMessage>", || {
lsecurity!(audit, "Begin auth event {:?}", msg);
@ -254,14 +242,14 @@ impl QueryServerReadV1 {
// Trigger a session clean *before* we take any auth steps.
// It's important to do this before to ensure that timeouts on
// the session are enforced.
idm_write.expire_auth_sessions(ct).await;
idm_auth.expire_auth_sessions(ct).await;
// Generally things like auth denied are in Ok() msgs
// so true errors should always trigger a rollback.
let res = idm_write
let res = idm_auth
.auth(&mut audit, &ae, ct)
.await
.and_then(|r| idm_write.commit(&mut audit).map(|_| r));
.and_then(|r| idm_auth.commit(&mut audit).map(|_| r));
lsecurity!(audit, "Sending auth result -> {:?}", res);
// Build the result.
@ -283,7 +271,7 @@ impl QueryServerReadV1 {
let mut audit = AuditScope::new("whoami", msg.eventid, self.log_level);
// TODO #62: Move this to IdmServer!!!
// Begin a read
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(&mut audit, "actors::v1_read::handle<WhoamiMessage>", || {
// Make an event from the whoami request. This will process the event and
// generate a selfuuid search.
@ -294,18 +282,21 @@ impl QueryServerReadV1 {
// this far.
let uat = msg.uat.clone().ok_or(OperationError::NotAuthenticated)?;
let srch =
match SearchEvent::from_whoami_request(&mut audit, msg.uat.as_ref(), &qs_read) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin whoami: {:?}", e);
return Err(e);
}
};
let srch = match SearchEvent::from_whoami_request(
&mut audit,
msg.uat.as_ref(),
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin whoami: {:?}", e);
return Err(e);
}
};
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(mut entries) => {
// assert there is only one ...
match entries.len() {
@ -314,7 +305,7 @@ impl QueryServerReadV1 {
#[allow(clippy::expect_used)]
let e = entries.pop().expect("Entry length mismatch!!!");
// Now convert to a response, and return
WhoamiResult::new(&mut audit, &qs_read, &e, uat)
WhoamiResult::new(&mut audit, &idms_prox_read.qs_read, &e, uat)
.map(|ok_wr| ok_wr.response())
}
// Somehow we matched multiple, which should be impossible.
@ -339,13 +330,17 @@ impl QueryServerReadV1 {
msg: InternalSearchMessage,
) -> Result<Vec<ProtoEntry>, OperationError> {
let mut audit = AuditScope::new("internal_search_message", msg.eventid, self.log_level);
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalSearchMessage>",
|| {
// Make an event from the request
let srch = match SearchEvent::from_internal_message(&mut audit, msg, &qs_read) {
let srch = match SearchEvent::from_internal_message(
&mut audit,
msg,
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin internal api search: {:?}", e);
@ -355,8 +350,8 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => SearchResult::new(&mut audit, &qs_read, &entries)
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => SearchResult::new(&mut audit, &idms_prox_read.qs_read, &entries)
.map(|ok_sr| ok_sr.into_proto_array()),
Err(e) => Err(e),
}
@ -378,26 +373,29 @@ impl QueryServerReadV1 {
msg.eventid,
self.log_level,
);
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalSearchRecycledMessage>",
|| {
// Make an event from the request
let srch =
match SearchEvent::from_internal_recycle_message(&mut audit, msg, &qs_read) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin recycled search: {:?}", e);
return Err(e);
}
};
let srch = match SearchEvent::from_internal_recycle_message(
&mut audit,
msg,
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
ladmin_error!(audit, "Failed to begin recycled search: {:?}", e);
return Err(e);
}
};
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => SearchResult::new(&mut audit, &qs_read, &entries)
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(entries) => SearchResult::new(&mut audit, &idms_prox_read.qs_read, &entries)
.map(|ok_sr| ok_sr.into_proto_array()),
Err(e) => Err(e),
}
@ -416,12 +414,13 @@ impl QueryServerReadV1 {
) -> Result<Option<String>, OperationError> {
let mut audit =
AuditScope::new("internal_radius_read_message", msg.eventid, self.log_level);
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalRadiusReadMessage>",
|| {
let target_uuid = qs_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
ladmin_error!(&mut audit, "Error resolving id to target");
@ -433,7 +432,7 @@ impl QueryServerReadV1 {
&mut audit,
msg.uat.as_ref(),
target_uuid,
&qs_read,
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
@ -445,7 +444,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", srch);
// We have to use search_ext to guarantee acs was applied.
match qs_read.search_ext(&mut audit, &srch) {
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(mut entries) => {
let r = entries
.pop()
@ -476,13 +475,13 @@ impl QueryServerReadV1 {
msg.eventid,
self.log_level,
);
let mut idm_read = self.idms.proxy_read_async().await;
let mut idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalRadiusTokenReadMessage>",
|| {
let target_uuid = idm_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
@ -493,7 +492,7 @@ impl QueryServerReadV1 {
// Make an event from the request
let rate = match RadiusAuthTokenEvent::from_parts(
&mut audit,
&idm_read.qs_read,
&idms_prox_read.qs_read,
msg.uat.as_ref(),
target_uuid,
) {
@ -513,7 +512,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", rate);
idm_read.get_radiusauthtoken(&mut audit, &rate, ct)
idms_prox_read.get_radiusauthtoken(&mut audit, &rate, ct)
}
);
self.log.send(audit).map_err(|_| {
@ -532,13 +531,13 @@ impl QueryServerReadV1 {
msg.eventid,
self.log_level,
);
let mut idm_read = self.idms.proxy_read_async().await;
let mut idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalUnixUserTokenReadMessage>",
|| {
let target_uuid = idm_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
@ -554,7 +553,7 @@ impl QueryServerReadV1 {
// Make an event from the request
let rate = match UnixUserTokenEvent::from_parts(
&mut audit,
&idm_read.qs_read,
&idms_prox_read.qs_read,
msg.uat.as_ref(),
target_uuid,
) {
@ -574,7 +573,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", rate);
idm_read.get_unixusertoken(&mut audit, &rate, ct)
idms_prox_read.get_unixusertoken(&mut audit, &rate, ct)
}
);
self.log.send(audit).map_err(|_| {
@ -593,12 +592,12 @@ impl QueryServerReadV1 {
msg.eventid,
self.log_level,
);
let mut idm_read = self.idms.proxy_read_async().await;
let mut idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalUnixGroupTokenReadMessage>",
|| {
let target_uuid = idm_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
@ -609,7 +608,7 @@ impl QueryServerReadV1 {
// Make an event from the request
let rate = match UnixGroupTokenEvent::from_parts(
&mut audit,
&idm_read.qs_read,
&idms_prox_read.qs_read,
msg.uat.as_ref(),
target_uuid,
) {
@ -622,7 +621,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", rate);
idm_read.get_unixgrouptoken(&mut audit, &rate)
idms_prox_read.get_unixgrouptoken(&mut audit, &rate)
}
);
self.log.send(audit).map_err(|_| {
@ -638,12 +637,13 @@ impl QueryServerReadV1 {
) -> Result<Vec<String>, OperationError> {
let mut audit =
AuditScope::new("internal_sshkey_read_message", msg.eventid, self.log_level);
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalSshKeyReadMessage>",
|| {
let target_uuid = qs_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
ladmin_error!(&mut audit, "Error resolving id to target");
@ -655,7 +655,7 @@ impl QueryServerReadV1 {
&mut audit,
msg.uat.as_ref(),
target_uuid,
&qs_read,
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
@ -666,7 +666,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(mut entries) => {
let r = entries
.pop()
@ -705,12 +705,13 @@ impl QueryServerReadV1 {
} = msg;
let mut audit =
AuditScope::new("internal_sshkey_tag_read_message", eventid, self.log_level);
let qs_read = self.qs.read_async().await;
let idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<InternalSshKeyTagReadMessage>",
|| {
let target_uuid = qs_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, uuid_or_name.as_str())
.map_err(|e| {
ladmin_info!(&mut audit, "Error resolving id to target");
@ -722,7 +723,7 @@ impl QueryServerReadV1 {
&mut audit,
uat.as_ref(),
target_uuid,
&qs_read,
&idms_prox_read.qs_read,
) {
Ok(s) => s,
Err(e) => {
@ -733,7 +734,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", srch);
match qs_read.search_ext(&mut audit, &srch) {
match idms_prox_read.qs_read.search_ext(&mut audit, &srch) {
Ok(mut entries) => {
let r = entries
.pop()
@ -771,10 +772,10 @@ impl QueryServerReadV1 {
msg: IdmAccountUnixAuthMessage,
) -> Result<Option<UnixUserToken>, OperationError> {
let mut audit = AuditScope::new("idm_account_unix_auth", msg.eventid, self.log_level);
let mut idm_write = self.idms.write_async().await;
let mut idm_auth = self.idms.auth_async().await;
// let res = lperf_op_segment!(&mut audit, "actors::v1_read::handle<IdmAccountUnixAuthMessage>", || {
// resolve the id
let target_uuid = idm_write
let target_uuid = idm_auth
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
@ -784,7 +785,7 @@ impl QueryServerReadV1 {
// Make an event from the request
let uuae = match UnixUserAuthEvent::from_parts(
&mut audit,
&idm_write.qs_read,
&idm_auth.qs_read,
msg.uat.as_ref(),
target_uuid,
msg.cred,
@ -805,10 +806,10 @@ impl QueryServerReadV1 {
OperationError::InvalidState
})?;
let res = idm_write
let res = idm_auth
.auth_unix(&mut audit, &uuae, ct)
.await
.and_then(|r| idm_write.commit(&mut audit).map(|_| r));
.and_then(|r| idm_auth.commit(&mut audit).map(|_| r));
lsecurity!(audit, "Sending result -> {:?}", res);
// res
@ -826,13 +827,13 @@ impl QueryServerReadV1 {
) -> Result<CredentialStatus, OperationError> {
let mut audit =
AuditScope::new("idm_credential_status_message", msg.eventid, self.log_level);
let mut idm_read = self.idms.proxy_read_async().await;
let mut idms_prox_read = self.idms.proxy_read_async().await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_read::handle<IdmCredentialStatusMessage>",
|| {
let target_uuid = idm_read
let target_uuid = idms_prox_read
.qs_read
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
@ -843,7 +844,7 @@ impl QueryServerReadV1 {
// Make an event from the request
let cse = match CredentialStatusEvent::from_parts(
&mut audit,
&idm_read.qs_read,
&idms_prox_read.qs_read,
msg.uat.as_ref(),
target_uuid,
) {
@ -856,7 +857,7 @@ impl QueryServerReadV1 {
ltrace!(audit, "Begin event {:?}", cse);
idm_read.get_credentialstatus(&mut audit, &cse)
idms_prox_read.get_credentialstatus(&mut audit, &cse)
}
);
self.log.send(audit).map_err(|_| {

View file

@ -1,8 +1,9 @@
use crate::audit::AuditScope;
use std::iter;
use std::sync::Arc;
use tokio::sync::mpsc::UnboundedSender as Sender;
use crate::prelude::*;
use crate::event::{
CreateEvent, DeleteEvent, ModifyEvent, PurgeRecycledEvent, PurgeTombstoneEvent,
ReviveRecycledEvent,
@ -19,7 +20,6 @@ use kanidm_proto::v1::OperationError;
use crate::filter::{Filter, FilterInvalid};
use crate::idm::delayed::DelayedAction;
use crate::idm::server::IdmServer;
use crate::server::{QueryServer, QueryServerTransaction};
use crate::utils::duration_from_epoch_now;
use kanidm_proto::v1::Entry as ProtoEntry;
@ -242,22 +242,15 @@ pub struct SetAttributeMessage {
pub struct QueryServerWriteV1 {
log: Sender<AuditScope>,
log_level: Option<u32>,
qs: QueryServer,
idms: Arc<IdmServer>,
}
impl QueryServerWriteV1 {
pub fn new(
log: Sender<AuditScope>,
log_level: Option<u32>,
qs: QueryServer,
idms: Arc<IdmServer>,
) -> Self {
pub fn new(log: Sender<AuditScope>, log_level: Option<u32>, idms: Arc<IdmServer>) -> Self {
info!("Starting query server v1 worker ...");
QueryServerWriteV1 {
log,
log_level,
qs,
idms,
}
}
@ -265,10 +258,9 @@ impl QueryServerWriteV1 {
pub fn start_static(
log: Sender<AuditScope>,
log_level: Option<u32>,
query_server: QueryServer,
idms: Arc<IdmServer>,
) -> &'static QueryServerWriteV1 {
let x = Box::new(QueryServerWriteV1::new(log, log_level, query_server, idms));
let x = Box::new(QueryServerWriteV1::new(log, log_level, idms));
let x_ptr = Box::leak(x);
&(*x_ptr)
@ -283,12 +275,15 @@ impl QueryServerWriteV1 {
proto_ml: &ProtoModifyList,
filter: Filter<FilterInvalid>,
) -> Result<(), OperationError> {
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
lperf_op_segment!(audit, audit_tag, || {
let target_uuid = qs_write.name_to_uuid(audit, uuid_or_name).map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
e
})?;
let target_uuid = idms_prox_write
.qs_write
.name_to_uuid(audit, uuid_or_name)
.map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
e
})?;
let mdf = match ModifyEvent::from_parts(
audit,
@ -296,7 +291,7 @@ impl QueryServerWriteV1 {
target_uuid,
proto_ml,
filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(m) => m,
Err(e) => {
@ -307,9 +302,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin modify event {:?}", mdf);
qs_write
idms_prox_write
.qs_write
.modify(audit, &mdf)
.and_then(|_| qs_write.commit(audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(audit).map(|_| ()))
})
}
@ -322,12 +318,15 @@ impl QueryServerWriteV1 {
ml: &ModifyList<ModifyInvalid>,
filter: Filter<FilterInvalid>,
) -> Result<(), OperationError> {
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
lperf_op_segment!(audit, audit_tag, || {
let target_uuid = qs_write.name_to_uuid(audit, uuid_or_name).map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
e
})?;
let target_uuid = idms_prox_write
.qs_write
.name_to_uuid(audit, uuid_or_name)
.map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
e
})?;
let mdf = match ModifyEvent::from_internal_parts(
audit,
@ -335,7 +334,7 @@ impl QueryServerWriteV1 {
target_uuid,
ml,
filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(m) => m,
Err(e) => {
@ -346,9 +345,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin modify event {:?}", mdf);
qs_write
idms_prox_write
.qs_write
.modify(audit, &mdf)
.and_then(|_| qs_write.commit(audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(audit).map(|_| ()))
})
}
@ -357,24 +357,30 @@ impl QueryServerWriteV1 {
msg: CreateMessage,
) -> Result<OperationResponse, OperationError> {
let mut audit = AuditScope::new("create", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<CreateMessage>",
|| {
let crt = match CreateEvent::from_message(&mut audit, &msg, &qs_write) {
Ok(c) => c,
Err(e) => {
ladmin_warning!(audit, "Failed to begin create: {:?}", e);
return Err(e);
}
};
let crt =
match CreateEvent::from_message(&mut audit, &msg, &idms_prox_write.qs_write) {
Ok(c) => c,
Err(e) => {
ladmin_warning!(audit, "Failed to begin create: {:?}", e);
return Err(e);
}
};
ltrace!(audit, "Begin create event {:?}", crt);
qs_write
idms_prox_write
.qs_write
.create(&mut audit, &crt)
.and_then(|_| qs_write.commit(&mut audit).map(|_| OperationResponse {}))
.and_then(|_| {
idms_prox_write
.commit(&mut audit)
.map(|_| OperationResponse {})
})
}
);
// At the end of the event we send it for logging.
@ -390,24 +396,30 @@ impl QueryServerWriteV1 {
msg: ModifyMessage,
) -> Result<OperationResponse, OperationError> {
let mut audit = AuditScope::new("modify", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_segment!(
&mut audit,
"actors::v1_write::handle<ModifyMessage>",
|| {
let mdf = match ModifyEvent::from_message(&mut audit, &msg, &qs_write) {
Ok(m) => m,
Err(e) => {
ladmin_error!(audit, "Failed to begin modify: {:?}", e);
return Err(e);
}
};
let mdf =
match ModifyEvent::from_message(&mut audit, &msg, &idms_prox_write.qs_write) {
Ok(m) => m,
Err(e) => {
ladmin_error!(audit, "Failed to begin modify: {:?}", e);
return Err(e);
}
};
ltrace!(audit, "Begin modify event {:?}", mdf);
qs_write
idms_prox_write
.qs_write
.modify(&mut audit, &mdf)
.and_then(|_| qs_write.commit(&mut audit).map(|_| OperationResponse {}))
.and_then(|_| {
idms_prox_write
.commit(&mut audit)
.map(|_| OperationResponse {})
})
}
);
self.log.send(audit).map_err(|_| {
@ -422,24 +434,30 @@ impl QueryServerWriteV1 {
msg: DeleteMessage,
) -> Result<OperationResponse, OperationError> {
let mut audit = AuditScope::new("delete", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<DeleteMessage>",
|| {
let del = match DeleteEvent::from_message(&mut audit, &msg, &qs_write) {
Ok(d) => d,
Err(e) => {
ladmin_error!(audit, "Failed to begin delete: {:?}", e);
return Err(e);
}
};
let del =
match DeleteEvent::from_message(&mut audit, &msg, &idms_prox_write.qs_write) {
Ok(d) => d,
Err(e) => {
ladmin_error!(audit, "Failed to begin delete: {:?}", e);
return Err(e);
}
};
ltrace!(audit, "Begin delete event {:?}", del);
qs_write
idms_prox_write
.qs_write
.delete(&mut audit, &del)
.and_then(|_| qs_write.commit(&mut audit).map(|_| OperationResponse {}))
.and_then(|_| {
idms_prox_write
.commit(&mut audit)
.map(|_| OperationResponse {})
})
}
);
self.log.send(audit).map_err(|_| {
@ -454,7 +472,7 @@ impl QueryServerWriteV1 {
msg: InternalDeleteMessage,
) -> Result<(), OperationError> {
let mut audit = AuditScope::new("internal_delete", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<InternalDeleteMessage>",
@ -463,7 +481,7 @@ impl QueryServerWriteV1 {
&mut audit,
msg.uat.as_ref(),
&msg.filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(d) => d,
Err(e) => {
@ -474,9 +492,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin delete event {:?}", del);
qs_write
idms_prox_write
.qs_write
.delete(&mut audit, &del)
.and_then(|_| qs_write.commit(&mut audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(&mut audit).map(|_| ()))
}
);
self.log.send(audit).map_err(|_| {
@ -491,7 +510,7 @@ impl QueryServerWriteV1 {
msg: ReviveRecycledMessage,
) -> Result<(), OperationError> {
let mut audit = AuditScope::new("revive", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<ReviveRecycledMessage>",
@ -500,7 +519,7 @@ impl QueryServerWriteV1 {
&mut audit,
msg.uat.as_ref(),
&msg.filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(r) => r,
Err(e) => {
@ -511,9 +530,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin revive event {:?}", rev);
qs_write
idms_prox_write
.qs_write
.revive_recycled(&mut audit, &rev)
.and_then(|_| qs_write.commit(&mut audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(&mut audit).map(|_| ()))
}
);
self.log.send(audit).map_err(|_| {
@ -823,12 +843,13 @@ impl QueryServerWriteV1 {
msg: PurgeAttributeMessage,
) -> Result<(), OperationError> {
let mut audit = AuditScope::new("purge_attribute", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<PurgeAttributeMessage>",
|| {
let target_uuid = qs_write
let target_uuid = idms_prox_write
.qs_write
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
@ -841,7 +862,7 @@ impl QueryServerWriteV1 {
target_uuid,
&msg.attr,
msg.filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(m) => m,
Err(e) => {
@ -852,9 +873,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin modify event {:?}", mdf);
qs_write
idms_prox_write
.qs_write
.modify(&mut audit, &mdf)
.and_then(|_| qs_write.commit(&mut audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(&mut audit).map(|_| ()))
}
);
self.log.send(audit).map_err(|_| {
@ -869,12 +891,13 @@ impl QueryServerWriteV1 {
msg: RemoveAttributeValueMessage,
) -> Result<(), OperationError> {
let mut audit = AuditScope::new("remove_attribute_value", msg.eventid, self.log_level);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
let res = lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<RemoveAttributeValueMessage>",
|| {
let target_uuid = qs_write
let target_uuid = idms_prox_write
.qs_write
.name_to_uuid(&mut audit, msg.uuid_or_name.as_str())
.map_err(|e| {
ladmin_error!(audit, "Error resolving id to target");
@ -890,7 +913,7 @@ impl QueryServerWriteV1 {
target_uuid,
&proto_ml,
msg.filter,
&qs_write,
&idms_prox_write.qs_write,
) {
Ok(m) => m,
Err(e) => {
@ -901,9 +924,10 @@ impl QueryServerWriteV1 {
ltrace!(audit, "Begin modify event {:?}", mdf);
qs_write
idms_prox_write
.qs_write
.modify(&mut audit, &mdf)
.and_then(|_| qs_write.commit(&mut audit).map(|_| ()))
.and_then(|_| idms_prox_write.commit(&mut audit).map(|_| ()))
}
);
self.log.send(audit).map_err(|_| {
@ -1219,15 +1243,16 @@ impl QueryServerWriteV1 {
let mut audit = AuditScope::new("purge tombstones", msg.eventid, self.log_level);
ltrace!(audit, "Begin purge tombstone event {:?}", msg);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<PurgeTombstoneEvent>",
|| {
let res = qs_write
let res = idms_prox_write
.qs_write
.purge_tombstones(&mut audit)
.and_then(|_| qs_write.commit(&mut audit));
.and_then(|_| idms_prox_write.commit(&mut audit));
ladmin_info!(audit, "Purge tombstones result: {:?}", res);
#[allow(clippy::expect_used)]
res.expect("Invalid Server State");
@ -1242,14 +1267,15 @@ impl QueryServerWriteV1 {
pub(crate) async fn handle_purgerecycledevent(&self, msg: PurgeRecycledEvent) {
let mut audit = AuditScope::new("purge recycled", msg.eventid, self.log_level);
ltrace!(audit, "Begin purge recycled event {:?}", msg);
let qs_write = self.qs.write_async(duration_from_epoch_now()).await;
let idms_prox_write = self.idms.proxy_write_async(duration_from_epoch_now()).await;
lperf_op_segment!(
&mut audit,
"actors::v1_write::handle<PurgeRecycledEvent>",
|| {
let res = qs_write
let res = idms_prox_write
.qs_write
.purge_recycled(&mut audit)
.and_then(|_| qs_write.commit(&mut audit));
.and_then(|_| idms_prox_write.commit(&mut audit));
ladmin_info!(audit, "Purge recycled result: {:?}", res);
#[allow(clippy::expect_used)]
res.expect("Invalid Server State");

View file

@ -6,6 +6,8 @@ use libc::umask;
use std::sync::Arc;
use tokio::sync::mpsc::unbounded_channel as unbounded;
use crate::prelude::*;
use crate::config::Configuration;
// SearchResult
@ -13,14 +15,12 @@ use crate::config::Configuration;
use crate::actors::v1_read::QueryServerReadV1;
use crate::actors::v1_write::QueryServerWriteV1;
use crate::async_log;
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig, BackendTransaction, FsType};
use crate::crypto::setup_tls;
use crate::idm::server::{IdmServer, IdmServerDelayed};
use crate::interval::IntervalActor;
use crate::ldap::LdapServer;
use crate::schema::Schema;
use crate::server::QueryServer;
use crate::status::StatusActor;
use crate::utils::duration_from_epoch_now;
@ -491,7 +491,7 @@ pub async fn create_server_core(config: Configuration) -> Result<(), ()> {
}
};
// Start the IDM server.
let (qs, idms, mut idms_delayed) = match setup_qs_idms(&mut audit, be, schema, &config) {
let (_qs, idms, mut idms_delayed) = match setup_qs_idms(&mut audit, be, schema, &config) {
Ok(t) => t,
Err(e) => {
audit.write_log();
@ -550,18 +550,13 @@ pub async fn create_server_core(config: Configuration) -> Result<(), ()> {
let server_read_ref = QueryServerReadV1::start_static(
log_tx.clone(),
config.log_level,
qs.clone(),
idms_arc.clone(),
ldap_arc.clone(),
);
// Create the server async write entry point.
let server_write_ref = QueryServerWriteV1::start_static(
log_tx.clone(),
config.log_level,
qs.clone(),
idms_arc.clone(),
);
let server_write_ref =
QueryServerWriteV1::start_static(log_tx.clone(), config.log_level, idms_arc.clone());
tokio::spawn(async move {
idms_delayed.process_all(server_write_ref).await;

View file

@ -26,16 +26,13 @@
//! [`filter`]: ../filter/index.html
//! [`schema`]: ../schema/index.html
use crate::audit::AuditScope;
use crate::credential::Credential;
use crate::filter::{Filter, FilterInvalid, FilterResolved, FilterValidResolved};
use crate::ldap::ldap_attr_entry_map;
use crate::modify::{Modify, ModifyInvalid, ModifyList, ModifyValid};
use crate::prelude::*;
use crate::repl::cid::Cid;
use crate::schema::{SchemaAttribute, SchemaClass, SchemaTransaction};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::{IndexType, SyntaxType};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::Entry as ProtoEntry;
@ -91,6 +88,10 @@ lazy_static! {
static ref PVCLASS_RECYCLED: PartialValue = PartialValue::new_class("recycled");
}
pub type EntrySealedCommitted = Entry<EntrySealed, EntryCommitted>;
pub type EntryInvalidCommitted = Entry<EntryInvalid, EntryCommitted>;
pub type EntryTuple = (EntrySealedCommitted, EntryInvalidCommitted);
// Entry should have a lifecycle of types. This is Raw (modifiable) and Entry (verified).
// This way, we can move between them, but only certain actions are possible on either
// This means modifications happen on Raw, but to move to Entry, you schema normalise.

View file

@ -1,7 +1,7 @@
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInit, EntryNew, EntryReduced, EntrySealed};
use crate::filter::{Filter, FilterInvalid, FilterValid};
use crate::idm::AuthState;
use crate::prelude::*;
use crate::schema::SchemaTransaction;
use crate::value::PartialValue;
use kanidm_proto::v1::Entry as ProtoEntry;
@ -11,9 +11,6 @@ use kanidm_proto::v1::{
};
// use error::OperationError;
use crate::modify::{ModifyInvalid, ModifyList, ModifyValid};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use kanidm_proto::v1::OperationError;
use crate::actors::v1_read::{

View file

@ -8,14 +8,11 @@
//! [`Filter`]: struct.Filter.html
//! [`Entry`]: ../entry/struct.Entry.html
use crate::audit::AuditScope;
use crate::be::{IdxKey, IdxKeyRef, IdxKeyToRef, IdxMeta};
use crate::event::{Event, EventOriginId};
use crate::ldap::ldap_attr_filter_map;
use crate::prelude::*;
use crate::schema::SchemaTransaction;
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::{IndexType, PartialValue};
use hashbrown::HashSet;
use kanidm_proto::v1::Filter as ProtoFilter;
@ -1276,16 +1273,13 @@ impl FilterResolved {
#[cfg(test)]
mod tests {
use crate::entry::{Entry, EntryInit, EntryNew, EntrySealed};
use crate::event::{CreateEvent, Event};
use crate::filter::{Filter, FilterInvalid, FILTER_DEPTH_MAX};
use crate::server::QueryServerTransaction;
use crate::value::{PartialValue, Value};
use crate::prelude::*;
use std::cmp::{Ordering, PartialOrd};
use std::collections::BTreeSet;
use kanidm_proto::v1::Filter as ProtoFilter;
use kanidm_proto::v1::OperationError;
use ldap3_server::simple::LdapFilter;
#[test]

View file

@ -1,10 +1,10 @@
use crate::entry::{Entry, EntryCommitted, EntryReduced, EntrySealed};
use kanidm_proto::v1::OperationError;
use crate::prelude::*;
use kanidm_proto::v1::CredentialStatus;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::UserAuthToken;
use crate::audit::AuditScope;
use crate::constants::UUID_ANONYMOUS;
use crate::credential::policy::CryptoPolicy;
use crate::credential::totp::TOTP;
@ -12,7 +12,6 @@ use crate::credential::{softlock::CredSoftLockPolicy, Credential};
use crate::idm::claim::Claim;
use crate::idm::group::Group;
use crate::modify::{ModifyInvalid, ModifyList};
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use std::time::Duration;

View file

@ -1,7 +1,7 @@
use crate::idm::account::Account;
use crate::idm::claim::Claim;
use crate::idm::AuthState;
use crate::{audit::AuditScope, value::Value};
use crate::prelude::*;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::{AuthAllowed, AuthCredential, AuthMech};
@ -726,8 +726,6 @@ impl AuthSession {
#[cfg(test)]
mod tests {
use crate::audit::AuditScope;
use crate::constants::{JSON_ADMIN_V1, JSON_ANONYMOUS_V1};
use crate::credential::policy::CryptoPolicy;
use crate::credential::totp::{TOTP, TOTP_DEFAULT_STEP};
use crate::credential::webauthn::WebauthnDomainConfig;
@ -738,7 +736,7 @@ mod tests {
};
use crate::idm::delayed::DelayedAction;
use crate::idm::AuthState;
use crate::value::Value;
use crate::prelude::*;
pub use std::collections::BTreeSet as Set;
use crate::utils::duration_from_epoch_now;

View file

@ -1,7 +1,6 @@
use crate::actors::v1_write::IdmAccountSetPasswordMessage;
use crate::audit::AuditScope;
use crate::event::Event;
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::prelude::*;
use uuid::Uuid;

View file

@ -1,8 +1,5 @@
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryReduced, EntrySealed};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::prelude::*;
use crate::value::PartialValue;
use kanidm_proto::v1::Group as ProtoGroup;
use kanidm_proto::v1::OperationError;

View file

@ -1,9 +1,9 @@
use crate::idm::group::Group;
use uuid::Uuid;
use crate::audit::AuditScope;
use crate::prelude::*;
use crate::entry::{Entry, EntryCommitted, EntryReduced};
use crate::server::QueryServerReadTransaction;
use crate::value::PartialValue;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::RadiusAuthToken;

View file

@ -1,6 +1,3 @@
use crate::audit::AuditScope;
use crate::constants::{AUTH_SESSION_TIMEOUT, MFAREG_SESSION_TIMEOUT, PW_MIN_LENGTH};
use crate::constants::{UUID_ANONYMOUS, UUID_SYSTEM_CONFIG};
use crate::credential::policy::CryptoPolicy;
use crate::credential::softlock::CredSoftLock;
use crate::credential::webauthn::WebauthnDomainConfig;
@ -18,10 +15,8 @@ use crate::idm::radius::RadiusAccount;
use crate::idm::unix::{UnixGroup, UnixUserAccount};
use crate::idm::AuthState;
use crate::ldap::LdapBoundToken;
use crate::server::QueryServerReadTransaction;
use crate::server::{QueryServer, QueryServerTransaction, QueryServerWriteTransaction};
use crate::prelude::*;
use crate::utils::{password_from_random, readable_password_from_random, uuid_from_duration, SID};
use crate::value::PartialValue;
use crate::actors::v1_write::QueryServerWriteV1;
use crate::idm::delayed::{
@ -29,7 +24,6 @@ use crate::idm::delayed::{
};
use kanidm_proto::v1::CredentialStatus;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::RadiusAuthToken;
use kanidm_proto::v1::SetCredentialResponse;
use kanidm_proto::v1::UnixGroupToken;
@ -50,7 +44,6 @@ use concread::hashmap::HashMap;
use rand::prelude::*;
use std::time::Duration;
use url::Url;
use uuid::Uuid;
use webauthn_rs::Webauthn;
@ -76,12 +69,10 @@ pub struct IdmServer {
webauthn: Webauthn<WebauthnDomainConfig>,
}
pub struct IdmServerWriteTransaction<'a> {
pub struct IdmServerAuthTransaction<'a> {
// Contains methods that require writes, but in the context of writing to
// the idm in memory structures (maybe the query server too). This is
// things like authentication
// _session_ticket: SemaphorePermit<'a>,
// sessions: BptreeMapWriteTxn<'a, Uuid, AuthSession>,
session_ticket: &'a Semaphore,
sessions: &'a BptreeMap<Uuid, AuthSession>,
@ -117,7 +108,7 @@ pub struct IdmServerDelayed {
}
impl IdmServer {
// TODO #59: Make number of authsessions configurable!!!
// TODO: Make number of authsessions configurable!!!
pub fn new(
au: &mut AuditScope,
qs: QueryServer,
@ -185,11 +176,11 @@ impl IdmServer {
}
#[cfg(test)]
pub fn write(&self) -> IdmServerWriteTransaction {
task::block_on(self.write_async())
pub fn auth(&self) -> IdmServerAuthTransaction {
task::block_on(self.auth_async())
}
pub async fn write_async(&self) -> IdmServerWriteTransaction<'_> {
pub async fn auth_async(&self) -> IdmServerAuthTransaction<'_> {
let mut sid = [0; 4];
let mut rng = StdRng::from_entropy();
rng.fill(&mut sid);
@ -197,7 +188,7 @@ impl IdmServer {
// let session_ticket = self.session_ticket.acquire().await;
let qs_read = self.qs.read_async().await;
IdmServerWriteTransaction {
IdmServerAuthTransaction {
// _session_ticket: session_ticket,
// sessions: self.sessions.write(),
session_ticket: &self.session_ticket,
@ -289,7 +280,7 @@ impl IdmServerDelayed {
}
}
impl<'a> IdmServerWriteTransaction<'a> {
impl<'a> IdmServerAuthTransaction<'a> {
#[cfg(test)]
pub fn is_sessionid_present(&self, sessionid: &Uuid) -> bool {
let session_read = self.sessions.read();
@ -766,7 +757,7 @@ impl<'a> IdmServerWriteTransaction<'a> {
pub fn commit(self, _au: &mut AuditScope) -> Result<(), OperationError> {
/*
lperf_trace_segment!(au, "idm::server::IdmServerWriteTransaction::commit", || {
lperf_trace_segment!(au, "idm::server::IdmServerAuthTransaction::commit", || {
self.sessions.commit();
Ok(())
})*/
@ -1527,10 +1518,14 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
}
pub fn commit(self, au: &mut AuditScope) -> Result<(), OperationError> {
lperf_trace_segment!(au, "idm::server::IdmServerWriteTransaction::commit", || {
self.mfareg_sessions.commit();
self.qs_write.commit(au)
})
lperf_trace_segment!(
au,
"idm::server::IdmServerProxyWriteTransaction::commit",
|| {
self.mfareg_sessions.commit();
self.qs_write.commit(au)
}
)
}
}
@ -1538,13 +1533,9 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
#[cfg(test)]
mod tests {
use crate::constants::{
AUTH_SESSION_TIMEOUT, MFAREG_SESSION_TIMEOUT, UUID_ADMIN, UUID_ANONYMOUS,
};
use crate::credential::policy::CryptoPolicy;
use crate::credential::totp::TOTP;
use crate::credential::{Credential, Password};
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::event::{AuthEvent, AuthResult, CreateEvent, ModifyEvent};
use crate::idm::delayed::{DelayedAction, WebauthnCounterIncrement};
use crate::idm::event::{
@ -1555,15 +1546,13 @@ mod tests {
};
use crate::idm::AuthState;
use crate::modify::{Modify, ModifyList};
use crate::value::{PartialValue, Value};
use crate::prelude::*;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::SetCredentialResponse;
use kanidm_proto::v1::{AuthAllowed, AuthMech};
use crate::audit::AuditScope;
use crate::idm::server::IdmServer;
// , IdmServerDelayed;
use crate::server::QueryServer;
use crate::utils::duration_from_epoch_now;
use async_std::task;
use smartstring::alias::String as AttrString;
@ -1585,11 +1574,11 @@ mod tests {
au: &mut AuditScope| {
let sid = {
// Start and test anonymous auth.
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
// Send the initial auth event for initialising the session
let anon_init = AuthEvent::anonymous_init();
// Expect success
let r1 = task::block_on(idms_write.auth(
let r1 = task::block_on(idms_auth.auth(
au,
&anon_init,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1631,15 +1620,15 @@ mod tests {
debug!("sessionid is ==> {:?}", sid);
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
sid
};
{
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_begin = AuthEvent::begin_mech(sid, AuthMech::Anonymous);
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_begin,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1676,15 +1665,15 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
};
{
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
// Now send the anonymous request, given the session id.
let anon_step = AuthEvent::cred_step_anonymous(sid);
// Expect success
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1719,7 +1708,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
}
});
}
@ -1732,12 +1721,12 @@ mod tests {
_idms_delayed: &IdmServerDelayed,
au: &mut AuditScope| {
{
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let sid = Uuid::new_v4();
let anon_step = AuthEvent::cred_step_anonymous(sid);
// Expect failure
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1790,10 +1779,10 @@ mod tests {
ct: Duration,
name: &str,
) -> Uuid {
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let admin_init = AuthEvent::named_init(name);
let r1 = task::block_on(idms_write.auth(au, &admin_init, ct));
let r1 = task::block_on(idms_auth.auth(au, &admin_init, ct));
let ar = r1.unwrap();
let AuthResult {
sessionid,
@ -1813,7 +1802,7 @@ mod tests {
// Now push that we want the Password Mech.
let admin_begin = AuthEvent::begin_mech(sessionid, AuthMech::Password);
let r2 = task::block_on(idms_write.auth(au, &admin_begin, ct));
let r2 = task::block_on(idms_auth.auth(au, &admin_begin, ct));
let ar = r2.unwrap();
let AuthResult {
sessionid,
@ -1831,7 +1820,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
sessionid
}
@ -1840,12 +1829,12 @@ mod tests {
let sid =
init_admin_authsession_sid(idms, au, Duration::from_secs(TEST_CURRENT_TIME), "admin");
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid, pw);
// Expect success
let r2 =
task::block_on(idms_write.auth(au, &anon_step, Duration::from_secs(TEST_CURRENT_TIME)));
task::block_on(idms_auth.auth(au, &anon_step, Duration::from_secs(TEST_CURRENT_TIME)));
debug!("r2 ==> {:?}", r2);
match r2 {
@ -1875,7 +1864,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
}
#[test]
@ -1904,11 +1893,11 @@ mod tests {
"admin@example.com",
);
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid, TEST_PASSWORD);
// Expect success
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1940,7 +1929,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
})
}
@ -1957,11 +1946,11 @@ mod tests {
Duration::from_secs(TEST_CURRENT_TIME),
"admin",
);
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid, TEST_PASSWORD_INC);
// Expect success
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -1993,7 +1982,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
})
}
@ -2039,19 +2028,19 @@ mod tests {
Duration::from_secs(TEST_CURRENT_TIME),
"admin",
);
let mut idms_write = idms.write();
assert!(idms_write.is_sessionid_present(&sid));
let mut idms_auth = idms.auth();
assert!(idms_auth.is_sessionid_present(&sid));
// Expire like we are currently "now". Should not affect our session.
task::block_on(idms_write.expire_auth_sessions(Duration::from_secs(TEST_CURRENT_TIME)));
assert!(idms_write.is_sessionid_present(&sid));
task::block_on(idms_auth.expire_auth_sessions(Duration::from_secs(TEST_CURRENT_TIME)));
assert!(idms_auth.is_sessionid_present(&sid));
// Expire as though we are in the future.
task::block_on(
idms_write.expire_auth_sessions(Duration::from_secs(TEST_CURRENT_EXPIRE)),
idms_auth.expire_auth_sessions(Duration::from_secs(TEST_CURRENT_EXPIRE)),
);
assert!(!idms_write.is_sessionid_present(&sid));
assert!(idms_write.commit(au).is_ok());
let idms_write = idms.write();
assert!(!idms_write.is_sessionid_present(&sid));
assert!(!idms_auth.is_sessionid_present(&sid));
assert!(idms_auth.commit(au).is_ok());
let idms_auth = idms.auth();
assert!(!idms_auth.is_sessionid_present(&sid));
})
}
@ -2259,11 +2248,11 @@ mod tests {
assert!(idms_prox_write.set_unix_account_password(au, &pce).is_ok());
assert!(idms_prox_write.commit(au).is_ok());
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
// Check auth verification of the password
let uuae_good = UnixUserAuthEvent::new_internal(&UUID_ADMIN, TEST_PASSWORD);
let a1 = task::block_on(idms_write.auth_unix(
let a1 = task::block_on(idms_auth.auth_unix(
au,
&uuae_good,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2274,7 +2263,7 @@ mod tests {
};
// Check bad password
let uuae_bad = UnixUserAuthEvent::new_internal(&UUID_ADMIN, TEST_PASSWORD_INC);
let a2 = task::block_on(idms_write.auth_unix(
let a2 = task::block_on(idms_auth.auth_unix(
au,
&uuae_bad,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2283,7 +2272,7 @@ mod tests {
Ok(None) => {}
_ => assert!(false),
};
assert!(idms_write.commit(au).is_ok());
assert!(idms_auth.commit(au).is_ok());
// Check deleting the password
let idms_prox_write = idms.proxy_write(duration_from_epoch_now());
@ -2298,8 +2287,8 @@ mod tests {
// And auth should now fail due to the lack of PW material (note that
// softlocking WONT kick in because the cred_uuid is gone!)
let mut idms_write = idms.write();
let a3 = task::block_on(idms_write.auth_unix(
let mut idms_auth = idms.auth();
let a3 = task::block_on(idms_auth.auth_unix(
au,
&uuae_good,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2308,7 +2297,7 @@ mod tests {
Ok(None) => {}
_ => assert!(false),
};
assert!(idms_write.commit(au).is_ok());
assert!(idms_auth.commit(au).is_ok());
})
}
@ -2526,8 +2515,8 @@ mod tests {
idms_delayed.is_empty_or_panic();
// Get the auth ready.
let uuae = UnixUserAuthEvent::new_internal(&UUID_ADMIN, "password");
let mut idms_write = idms.write();
let a1 = task::block_on(idms_write.auth_unix(
let mut idms_auth = idms.auth();
let a1 = task::block_on(idms_auth.auth_unix(
au,
&uuae,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2536,14 +2525,14 @@ mod tests {
Ok(Some(_tok)) => {}
_ => assert!(false),
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// The upgrade was queued
// Process it.
let da = idms_delayed.try_recv().expect("invalid");
let _r = task::block_on(idms.delayed_action(au, duration_from_epoch_now(), da));
// Go again
let mut idms_write = idms.write();
let a2 = task::block_on(idms_write.auth_unix(
let mut idms_auth = idms.auth();
let a2 = task::block_on(idms_auth.auth_unix(
au,
&uuae,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2552,7 +2541,7 @@ mod tests {
Ok(Some(_tok)) => {}
_ => assert!(false),
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// No delayed action was queued.
idms_delayed.is_empty_or_panic();
})
@ -2604,9 +2593,9 @@ mod tests {
let time_low = Duration::from_secs(TEST_NOT_YET_VALID_TIME);
let time_high = Duration::from_secs(TEST_AFTER_EXPIRY);
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let admin_init = AuthEvent::named_init("admin");
let r1 = task::block_on(idms_write.auth(au, &admin_init, time_low));
let r1 = task::block_on(idms_auth.auth(au, &admin_init, time_low));
let ar = r1.unwrap();
let AuthResult {
@ -2623,12 +2612,12 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// And here!
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let admin_init = AuthEvent::named_init("admin");
let r1 = task::block_on(idms_write.auth(au, &admin_init, time_high));
let r1 = task::block_on(idms_auth.auth(au, &admin_init, time_high));
let ar = r1.unwrap();
let AuthResult {
@ -2645,7 +2634,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
})
}
@ -2684,10 +2673,10 @@ mod tests {
assert!(idms_prox_write.commit(au).is_ok());
// Now check auth when the time is too high or too low.
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let uuae_good = UnixUserAuthEvent::new_internal(&UUID_ADMIN, TEST_PASSWORD);
let a1 = task::block_on(idms_write.auth_unix(au, &uuae_good, time_low));
let a1 = task::block_on(idms_auth.auth_unix(au, &uuae_good, time_low));
// Should this actually send an error with the details? Or just silently act as
// badpw?
match a1 {
@ -2695,13 +2684,13 @@ mod tests {
_ => assert!(false),
};
let a2 = task::block_on(idms_write.auth_unix(au, &uuae_good, time_high));
let a2 = task::block_on(idms_auth.auth_unix(au, &uuae_good, time_high));
match a2 {
Ok(None) => {}
_ => assert!(false),
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// Also check the generated unix tokens are invalid.
let mut idms_prox_read = idms.proxy_read();
let uute = UnixUserTokenEvent::new_internal(UUID_ADMIN.clone());
@ -2778,10 +2767,10 @@ mod tests {
Duration::from_secs(TEST_CURRENT_TIME),
"admin",
);
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid, TEST_PASSWORD_INC);
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2811,15 +2800,15 @@ mod tests {
panic!();
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// Auth init, softlock present, count == 1, same time (so before unlock_at)
// aka Auth valid immediate, (ct < exp), autofail
// aka Auth invalid immediate, (ct < exp), autofail
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let admin_init = AuthEvent::named_init("admin");
let r1 = task::block_on(idms_write.auth(
let r1 = task::block_on(idms_auth.auth(
au,
&admin_init,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2842,7 +2831,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// Auth invalid once softlock pass (count == 2, exp_at grows)
// Tested in the softlock state machine.
@ -2855,11 +2844,11 @@ mod tests {
"admin",
);
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid, TEST_PASSWORD);
// Expect success
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME + 2),
@ -2891,7 +2880,7 @@ mod tests {
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// Auth valid after reset at, count == 0.
// Tested in the softlock state machine.
@ -2925,10 +2914,10 @@ mod tests {
"admin",
);
// Get the detail wrong in sid_later.
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid_later, TEST_PASSWORD_INC);
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2958,14 +2947,14 @@ mod tests {
panic!();
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
// Now check that sid_early is denied due to softlock.
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let anon_step = AuthEvent::cred_step_password(sid_early, TEST_PASSWORD);
// Expect success
let r2 = task::block_on(idms_write.auth(
let r2 = task::block_on(idms_auth.auth(
au,
&anon_step,
Duration::from_secs(TEST_CURRENT_TIME),
@ -2994,7 +2983,7 @@ mod tests {
panic!();
}
};
idms_write.commit(au).expect("Must not fail");
idms_auth.commit(au).expect("Must not fail");
})
}
@ -3025,11 +3014,11 @@ mod tests {
assert!(idms_prox_write.set_unix_account_password(au, &pce).is_ok());
assert!(idms_prox_write.commit(au).is_ok());
let mut idms_write = idms.write();
let mut idms_auth = idms.auth();
let uuae_good = UnixUserAuthEvent::new_internal(&UUID_ADMIN, TEST_PASSWORD);
let uuae_bad = UnixUserAuthEvent::new_internal(&UUID_ADMIN, TEST_PASSWORD_INC);
let a2 = task::block_on(idms_write.auth_unix(
let a2 = task::block_on(idms_auth.auth_unix(
au,
&uuae_bad,
Duration::from_secs(TEST_CURRENT_TIME),
@ -3040,7 +3029,7 @@ mod tests {
};
// Now if we immediately auth again, should fail at same time due to SL
let a1 = task::block_on(idms_write.auth_unix(
let a1 = task::block_on(idms_auth.auth_unix(
au,
&uuae_good,
Duration::from_secs(TEST_CURRENT_TIME),
@ -3051,7 +3040,7 @@ mod tests {
};
// And then later, works because of SL lifting.
let a1 = task::block_on(idms_write.auth_unix(
let a1 = task::block_on(idms_auth.auth_unix(
au,
&uuae_good,
Duration::from_secs(TEST_CURRENT_TIME + 2),
@ -3061,7 +3050,7 @@ mod tests {
_ => assert!(false),
};
assert!(idms_write.commit(au).is_ok());
assert!(idms_auth.commit(au).is_ok());
})
}

View file

@ -1,15 +1,9 @@
use uuid::Uuid;
use crate::audit::AuditScope;
use crate::constants::UUID_ANONYMOUS;
use crate::credential::policy::CryptoPolicy;
use crate::credential::{softlock::CredSoftLockPolicy, Credential};
use crate::entry::{Entry, EntryCommitted, EntryReduced, EntrySealed};
use crate::modify::{ModifyInvalid, ModifyList};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::{PartialValue, Value};
use crate::prelude::*;
use kanidm_proto::v1::OperationError;
use kanidm_proto::v1::{UnixGroupToken, UnixUserToken};

View file

@ -1,14 +1,11 @@
use crate::audit::AuditScope;
use crate::constants::{STR_UUID_DOMAIN_INFO, UUID_ANONYMOUS, UUID_DOMAIN_INFO};
use crate::event::SearchEvent;
use crate::idm::event::LdapAuthEvent;
use crate::idm::server::IdmServer;
use crate::server::QueryServerTransaction;
use crate::prelude::*;
use async_std::task;
use kanidm_proto::v1::{OperationError, UserAuthToken};
use ldap3_server::simple::*;
use regex::Regex;
use smartstring::alias::String as AttrString;
use std::collections::BTreeSet;
use std::iter;
use std::time::SystemTime;
@ -301,7 +298,7 @@ impl LdapServer {
"Attempt LDAP Bind for {}",
if dn == "" { "anonymous" } else { dn }
);
let mut idm_write = idms.write_async().await;
let mut idm_auth = idms.auth_async().await;
let target_uuid: Uuid = if dn == "" {
if pw == "" {
@ -329,7 +326,7 @@ impl LdapServer {
return Err(OperationError::NoMatchingEntries);
}
idm_write
idm_auth
.qs_read
.name_to_uuid(au, rdn.as_str())
.map_err(|e| {
@ -346,8 +343,8 @@ impl LdapServer {
})?;
let lae = LdapAuthEvent::from_parts(au, target_uuid, pw.to_string())?;
idm_write.auth_ldap(au, &lae, ct).await.and_then(|r| {
idm_write.commit(au).map(|_| {
idm_auth.auth_ldap(au, &lae, ct).await.and_then(|r| {
idm_auth.commit(au).map(|_| {
if r.is_some() {
lsecurity!(au, "✅ LDAP Bind success {}", dn);
} else {
@ -476,20 +473,12 @@ pub(crate) fn ldap_attr_entry_map(attr: &str) -> String {
#[cfg(test)]
mod tests {
use crate::constants::{STR_UUID_ADMIN, UUID_ADMIN, UUID_ANONYMOUS};
// use crate::prelude::*;
use crate::event::ModifyEvent;
use crate::idm::event::UnixPasswordChangeEvent;
use crate::modify::{Modify, ModifyList};
use crate::value::{PartialValue, Value};
// use kanidm_proto::v1::OperationError;
// use crate::audit::AuditScope;
// use crate::idm::server::IdmServer;
// use crate::server::QueryServer;
// use crate::utils::duration_from_epoch_now;
// use uuid::Uuid;
use crate::ldap::LdapServer;
use crate::modify::{Modify, ModifyList};
use async_std::task;
use smartstring::alias::String as AttrString;
const TEST_PASSWORD: &'static str = "ntaoeuntnaoeuhraohuercahu😍";

View file

@ -54,3 +54,21 @@ mod status;
pub mod config;
pub mod core;
pub mod prelude {
pub use kanidm_proto::v1::OperationError;
pub use smartstring::alias::String as AttrString;
pub use uuid::Uuid;
pub use crate::audit::AuditScope;
pub use crate::constants::*;
pub use crate::entry::{
Entry, EntryCommitted, EntryInit, EntryInvalid, EntryInvalidCommitted, EntryNew,
EntryReduced, EntrySealed, EntrySealedCommitted, EntryTuple, EntryValid,
};
pub use crate::server::{
QueryServer, QueryServerReadTransaction, QueryServerTransaction,
QueryServerWriteTransaction,
};
pub use crate::value::{IndexType, PartialValue, SyntaxType, Value};
}

View file

@ -68,10 +68,9 @@ macro_rules! setup_test {
#[cfg(test)]
macro_rules! run_test_no_init {
($test_fn:expr) => {{
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig};
use crate::prelude::*;
use crate::schema::Schema;
use crate::server::QueryServer;
use crate::utils::duration_from_epoch_now;
use env_logger;
@ -112,10 +111,9 @@ macro_rules! run_test_no_init {
#[cfg(test)]
macro_rules! run_test {
($test_fn:expr) => {{
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig};
use crate::prelude::*;
use crate::schema::Schema;
use crate::server::QueryServer;
#[allow(unused_imports)]
use crate::utils::duration_from_epoch_now;
@ -165,16 +163,14 @@ macro_rules! entry_str_to_account {
macro_rules! run_idm_test_inner {
($test_fn:expr) => {{
use crate::audit::AuditScope;
#[allow(unused_imports)]
use crate::be::{Backend, BackendConfig};
#[allow(unused_imports)]
use crate::idm::server::{IdmServer, IdmServerDelayed};
use crate::prelude::*;
#[allow(unused_imports)]
use crate::schema::Schema;
#[allow(unused_imports)]
use crate::server::QueryServer;
#[allow(unused_imports)]
use crate::utils::duration_from_epoch_now;
use env_logger;
@ -241,11 +237,10 @@ macro_rules! run_create_test {
$internal:expr,
$check:expr
) => {{
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig};
use crate::event::CreateEvent;
use crate::prelude::*;
use crate::schema::Schema;
use crate::server::QueryServer;
use crate::utils::duration_from_epoch_now;
let mut au = AuditScope::new("run_create_test", uuid::Uuid::new_v4(), None);
@ -296,11 +291,10 @@ macro_rules! run_modify_test {
$internal:expr,
$check:expr
) => {{
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig};
use crate::event::ModifyEvent;
use crate::prelude::*;
use crate::schema::Schema;
use crate::server::QueryServer;
use crate::utils::duration_from_epoch_now;
let mut au = AuditScope::new("run_modify_test", uuid::Uuid::new_v4(), None);
@ -358,11 +352,10 @@ macro_rules! run_delete_test {
$internal:expr,
$check:expr
) => {{
use crate::audit::AuditScope;
use crate::be::{Backend, BackendConfig};
use crate::event::DeleteEvent;
use crate::prelude::*;
use crate::schema::Schema;
use crate::server::QueryServer;
use crate::utils::duration_from_epoch_now;
let mut au = AuditScope::new("run_delete_test", uuid::Uuid::new_v4(), None);

View file

@ -1,9 +1,8 @@
use crate::audit::AuditScope;
use crate::prelude::*;
use kanidm_proto::v1::Modify as ProtoModify;
use kanidm_proto::v1::ModifyList as ProtoModifyList;
use crate::schema::SchemaTransaction;
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{OperationError, SchemaError};

View file

@ -4,16 +4,11 @@
// both change approaches.
//
//
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew};
use crate::event::{CreateEvent, ModifyEvent};
use crate::plugins::Plugin;
use crate::prelude::*;
use crate::schema::SchemaTransaction;
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::PartialValue;
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
use kanidm_proto::v1::{ConsistencyError, PluginError};
use std::collections::BTreeMap;
@ -196,11 +191,10 @@ impl Plugin for AttrUnique {
#[cfg(test)]
mod tests {
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::modify::{Modify, ModifyList};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{OperationError, PluginError};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
use kanidm_proto::v1::PluginError;
// Test entry in db, and same name, reject.
#[test]
fn test_pre_create_name_unique() {

View file

@ -1,20 +1,11 @@
use crate::plugins::Plugin;
use hashbrown::HashSet;
use std::collections::BTreeSet;
use uuid::Uuid;
use crate::audit::AuditScope;
// use crate::constants::{STR_UUID_ADMIN, STR_UUID_ANONYMOUS, STR_UUID_DOES_NOT_EXIST};
use crate::constants::{UUID_ADMIN, UUID_ANONYMOUS, UUID_DOES_NOT_EXIST};
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew};
use crate::event::{CreateEvent, ModifyEvent};
use crate::modify::Modify;
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
// use utils::uuid_from_now;
use crate::prelude::*;
use kanidm_proto::v1::{ConsistencyError, PluginError};
lazy_static! {
static ref CLASS_OBJECT: Value = Value::new_class("object");
@ -244,16 +235,9 @@ impl Plugin for Base {
#[cfg(test)]
mod tests {
// #[macro_use]
// use crate::plugins::Plugin;
use crate::constants::JSON_ADMIN_V1;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::modify::{Modify, ModifyList};
use crate::server::QueryServerTransaction;
use crate::server::QueryServerWriteTransaction;
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{OperationError, PluginError};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
use kanidm_proto::v1::PluginError;
const JSON_ADMIN_ALLOW_ALL: &'static str = r#"{
"attrs": {

View file

@ -6,12 +6,8 @@
// relationships.
use crate::plugins::Plugin;
use crate::audit::AuditScope;
use crate::constants::UUID_DOMAIN_INFO;
use crate::entry::{Entry, EntryInvalid, EntryNew};
use crate::event::CreateEvent;
use crate::server::QueryServerWriteTransaction;
use crate::value::{PartialValue, Value};
use crate::prelude::*;
use kanidm_proto::v1::OperationError;
lazy_static! {
@ -57,10 +53,8 @@ impl Plugin for Domain {
#[cfg(test)]
mod tests {
use crate::constants::UUID_DOMAIN_INFO;
use crate::server::QueryServerTransaction;
use crate::value::PartialValue;
// use uuid::Uuid;
// use crate::prelude::*;
// test we can create and generate the id
#[test]
fn test_domain_generate_uuid() {

View file

@ -1,17 +1,10 @@
// A plugin that generates gid numbers on types that require them for posix
// support.
use crate::plugins::Plugin;
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew};
use crate::event::{CreateEvent, ModifyEvent};
// use crate::server::QueryServerTransaction;
use crate::server::QueryServerWriteTransaction;
use crate::plugins::Plugin;
use crate::prelude::*;
use crate::utils::uuid_to_gid_u32;
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::OperationError;
/// Systemd dynamic units allocate between 6118465519, most distros allocate
/// system uids from 0 - 1000, and many others give user ids between 1000 to
@ -106,12 +99,7 @@ impl Plugin for GidNumber {
#[cfg(test)]
mod tests {
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::OperationError;
use uuid::Uuid;
use crate::prelude::*;
fn check_gid(
au: &mut AuditScope,

View file

@ -10,13 +10,11 @@
// As a result, we first need to run refint to clean up all dangling references, then memberof
// fixes the graph of memberships
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntrySealed};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::prelude::*;
// use crate::modify::{Modify, ModifyList};
use crate::plugins::Plugin;
use crate::server::QueryServerTransaction;
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{ConsistencyError, OperationError};
@ -417,14 +415,8 @@ impl Plugin for MemberOf {
#[cfg(test)]
mod tests {
// #[macro_use]
// use crate::plugins::Plugin;
use crate::entry::{Entry, EntryInit, EntryNew};
// use crate::error::OperationError;
use crate::modify::{Modify, ModifyList};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
const UUID_A: &'static str = "aaaaaaaa-f82e-4484-a407-181aa03bda5c";
const UUID_B: &'static str = "bbbbbbbb-2438-4384-9891-48f4c8172e9b";

View file

@ -1,7 +1,6 @@
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::prelude::*;
use kanidm_proto::v1::{ConsistencyError, OperationError};
mod attrunique;

View file

@ -1,12 +1,9 @@
// Transform password import requests into proper kanidm credentials.
use crate::audit::AuditScope;
use crate::credential::{Credential, Password};
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew};
use crate::event::{CreateEvent, ModifyEvent};
use crate::plugins::Plugin;
use crate::server::QueryServerWriteTransaction;
use crate::value::Value;
use kanidm_proto::v1::{OperationError, PluginError};
use crate::prelude::*;
use kanidm_proto::v1::PluginError;
use std::convert::TryFrom;
pub struct PasswordImport {}
@ -129,12 +126,8 @@ mod tests {
use crate::credential::policy::CryptoPolicy;
use crate::credential::totp::{TOTP, TOTP_DEFAULT_STEP};
use crate::credential::{Credential, CredentialType};
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::modify::{Modify, ModifyList};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use smartstring::alias::String as AttrString;
use uuid::Uuid;
use crate::prelude::*;
const IMPORT_HASH: &'static str =
"pbkdf2_sha256$36000$xIEozuZVAoYm$uW1b35DUKyhvQAf1mBqMvoBDcqSD06juzyO/nmyV0+w=";

View file

@ -1,15 +1,12 @@
// System protected objects. Items matching specific requirements
// may only have certain modifications performed.
use crate::plugins::Plugin;
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
use crate::plugins::Plugin;
use crate::prelude::*;
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::modify::Modify;
use crate::server::QueryServerWriteTransaction;
use crate::value::{PartialValue, Value};
use hashbrown::HashSet;
use kanidm_proto::v1::OperationError;
pub struct Protected {}
@ -208,10 +205,7 @@ impl Plugin for Protected {
#[cfg(test)]
mod tests {
use crate::constants::JSON_ADMIN_V1;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::OperationError;
use crate::prelude::*;
const JSON_ADMIN_ALLOW_ALL: &'static str = r#"{
"attrs": {

View file

@ -12,18 +12,14 @@
use hashbrown::HashSet as Set;
use std::collections::BTreeSet;
use crate::audit::AuditScope;
use crate::entry::{Entry, EntryCommitted, EntrySealed};
use crate::plugins::Plugin;
use crate::prelude::*;
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent};
use crate::filter::f_eq;
use crate::modify::Modify;
use crate::plugins::Plugin;
use crate::schema::SchemaTransaction;
use crate::server::QueryServerTransaction;
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
use uuid::Uuid;
use kanidm_proto::v1::{ConsistencyError, PluginError};
// NOTE: This *must* be after base.rs!!!
@ -256,15 +252,9 @@ impl Plugin for ReferentialIntegrity {
#[cfg(test)]
mod tests {
// #[macro_use]
// use crate::plugins::Plugin;
use crate::constants::UUID_DOES_NOT_EXIST;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::modify::{Modify, ModifyList};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{OperationError, PluginError};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
use kanidm_proto::v1::PluginError;
// The create references a uuid that doesn't exist - reject
#[test]

View file

@ -1,14 +1,11 @@
// Generate and manage spn's for all entries in the domain. Also deals with
// the infrequent - but possible - case where a domain is renamed.
use crate::plugins::Plugin;
use crate::prelude::*;
use crate::audit::AuditScope;
use crate::constants::UUID_DOMAIN_INFO;
use crate::entry::{Entry, EntryCommitted, EntryInvalid, EntryNew, EntrySealed};
use crate::event::{CreateEvent, ModifyEvent};
use crate::server::{
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
};
use crate::value::PartialValue;
// use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{ConsistencyError, OperationError};
@ -253,10 +250,7 @@ impl Plugin for Spn {
#[cfg(test)]
mod tests {
use crate::constants::UUID_ADMIN;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use crate::prelude::*;
#[test]
fn test_spn_generate_create() {

View file

@ -18,14 +18,11 @@
use crate::audit::AuditScope;
use crate::be::IdxKey;
use crate::constants::*;
use crate::entry::{Entry, EntryCommitted, EntryInit, EntryNew, EntrySealed};
use crate::value::{IndexType, PartialValue, SyntaxType, Value};
use crate::prelude::*;
use kanidm_proto::v1::{ConsistencyError, OperationError, SchemaError};
use hashbrown::HashMap;
use hashbrown::HashSet;
use smartstring::alias::String as AttrString;
use std::borrow::Borrow;
use std::collections::BTreeSet;
use uuid::Uuid;
@ -1475,15 +1472,10 @@ impl Schema {
#[cfg(test)]
mod tests {
use crate::audit::AuditScope;
// use crate::constants::*;
use crate::entry::{Entry, EntryInit, EntryInvalid, EntryNew, EntryValid};
use kanidm_proto::v1::{ConsistencyError, SchemaError};
// use crate::filter::{Filter, FilterValid};
use crate::prelude::*;
use crate::schema::SchemaTransaction;
use crate::schema::{IndexType, Schema, SchemaAttribute, SchemaClass, SyntaxType};
use crate::value::{PartialValue, Value};
use smartstring::alias::String as AttrString;
use kanidm_proto::v1::{ConsistencyError, SchemaError};
use uuid::Uuid;
// use crate::proto_v1::Filter as ProtoFilter;

View file

@ -5,27 +5,21 @@
// that otherwise can't be cloned. Think Mutex.
use async_std::task;
use concread::arcache::{ARCache, ARCacheReadTxn};
use hashbrown::HashMap;
use hashbrown::{HashMap, HashSet};
use std::cell::Cell;
use std::collections::BTreeSet;
use std::sync::Arc;
use std::time::Duration;
use tokio::sync::{Semaphore, SemaphorePermit};
use uuid::Uuid;
use crate::audit::AuditScope;
use crate::be::{Backend, BackendReadTransaction, BackendTransaction, BackendWriteTransaction};
use crate::access::{
AccessControlCreate, AccessControlDelete, AccessControlModify, AccessControlSearch,
AccessControls, AccessControlsReadTransaction, AccessControlsTransaction,
AccessControlsWriteTransaction,
};
use crate::be::{Backend, BackendReadTransaction, BackendTransaction, BackendWriteTransaction};
use crate::prelude::*;
// We use so many, we just import them all ...
use crate::constants::*;
use crate::entry::{
Entry, EntryCommitted, EntryInit, EntryInvalid, EntryNew, EntryReduced, EntrySealed,
};
use crate::event::{
CreateEvent, DeleteEvent, Event, EventOrigin, EventOriginId, ExistsEvent, ModifyEvent,
ReviveRecycledEvent, SearchEvent,
@ -38,13 +32,7 @@ use crate::schema::{
Schema, SchemaAttribute, SchemaClass, SchemaReadTransaction, SchemaTransaction,
SchemaWriteTransaction,
};
use crate::value::{PartialValue, SyntaxType, Value};
use kanidm_proto::v1::{ConsistencyError, OperationError, SchemaError};
use smartstring::alias::String as AttrString;
type EntrySealedCommitted = Entry<EntrySealed, EntryCommitted>;
type EntryInvalidCommitted = Entry<EntryInvalid, EntryCommitted>;
type EntryTuple = (EntrySealedCommitted, EntryInvalidCommitted);
use kanidm_proto::v1::{ConsistencyError, SchemaError};
const RESOLVE_FILTER_CACHE_MAX: usize = 4096;
const RESOLVE_FILTER_CACHE_LOCAL: usize = 0;
@ -99,7 +87,7 @@ pub struct QueryServerWriteTransaction<'a> {
changed_schema: Cell<bool>,
changed_acp: Cell<bool>,
// Store the list of changed uuids for other invalidation needs?
changed_uuid: Cell<Vec<Uuid>>,
changed_uuid: Cell<HashSet<Uuid>>,
_db_ticket: SemaphorePermit<'a>,
_write_ticket: SemaphorePermit<'a>,
resolve_filter_cache:
@ -912,7 +900,7 @@ impl QueryServer {
accesscontrols: self.accesscontrols.write(),
changed_schema: Cell::new(false),
changed_acp: Cell::new(false),
changed_uuid: Cell::new(Vec::new()),
changed_uuid: Cell::new(HashSet::new()),
_db_ticket: db_ticket,
_write_ticket: write_ticket,
resolve_filter_cache: Cell::new(self.resolve_filter_cache.read()),
@ -997,7 +985,7 @@ impl QueryServer {
.initialise_idm(audit)
.and_then(|_| ts_write_3.commit(audit))?;
ladmin_info!(audit, "ready to rock! 🤘");
ladmin_info!(audit, "ready to rock! 🪨 ");
Ok(())
}
@ -2455,6 +2443,10 @@ impl<'a> QueryServerWriteTransaction<'a> {
self.be_txn.upgrade_reindex(audit, v)
}
pub fn get_changed_uuids(&self) -> &HashSet<Uuid> {
unsafe { &(*self.changed_uuid.as_ptr()) }
}
pub fn commit(mut self, audit: &mut AuditScope) -> Result<(), OperationError> {
// This could be faster if we cache the set of classes changed
// in an operation so we can check if we need to do the reload or not
@ -2510,23 +2502,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
#[cfg(test)]
mod tests {
use crate::audit::AuditScope;
use crate::constants::{
CHANGELOG_MAX_AGE, JSON_ADMIN_V1, JSON_DOMAIN_INFO_V1, JSON_SYSTEM_CONFIG_V1,
JSON_SYSTEM_INFO_V1, RECYCLEBIN_MAX_AGE, SYSTEM_INDEX_VERSION, UUID_ADMIN,
UUID_DOMAIN_INFO,
};
use crate::credential::policy::CryptoPolicy;
use crate::credential::Credential;
use crate::entry::{Entry, EntryInit, EntryNew};
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, ReviveRecycledEvent, SearchEvent};
use crate::modify::{Modify, ModifyList};
use crate::server::{QueryServerTransaction, QueryServerWriteTransaction};
use crate::value::{PartialValue, Value};
use kanidm_proto::v1::{OperationError, SchemaError};
use smartstring::alias::String as AttrString;
use crate::prelude::*;
use kanidm_proto::v1::SchemaError;
use std::time::Duration;
use uuid::Uuid;
#[test]
fn test_qs_create_user() {