diff --git a/.gitignore b/.gitignore index 4f632ca32..61c358abc 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ /insecure **/*.rs.bk test.db +/vendor diff --git a/kanidm_client/src/lib.rs b/kanidm_client/src/lib.rs index c2f1febe2..d7df97559 100644 --- a/kanidm_client/src/lib.rs +++ b/kanidm_client/src/lib.rs @@ -12,15 +12,15 @@ use std::io::Read; use kanidm_proto::v1::{ AuthCredential, AuthRequest, AuthResponse, AuthState, AuthStep, CreateRequest, DeleteRequest, - Entry, Filter, ModifyList, ModifyRequest, OperationResponse, SearchRequest, SearchResponse, - SetAuthCredential, SingleStringRequest, UserAuthToken, WhoamiResponse, + Entry, Filter, ModifyList, ModifyRequest, OperationError, OperationResponse, SearchRequest, + SearchResponse, SetAuthCredential, SingleStringRequest, UserAuthToken, WhoamiResponse, }; use serde_json; #[derive(Debug)] pub enum ClientError { Unauthorized, - Http(reqwest::StatusCode), + Http(reqwest::StatusCode, Option), Transport(reqwest::Error), AuthenticationFailed, JsonParse, @@ -100,7 +100,7 @@ impl KanidmClient { match response.status() { reqwest::StatusCode::OK => {} - unexpect => return Err(ClientError::Http(unexpect)), + unexpect => return Err(ClientError::Http(unexpect, response.json().ok())), } // TODO: What about errors @@ -127,7 +127,7 @@ impl KanidmClient { match response.status() { reqwest::StatusCode::OK => {} - unexpect => return Err(ClientError::Http(unexpect)), + unexpect => return Err(ClientError::Http(unexpect, response.json().ok())), } // TODO: What about errors @@ -146,7 +146,7 @@ impl KanidmClient { match response.status() { reqwest::StatusCode::OK => {} - unexpect => return Err(ClientError::Http(unexpect)), + unexpect => return Err(ClientError::Http(unexpect, response.json().ok())), } // TODO: What about errors @@ -165,7 +165,7 @@ impl KanidmClient { // Continue to process. reqwest::StatusCode::OK => {} reqwest::StatusCode::UNAUTHORIZED => return Ok(None), - unexpect => return Err(ClientError::Http(unexpect)), + unexpect => return Err(ClientError::Http(unexpect, response.json().ok())), } let r: WhoamiResponse = serde_json::from_str(response.text().unwrap().as_str()).unwrap(); diff --git a/kanidm_proto/src/v1.rs b/kanidm_proto/src/v1.rs index a232325f5..a7f479b67 100644 --- a/kanidm_proto/src/v1.rs +++ b/kanidm_proto/src/v1.rs @@ -17,6 +17,13 @@ pub enum SchemaError { Corrupted, } +#[derive(Serialize, Deserialize, Debug, PartialEq)] +pub enum PluginError { + AttrUnique(String), + Base(String), + ReferentialIntegrity(String), +} + #[derive(Serialize, Deserialize, Debug, PartialEq)] pub enum OperationError { EmptyRequest, @@ -25,20 +32,20 @@ pub enum OperationError { CorruptedEntry(u64), ConsistencyError(Vec>), SchemaViolation(SchemaError), - Plugin, + Plugin(PluginError), FilterGeneration, FilterUUIDResolution, InvalidAttributeName(String), - InvalidAttribute(&'static str), + InvalidAttribute(String), InvalidDBState, InvalidEntryID, InvalidRequestState, InvalidState, InvalidEntryState, InvalidUuid, - InvalidACPState(&'static str), - InvalidSchemaState(&'static str), - InvalidAccountState(&'static str), + InvalidACPState(String), + InvalidSchemaState(String), + InvalidAccountState(String), BackendEngine, SQLiteError, //(RusqliteError) FsError, @@ -46,9 +53,10 @@ pub enum OperationError { SerdeCborError, AccessDenied, NotAuthenticated, - InvalidAuthState(&'static str), + InvalidAuthState(String), InvalidSessionState, SystemProtectedObject, + SystemProtectedAttribute, } #[derive(Serialize, Deserialize, Debug, PartialEq)] @@ -62,7 +70,7 @@ pub enum ConsistencyError { UuidNotUnique(String), RefintNotUpheld(u64), MemberOfInvalid(u64), - InvalidAttributeType(&'static str), + InvalidAttributeType(String), DuplicateUniqueAttribute(String), } diff --git a/kanidmd/src/lib/access.rs b/kanidmd/src/lib/access.rs index fb329109f..c4159ab8c 100644 --- a/kanidmd/src/lib/access.rs +++ b/kanidmd/src/lib/access.rs @@ -58,7 +58,7 @@ impl AccessControlSearch { if !value.attribute_value_pres("class", &CLASS_ACS) { audit_log!(audit, "class access_control_search not present."); return Err(OperationError::InvalidACPState( - "Missing access_control_search", + "Missing access_control_search".to_string(), )); } @@ -66,7 +66,9 @@ impl AccessControlSearch { audit, value .get_ava_string("acp_search_attr") - .ok_or(OperationError::InvalidACPState("Missing acp_search_attr")) + .ok_or(OperationError::InvalidACPState( + "Missing acp_search_attr".to_string() + )) ); let acp = AccessControlProfile::try_from(audit, qs, value)?; @@ -111,7 +113,7 @@ impl AccessControlDelete { if !value.attribute_value_pres("class", &CLASS_ACD) { audit_log!(audit, "class access_control_delete not present."); return Err(OperationError::InvalidACPState( - "Missing access_control_delete", + "Missing access_control_delete".to_string(), )); } @@ -154,7 +156,7 @@ impl AccessControlCreate { if !value.attribute_value_pres("class", &CLASS_ACC) { audit_log!(audit, "class access_control_create not present."); return Err(OperationError::InvalidACPState( - "Missing access_control_create", + "Missing access_control_create".to_string(), )); } @@ -212,7 +214,7 @@ impl AccessControlModify { if !value.attribute_value_pres("class", &CLASS_ACM) { audit_log!(audit, "class access_control_modify not present."); return Err(OperationError::InvalidACPState( - "Missing access_control_modify", + "Missing access_control_modify".to_string(), )); } @@ -281,7 +283,7 @@ impl AccessControlProfile { if !value.attribute_value_pres("class", &CLASS_ACP) { audit_log!(audit, "class access_control_profile not present."); return Err(OperationError::InvalidACPState( - "Missing access_control_profile", + "Missing access_control_profile".to_string(), )); } @@ -290,7 +292,7 @@ impl AccessControlProfile { audit, value .get_ava_single_str("name") - .ok_or(OperationError::InvalidACPState("Missing name")) + .ok_or(OperationError::InvalidACPState("Missing name".to_string())) ) .to_string(); // copy uuid @@ -298,16 +300,16 @@ impl AccessControlProfile { // receiver, and turn to real filter let receiver_f: ProtoFilter = try_audit!( audit, - value - .get_ava_single_protofilter("acp_receiver") - .ok_or(OperationError::InvalidACPState("Missing acp_receiver")) + value.get_ava_single_protofilter("acp_receiver").ok_or( + OperationError::InvalidACPState("Missing acp_receiver".to_string()) + ) ); // targetscope, and turn to real filter let targetscope_f: ProtoFilter = try_audit!( audit, - value - .get_ava_single_protofilter("acp_targetscope") - .ok_or(OperationError::InvalidACPState("Missing acp_targetscope")) + value.get_ava_single_protofilter("acp_targetscope").ok_or( + OperationError::InvalidACPState("Missing acp_targetscope".to_string()) + ) ); let receiver_i = try_audit!(audit, Filter::from_rw(audit, &receiver_f, qs)); diff --git a/kanidmd/src/lib/core.rs b/kanidmd/src/lib/core.rs index 2072d5bdf..4f4e64c22 100644 --- a/kanidmd/src/lib/core.rs +++ b/kanidmd/src/lib/core.rs @@ -55,6 +55,19 @@ fn get_current_user(req: &HttpRequest) -> Option { } } +fn operation_error_to_response(e: OperationError) -> HttpResponse { + match e { + OperationError::NotAuthenticated => HttpResponse::Unauthorized().json(e), + OperationError::AccessDenied | OperationError::SystemProtectedObject => { + HttpResponse::Forbidden().json(e) + } + OperationError::EmptyRequest + | OperationError::NoMatchingEntries + | OperationError::SchemaViolation(_) => HttpResponse::BadRequest().json(e), + _ => HttpResponse::InternalServerError().json(e), + } +} + macro_rules! json_event_post { ($req:expr, $state:expr, $message_type:ty, $request_type:ty) => {{ // This is copied every request. Is there a better way? @@ -100,7 +113,7 @@ macro_rules! json_event_post { .from_err() .and_then(|res| match res { Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)), - Err(e) => Ok(HttpResponse::InternalServerError().json(e)), + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -127,10 +140,7 @@ macro_rules! json_event_get { let res = $state.qe.send(obj).from_err().and_then(|res| match res { Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)), - Err(e) => match e { - OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)), - _ => Ok(HttpResponse::InternalServerError().json(e)), - }, + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -184,10 +194,7 @@ fn json_rest_event_get( let res = state.qe.send(obj).from_err().and_then(|res| match res { Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)), - Err(e) => match e { - OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)), - _ => Ok(HttpResponse::InternalServerError().json(e)), - }, + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -210,10 +217,7 @@ fn json_rest_event_get_id( // Only send back the first result, or None Ok(HttpResponse::Ok().json(event_result.pop())) } - Err(e) => match e { - OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)), - _ => Ok(HttpResponse::InternalServerError().json(e)), - }, + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -257,7 +261,7 @@ fn json_rest_event_credential_put( let m_obj = InternalCredentialSetMessage::new(uat, id, cred_id, obj); let res = state.qe.send(m_obj).from_err().and_then(|res| match res { Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)), - Err(e) => Ok(HttpResponse::InternalServerError().json(e)), + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -321,10 +325,7 @@ fn schema_attributetype_get_id( // Only send back the first result, or None Ok(HttpResponse::Ok().json(event_result.pop())) } - Err(e) => match e { - OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)), - _ => Ok(HttpResponse::InternalServerError().json(e)), - }, + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -355,10 +356,7 @@ fn schema_classtype_get_id( // Only send back the first result, or None Ok(HttpResponse::Ok().json(event_result.pop())) } - Err(e) => match e { - OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)), - _ => Ok(HttpResponse::InternalServerError().json(e)), - }, + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) @@ -472,7 +470,7 @@ fn auth( AuthState::Denied(_) => { // Remove the auth-session-id req.session().remove("auth-session-id"); - Ok(HttpResponse::Ok().json(ar)) + Ok(HttpResponse::Unauthorized().json(ar)) } AuthState::Continue(_) => { // Ensure the auth-session-id is set @@ -489,7 +487,7 @@ fn auth( } } } - Err(e) => Ok(HttpResponse::InternalServerError().json(e)), + Err(e) => Ok(operation_error_to_response(e)), }); Box::new(res) } diff --git a/kanidmd/src/lib/event.rs b/kanidmd/src/lib/event.rs index 434f6625c..359d99546 100644 --- a/kanidmd/src/lib/event.rs +++ b/kanidmd/src/lib/event.rs @@ -670,7 +670,7 @@ impl AuthEventStep { AuthStep::Init(name, appid) => { if sid.is_some() { Err(OperationError::InvalidAuthState( - "session id present in init", + "session id present in init".to_string(), )) } else { Ok(AuthEventStep::Init(AuthEventStepInit { @@ -685,7 +685,7 @@ impl AuthEventStep { creds: creds, })), None => Err(OperationError::InvalidAuthState( - "session id not present in cred", + "session id not present in cred".to_string(), )), }, } diff --git a/kanidmd/src/lib/idm/account.rs b/kanidmd/src/lib/idm/account.rs index 4020101ee..0457f925a 100644 --- a/kanidmd/src/lib/idm/account.rs +++ b/kanidmd/src/lib/idm/account.rs @@ -42,7 +42,7 @@ impl Account { // Check the classes if !value.attribute_value_pres("class", &PVCLASS_ACCOUNT) { return Err(OperationError::InvalidAccountState( - "Missing class: account", + "Missing class: account".to_string(), )); } @@ -51,11 +51,11 @@ impl Account { value .get_ava_single_string("name") .ok_or(OperationError::InvalidAccountState( - "Missing attribute: name", + "Missing attribute: name".to_string(), ))?; let displayname = value.get_ava_single_string("displayname").ok_or( - OperationError::InvalidAccountState("Missing attribute: displayname"), + OperationError::InvalidAccountState("Missing attribute: displayname".to_string()), )?; let primary = value diff --git a/kanidmd/src/lib/idm/authsession.rs b/kanidmd/src/lib/idm/authsession.rs index dcfab8ddc..80b530c4e 100644 --- a/kanidmd/src/lib/idm/authsession.rs +++ b/kanidmd/src/lib/idm/authsession.rs @@ -199,7 +199,7 @@ impl AuthSession { ) -> Result { if self.finished { return Err(OperationError::InvalidAuthState( - "session already finalised!", + "session already finalised!".to_string(), )); } diff --git a/kanidmd/src/lib/plugins/attrunique.rs b/kanidmd/src/lib/plugins/attrunique.rs index 9ccc11ca9..dab1a49f0 100644 --- a/kanidmd/src/lib/plugins/attrunique.rs +++ b/kanidmd/src/lib/plugins/attrunique.rs @@ -13,7 +13,7 @@ use crate::server::{ QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction, }; use crate::value::PartialValue; -use kanidm_proto::v1::{ConsistencyError, OperationError}; +use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError}; use std::collections::BTreeMap; @@ -59,7 +59,9 @@ fn get_cand_attr_set( vr, uuid ); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::AttrUnique( + "ava already exists".to_string(), + ))); } } } @@ -109,7 +111,9 @@ fn enforce_unique( // If all okay, okay! if conflict_cand.len() > 0 { - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::AttrUnique( + "duplicate value detected".to_string(), + ))); } Ok(()) diff --git a/kanidmd/src/lib/plugins/base.rs b/kanidmd/src/lib/plugins/base.rs index 7be1af2f3..509b05a56 100644 --- a/kanidmd/src/lib/plugins/base.rs +++ b/kanidmd/src/lib/plugins/base.rs @@ -13,7 +13,7 @@ use crate::server::{ QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction, }; use crate::value::{PartialValue, Value}; -use kanidm_proto::v1::{ConsistencyError, OperationError}; +use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError}; lazy_static! { static ref CLASS_OBJECT: Value = Value::new_class("object"); @@ -66,7 +66,9 @@ impl Plugin for Base { // Actually check we have a value, could be empty array ... if u.len() > 1 { audit_log!(au, "Entry defines uuid attr, but multiple values."); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::Base( + "Uuid has multiple values".to_string(), + ))); }; // Schema of the value v, is checked in the filter generation. Neat! @@ -78,7 +80,9 @@ impl Plugin for Base { let v: Value = try_audit!( au, u.first() - .ok_or(OperationError::Plugin) + .ok_or(OperationError::Plugin(PluginError::Base( + "Uuid format invalid".to_string() + ))) .map(|v| (*v).clone()) ); v @@ -104,14 +108,16 @@ impl Plugin for Base { for entry in cand.iter() { let uuid_ref: &Uuid = entry .get_ava_single("uuid") - .ok_or(OperationError::Plugin)? + .ok_or(OperationError::InvalidEntryState)? .to_uuid() - .ok_or(OperationError::Plugin)?; + .ok_or(OperationError::InvalidAttribute("uuid".to_string()))?; audit_log!(au, "Entry valid UUID: {:?}", entry); match cand_uuid.insert(uuid_ref) { false => { audit_log!(au, "uuid duplicate found in create set! {:?}", uuid_ref); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::Base( + "Uuid duplicate detected in request".to_string(), + ))); } true => {} } @@ -137,7 +143,9 @@ impl Plugin for Base { "uuid from protected system UUID range found in create set! {:?}", overlap ); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::Base( + "Uuid must not be in protected range".to_string(), + ))); } } @@ -147,7 +155,9 @@ impl Plugin for Base { "uuid \"does not exist\" found in create set! {:?}", uuid_does_not_exist ); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::Base( + "UUID_DOES_NOT_EXIST may not exist!".to_string(), + ))); } // Now from each element, generate a filter to search for all of them @@ -175,12 +185,14 @@ impl Plugin for Base { Ok(b) => { if b == true { audit_log!(au, "A UUID already exists, rejecting."); - return Err(OperationError::Plugin); + return Err(OperationError::Plugin(PluginError::Base( + "Uuid duplicate found in database".to_string(), + ))); } } Err(e) => { audit_log!(au, "Error occured checking UUID existance. {:?}", e); - return Err(OperationError::Plugin); + return Err(e); } } @@ -201,7 +213,7 @@ impl Plugin for Base { }; if attr == "uuid" { audit_log!(au, "Modifications to UUID's are NOT ALLOWED"); - return Err(OperationError::Plugin); + return Err(OperationError::SystemProtectedAttribute); } } Ok(()) diff --git a/kanidmd/src/lib/plugins/mod.rs b/kanidmd/src/lib/plugins/mod.rs index 20f872d4f..b16c1f78a 100644 --- a/kanidmd/src/lib/plugins/mod.rs +++ b/kanidmd/src/lib/plugins/mod.rs @@ -28,7 +28,7 @@ trait Plugin { "plugin {} has an unimplemented pre_create_transform!", Self::id() ); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn pre_create( @@ -39,7 +39,7 @@ trait Plugin { _ce: &CreateEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented pre_create!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn post_create( @@ -50,7 +50,7 @@ trait Plugin { _ce: &CreateEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented post_create!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn pre_modify( @@ -60,7 +60,7 @@ trait Plugin { _me: &ModifyEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented pre_modify!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn post_modify( @@ -72,7 +72,7 @@ trait Plugin { _ce: &ModifyEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented post_modify!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn pre_delete( @@ -82,7 +82,7 @@ trait Plugin { _de: &DeleteEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented pre_delete!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn post_delete( @@ -93,7 +93,7 @@ trait Plugin { _ce: &DeleteEvent, ) -> Result<(), OperationError> { debug!("plugin {} has an unimplemented post_delete!", Self::id()); - Err(OperationError::Plugin) + Err(OperationError::InvalidState) } fn verify( diff --git a/kanidmd/src/lib/plugins/refint.rs b/kanidmd/src/lib/plugins/refint.rs index a6e019862..94924475a 100644 --- a/kanidmd/src/lib/plugins/refint.rs +++ b/kanidmd/src/lib/plugins/refint.rs @@ -20,7 +20,7 @@ use crate::schema::SchemaTransaction; use crate::server::QueryServerTransaction; use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction}; use crate::value::{PartialValue, Value}; -use kanidm_proto::v1::{ConsistencyError, OperationError}; +use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError}; use uuid::Uuid; // NOTE: This *must* be after base.rs!!! @@ -35,7 +35,14 @@ impl ReferentialIntegrity { uuid_value: &Value, ) -> Result<(), OperationError> { debug!("{:?}", uuid_value); - let uuid = try_audit!(au, uuid_value.to_ref_uuid().ok_or(OperationError::Plugin)); + let uuid = try_audit!( + au, + uuid_value + .to_ref_uuid() + .ok_or(OperationError::InvalidAttribute( + "uuid could not become reference value".to_string() + )) + ); let mut au_qs = AuditScope::new("qs_exist"); // NOTE: This only checks LIVE entries (not using filter_all) let filt_in = filter!(f_eq("uuid", PartialValue::new_uuid(uuid.clone()))); @@ -53,7 +60,9 @@ impl ReferentialIntegrity { rtype, uuid ); - Err(OperationError::Plugin) + Err(OperationError::Plugin(PluginError::ReferentialIntegrity( + "Uuid referenced not found in database".to_string(), + ))) } } } @@ -225,7 +234,7 @@ impl Plugin for ReferentialIntegrity { } } None => res.push(Err(ConsistencyError::InvalidAttributeType( - "A non-value-ref type was found.", + "A non-value-ref type was found.".to_string(), ))), } } diff --git a/kanidmd/src/lib/schema.rs b/kanidmd/src/lib/schema.rs index ba523734f..5384dd466 100644 --- a/kanidmd/src/lib/schema.rs +++ b/kanidmd/src/lib/schema.rs @@ -47,39 +47,47 @@ impl SchemaAttribute { // class if !value.attribute_value_pres("class", &PVCLASS_ATTRIBUTETYPE) { audit_log!(audit, "class attribute type not present"); - return Err(OperationError::InvalidSchemaState("missing attributetype")); + return Err(OperationError::InvalidSchemaState( + "missing attributetype".to_string(), + )); } // uuid let uuid = value.get_uuid().clone(); // name - let name = try_audit!( - audit, - value - .get_ava_single_string("attributename") - .ok_or(OperationError::InvalidSchemaState("missing attributename")) - ); + let name = + try_audit!( + audit, + value.get_ava_single_string("attributename").ok_or( + OperationError::InvalidSchemaState("missing attributename".to_string()) + ) + ); // description - let description = try_audit!( - audit, - value - .get_ava_single_string("description") - .ok_or(OperationError::InvalidSchemaState("missing description")) - ); + let description = + try_audit!( + audit, + value.get_ava_single_string("description").ok_or( + OperationError::InvalidSchemaState("missing description".to_string()) + ) + ); // multivalue let multivalue = try_audit!( audit, value .get_ava_single_bool("multivalue") - .ok_or(OperationError::InvalidSchemaState("missing multivalue")) + .ok_or(OperationError::InvalidSchemaState( + "missing multivalue".to_string() + )) ); let unique = try_audit!( audit, value .get_ava_single_bool("unique") - .ok_or(OperationError::InvalidSchemaState("missing unique")) + .ok_or(OperationError::InvalidSchemaState( + "missing unique".to_string() + )) ); // index vec // even if empty, it SHOULD be present ... (is that value to put an empty set?) @@ -92,7 +100,7 @@ impl SchemaAttribute { .into_iter() .map(|v: &IndexType| v.clone()) .collect())) - .map_err(|_| OperationError::InvalidSchemaState("Invalid index")) + .map_err(|_| OperationError::InvalidSchemaState("Invalid index".to_string())) ); // syntax type let syntax = try_audit!( @@ -100,7 +108,9 @@ impl SchemaAttribute { value .get_ava_single_syntax("syntax") .and_then(|s: &SyntaxType| Some(s.clone())) - .ok_or(OperationError::InvalidSchemaState("missing syntax")) + .ok_or(OperationError::InvalidSchemaState( + "missing syntax".to_string() + )) ); Ok(SchemaAttribute { @@ -339,7 +349,9 @@ impl SchemaClass { // Convert entry to a schema class. if !value.attribute_value_pres("class", &PVCLASS_CLASSTYPE) { audit_log!(audit, "class classtype not present"); - return Err(OperationError::InvalidSchemaState("missing classtype")); + return Err(OperationError::InvalidSchemaState( + "missing classtype".to_string(), + )); } // uuid @@ -350,36 +362,41 @@ impl SchemaClass { audit, value .get_ava_single_string("classname") - .ok_or(OperationError::InvalidSchemaState("missing classname")) + .ok_or(OperationError::InvalidSchemaState( + "missing classname".to_string() + )) ); // description - let description = try_audit!( - audit, - value - .get_ava_single_string("description") - .ok_or(OperationError::InvalidSchemaState("missing description")) - ); + let description = + try_audit!( + audit, + value.get_ava_single_string("description").ok_or( + OperationError::InvalidSchemaState("missing description".to_string()) + ) + ); // These are all "optional" lists of strings. let systemmay = value .get_ava_opt_string("systemmay") .ok_or(OperationError::InvalidSchemaState( - "Missing or invalid systemmay", + "Missing or invalid systemmay".to_string(), ))?; let systemmust = value .get_ava_opt_string("systemmust") .ok_or(OperationError::InvalidSchemaState( - "Missing or invalid systemmust", + "Missing or invalid systemmust".to_string(), ))?; let may = value .get_ava_opt_string("may") - .ok_or(OperationError::InvalidSchemaState("Missing or invalid may"))?; + .ok_or(OperationError::InvalidSchemaState( + "Missing or invalid may".to_string(), + ))?; let must = value .get_ava_opt_string("must") .ok_or(OperationError::InvalidSchemaState( - "Missing or invalid must", + "Missing or invalid must".to_string(), ))?; Ok(SchemaClass { diff --git a/kanidmd/src/lib/server.rs b/kanidmd/src/lib/server.rs index 7c186d475..07a3b6d47 100644 --- a/kanidmd/src/lib/server.rs +++ b/kanidmd/src/lib/server.rs @@ -364,11 +364,11 @@ pub trait QueryServerTransaction { SyntaxType::UTF8STRING => Ok(Value::new_utf8(value.clone())), SyntaxType::UTF8STRING_INSENSITIVE => Ok(Value::new_iutf8s(value.as_str())), SyntaxType::BOOLEAN => Value::new_bools(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid boolean syntax")), + .ok_or(OperationError::InvalidAttribute("Invalid boolean syntax".to_string())), SyntaxType::SYNTAX_ID => Value::new_syntaxs(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid Syntax syntax")), + .ok_or(OperationError::InvalidAttribute("Invalid Syntax syntax".to_string())), SyntaxType::INDEX_ID => Value::new_indexs(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid Index syntax")), + .ok_or(OperationError::InvalidAttribute("Invalid Index syntax".to_string())), SyntaxType::UUID => { // It's a uuid - we do NOT check for existance, because that // could be revealing or disclosing - it is up to acp to assert @@ -386,7 +386,7 @@ pub trait QueryServerTransaction { Some(Value::new_uuid(un)) }) // I think this is unreachable due to how the .or_else works. - .ok_or(OperationError::InvalidAttribute("Invalid UUID syntax")) + .ok_or(OperationError::InvalidAttribute("Invalid UUID syntax".to_string())) } SyntaxType::REFERENCE_UUID => { // See comments above. @@ -398,11 +398,11 @@ pub trait QueryServerTransaction { Some(Value::new_refer(un)) }) // I think this is unreachable due to how the .or_else works. - .ok_or(OperationError::InvalidAttribute("Invalid Reference syntax")) + .ok_or(OperationError::InvalidAttribute("Invalid Reference syntax".to_string())) } SyntaxType::JSON_FILTER => Value::new_json_filter(value) - .ok_or(OperationError::InvalidAttribute("Invalid Filter syntax")), - SyntaxType::CREDENTIAL => Err(OperationError::InvalidAttribute("Credentials can not be supplied through modification - please use the IDM api")), + .ok_or(OperationError::InvalidAttribute("Invalid Filter syntax".to_string())), + SyntaxType::CREDENTIAL => Err(OperationError::InvalidAttribute("Credentials can not be supplied through modification - please use the IDM api".to_string())), } } None => { @@ -431,12 +431,15 @@ pub trait QueryServerTransaction { SyntaxType::UTF8STRING_INSENSITIVE => { Ok(PartialValue::new_iutf8s(value.as_str())) } - SyntaxType::BOOLEAN => PartialValue::new_bools(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid boolean syntax")), - SyntaxType::SYNTAX_ID => PartialValue::new_syntaxs(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid Syntax syntax")), - SyntaxType::INDEX_ID => PartialValue::new_indexs(value.as_str()) - .ok_or(OperationError::InvalidAttribute("Invalid Index syntax")), + SyntaxType::BOOLEAN => PartialValue::new_bools(value.as_str()).ok_or( + OperationError::InvalidAttribute("Invalid boolean syntax".to_string()), + ), + SyntaxType::SYNTAX_ID => PartialValue::new_syntaxs(value.as_str()).ok_or( + OperationError::InvalidAttribute("Invalid Syntax syntax".to_string()), + ), + SyntaxType::INDEX_ID => PartialValue::new_indexs(value.as_str()).ok_or( + OperationError::InvalidAttribute("Invalid Index syntax".to_string()), + ), SyntaxType::UUID => { PartialValue::new_uuids(value.as_str()) .or_else(|| { @@ -450,7 +453,9 @@ pub trait QueryServerTransaction { Some(PartialValue::new_uuid(un)) }) // I think this is unreachable due to how the .or_else works. - .ok_or(OperationError::InvalidAttribute("Invalid UUID syntax")) + .ok_or(OperationError::InvalidAttribute( + "Invalid UUID syntax".to_string(), + )) } SyntaxType::REFERENCE_UUID => { // See comments above. @@ -462,10 +467,13 @@ pub trait QueryServerTransaction { Some(PartialValue::new_refer(un)) }) // I think this is unreachable due to how the .or_else works. - .ok_or(OperationError::InvalidAttribute("Invalid Reference syntax")) + .ok_or(OperationError::InvalidAttribute( + "Invalid Reference syntax".to_string(), + )) } - SyntaxType::JSON_FILTER => PartialValue::new_json_filter(value) - .ok_or(OperationError::InvalidAttribute("Invalid Filter syntax")), + SyntaxType::JSON_FILTER => PartialValue::new_json_filter(value).ok_or( + OperationError::InvalidAttribute("Invalid Filter syntax".to_string()), + ), SyntaxType::CREDENTIAL => Ok(PartialValue::new_credential_tag(value.as_str())), } }