mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 20:47:01 +01:00
Fix oauth2 response value and other wasm goodies (#1135)
This commit is contained in:
parent
a55c0ca68d
commit
6c67041fda
|
@ -328,6 +328,11 @@ async fn oauth2_authorise(
|
||||||
res.insert_header("WWW-Authenticate", "Bearer");
|
res.insert_header("WWW-Authenticate", "Bearer");
|
||||||
Ok(res)
|
Ok(res)
|
||||||
}
|
}
|
||||||
|
Err(Oauth2Error::AccessDenied) => {
|
||||||
|
// If scopes are not available for this account.
|
||||||
|
let res = tide::Response::new(tide::StatusCode::Forbidden);
|
||||||
|
Ok(res)
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
RFC - If the request fails due to a missing, invalid, or mismatching
|
RFC - If the request fails due to a missing, invalid, or mismatching
|
||||||
redirection URI, or if the client identifier is missing or invalid,
|
redirection URI, or if the client identifier is missing or invalid,
|
||||||
|
@ -428,7 +433,7 @@ async fn oauth2_authorise_permit(
|
||||||
// Turns out this instinct was correct:
|
// Turns out this instinct was correct:
|
||||||
// https://www.proofpoint.com/us/blog/cloud-security/microsoft-and-github-oauth-implementation-vulnerabilities-lead-redirection
|
// https://www.proofpoint.com/us/blog/cloud-security/microsoft-and-github-oauth-implementation-vulnerabilities-lead-redirection
|
||||||
// Possible to use this with a malicious client configuration to phish / spam.
|
// Possible to use this with a malicious client configuration to phish / spam.
|
||||||
tide::Response::new(500)
|
tide::Response::new(tide::StatusCode::InternalServerError)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
res.insert_header("X-KANIDM-OPID", hvalue);
|
res.insert_header("X-KANIDM-OPID", hvalue);
|
||||||
|
|
|
@ -166,15 +166,15 @@ pub(crate) async fn create_ldap_server(
|
||||||
if address.starts_with(":::") {
|
if address.starts_with(":::") {
|
||||||
// takes :::xxxx to xxxx
|
// takes :::xxxx to xxxx
|
||||||
let port = address.replacen(":::", "", 1);
|
let port = address.replacen(":::", "", 1);
|
||||||
eprintln!("Address '{}' looks like an attempt to wildcard bind with IPv6 on port {} - please try using ldapbindaddress = '[::]:{}'", address, port, port);
|
error!("Address '{}' looks like an attempt to wildcard bind with IPv6 on port {} - please try using ldapbindaddress = '[::]:{}'", address, port, port);
|
||||||
};
|
};
|
||||||
|
|
||||||
let addr = net::SocketAddr::from_str(address).map_err(|e| {
|
let addr = net::SocketAddr::from_str(address).map_err(|e| {
|
||||||
eprintln!("Could not parse LDAP server address {} -> {:?}", address, e);
|
error!("Could not parse LDAP server address {} -> {:?}", address, e);
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let listener = TcpListener::bind(&addr).await.map_err(|e| {
|
let listener = TcpListener::bind(&addr).await.map_err(|e| {
|
||||||
eprintln!(
|
error!(
|
||||||
"Could not bind to LDAP server address {} -> {:?}",
|
"Could not bind to LDAP server address {} -> {:?}",
|
||||||
address, e
|
address, e
|
||||||
);
|
);
|
||||||
|
@ -182,12 +182,12 @@ pub(crate) async fn create_ldap_server(
|
||||||
|
|
||||||
match opt_tls_params {
|
match opt_tls_params {
|
||||||
Some(tls_params) => {
|
Some(tls_params) => {
|
||||||
eprintln!("Starting LDAPS interface ldaps://{} ...", address);
|
info!("Starting LDAPS interface ldaps://{} ...", address);
|
||||||
let tls_parms = tls_params.build();
|
let tls_parms = tls_params.build();
|
||||||
tokio::spawn(tls_acceptor(listener, tls_parms, qe_r_ref));
|
tokio::spawn(tls_acceptor(listener, tls_parms, qe_r_ref));
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
eprintln!("The server won't run without TLS!");
|
error!("The server won't run without TLS!");
|
||||||
return Err(());
|
return Err(());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@ if [ -z "$KANI_TMP" ]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$KANI_CARGO_OPTS" ]; then
|
if [ -z "$KANI_CARGO_OPTS" ]; then
|
||||||
KANI_CARGO_OPTS=--debug
|
KANI_CARGO_OPTS=""
|
||||||
fi
|
fi
|
||||||
|
|
||||||
CONFIG_FILE="../../examples/insecure_server.toml"
|
CONFIG_FILE="../../examples/insecure_server.toml"
|
||||||
|
|
|
@ -1894,6 +1894,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
// get the account
|
// get the account
|
||||||
let account = self.target_to_account(&pwu.target_uuid)?;
|
let account = self.target_to_account(&pwu.target_uuid)?;
|
||||||
|
|
||||||
|
info!(session_id = %pwu.target_uuid, "Processing password hash upgrade");
|
||||||
|
|
||||||
// check, does the pw still match?
|
// check, does the pw still match?
|
||||||
let same = account.check_credential_pw(pwu.existing_password.as_str())?;
|
let same = account.check_credential_pw(pwu.existing_password.as_str())?;
|
||||||
|
|
||||||
|
@ -1917,6 +1919,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn process_unixpwupgrade(&mut self, pwu: &UnixPasswordUpgrade) -> Result<(), OperationError> {
|
fn process_unixpwupgrade(&mut self, pwu: &UnixPasswordUpgrade) -> Result<(), OperationError> {
|
||||||
|
info!(session_id = %pwu.target_uuid, "Processing unix password hash upgrade");
|
||||||
|
|
||||||
let account = self
|
let account = self
|
||||||
.qs_write
|
.qs_write
|
||||||
.internal_search_uuid(&pwu.target_uuid)
|
.internal_search_uuid(&pwu.target_uuid)
|
||||||
|
@ -1951,6 +1955,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
wci: &WebauthnCounterIncrement,
|
wci: &WebauthnCounterIncrement,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
|
info!(session_id = %wci.target_uuid, "Processing webauthn counter increment");
|
||||||
|
|
||||||
let mut account = self.target_to_account(&wci.target_uuid)?;
|
let mut account = self.target_to_account(&wci.target_uuid)?;
|
||||||
|
|
||||||
// Generate an optional mod and then attempt to apply it.
|
// Generate an optional mod and then attempt to apply it.
|
||||||
|
@ -1977,6 +1983,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
&mut self,
|
&mut self,
|
||||||
bcr: &BackupCodeRemoval,
|
bcr: &BackupCodeRemoval,
|
||||||
) -> Result<(), OperationError> {
|
) -> Result<(), OperationError> {
|
||||||
|
info!(session_id = %bcr.target_uuid, "Processing backup code removal");
|
||||||
|
|
||||||
let account = self.target_to_account(&bcr.target_uuid)?;
|
let account = self.target_to_account(&bcr.target_uuid)?;
|
||||||
// Generate an optional mod and then attempt to apply it.
|
// Generate an optional mod and then attempt to apply it.
|
||||||
let modlist = account
|
let modlist = account
|
||||||
|
|
|
@ -125,6 +125,15 @@ function takeObject(idx) {
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cachedBigInt64Memory0 = new BigInt64Array();
|
||||||
|
|
||||||
|
function getBigInt64Memory0() {
|
||||||
|
if (cachedBigInt64Memory0.byteLength === 0) {
|
||||||
|
cachedBigInt64Memory0 = new BigInt64Array(wasm.memory.buffer);
|
||||||
|
}
|
||||||
|
return cachedBigInt64Memory0;
|
||||||
|
}
|
||||||
|
|
||||||
function debugString(val) {
|
function debugString(val) {
|
||||||
// primitive types
|
// primitive types
|
||||||
const type = typeof val;
|
const type = typeof val;
|
||||||
|
@ -222,9 +231,9 @@ function addBorrowedObject(obj) {
|
||||||
heap[--stack_pointer] = obj;
|
heap[--stack_pointer] = obj;
|
||||||
return stack_pointer;
|
return stack_pointer;
|
||||||
}
|
}
|
||||||
function __wbg_adapter_36(arg0, arg1, arg2) {
|
function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hc4597b5e800bc69f(arg0, arg1, addBorrowedObject(arg2));
|
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha070437c619effa2(arg0, arg1, addBorrowedObject(arg2));
|
||||||
} finally {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
heap[stack_pointer++] = undefined;
|
||||||
}
|
}
|
||||||
|
@ -251,12 +260,12 @@ function makeClosure(arg0, arg1, dtor, f) {
|
||||||
|
|
||||||
return real;
|
return real;
|
||||||
}
|
}
|
||||||
function __wbg_adapter_39(arg0, arg1, arg2) {
|
function __wbg_adapter_51(arg0, arg1, arg2) {
|
||||||
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0a5a9d3730766f31(arg0, arg1, addHeapObject(arg2));
|
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hd36b5f2296664138(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wbg_adapter_42(arg0, arg1, arg2) {
|
function __wbg_adapter_54(arg0, arg1, arg2) {
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h45c01f13304b15cf(arg0, arg1, addHeapObject(arg2));
|
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h83dbed9e96aca169(arg0, arg1, addHeapObject(arg2));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -336,14 +345,14 @@ async function load(module, imports) {
|
||||||
function getImports() {
|
function getImports() {
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_is_bigint = function(arg0) {
|
|
||||||
const ret = typeof(getObject(arg0)) === 'bigint';
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||||
const ret = getObject(arg0) === undefined;
|
const ret = getObject(arg0) === undefined;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
||||||
|
const ret = getObject(arg0) in getObject(arg1);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
||||||
const obj = getObject(arg1);
|
const obj = getObject(arg1);
|
||||||
const ret = typeof(obj) === 'number' ? obj : undefined;
|
const ret = typeof(obj) === 'number' ? obj : undefined;
|
||||||
|
@ -363,6 +372,10 @@ function getImports() {
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_is_bigint = function(arg0) {
|
||||||
|
const ret = typeof(getObject(arg0)) === 'bigint';
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_is_object = function(arg0) {
|
imports.wbg.__wbindgen_is_object = function(arg0) {
|
||||||
const val = getObject(arg0);
|
const val = getObject(arg0);
|
||||||
const ret = typeof(val) === 'object' && val !== null;
|
const ret = typeof(val) === 'object' && val !== null;
|
||||||
|
@ -372,6 +385,18 @@ function getImports() {
|
||||||
const ret = typeof(getObject(arg0)) === 'string';
|
const ret = typeof(getObject(arg0)) === 'string';
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_bigint_from_i64 = function(arg0) {
|
||||||
|
const ret = arg0;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbindgen_bigint_from_u64 = function(arg0) {
|
||||||
|
const ret = BigInt.asUintN(64, arg0);
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
|
imports.wbg.__wbindgen_error_new = function(arg0, arg1) {
|
||||||
|
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||||
const ret = getObject(arg0);
|
const ret = getObject(arg0);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -380,6 +405,10 @@ function getImports() {
|
||||||
const ret = getStringFromWasm0(arg0, arg1);
|
const ret = getStringFromWasm0(arg0, arg1);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_jsval_eq = function(arg0, arg1) {
|
||||||
|
const ret = getObject(arg0) === getObject(arg1);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||||
takeObject(arg0);
|
takeObject(arg0);
|
||||||
};
|
};
|
||||||
|
@ -417,31 +446,15 @@ function getImports() {
|
||||||
wasm.__wbindgen_free(arg0, arg1);
|
wasm.__wbindgen_free(arg0, arg1);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_BigInt_d0c7d465bfa30d3b = function(arg0) {
|
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
|
||||||
const ret = BigInt(arg0);
|
const ret = getObject(arg0) == getObject(arg1);
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_BigInt_1fab4952b6c4a499 = function(arg0) {
|
|
||||||
const ret = BigInt(BigInt.asUintN(64, arg0));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_is_null = function(arg0) {
|
|
||||||
const ret = getObject(arg0) === null;
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_BigInt_06819bca5a5bedef = function(arg0) {
|
imports.wbg.__wbg_getwithrefkey_15c62c2b8546208d = function(arg0, arg1) {
|
||||||
const ret = BigInt(getObject(arg0));
|
const ret = getObject(arg0)[getObject(arg1)];
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_BigInt_67359e71cae1c6c9 = function(arg0) {
|
|
||||||
const ret = BigInt(getObject(arg0));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_get_2268d91a19a98b92 = function(arg0, arg1) {
|
|
||||||
const ret = getObject(arg0)[takeObject(arg1)];
|
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_set_c943d600fa71e4dd = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_set_20cbc34131e76824 = function(arg0, arg1, arg2) {
|
||||||
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
getObject(arg0)[takeObject(arg1)] = takeObject(arg2);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_debug_783a3d4910bc24c7 = function(arg0, arg1) {
|
imports.wbg.__wbg_debug_783a3d4910bc24c7 = function(arg0, arg1) {
|
||||||
|
@ -919,10 +932,6 @@ function getImports() {
|
||||||
const ret = result;
|
const ret = result;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_new_8d2af00bc1e329ee = function(arg0, arg1) {
|
|
||||||
const ret = new Error(getStringFromWasm0(arg0, arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_message_fe2af63ccc8985bc = function(arg0) {
|
imports.wbg.__wbg_message_fe2af63ccc8985bc = function(arg0) {
|
||||||
const ret = getObject(arg0).message;
|
const ret = getObject(arg0).message;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -1000,10 +1009,6 @@ function getImports() {
|
||||||
const ret = result;
|
const ret = result;
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_has_8359f114ce042f5a = function() { return handleError(function (arg0, arg1) {
|
|
||||||
const ret = Reflect.has(getObject(arg0), getObject(arg1));
|
|
||||||
return ret;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_set_bf3f89b92d5a34bf = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_set_bf3f89b92d5a34bf = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -1012,6 +1017,12 @@ function getImports() {
|
||||||
const ret = JSON.stringify(getObject(arg0));
|
const ret = JSON.stringify(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbindgen_bigint_get_as_i64 = function(arg0, arg1) {
|
||||||
|
const v = getObject(arg1);
|
||||||
|
const ret = typeof(v) === 'bigint' ? v : undefined;
|
||||||
|
getBigInt64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0n : ret;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||||
const ret = debugString(getObject(arg1));
|
const ret = debugString(getObject(arg1));
|
||||||
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -1026,16 +1037,16 @@ function getImports() {
|
||||||
const ret = wasm.memory;
|
const ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper5843 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper5891 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1415, __wbg_adapter_36);
|
const ret = makeMutClosure(arg0, arg1, 1425, __wbg_adapter_48);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper6004 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper6051 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeClosure(arg0, arg1, 1450, __wbg_adapter_39);
|
const ret = makeClosure(arg0, arg1, 1460, __wbg_adapter_51);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper6732 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper6781 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1712, __wbg_adapter_42);
|
const ret = makeMutClosure(arg0, arg1, 1724, __wbg_adapter_54);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1049,6 +1060,7 @@ function initMemory(imports, maybe_memory) {
|
||||||
function finalizeInit(instance, module) {
|
function finalizeInit(instance, module) {
|
||||||
wasm = instance.exports;
|
wasm = instance.exports;
|
||||||
init.__wbindgen_wasm_module = module;
|
init.__wbindgen_wasm_module = module;
|
||||||
|
cachedBigInt64Memory0 = new BigInt64Array();
|
||||||
cachedFloat64Memory0 = new Float64Array();
|
cachedFloat64Memory0 = new Float64Array();
|
||||||
cachedInt32Memory0 = new Int32Array();
|
cachedInt32Memory0 = new Int32Array();
|
||||||
cachedUint32Memory0 = new Uint32Array();
|
cachedUint32Memory0 = new Uint32Array();
|
||||||
|
|
Binary file not shown.
|
@ -30,6 +30,7 @@ enum State {
|
||||||
consent_token: String,
|
consent_token: String,
|
||||||
},
|
},
|
||||||
ConsentGranted(String),
|
ConsentGranted(String),
|
||||||
|
AccessDenied(Option<String>),
|
||||||
ErrInvalidRequest,
|
ErrInvalidRequest,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,6 +49,9 @@ pub enum Oauth2Msg {
|
||||||
consent_token: String,
|
consent_token: String,
|
||||||
},
|
},
|
||||||
Redirect(String),
|
Redirect(String),
|
||||||
|
AccessDenied {
|
||||||
|
kopid: Option<String>,
|
||||||
|
},
|
||||||
Error {
|
Error {
|
||||||
emsg: String,
|
emsg: String,
|
||||||
kopid: Option<String>,
|
kopid: Option<String>,
|
||||||
|
@ -160,6 +164,8 @@ impl Oauth2App {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if status == 403 {
|
||||||
|
Ok(Oauth2Msg::AccessDenied { kopid })
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let text = JsFuture::from(resp.text()?).await?;
|
||||||
let emsg = text.as_string().unwrap_or_else(|| "".to_string());
|
let emsg = text.as_string().unwrap_or_else(|| "".to_string());
|
||||||
|
@ -380,6 +386,11 @@ impl Component for Oauth2App {
|
||||||
// We need to send off fetch task here.
|
// We need to send off fetch task here.
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
Oauth2Msg::AccessDenied { kopid } => {
|
||||||
|
console::error!(format!("{:?}", kopid).as_str());
|
||||||
|
self.state = State::AccessDenied(kopid);
|
||||||
|
true
|
||||||
|
}
|
||||||
Oauth2Msg::Error { emsg, kopid } => {
|
Oauth2Msg::Error { emsg, kopid } => {
|
||||||
self.state = State::ErrInvalidRequest;
|
self.state = State::ErrInvalidRequest;
|
||||||
console::error!(format!("{:?}", kopid).as_str());
|
console::error!(format!("{:?}", kopid).as_str());
|
||||||
|
@ -505,6 +516,24 @@ impl Component for Oauth2App {
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
State::AccessDenied(kopid) => {
|
||||||
|
html! {
|
||||||
|
<div class="alert alert-danger" role="alert">
|
||||||
|
<h1>{ "Access Denied" } </h1>
|
||||||
|
<p>
|
||||||
|
{ "You do not have access to the requested resources." }
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
{ if let Some(opid) = kopid {
|
||||||
|
format!("Operation ID: {}", opid)
|
||||||
|
} else {
|
||||||
|
"Operation ID: -".to_string()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
State::ErrInvalidRequest => {
|
State::ErrInvalidRequest => {
|
||||||
html! {
|
html! {
|
||||||
<div class="alert alert-danger" role="alert">
|
<div class="alert alert-danger" role="alert">
|
||||||
|
|
|
@ -70,6 +70,7 @@ pub enum AdminRoute {
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
LoginRequired,
|
LoginRequired,
|
||||||
|
LoggingOut,
|
||||||
Verifying,
|
Verifying,
|
||||||
Authenticated(String),
|
Authenticated(String),
|
||||||
Error { emsg: String, kopid: Option<String> },
|
Error { emsg: String, kopid: Option<String> },
|
||||||
|
@ -91,6 +92,7 @@ pub struct ViewsApp {
|
||||||
pub enum ViewsMsg {
|
pub enum ViewsMsg {
|
||||||
Verified(String),
|
Verified(String),
|
||||||
Logout,
|
Logout,
|
||||||
|
LogoutComplete,
|
||||||
ProfileInfoRecieved { uat: UserAuthToken },
|
ProfileInfoRecieved { uat: UserAuthToken },
|
||||||
Error { emsg: String, kopid: Option<String> },
|
Error { emsg: String, kopid: Option<String> },
|
||||||
}
|
}
|
||||||
|
@ -159,7 +161,22 @@ impl Component for ViewsApp {
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
ViewsMsg::Logout => {
|
ViewsMsg::Logout => {
|
||||||
models::clear_bearer_token();
|
match models::get_bearer_token() {
|
||||||
|
Some(tk) => {
|
||||||
|
models::clear_bearer_token();
|
||||||
|
ctx.link().send_future(async {
|
||||||
|
match Self::fetch_logout(tk).await {
|
||||||
|
Ok(v) => v,
|
||||||
|
Err(v) => v.into(),
|
||||||
|
}
|
||||||
|
});
|
||||||
|
self.state = State::LoggingOut;
|
||||||
|
}
|
||||||
|
None => self.state = State::LoginRequired,
|
||||||
|
}
|
||||||
|
true
|
||||||
|
}
|
||||||
|
ViewsMsg::LogoutComplete => {
|
||||||
self.state = State::LoginRequired;
|
self.state = State::LoginRequired;
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
@ -199,7 +216,7 @@ impl Component for ViewsApp {
|
||||||
.push(Route::Login);
|
.push(Route::Login);
|
||||||
html! { <div></div> }
|
html! { <div></div> }
|
||||||
}
|
}
|
||||||
State::Verifying => {
|
State::LoggingOut | State::Verifying => {
|
||||||
html! {
|
html! {
|
||||||
<main class="text-center form-signin h-100">
|
<main class="text-center form-signin h-100">
|
||||||
<div class="vert-center">
|
<div class="vert-center">
|
||||||
|
@ -366,7 +383,7 @@ impl ViewsApp {
|
||||||
Ok(ViewsMsg::Verified(token))
|
Ok(ViewsMsg::Verified(token))
|
||||||
} else if status == 401 {
|
} else if status == 401 {
|
||||||
// Not valid, re-auth
|
// Not valid, re-auth
|
||||||
Ok(ViewsMsg::Logout)
|
Ok(ViewsMsg::LogoutComplete)
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let headers = resp.headers();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||||
|
@ -390,6 +407,38 @@ impl ViewsApp {
|
||||||
uat: uat.into_inner(),
|
uat: uat.into_inner(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async fn fetch_logout(token: String) -> Result<ViewsMsg, FetchError> {
|
||||||
|
let mut opts = RequestInit::new();
|
||||||
|
opts.method("GET");
|
||||||
|
opts.mode(RequestMode::SameOrigin);
|
||||||
|
|
||||||
|
let request = Request::new_with_str_and_init("/v1/logout", &opts)?;
|
||||||
|
|
||||||
|
request
|
||||||
|
.headers()
|
||||||
|
.set("content-type", "application/json")
|
||||||
|
.expect_throw("failed to set header");
|
||||||
|
request
|
||||||
|
.headers()
|
||||||
|
.set("authorization", format!("Bearer {}", token).as_str())
|
||||||
|
.expect_throw("failed to set header");
|
||||||
|
|
||||||
|
let window = utils::window();
|
||||||
|
let resp_value = JsFuture::from(window.fetch_with_request(&request)).await?;
|
||||||
|
let resp: Response = resp_value.dyn_into().expect_throw("Invalid response type");
|
||||||
|
let status = resp.status();
|
||||||
|
|
||||||
|
if status == 200 {
|
||||||
|
Ok(ViewsMsg::LogoutComplete)
|
||||||
|
} else {
|
||||||
|
let headers = resp.headers();
|
||||||
|
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||||
|
let text = JsFuture::from(resp.text()?).await?;
|
||||||
|
let emsg = text.as_string().unwrap_or_else(|| "".to_string());
|
||||||
|
Ok(ViewsMsg::Error { emsg, kopid })
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn admin_routes(route: &AdminRoute) -> Html {
|
fn admin_routes(route: &AdminRoute) -> Html {
|
||||||
|
|
Loading…
Reference in a new issue