mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
Better WebAuthn and other error responses (#2608)
This commit is contained in:
parent
f779c4ebf7
commit
3c01a96348
|
@ -28,19 +28,17 @@ use compact_jwt::Jwk;
|
|||
|
||||
use kanidm_proto::constants::uri::V1_AUTH_VALID;
|
||||
use kanidm_proto::constants::{
|
||||
APPLICATION_JSON, ATTR_DOMAIN_DISPLAY_NAME, ATTR_DOMAIN_LDAP_BASEDN, ATTR_DOMAIN_SSID,
|
||||
ATTR_ENTRY_MANAGED_BY, ATTR_KEY_ACTION_REVOKE, ATTR_LDAP_ALLOW_UNIX_PW_BIND, ATTR_NAME,
|
||||
CLIENT_TOKEN_CACHE, KOPID, KVERSION,
|
||||
ATTR_DOMAIN_DISPLAY_NAME, ATTR_DOMAIN_LDAP_BASEDN, ATTR_DOMAIN_SSID, ATTR_ENTRY_MANAGED_BY,
|
||||
ATTR_KEY_ACTION_REVOKE, ATTR_LDAP_ALLOW_UNIX_PW_BIND, ATTR_NAME, CLIENT_TOKEN_CACHE, KOPID,
|
||||
KVERSION,
|
||||
};
|
||||
use kanidm_proto::internal::*;
|
||||
use kanidm_proto::v1::*;
|
||||
use reqwest::header::CONTENT_TYPE;
|
||||
use reqwest::Response;
|
||||
pub use reqwest::StatusCode;
|
||||
use serde::de::DeserializeOwned;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::error::Error as SerdeJsonError;
|
||||
use serde_json::json;
|
||||
use tokio::sync::{Mutex, RwLock};
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
@ -704,13 +702,7 @@ impl KanidmClient {
|
|||
dest: &str,
|
||||
request: &R,
|
||||
) -> Result<T, ClientError> {
|
||||
let req_string = serde_json::to_string(request).map_err(ClientError::JsonEncode)?;
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.post(self.make_url(dest))
|
||||
.body(req_string)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||
let response = self.client.post(self.make_url(dest)).json(request);
|
||||
|
||||
let response = response
|
||||
.send()
|
||||
|
@ -744,13 +736,8 @@ impl KanidmClient {
|
|||
request: R,
|
||||
) -> Result<T, ClientError> {
|
||||
trace!("perform_auth_post_request connecting to {}", dest);
|
||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.post(self.make_url(dest))
|
||||
.body(req_string)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||
let response = self.client.post(self.make_url(dest)).json(&request);
|
||||
|
||||
// If we have a bearer token, set it now.
|
||||
let response = {
|
||||
|
@ -794,12 +781,7 @@ impl KanidmClient {
|
|||
dest: &str,
|
||||
request: R,
|
||||
) -> Result<T, ClientError> {
|
||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||
let response = self
|
||||
.client
|
||||
.post(self.make_url(dest))
|
||||
.body(req_string)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||
let response = self.client.post(self.make_url(dest)).json(&request);
|
||||
|
||||
let response = {
|
||||
let tguard = self.bearer_token.read().await;
|
||||
|
@ -841,12 +823,8 @@ impl KanidmClient {
|
|||
dest: &str,
|
||||
request: R,
|
||||
) -> Result<T, ClientError> {
|
||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||
let response = self.client.put(self.make_url(dest)).json(&request);
|
||||
|
||||
let response = self
|
||||
.client
|
||||
.put(self.make_url(dest))
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||
let response = {
|
||||
let tguard = self.bearer_token.read().await;
|
||||
if let Some(token) = &(*tguard) {
|
||||
|
@ -857,7 +835,6 @@ impl KanidmClient {
|
|||
};
|
||||
|
||||
let response = response
|
||||
.body(req_string)
|
||||
.send()
|
||||
.await
|
||||
.map_err(|err| self.handle_response_error(err))?;
|
||||
|
@ -892,12 +869,7 @@ impl KanidmClient {
|
|||
dest: &str,
|
||||
request: R,
|
||||
) -> Result<T, ClientError> {
|
||||
let req_string = serde_json::to_string(&request).map_err(ClientError::JsonEncode)?;
|
||||
let response = self
|
||||
.client
|
||||
.patch(self.make_url(dest))
|
||||
.body(req_string)
|
||||
.header(CONTENT_TYPE, APPLICATION_JSON);
|
||||
let response = self.client.patch(self.make_url(dest)).json(&request);
|
||||
|
||||
let response = {
|
||||
let tguard = self.bearer_token.read().await;
|
||||
|
@ -980,7 +952,7 @@ impl KanidmClient {
|
|||
.client
|
||||
.delete(self.make_url(dest))
|
||||
// empty-ish body that makes the parser happy
|
||||
.json(&json!([]));
|
||||
.json(&serde_json::json!([]));
|
||||
|
||||
let response = {
|
||||
let tguard = self.bearer_token.read().await;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use utoipa::ToSchema;
|
||||
use uuid::Uuid;
|
||||
|
@ -127,6 +129,7 @@ pub enum OperationError {
|
|||
// Credential Update Errors
|
||||
CU0001WebauthnAttestationNotTrusted,
|
||||
CU0002WebauthnRegistrationError,
|
||||
CU0003WebauthnUserNotVerified,
|
||||
// ValueSet errors
|
||||
VS0001IncomingReplSshPublicKey,
|
||||
// Value Errors
|
||||
|
@ -203,3 +206,160 @@ impl PartialEq for OperationError {
|
|||
std::mem::discriminant(self) == std::mem::discriminant(other)
|
||||
}
|
||||
}
|
||||
|
||||
impl Display for OperationError {
|
||||
fn fmt(&self, f: &mut Formatter) -> std::fmt::Result {
|
||||
let mut output = format!("{:?}", self)
|
||||
.split("::")
|
||||
.last()
|
||||
.unwrap_or("")
|
||||
.to_string();
|
||||
|
||||
if let Some(msg) = self.message() {
|
||||
output += &format!(" - {}", msg);
|
||||
};
|
||||
f.write_str(&output)
|
||||
}
|
||||
}
|
||||
|
||||
impl OperationError {
|
||||
/// Return the message associated with the error if there is one.
|
||||
fn message(&self) -> Option<&'static str> {
|
||||
match self {
|
||||
OperationError::SessionExpired => None,
|
||||
OperationError::EmptyRequest => None,
|
||||
OperationError::Backend => None,
|
||||
OperationError::NoMatchingEntries => None,
|
||||
OperationError::NoMatchingAttributes => None,
|
||||
OperationError::CorruptedEntry(_) => None,
|
||||
OperationError::CorruptedIndex(_) => None,
|
||||
OperationError::ConsistencyError(_) => None,
|
||||
OperationError::SchemaViolation(_) => None,
|
||||
OperationError::Plugin(_) => None,
|
||||
OperationError::FilterGeneration => None,
|
||||
OperationError::FilterUuidResolution => None,
|
||||
OperationError::InvalidAttributeName(_) => None,
|
||||
OperationError::InvalidAttribute(_) => None,
|
||||
OperationError::InvalidDbState => None,
|
||||
OperationError::InvalidCacheState => None,
|
||||
OperationError::InvalidValueState => None,
|
||||
OperationError::InvalidEntryId => None,
|
||||
OperationError::InvalidRequestState => None,
|
||||
OperationError::InvalidSyncState => None,
|
||||
OperationError::InvalidState => None,
|
||||
OperationError::InvalidEntryState => None,
|
||||
OperationError::InvalidUuid => None,
|
||||
OperationError::InvalidReplChangeId => None,
|
||||
OperationError::InvalidAcpState(_) => None,
|
||||
OperationError::InvalidSchemaState(_) => None,
|
||||
OperationError::InvalidAccountState(_) => None,
|
||||
OperationError::MissingEntries => None,
|
||||
OperationError::ModifyAssertionFailed => None,
|
||||
OperationError::BackendEngine => None,
|
||||
OperationError::SqliteError => None,
|
||||
OperationError::FsError => None,
|
||||
OperationError::SerdeJsonError => None,
|
||||
OperationError::SerdeCborError => None,
|
||||
OperationError::AccessDenied => None,
|
||||
OperationError::NotAuthenticated => None,
|
||||
OperationError::NotAuthorised => None,
|
||||
OperationError::InvalidAuthState(_) => None,
|
||||
OperationError::InvalidSessionState => None,
|
||||
OperationError::SystemProtectedObject => None,
|
||||
OperationError::SystemProtectedAttribute => None,
|
||||
OperationError::PasswordQuality(_) => None,
|
||||
OperationError::CryptographyError => None,
|
||||
OperationError::ResourceLimit => None,
|
||||
OperationError::QueueDisconnected => None,
|
||||
OperationError::Webauthn => None,
|
||||
OperationError::Wait(_) => None,
|
||||
OperationError::ReplReplayFailure => None,
|
||||
OperationError::ReplEntryNotChanged => None,
|
||||
OperationError::ReplInvalidRUVState => None,
|
||||
OperationError::ReplDomainLevelUnsatisfiable => None,
|
||||
OperationError::ReplDomainUuidMismatch => None,
|
||||
OperationError::ReplServerUuidSplitDataState => None,
|
||||
OperationError::TransactionAlreadyCommitted => None,
|
||||
OperationError::ValueDenyName => None,
|
||||
OperationError::CU0002WebauthnRegistrationError => None,
|
||||
OperationError::CU0003WebauthnUserNotVerified => Some("User Verification bit not set while registering credential, you may need to configure a PIN on this device."),
|
||||
OperationError::CU0001WebauthnAttestationNotTrusted => None,
|
||||
OperationError::VS0001IncomingReplSshPublicKey => None,
|
||||
OperationError::VL0001ValueSshPublicKeyString => None,
|
||||
OperationError::SC0001IncomingSshPublicKey => None,
|
||||
OperationError::MG0001InvalidReMigrationLevel => None,
|
||||
OperationError::MG0002RaiseDomainLevelExceedsMaximum => None,
|
||||
OperationError::MG0003ServerPhaseInvalidForMigration => None,
|
||||
OperationError::DB0001MismatchedRestoreVersion => None,
|
||||
OperationError::DB0002MismatchedRestoreVersion => None,
|
||||
OperationError::MG0004DomainLevelInDevelopment => None,
|
||||
OperationError::MG0005GidConstraintsNotMet => None,
|
||||
OperationError::KP0001KeyProviderNotLoaded => None,
|
||||
OperationError::KP0002KeyProviderInvalidClass => None,
|
||||
OperationError::KP0003KeyProviderInvalidType => None,
|
||||
OperationError::KP0004KeyProviderMissingAttributeName => None,
|
||||
OperationError::KP0005KeyProviderDuplicate => None,
|
||||
OperationError::KP0006KeyObjectJwtEs256Generation => None,
|
||||
OperationError::KP0007KeyProviderDefaultNotAvailable => None,
|
||||
OperationError::KP0008KeyObjectMissingUuid => None,
|
||||
OperationError::KP0009KeyObjectPrivateToDer => None,
|
||||
OperationError::KP0010KeyObjectSignerToVerifier => None,
|
||||
OperationError::KP0011KeyObjectMissingClass => None,
|
||||
OperationError::KP0012KeyObjectMissingProvider => None,
|
||||
OperationError::KP0012KeyProviderNotLoaded => None,
|
||||
OperationError::KP0013KeyObjectJwsEs256DerInvalid => None,
|
||||
OperationError::KP0014KeyObjectSignerToVerifier => None,
|
||||
OperationError::KP0015KeyObjectJwsEs256DerInvalid => None,
|
||||
OperationError::KP0016KeyObjectJwsEs256DerInvalid => None,
|
||||
OperationError::KP0017KeyProviderNoSuchKey => None,
|
||||
OperationError::KP0018KeyProviderNoSuchKey => None,
|
||||
OperationError::KP0019KeyProviderUnsupportedAlgorithm => None,
|
||||
OperationError::KP0020KeyObjectNoActiveSigningKeys => None,
|
||||
OperationError::KP0021KeyObjectJwsEs256Signature => None,
|
||||
OperationError::KP0022KeyObjectJwsNotAssociated => None,
|
||||
OperationError::KP0023KeyObjectJwsKeyRevoked => None,
|
||||
OperationError::KP0024KeyObjectJwsInvalid => None,
|
||||
OperationError::KP0025KeyProviderNotAvailable => None,
|
||||
OperationError::KP0026KeyObjectNoSuchKey => None,
|
||||
OperationError::KP0027KeyObjectPublicToDer => None,
|
||||
OperationError::KP0028KeyObjectImportJwsEs256DerInvalid => None,
|
||||
OperationError::KP0029KeyObjectSignerToVerifier => None,
|
||||
OperationError::KP0030KeyObjectPublicToDer => None,
|
||||
OperationError::KP0031KeyObjectNotFound => None,
|
||||
OperationError::KP0032KeyProviderNoSuchKey => None,
|
||||
OperationError::KP0033KeyProviderNoSuchKey => None,
|
||||
OperationError::KP0034KeyProviderUnsupportedAlgorithm => None,
|
||||
OperationError::KP0035KeyObjectJweA128GCMGeneration => None,
|
||||
OperationError::KP0036KeyObjectPrivateToBytes => None,
|
||||
OperationError::KP0037KeyObjectImportJweA128GCMInvalid => None,
|
||||
OperationError::KP0038KeyObjectImportJweA128GCMInvalid => None,
|
||||
OperationError::KP0039KeyObjectJweNotAssociated => None,
|
||||
OperationError::KP0040KeyObjectJweInvalid => None,
|
||||
OperationError::KP0041KeyObjectJweRevoked => None,
|
||||
OperationError::KP0042KeyObjectNoActiveEncryptionKeys => None,
|
||||
OperationError::KP0043KeyObjectJweA128GCMEncryption => None,
|
||||
OperationError::KP0044KeyObjectJwsPublicJwk => None,
|
||||
OperationError::PL0001GidOverlapsSystemRange => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_operationerror_as_nice_string() {
|
||||
assert_eq!(
|
||||
OperationError::CU0001WebauthnAttestationNotTrusted.to_string(),
|
||||
"CU0001WebauthnAttestationNotTrusted".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
OperationError::CU0003WebauthnUserNotVerified.to_string(),
|
||||
"CU0003WebauthnUserNotVerified - User Verification bit not set while registering credential, you may need to configure a PIN on this device.".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
OperationError::SessionExpired.to_string(),
|
||||
"SessionExpired".to_string()
|
||||
);
|
||||
assert_eq!(
|
||||
OperationError::CorruptedEntry(12345).to_string(),
|
||||
"CorruptedEntry(12345)".to_string()
|
||||
);
|
||||
}
|
||||
|
|
|
@ -128,7 +128,7 @@ echo "Creating the ${OAUTH2_RP_ID} OAuth2 RP Supplemental Scope Map"
|
|||
${KANIDM} system oauth2 update-sup-scope-map "${OAUTH2_RP_ID}" "${TEST_GROUP}" admin -D "${IDM_ADMIN_USER}"
|
||||
|
||||
echo "Creating a claim map for RS ${OAUTH2_RP_ID}"
|
||||
${KANIDM} system oauth2 update-claim-map "${OAUTH2_RP_ID}" testclaim "${TEST_GROUP}" foo bar
|
||||
${KANIDM} system oauth2 update-claim-map "${OAUTH2_RP_ID}" testclaim "${TEST_GROUP}" foo bar -D "${IDM_ADMIN_USER}"
|
||||
|
||||
echo "Creating the OAuth2 RP Secondary Supplemental Crab-baite Scope Map.... wait, no that's not a thing."
|
||||
|
||||
|
|
|
@ -277,6 +277,8 @@ impl Modify for SecurityAddon {
|
|||
response_schema::Result,
|
||||
// terrible workaround for other things
|
||||
response_schema::ScimEntry,
|
||||
// terrible workaround for other things
|
||||
response_schema::Jwk,
|
||||
|
||||
WebError,
|
||||
)
|
||||
|
|
|
@ -91,3 +91,6 @@ pub(crate) struct Result {}
|
|||
#[derive(Debug, Clone, ToSchema)]
|
||||
// TODO: this should be handled elsewhere, but ... I don't know how to make it possible in utoipa
|
||||
pub(crate) struct ScimEntry {}
|
||||
|
||||
#[derive(Debug, Clone, ToSchema)]
|
||||
pub(crate) struct Jwk {}
|
||||
|
|
|
@ -40,12 +40,11 @@ impl IntoResponse for WebError {
|
|||
(StatusCode::INTERNAL_SERVER_ERROR, inner).into_response()
|
||||
}
|
||||
WebError::OperationError(inner) => {
|
||||
let (response_code, headers) = match &inner {
|
||||
let (code, headers) = match &inner {
|
||||
OperationError::NotAuthenticated | OperationError::SessionExpired => {
|
||||
// https://datatracker.ietf.org/doc/html/rfc7235#section-4.1
|
||||
(
|
||||
StatusCode::UNAUTHORIZED,
|
||||
// Some([("WWW-Authenticate", "Bearer")]),
|
||||
Some([("WWW-Authenticate", "Bearer"); 1]),
|
||||
)
|
||||
}
|
||||
|
@ -55,14 +54,17 @@ impl IntoResponse for WebError {
|
|||
OperationError::NoMatchingEntries => (StatusCode::NOT_FOUND, None),
|
||||
OperationError::PasswordQuality(_)
|
||||
| OperationError::EmptyRequest
|
||||
| OperationError::SchemaViolation(_) => (StatusCode::BAD_REQUEST, None),
|
||||
| OperationError::SchemaViolation(_)
|
||||
| OperationError::CU0003WebauthnUserNotVerified => {
|
||||
(StatusCode::BAD_REQUEST, None)
|
||||
}
|
||||
_ => (StatusCode::INTERNAL_SERVER_ERROR, None),
|
||||
};
|
||||
let body =
|
||||
serde_json::to_string(&inner).unwrap_or_else(|_err| format!("{:?}", inner));
|
||||
let body = serde_json::to_string(&inner).unwrap_or(inner.to_string());
|
||||
|
||||
match headers {
|
||||
Some(headers) => (response_code, headers, body).into_response(),
|
||||
None => (response_code, body).into_response(),
|
||||
Some(headers) => (code, headers, body).into_response(),
|
||||
None => (code, body).into_response(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2099,7 +2099,12 @@ impl<'a> IdmServerCredUpdateTransaction<'a> {
|
|||
.finish_passkey_registration(reg, pk_reg)
|
||||
.map_err(|e| {
|
||||
error!(eclass=?e, emsg=%e, "Unable to complete passkey registration");
|
||||
OperationError::Webauthn
|
||||
match e {
|
||||
WebauthnError::UserNotVerified => {
|
||||
OperationError::CU0003WebauthnUserNotVerified
|
||||
}
|
||||
_ => OperationError::CU0002WebauthnRegistrationError,
|
||||
}
|
||||
});
|
||||
|
||||
// The reg is done. Clean up state before returning errors.
|
||||
|
@ -2220,13 +2225,16 @@ impl<'a> IdmServerCredUpdateTransaction<'a> {
|
|||
.webauthn
|
||||
.finish_attested_passkey_registration(reg, pk_reg)
|
||||
.map_err(|e| {
|
||||
error!(eclass=?e, emsg=%e, "Unable to complete passkey registration");
|
||||
error!(eclass=?e, emsg=%e, "Unable to complete attested passkey registration");
|
||||
|
||||
match e {
|
||||
WebauthnError::AttestationChainNotTrusted(_)
|
||||
| WebauthnError::AttestationNotVerifiable => {
|
||||
OperationError::CU0001WebauthnAttestationNotTrusted
|
||||
}
|
||||
},
|
||||
WebauthnError::UserNotVerified => {
|
||||
OperationError::CU0003WebauthnUserNotVerified
|
||||
},
|
||||
_ => OperationError::CU0002WebauthnRegistrationError,
|
||||
}
|
||||
});
|
||||
|
|
|
@ -42,7 +42,7 @@ async fn get_webdriver_client() -> fantoccini::Client {
|
|||
Err(_) => {
|
||||
// trying the default chromedriver port
|
||||
eprintln!("Couldn't connect on 4444, trying 9515");
|
||||
fantoccini::ClientBuilder::new(hyper_tls::HttpsConnector::new())
|
||||
fantoccini::ClientBuilder::native()
|
||||
.connect("http://localhost:9515")
|
||||
.await
|
||||
.unwrap()
|
||||
|
@ -56,7 +56,7 @@ async fn get_webdriver_client() -> fantoccini::Client {
|
|||
}
|
||||
});
|
||||
let cap: Capabilities = serde_json::from_value(cap).unwrap();
|
||||
fantoccini::ClientBuilder::new(hyper_tls::HttpsConnector::new())
|
||||
fantoccini::ClientBuilder::native()
|
||||
.capabilities(cap)
|
||||
.connect("http://localhost:9515")
|
||||
.await
|
||||
|
|
Binary file not shown.
Binary file not shown.
BIN
server/web_ui/pkg/external/bootstrap.min.css.br
vendored
BIN
server/web_ui/pkg/external/bootstrap.min.css.br
vendored
Binary file not shown.
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
BIN
server/web_ui/pkg/external/bootstrap.min.css.map.br
vendored
Binary file not shown.
BIN
server/web_ui/pkg/external/viz.js.br
vendored
BIN
server/web_ui/pkg/external/viz.js.br
vendored
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -232,19 +232,19 @@ function addBorrowedObject(obj) {
|
|||
}
|
||||
function __wbg_adapter_38(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h5869fca7f8c0640c(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h310d1129d0c292ca(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_41(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1aa6653248d58742(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h027c38da75b21f7b(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function __wbg_adapter_44(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__haed7e087111b3b75(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hea5c5c7c205dc9e3(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
|
@ -686,6 +686,13 @@ function __wbg_get_imports() {
|
|||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_parentNode_6be3abff20e1a5fb = function(arg0) {
|
||||
const ret = getObject(arg0).parentNode;
|
||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||
|
@ -755,13 +762,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_pushState_b8e8d346f8bb33fd = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_headers_abb199c3be8d817c = function(arg0) {
|
||||
const ret = getObject(arg0).headers;
|
||||
return addHeapObject(ret);
|
||||
|
@ -963,16 +963,16 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1260 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 582, __wbg_adapter_38);
|
||||
imports.wbg.__wbindgen_closure_wrapper1262 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 585, __wbg_adapter_38);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1368 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 630, __wbg_adapter_41);
|
||||
imports.wbg.__wbindgen_closure_wrapper1369 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 631, __wbg_adapter_41);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1399 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 647, __wbg_adapter_44);
|
||||
imports.wbg.__wbindgen_closure_wrapper1400 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 648, __wbg_adapter_44);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -239,19 +239,19 @@ function addBorrowedObject(obj) {
|
|||
}
|
||||
function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hde2cadb5f0b706d2(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h17ac9e19f3ddff30(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_51(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1aa6653248d58742(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h027c38da75b21f7b(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function __wbg_adapter_54(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1adeb92879459ba7(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h6d223bcdfbf7f3c4(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
|
@ -630,6 +630,12 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_focus_39d4b8ba8ff9df14 = function() { return handleError(function (arg0) {
|
||||
getObject(arg0).focus();
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_remove_698118fb25ab8150 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -637,12 +643,6 @@ function __wbg_get_imports() {
|
|||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_add_dcb05a8ba423bdac = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_remove_698118fb25ab8150 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -1101,7 +1101,7 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1415 = function(arg0, arg1, arg2) {
|
||||
imports.wbg.__wbindgen_closure_wrapper1416 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 538, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -232,7 +232,7 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
|||
return real;
|
||||
}
|
||||
function __wbg_adapter_48(arg0, arg1) {
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h96f7c6547f3957ee(arg0, arg1);
|
||||
wasm._dyn_core__ops__function__FnMut_____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h4032d96dca0d1c1e(arg0, arg1);
|
||||
}
|
||||
|
||||
let stack_pointer = 128;
|
||||
|
@ -244,19 +244,19 @@ function addBorrowedObject(obj) {
|
|||
}
|
||||
function __wbg_adapter_51(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb105de8e9efc9ac9(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h73c5fab6b46e1b10(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
function __wbg_adapter_54(arg0, arg1, arg2) {
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1aa6653248d58742(arg0, arg1, addHeapObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h027c38da75b21f7b(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
function __wbg_adapter_57(arg0, arg1, arg2) {
|
||||
try {
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__he6ae5361a1f44a8b(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h54846433116134af(arg0, arg1, addBorrowedObject(arg2));
|
||||
} finally {
|
||||
heap[stack_pointer++] = undefined;
|
||||
}
|
||||
|
@ -658,13 +658,6 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).get(getStringFromWasm0(arg1, arg2));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_addEventListener_4283b15b4f039eb5 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||
}, arguments) };
|
||||
|
@ -677,6 +670,13 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_remove_698118fb25ab8150 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_href_2edbae9e92cdfeff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
const len1 = WASM_VECTOR_LEN;
|
||||
getInt32Memory0()[arg0 / 4 + 1] = len1;
|
||||
getInt32Memory0()[arg0 / 4 + 0] = ptr1;
|
||||
};
|
||||
imports.wbg.__wbg_href_706b235ecfe6848c = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg1).href;
|
||||
const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -1148,20 +1148,20 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper1348 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 692, __wbg_adapter_48);
|
||||
imports.wbg.__wbindgen_closure_wrapper971 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 583, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3876 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1949, __wbg_adapter_51);
|
||||
imports.wbg.__wbindgen_closure_wrapper3891 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1956, __wbg_adapter_51);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3955 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1975, __wbg_adapter_54);
|
||||
imports.wbg.__wbindgen_closure_wrapper3970 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1982, __wbg_adapter_54);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper3986 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1992, __wbg_adapter_57);
|
||||
imports.wbg.__wbindgen_closure_wrapper4001 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1999, __wbg_adapter_57);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -9,7 +9,7 @@ use kanidm_proto::internal::{Filter, Modify, ModifyList};
|
|||
use kanidm_proto::v1::Entry;
|
||||
use serde::de::DeserializeOwned;
|
||||
|
||||
use crate::RawOpt;
|
||||
use crate::{OutputMode, RawOpt};
|
||||
|
||||
fn read_file<T: DeserializeOwned, P: AsRef<Path>>(path: P) -> Result<T, Box<dyn Error>> {
|
||||
let f = File::open(path)?;
|
||||
|
@ -36,13 +36,24 @@ impl RawOpt {
|
|||
let filter: Filter = match serde_json::from_str(sopt.filter.as_str()) {
|
||||
Ok(f) => f,
|
||||
Err(e) => {
|
||||
error!("Error -> {:?}", e);
|
||||
error!("Error parsing filter -> {:?}", e);
|
||||
return;
|
||||
}
|
||||
};
|
||||
|
||||
match client.search(filter).await {
|
||||
Ok(rset) => rset.iter().for_each(|e| println!("{}", e)),
|
||||
Ok(rset) => match sopt.commonopts.output_mode {
|
||||
#[allow(clippy::expect_used)]
|
||||
OutputMode::Json => {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::to_string(&rset).expect("Failed to serialize entry!")
|
||||
)
|
||||
}
|
||||
OutputMode::Text => {
|
||||
rset.iter().for_each(|e| println!("{}", e));
|
||||
}
|
||||
},
|
||||
Err(e) => error!("Error -> {:?}", e),
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue