mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Refactor client lib to expose msgs, and improve the messages in plugins (#114)
Implements #100. This refactors our error types to be deserialiseable, and exposes these through the clienterror type with the status codes. There is probably still a lot of improvements here to be made, but they'll be shaken out as the client libs develop I think and we start to see what errors should be exposed.
This commit is contained in:
parent
09bc31e2f5
commit
6b0b2ad040
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -5,3 +5,4 @@
|
||||||
/insecure
|
/insecure
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
test.db
|
test.db
|
||||||
|
/vendor
|
||||||
|
|
|
@ -12,15 +12,15 @@ use std::io::Read;
|
||||||
|
|
||||||
use kanidm_proto::v1::{
|
use kanidm_proto::v1::{
|
||||||
AuthCredential, AuthRequest, AuthResponse, AuthState, AuthStep, CreateRequest, DeleteRequest,
|
AuthCredential, AuthRequest, AuthResponse, AuthState, AuthStep, CreateRequest, DeleteRequest,
|
||||||
Entry, Filter, ModifyList, ModifyRequest, OperationResponse, SearchRequest, SearchResponse,
|
Entry, Filter, ModifyList, ModifyRequest, OperationError, OperationResponse, SearchRequest,
|
||||||
SetAuthCredential, SingleStringRequest, UserAuthToken, WhoamiResponse,
|
SearchResponse, SetAuthCredential, SingleStringRequest, UserAuthToken, WhoamiResponse,
|
||||||
};
|
};
|
||||||
use serde_json;
|
use serde_json;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum ClientError {
|
pub enum ClientError {
|
||||||
Unauthorized,
|
Unauthorized,
|
||||||
Http(reqwest::StatusCode),
|
Http(reqwest::StatusCode, Option<OperationError>),
|
||||||
Transport(reqwest::Error),
|
Transport(reqwest::Error),
|
||||||
AuthenticationFailed,
|
AuthenticationFailed,
|
||||||
JsonParse,
|
JsonParse,
|
||||||
|
@ -100,7 +100,7 @@ impl KanidmClient {
|
||||||
|
|
||||||
match response.status() {
|
match response.status() {
|
||||||
reqwest::StatusCode::OK => {}
|
reqwest::StatusCode::OK => {}
|
||||||
unexpect => return Err(ClientError::Http(unexpect)),
|
unexpect => return Err(ClientError::Http(unexpect, response.json().ok())),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What about errors
|
// TODO: What about errors
|
||||||
|
@ -127,7 +127,7 @@ impl KanidmClient {
|
||||||
|
|
||||||
match response.status() {
|
match response.status() {
|
||||||
reqwest::StatusCode::OK => {}
|
reqwest::StatusCode::OK => {}
|
||||||
unexpect => return Err(ClientError::Http(unexpect)),
|
unexpect => return Err(ClientError::Http(unexpect, response.json().ok())),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What about errors
|
// TODO: What about errors
|
||||||
|
@ -146,7 +146,7 @@ impl KanidmClient {
|
||||||
|
|
||||||
match response.status() {
|
match response.status() {
|
||||||
reqwest::StatusCode::OK => {}
|
reqwest::StatusCode::OK => {}
|
||||||
unexpect => return Err(ClientError::Http(unexpect)),
|
unexpect => return Err(ClientError::Http(unexpect, response.json().ok())),
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: What about errors
|
// TODO: What about errors
|
||||||
|
@ -165,7 +165,7 @@ impl KanidmClient {
|
||||||
// Continue to process.
|
// Continue to process.
|
||||||
reqwest::StatusCode::OK => {}
|
reqwest::StatusCode::OK => {}
|
||||||
reqwest::StatusCode::UNAUTHORIZED => return Ok(None),
|
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();
|
let r: WhoamiResponse = serde_json::from_str(response.text().unwrap().as_str()).unwrap();
|
||||||
|
|
|
@ -17,6 +17,13 @@ pub enum SchemaError {
|
||||||
Corrupted,
|
Corrupted,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
|
pub enum PluginError {
|
||||||
|
AttrUnique(String),
|
||||||
|
Base(String),
|
||||||
|
ReferentialIntegrity(String),
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
pub enum OperationError {
|
pub enum OperationError {
|
||||||
EmptyRequest,
|
EmptyRequest,
|
||||||
|
@ -25,20 +32,20 @@ pub enum OperationError {
|
||||||
CorruptedEntry(u64),
|
CorruptedEntry(u64),
|
||||||
ConsistencyError(Vec<Result<(), ConsistencyError>>),
|
ConsistencyError(Vec<Result<(), ConsistencyError>>),
|
||||||
SchemaViolation(SchemaError),
|
SchemaViolation(SchemaError),
|
||||||
Plugin,
|
Plugin(PluginError),
|
||||||
FilterGeneration,
|
FilterGeneration,
|
||||||
FilterUUIDResolution,
|
FilterUUIDResolution,
|
||||||
InvalidAttributeName(String),
|
InvalidAttributeName(String),
|
||||||
InvalidAttribute(&'static str),
|
InvalidAttribute(String),
|
||||||
InvalidDBState,
|
InvalidDBState,
|
||||||
InvalidEntryID,
|
InvalidEntryID,
|
||||||
InvalidRequestState,
|
InvalidRequestState,
|
||||||
InvalidState,
|
InvalidState,
|
||||||
InvalidEntryState,
|
InvalidEntryState,
|
||||||
InvalidUuid,
|
InvalidUuid,
|
||||||
InvalidACPState(&'static str),
|
InvalidACPState(String),
|
||||||
InvalidSchemaState(&'static str),
|
InvalidSchemaState(String),
|
||||||
InvalidAccountState(&'static str),
|
InvalidAccountState(String),
|
||||||
BackendEngine,
|
BackendEngine,
|
||||||
SQLiteError, //(RusqliteError)
|
SQLiteError, //(RusqliteError)
|
||||||
FsError,
|
FsError,
|
||||||
|
@ -46,9 +53,10 @@ pub enum OperationError {
|
||||||
SerdeCborError,
|
SerdeCborError,
|
||||||
AccessDenied,
|
AccessDenied,
|
||||||
NotAuthenticated,
|
NotAuthenticated,
|
||||||
InvalidAuthState(&'static str),
|
InvalidAuthState(String),
|
||||||
InvalidSessionState,
|
InvalidSessionState,
|
||||||
SystemProtectedObject,
|
SystemProtectedObject,
|
||||||
|
SystemProtectedAttribute,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
#[derive(Serialize, Deserialize, Debug, PartialEq)]
|
||||||
|
@ -62,7 +70,7 @@ pub enum ConsistencyError {
|
||||||
UuidNotUnique(String),
|
UuidNotUnique(String),
|
||||||
RefintNotUpheld(u64),
|
RefintNotUpheld(u64),
|
||||||
MemberOfInvalid(u64),
|
MemberOfInvalid(u64),
|
||||||
InvalidAttributeType(&'static str),
|
InvalidAttributeType(String),
|
||||||
DuplicateUniqueAttribute(String),
|
DuplicateUniqueAttribute(String),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -58,7 +58,7 @@ impl AccessControlSearch {
|
||||||
if !value.attribute_value_pres("class", &CLASS_ACS) {
|
if !value.attribute_value_pres("class", &CLASS_ACS) {
|
||||||
audit_log!(audit, "class access_control_search not present.");
|
audit_log!(audit, "class access_control_search not present.");
|
||||||
return Err(OperationError::InvalidACPState(
|
return Err(OperationError::InvalidACPState(
|
||||||
"Missing access_control_search",
|
"Missing access_control_search".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,7 +66,9 @@ impl AccessControlSearch {
|
||||||
audit,
|
audit,
|
||||||
value
|
value
|
||||||
.get_ava_string("acp_search_attr")
|
.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)?;
|
let acp = AccessControlProfile::try_from(audit, qs, value)?;
|
||||||
|
@ -111,7 +113,7 @@ impl AccessControlDelete {
|
||||||
if !value.attribute_value_pres("class", &CLASS_ACD) {
|
if !value.attribute_value_pres("class", &CLASS_ACD) {
|
||||||
audit_log!(audit, "class access_control_delete not present.");
|
audit_log!(audit, "class access_control_delete not present.");
|
||||||
return Err(OperationError::InvalidACPState(
|
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) {
|
if !value.attribute_value_pres("class", &CLASS_ACC) {
|
||||||
audit_log!(audit, "class access_control_create not present.");
|
audit_log!(audit, "class access_control_create not present.");
|
||||||
return Err(OperationError::InvalidACPState(
|
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) {
|
if !value.attribute_value_pres("class", &CLASS_ACM) {
|
||||||
audit_log!(audit, "class access_control_modify not present.");
|
audit_log!(audit, "class access_control_modify not present.");
|
||||||
return Err(OperationError::InvalidACPState(
|
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) {
|
if !value.attribute_value_pres("class", &CLASS_ACP) {
|
||||||
audit_log!(audit, "class access_control_profile not present.");
|
audit_log!(audit, "class access_control_profile not present.");
|
||||||
return Err(OperationError::InvalidACPState(
|
return Err(OperationError::InvalidACPState(
|
||||||
"Missing access_control_profile",
|
"Missing access_control_profile".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -290,7 +292,7 @@ impl AccessControlProfile {
|
||||||
audit,
|
audit,
|
||||||
value
|
value
|
||||||
.get_ava_single_str("name")
|
.get_ava_single_str("name")
|
||||||
.ok_or(OperationError::InvalidACPState("Missing name"))
|
.ok_or(OperationError::InvalidACPState("Missing name".to_string()))
|
||||||
)
|
)
|
||||||
.to_string();
|
.to_string();
|
||||||
// copy uuid
|
// copy uuid
|
||||||
|
@ -298,16 +300,16 @@ impl AccessControlProfile {
|
||||||
// receiver, and turn to real filter
|
// receiver, and turn to real filter
|
||||||
let receiver_f: ProtoFilter = try_audit!(
|
let receiver_f: ProtoFilter = try_audit!(
|
||||||
audit,
|
audit,
|
||||||
value
|
value.get_ava_single_protofilter("acp_receiver").ok_or(
|
||||||
.get_ava_single_protofilter("acp_receiver")
|
OperationError::InvalidACPState("Missing acp_receiver".to_string())
|
||||||
.ok_or(OperationError::InvalidACPState("Missing acp_receiver"))
|
)
|
||||||
);
|
);
|
||||||
// targetscope, and turn to real filter
|
// targetscope, and turn to real filter
|
||||||
let targetscope_f: ProtoFilter = try_audit!(
|
let targetscope_f: ProtoFilter = try_audit!(
|
||||||
audit,
|
audit,
|
||||||
value
|
value.get_ava_single_protofilter("acp_targetscope").ok_or(
|
||||||
.get_ava_single_protofilter("acp_targetscope")
|
OperationError::InvalidACPState("Missing acp_targetscope".to_string())
|
||||||
.ok_or(OperationError::InvalidACPState("Missing acp_targetscope"))
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
let receiver_i = try_audit!(audit, Filter::from_rw(audit, &receiver_f, qs));
|
let receiver_i = try_audit!(audit, Filter::from_rw(audit, &receiver_f, qs));
|
||||||
|
|
|
@ -55,6 +55,19 @@ fn get_current_user(req: &HttpRequest<AppState>) -> Option<UserAuthToken> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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 {
|
macro_rules! json_event_post {
|
||||||
($req:expr, $state:expr, $message_type:ty, $request_type:ty) => {{
|
($req:expr, $state:expr, $message_type:ty, $request_type:ty) => {{
|
||||||
// This is copied every request. Is there a better way?
|
// This is copied every request. Is there a better way?
|
||||||
|
@ -100,7 +113,7 @@ macro_rules! json_event_post {
|
||||||
.from_err()
|
.from_err()
|
||||||
.and_then(|res| match res {
|
.and_then(|res| match res {
|
||||||
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
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)
|
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 {
|
let res = $state.qe.send(obj).from_err().and_then(|res| match res {
|
||||||
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
||||||
Err(e) => match e {
|
Err(e) => Ok(operation_error_to_response(e)),
|
||||||
OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)),
|
|
||||||
_ => Ok(HttpResponse::InternalServerError().json(e)),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(res)
|
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 {
|
let res = state.qe.send(obj).from_err().and_then(|res| match res {
|
||||||
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
||||||
Err(e) => match e {
|
Err(e) => Ok(operation_error_to_response(e)),
|
||||||
OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)),
|
|
||||||
_ => Ok(HttpResponse::InternalServerError().json(e)),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(res)
|
Box::new(res)
|
||||||
|
@ -210,10 +217,7 @@ fn json_rest_event_get_id(
|
||||||
// Only send back the first result, or None
|
// Only send back the first result, or None
|
||||||
Ok(HttpResponse::Ok().json(event_result.pop()))
|
Ok(HttpResponse::Ok().json(event_result.pop()))
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => Ok(operation_error_to_response(e)),
|
||||||
OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)),
|
|
||||||
_ => Ok(HttpResponse::InternalServerError().json(e)),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(res)
|
Box::new(res)
|
||||||
|
@ -257,7 +261,7 @@ fn json_rest_event_credential_put(
|
||||||
let m_obj = InternalCredentialSetMessage::new(uat, id, cred_id, obj);
|
let m_obj = InternalCredentialSetMessage::new(uat, id, cred_id, obj);
|
||||||
let res = state.qe.send(m_obj).from_err().and_then(|res| match res {
|
let res = state.qe.send(m_obj).from_err().and_then(|res| match res {
|
||||||
Ok(event_result) => Ok(HttpResponse::Ok().json(event_result)),
|
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)
|
Box::new(res)
|
||||||
|
@ -321,10 +325,7 @@ fn schema_attributetype_get_id(
|
||||||
// Only send back the first result, or None
|
// Only send back the first result, or None
|
||||||
Ok(HttpResponse::Ok().json(event_result.pop()))
|
Ok(HttpResponse::Ok().json(event_result.pop()))
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => Ok(operation_error_to_response(e)),
|
||||||
OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)),
|
|
||||||
_ => Ok(HttpResponse::InternalServerError().json(e)),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(res)
|
Box::new(res)
|
||||||
|
@ -355,10 +356,7 @@ fn schema_classtype_get_id(
|
||||||
// Only send back the first result, or None
|
// Only send back the first result, or None
|
||||||
Ok(HttpResponse::Ok().json(event_result.pop()))
|
Ok(HttpResponse::Ok().json(event_result.pop()))
|
||||||
}
|
}
|
||||||
Err(e) => match e {
|
Err(e) => Ok(operation_error_to_response(e)),
|
||||||
OperationError::NotAuthenticated => Ok(HttpResponse::Unauthorized().json(e)),
|
|
||||||
_ => Ok(HttpResponse::InternalServerError().json(e)),
|
|
||||||
},
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(res)
|
Box::new(res)
|
||||||
|
@ -472,7 +470,7 @@ fn auth(
|
||||||
AuthState::Denied(_) => {
|
AuthState::Denied(_) => {
|
||||||
// Remove the auth-session-id
|
// Remove the auth-session-id
|
||||||
req.session().remove("auth-session-id");
|
req.session().remove("auth-session-id");
|
||||||
Ok(HttpResponse::Ok().json(ar))
|
Ok(HttpResponse::Unauthorized().json(ar))
|
||||||
}
|
}
|
||||||
AuthState::Continue(_) => {
|
AuthState::Continue(_) => {
|
||||||
// Ensure the auth-session-id is set
|
// 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)
|
Box::new(res)
|
||||||
}
|
}
|
||||||
|
|
|
@ -670,7 +670,7 @@ impl AuthEventStep {
|
||||||
AuthStep::Init(name, appid) => {
|
AuthStep::Init(name, appid) => {
|
||||||
if sid.is_some() {
|
if sid.is_some() {
|
||||||
Err(OperationError::InvalidAuthState(
|
Err(OperationError::InvalidAuthState(
|
||||||
"session id present in init",
|
"session id present in init".to_string(),
|
||||||
))
|
))
|
||||||
} else {
|
} else {
|
||||||
Ok(AuthEventStep::Init(AuthEventStepInit {
|
Ok(AuthEventStep::Init(AuthEventStepInit {
|
||||||
|
@ -685,7 +685,7 @@ impl AuthEventStep {
|
||||||
creds: creds,
|
creds: creds,
|
||||||
})),
|
})),
|
||||||
None => Err(OperationError::InvalidAuthState(
|
None => Err(OperationError::InvalidAuthState(
|
||||||
"session id not present in cred",
|
"session id not present in cred".to_string(),
|
||||||
)),
|
)),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,7 +42,7 @@ impl Account {
|
||||||
// Check the classes
|
// Check the classes
|
||||||
if !value.attribute_value_pres("class", &PVCLASS_ACCOUNT) {
|
if !value.attribute_value_pres("class", &PVCLASS_ACCOUNT) {
|
||||||
return Err(OperationError::InvalidAccountState(
|
return Err(OperationError::InvalidAccountState(
|
||||||
"Missing class: account",
|
"Missing class: account".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,11 +51,11 @@ impl Account {
|
||||||
value
|
value
|
||||||
.get_ava_single_string("name")
|
.get_ava_single_string("name")
|
||||||
.ok_or(OperationError::InvalidAccountState(
|
.ok_or(OperationError::InvalidAccountState(
|
||||||
"Missing attribute: name",
|
"Missing attribute: name".to_string(),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
let displayname = value.get_ava_single_string("displayname").ok_or(
|
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
|
let primary = value
|
||||||
|
|
|
@ -199,7 +199,7 @@ impl AuthSession {
|
||||||
) -> Result<AuthState, OperationError> {
|
) -> Result<AuthState, OperationError> {
|
||||||
if self.finished {
|
if self.finished {
|
||||||
return Err(OperationError::InvalidAuthState(
|
return Err(OperationError::InvalidAuthState(
|
||||||
"session already finalised!",
|
"session already finalised!".to_string(),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::server::{
|
||||||
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
||||||
};
|
};
|
||||||
use crate::value::PartialValue;
|
use crate::value::PartialValue;
|
||||||
use kanidm_proto::v1::{ConsistencyError, OperationError};
|
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
|
||||||
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
|
@ -59,7 +59,9 @@ fn get_cand_attr_set<VALID, STATE>(
|
||||||
vr,
|
vr,
|
||||||
uuid
|
uuid
|
||||||
);
|
);
|
||||||
return Err(OperationError::Plugin);
|
return Err(OperationError::Plugin(PluginError::AttrUnique(
|
||||||
|
"ava already exists".to_string(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -109,7 +111,9 @@ fn enforce_unique<STATE>(
|
||||||
|
|
||||||
// If all okay, okay!
|
// If all okay, okay!
|
||||||
if conflict_cand.len() > 0 {
|
if conflict_cand.len() > 0 {
|
||||||
return Err(OperationError::Plugin);
|
return Err(OperationError::Plugin(PluginError::AttrUnique(
|
||||||
|
"duplicate value detected".to_string(),
|
||||||
|
)));
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -13,7 +13,7 @@ use crate::server::{
|
||||||
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
QueryServerReadTransaction, QueryServerTransaction, QueryServerWriteTransaction,
|
||||||
};
|
};
|
||||||
use crate::value::{PartialValue, Value};
|
use crate::value::{PartialValue, Value};
|
||||||
use kanidm_proto::v1::{ConsistencyError, OperationError};
|
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
static ref CLASS_OBJECT: Value = Value::new_class("object");
|
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 ...
|
// Actually check we have a value, could be empty array ...
|
||||||
if u.len() > 1 {
|
if u.len() > 1 {
|
||||||
audit_log!(au, "Entry defines uuid attr, but multiple values.");
|
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!
|
// 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!(
|
let v: Value = try_audit!(
|
||||||
au,
|
au,
|
||||||
u.first()
|
u.first()
|
||||||
.ok_or(OperationError::Plugin)
|
.ok_or(OperationError::Plugin(PluginError::Base(
|
||||||
|
"Uuid format invalid".to_string()
|
||||||
|
)))
|
||||||
.map(|v| (*v).clone())
|
.map(|v| (*v).clone())
|
||||||
);
|
);
|
||||||
v
|
v
|
||||||
|
@ -104,14 +108,16 @@ impl Plugin for Base {
|
||||||
for entry in cand.iter() {
|
for entry in cand.iter() {
|
||||||
let uuid_ref: &Uuid = entry
|
let uuid_ref: &Uuid = entry
|
||||||
.get_ava_single("uuid")
|
.get_ava_single("uuid")
|
||||||
.ok_or(OperationError::Plugin)?
|
.ok_or(OperationError::InvalidEntryState)?
|
||||||
.to_uuid()
|
.to_uuid()
|
||||||
.ok_or(OperationError::Plugin)?;
|
.ok_or(OperationError::InvalidAttribute("uuid".to_string()))?;
|
||||||
audit_log!(au, "Entry valid UUID: {:?}", entry);
|
audit_log!(au, "Entry valid UUID: {:?}", entry);
|
||||||
match cand_uuid.insert(uuid_ref) {
|
match cand_uuid.insert(uuid_ref) {
|
||||||
false => {
|
false => {
|
||||||
audit_log!(au, "uuid duplicate found in create set! {:?}", uuid_ref);
|
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 => {}
|
true => {}
|
||||||
}
|
}
|
||||||
|
@ -137,7 +143,9 @@ impl Plugin for Base {
|
||||||
"uuid from protected system UUID range found in create set! {:?}",
|
"uuid from protected system UUID range found in create set! {:?}",
|
||||||
overlap
|
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\" found in create set! {:?}",
|
||||||
uuid_does_not_exist
|
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
|
// Now from each element, generate a filter to search for all of them
|
||||||
|
@ -175,12 +185,14 @@ impl Plugin for Base {
|
||||||
Ok(b) => {
|
Ok(b) => {
|
||||||
if b == true {
|
if b == true {
|
||||||
audit_log!(au, "A UUID already exists, rejecting.");
|
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) => {
|
Err(e) => {
|
||||||
audit_log!(au, "Error occured checking UUID existance. {:?}", 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" {
|
if attr == "uuid" {
|
||||||
audit_log!(au, "Modifications to UUID's are NOT ALLOWED");
|
audit_log!(au, "Modifications to UUID's are NOT ALLOWED");
|
||||||
return Err(OperationError::Plugin);
|
return Err(OperationError::SystemProtectedAttribute);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
@ -28,7 +28,7 @@ trait Plugin {
|
||||||
"plugin {} has an unimplemented pre_create_transform!",
|
"plugin {} has an unimplemented pre_create_transform!",
|
||||||
Self::id()
|
Self::id()
|
||||||
);
|
);
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_create(
|
fn pre_create(
|
||||||
|
@ -39,7 +39,7 @@ trait Plugin {
|
||||||
_ce: &CreateEvent,
|
_ce: &CreateEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented pre_create!", Self::id());
|
debug!("plugin {} has an unimplemented pre_create!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_create(
|
fn post_create(
|
||||||
|
@ -50,7 +50,7 @@ trait Plugin {
|
||||||
_ce: &CreateEvent,
|
_ce: &CreateEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented post_create!", Self::id());
|
debug!("plugin {} has an unimplemented post_create!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_modify(
|
fn pre_modify(
|
||||||
|
@ -60,7 +60,7 @@ trait Plugin {
|
||||||
_me: &ModifyEvent,
|
_me: &ModifyEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented pre_modify!", Self::id());
|
debug!("plugin {} has an unimplemented pre_modify!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_modify(
|
fn post_modify(
|
||||||
|
@ -72,7 +72,7 @@ trait Plugin {
|
||||||
_ce: &ModifyEvent,
|
_ce: &ModifyEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented post_modify!", Self::id());
|
debug!("plugin {} has an unimplemented post_modify!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn pre_delete(
|
fn pre_delete(
|
||||||
|
@ -82,7 +82,7 @@ trait Plugin {
|
||||||
_de: &DeleteEvent,
|
_de: &DeleteEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented pre_delete!", Self::id());
|
debug!("plugin {} has an unimplemented pre_delete!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn post_delete(
|
fn post_delete(
|
||||||
|
@ -93,7 +93,7 @@ trait Plugin {
|
||||||
_ce: &DeleteEvent,
|
_ce: &DeleteEvent,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("plugin {} has an unimplemented post_delete!", Self::id());
|
debug!("plugin {} has an unimplemented post_delete!", Self::id());
|
||||||
Err(OperationError::Plugin)
|
Err(OperationError::InvalidState)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn verify(
|
fn verify(
|
||||||
|
|
|
@ -20,7 +20,7 @@ use crate::schema::SchemaTransaction;
|
||||||
use crate::server::QueryServerTransaction;
|
use crate::server::QueryServerTransaction;
|
||||||
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
use crate::server::{QueryServerReadTransaction, QueryServerWriteTransaction};
|
||||||
use crate::value::{PartialValue, Value};
|
use crate::value::{PartialValue, Value};
|
||||||
use kanidm_proto::v1::{ConsistencyError, OperationError};
|
use kanidm_proto::v1::{ConsistencyError, OperationError, PluginError};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
// NOTE: This *must* be after base.rs!!!
|
// NOTE: This *must* be after base.rs!!!
|
||||||
|
@ -35,7 +35,14 @@ impl ReferentialIntegrity {
|
||||||
uuid_value: &Value,
|
uuid_value: &Value,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
debug!("{:?}", uuid_value);
|
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");
|
let mut au_qs = AuditScope::new("qs_exist");
|
||||||
// NOTE: This only checks LIVE entries (not using filter_all)
|
// NOTE: This only checks LIVE entries (not using filter_all)
|
||||||
let filt_in = filter!(f_eq("uuid", PartialValue::new_uuid(uuid.clone())));
|
let filt_in = filter!(f_eq("uuid", PartialValue::new_uuid(uuid.clone())));
|
||||||
|
@ -53,7 +60,9 @@ impl ReferentialIntegrity {
|
||||||
rtype,
|
rtype,
|
||||||
uuid
|
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(
|
None => res.push(Err(ConsistencyError::InvalidAttributeType(
|
||||||
"A non-value-ref type was found.",
|
"A non-value-ref type was found.".to_string(),
|
||||||
))),
|
))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,39 +47,47 @@ impl SchemaAttribute {
|
||||||
// class
|
// class
|
||||||
if !value.attribute_value_pres("class", &PVCLASS_ATTRIBUTETYPE) {
|
if !value.attribute_value_pres("class", &PVCLASS_ATTRIBUTETYPE) {
|
||||||
audit_log!(audit, "class attribute type not present");
|
audit_log!(audit, "class attribute type not present");
|
||||||
return Err(OperationError::InvalidSchemaState("missing attributetype"));
|
return Err(OperationError::InvalidSchemaState(
|
||||||
|
"missing attributetype".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// uuid
|
// uuid
|
||||||
let uuid = value.get_uuid().clone();
|
let uuid = value.get_uuid().clone();
|
||||||
|
|
||||||
// name
|
// name
|
||||||
let name = try_audit!(
|
let name =
|
||||||
audit,
|
try_audit!(
|
||||||
value
|
audit,
|
||||||
.get_ava_single_string("attributename")
|
value.get_ava_single_string("attributename").ok_or(
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing attributename"))
|
OperationError::InvalidSchemaState("missing attributename".to_string())
|
||||||
);
|
)
|
||||||
|
);
|
||||||
// description
|
// description
|
||||||
let description = try_audit!(
|
let description =
|
||||||
audit,
|
try_audit!(
|
||||||
value
|
audit,
|
||||||
.get_ava_single_string("description")
|
value.get_ava_single_string("description").ok_or(
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing description"))
|
OperationError::InvalidSchemaState("missing description".to_string())
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// multivalue
|
// multivalue
|
||||||
let multivalue = try_audit!(
|
let multivalue = try_audit!(
|
||||||
audit,
|
audit,
|
||||||
value
|
value
|
||||||
.get_ava_single_bool("multivalue")
|
.get_ava_single_bool("multivalue")
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing multivalue"))
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
|
"missing multivalue".to_string()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
let unique = try_audit!(
|
let unique = try_audit!(
|
||||||
audit,
|
audit,
|
||||||
value
|
value
|
||||||
.get_ava_single_bool("unique")
|
.get_ava_single_bool("unique")
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing unique"))
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
|
"missing unique".to_string()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
// index vec
|
// index vec
|
||||||
// even if empty, it SHOULD be present ... (is that value to put an empty set?)
|
// even if empty, it SHOULD be present ... (is that value to put an empty set?)
|
||||||
|
@ -92,7 +100,7 @@ impl SchemaAttribute {
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(|v: &IndexType| v.clone())
|
.map(|v: &IndexType| v.clone())
|
||||||
.collect()))
|
.collect()))
|
||||||
.map_err(|_| OperationError::InvalidSchemaState("Invalid index"))
|
.map_err(|_| OperationError::InvalidSchemaState("Invalid index".to_string()))
|
||||||
);
|
);
|
||||||
// syntax type
|
// syntax type
|
||||||
let syntax = try_audit!(
|
let syntax = try_audit!(
|
||||||
|
@ -100,7 +108,9 @@ impl SchemaAttribute {
|
||||||
value
|
value
|
||||||
.get_ava_single_syntax("syntax")
|
.get_ava_single_syntax("syntax")
|
||||||
.and_then(|s: &SyntaxType| Some(s.clone()))
|
.and_then(|s: &SyntaxType| Some(s.clone()))
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing syntax"))
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
|
"missing syntax".to_string()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
|
|
||||||
Ok(SchemaAttribute {
|
Ok(SchemaAttribute {
|
||||||
|
@ -339,7 +349,9 @@ impl SchemaClass {
|
||||||
// Convert entry to a schema class.
|
// Convert entry to a schema class.
|
||||||
if !value.attribute_value_pres("class", &PVCLASS_CLASSTYPE) {
|
if !value.attribute_value_pres("class", &PVCLASS_CLASSTYPE) {
|
||||||
audit_log!(audit, "class classtype not present");
|
audit_log!(audit, "class classtype not present");
|
||||||
return Err(OperationError::InvalidSchemaState("missing classtype"));
|
return Err(OperationError::InvalidSchemaState(
|
||||||
|
"missing classtype".to_string(),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
// uuid
|
// uuid
|
||||||
|
@ -350,36 +362,41 @@ impl SchemaClass {
|
||||||
audit,
|
audit,
|
||||||
value
|
value
|
||||||
.get_ava_single_string("classname")
|
.get_ava_single_string("classname")
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing classname"))
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
|
"missing classname".to_string()
|
||||||
|
))
|
||||||
);
|
);
|
||||||
// description
|
// description
|
||||||
let description = try_audit!(
|
let description =
|
||||||
audit,
|
try_audit!(
|
||||||
value
|
audit,
|
||||||
.get_ava_single_string("description")
|
value.get_ava_single_string("description").ok_or(
|
||||||
.ok_or(OperationError::InvalidSchemaState("missing description"))
|
OperationError::InvalidSchemaState("missing description".to_string())
|
||||||
);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
// These are all "optional" lists of strings.
|
// These are all "optional" lists of strings.
|
||||||
let systemmay =
|
let systemmay =
|
||||||
value
|
value
|
||||||
.get_ava_opt_string("systemmay")
|
.get_ava_opt_string("systemmay")
|
||||||
.ok_or(OperationError::InvalidSchemaState(
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
"Missing or invalid systemmay",
|
"Missing or invalid systemmay".to_string(),
|
||||||
))?;
|
))?;
|
||||||
let systemmust =
|
let systemmust =
|
||||||
value
|
value
|
||||||
.get_ava_opt_string("systemmust")
|
.get_ava_opt_string("systemmust")
|
||||||
.ok_or(OperationError::InvalidSchemaState(
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
"Missing or invalid systemmust",
|
"Missing or invalid systemmust".to_string(),
|
||||||
))?;
|
))?;
|
||||||
let may = value
|
let may = value
|
||||||
.get_ava_opt_string("may")
|
.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
|
let must = value
|
||||||
.get_ava_opt_string("must")
|
.get_ava_opt_string("must")
|
||||||
.ok_or(OperationError::InvalidSchemaState(
|
.ok_or(OperationError::InvalidSchemaState(
|
||||||
"Missing or invalid must",
|
"Missing or invalid must".to_string(),
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
Ok(SchemaClass {
|
Ok(SchemaClass {
|
||||||
|
|
|
@ -364,11 +364,11 @@ pub trait QueryServerTransaction {
|
||||||
SyntaxType::UTF8STRING => Ok(Value::new_utf8(value.clone())),
|
SyntaxType::UTF8STRING => Ok(Value::new_utf8(value.clone())),
|
||||||
SyntaxType::UTF8STRING_INSENSITIVE => Ok(Value::new_iutf8s(value.as_str())),
|
SyntaxType::UTF8STRING_INSENSITIVE => Ok(Value::new_iutf8s(value.as_str())),
|
||||||
SyntaxType::BOOLEAN => Value::new_bools(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())
|
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())
|
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 => {
|
SyntaxType::UUID => {
|
||||||
// It's a uuid - we do NOT check for existance, because that
|
// It's a uuid - we do NOT check for existance, because that
|
||||||
// could be revealing or disclosing - it is up to acp to assert
|
// could be revealing or disclosing - it is up to acp to assert
|
||||||
|
@ -386,7 +386,7 @@ pub trait QueryServerTransaction {
|
||||||
Some(Value::new_uuid(un))
|
Some(Value::new_uuid(un))
|
||||||
})
|
})
|
||||||
// I think this is unreachable due to how the .or_else works.
|
// 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 => {
|
SyntaxType::REFERENCE_UUID => {
|
||||||
// See comments above.
|
// See comments above.
|
||||||
|
@ -398,11 +398,11 @@ pub trait QueryServerTransaction {
|
||||||
Some(Value::new_refer(un))
|
Some(Value::new_refer(un))
|
||||||
})
|
})
|
||||||
// I think this is unreachable due to how the .or_else works.
|
// 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)
|
SyntaxType::JSON_FILTER => Value::new_json_filter(value)
|
||||||
.ok_or(OperationError::InvalidAttribute("Invalid Filter syntax")),
|
.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")),
|
SyntaxType::CREDENTIAL => Err(OperationError::InvalidAttribute("Credentials can not be supplied through modification - please use the IDM api".to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -431,12 +431,15 @@ pub trait QueryServerTransaction {
|
||||||
SyntaxType::UTF8STRING_INSENSITIVE => {
|
SyntaxType::UTF8STRING_INSENSITIVE => {
|
||||||
Ok(PartialValue::new_iutf8s(value.as_str()))
|
Ok(PartialValue::new_iutf8s(value.as_str()))
|
||||||
}
|
}
|
||||||
SyntaxType::BOOLEAN => PartialValue::new_bools(value.as_str())
|
SyntaxType::BOOLEAN => PartialValue::new_bools(value.as_str()).ok_or(
|
||||||
.ok_or(OperationError::InvalidAttribute("Invalid boolean syntax")),
|
OperationError::InvalidAttribute("Invalid boolean syntax".to_string()),
|
||||||
SyntaxType::SYNTAX_ID => PartialValue::new_syntaxs(value.as_str())
|
),
|
||||||
.ok_or(OperationError::InvalidAttribute("Invalid Syntax syntax")),
|
SyntaxType::SYNTAX_ID => PartialValue::new_syntaxs(value.as_str()).ok_or(
|
||||||
SyntaxType::INDEX_ID => PartialValue::new_indexs(value.as_str())
|
OperationError::InvalidAttribute("Invalid Syntax syntax".to_string()),
|
||||||
.ok_or(OperationError::InvalidAttribute("Invalid Index syntax")),
|
),
|
||||||
|
SyntaxType::INDEX_ID => PartialValue::new_indexs(value.as_str()).ok_or(
|
||||||
|
OperationError::InvalidAttribute("Invalid Index syntax".to_string()),
|
||||||
|
),
|
||||||
SyntaxType::UUID => {
|
SyntaxType::UUID => {
|
||||||
PartialValue::new_uuids(value.as_str())
|
PartialValue::new_uuids(value.as_str())
|
||||||
.or_else(|| {
|
.or_else(|| {
|
||||||
|
@ -450,7 +453,9 @@ pub trait QueryServerTransaction {
|
||||||
Some(PartialValue::new_uuid(un))
|
Some(PartialValue::new_uuid(un))
|
||||||
})
|
})
|
||||||
// I think this is unreachable due to how the .or_else works.
|
// 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 => {
|
SyntaxType::REFERENCE_UUID => {
|
||||||
// See comments above.
|
// See comments above.
|
||||||
|
@ -462,10 +467,13 @@ pub trait QueryServerTransaction {
|
||||||
Some(PartialValue::new_refer(un))
|
Some(PartialValue::new_refer(un))
|
||||||
})
|
})
|
||||||
// I think this is unreachable due to how the .or_else works.
|
// 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)
|
SyntaxType::JSON_FILTER => PartialValue::new_json_filter(value).ok_or(
|
||||||
.ok_or(OperationError::InvalidAttribute("Invalid Filter syntax")),
|
OperationError::InvalidAttribute("Invalid Filter syntax".to_string()),
|
||||||
|
),
|
||||||
SyntaxType::CREDENTIAL => Ok(PartialValue::new_credential_tag(value.as_str())),
|
SyntaxType::CREDENTIAL => Ok(PartialValue::new_credential_tag(value.as_str())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue