Fix oauth2 response value and other wasm goodies (#1135)

This commit is contained in:
Firstyear 2022-10-18 19:15:22 +10:00 committed by GitHub
parent a55c0ca68d
commit 6c67041fda
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
8 changed files with 158 additions and 55 deletions

View file

@ -328,6 +328,11 @@ async fn oauth2_authorise(
res.insert_header("WWW-Authenticate", "Bearer");
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
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:
// 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.
tide::Response::new(500)
tide::Response::new(tide::StatusCode::InternalServerError)
}
};
res.insert_header("X-KANIDM-OPID", hvalue);

View file

@ -166,15 +166,15 @@ pub(crate) async fn create_ldap_server(
if address.starts_with(":::") {
// takes :::xxxx to xxxx
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| {
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| {
eprintln!(
error!(
"Could not bind to LDAP server address {} -> {:?}",
address, e
);
@ -182,12 +182,12 @@ pub(crate) async fn create_ldap_server(
match opt_tls_params {
Some(tls_params) => {
eprintln!("Starting LDAPS interface ldaps://{} ...", address);
info!("Starting LDAPS interface ldaps://{} ...", address);
let tls_parms = tls_params.build();
tokio::spawn(tls_acceptor(listener, tls_parms, qe_r_ref));
}
None => {
eprintln!("The server won't run without TLS!");
error!("The server won't run without TLS!");
return Err(());
}
}

View file

@ -7,7 +7,7 @@ if [ -z "$KANI_TMP" ]; then
fi
if [ -z "$KANI_CARGO_OPTS" ]; then
KANI_CARGO_OPTS=--debug
KANI_CARGO_OPTS=""
fi
CONFIG_FILE="../../examples/insecure_server.toml"

View file

@ -1894,6 +1894,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
// get the account
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?
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> {
info!(session_id = %pwu.target_uuid, "Processing unix password hash upgrade");
let account = self
.qs_write
.internal_search_uuid(&pwu.target_uuid)
@ -1951,6 +1955,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
&mut self,
wci: &WebauthnCounterIncrement,
) -> Result<(), OperationError> {
info!(session_id = %wci.target_uuid, "Processing webauthn counter increment");
let mut account = self.target_to_account(&wci.target_uuid)?;
// Generate an optional mod and then attempt to apply it.
@ -1977,6 +1983,8 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
&mut self,
bcr: &BackupCodeRemoval,
) -> Result<(), OperationError> {
info!(session_id = %bcr.target_uuid, "Processing backup code removal");
let account = self.target_to_account(&bcr.target_uuid)?;
// Generate an optional mod and then attempt to apply it.
let modlist = account

View file

@ -125,6 +125,15 @@ function takeObject(idx) {
return ret;
}
let cachedBigInt64Memory0 = new BigInt64Array();
function getBigInt64Memory0() {
if (cachedBigInt64Memory0.byteLength === 0) {
cachedBigInt64Memory0 = new BigInt64Array(wasm.memory.buffer);
}
return cachedBigInt64Memory0;
}
function debugString(val) {
// primitive types
const type = typeof val;
@ -222,9 +231,9 @@ function addBorrowedObject(obj) {
heap[--stack_pointer] = obj;
return stack_pointer;
}
function __wbg_adapter_36(arg0, arg1, arg2) {
function __wbg_adapter_48(arg0, arg1, arg2) {
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 {
heap[stack_pointer++] = undefined;
}
@ -251,12 +260,12 @@ function makeClosure(arg0, arg1, dtor, f) {
return real;
}
function __wbg_adapter_39(arg0, arg1, arg2) {
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h0a5a9d3730766f31(arg0, arg1, addHeapObject(arg2));
function __wbg_adapter_51(arg0, arg1, 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) {
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h45c01f13304b15cf(arg0, arg1, addHeapObject(arg2));
function __wbg_adapter_54(arg0, arg1, 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() {
const imports = {};
imports.wbg = {};
imports.wbg.__wbindgen_is_bigint = function(arg0) {
const ret = typeof(getObject(arg0)) === 'bigint';
return ret;
};
imports.wbg.__wbindgen_is_undefined = function(arg0) {
const ret = getObject(arg0) === undefined;
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) {
const obj = getObject(arg1);
const ret = typeof(obj) === 'number' ? obj : undefined;
@ -363,6 +372,10 @@ function getImports() {
getInt32Memory0()[arg0 / 4 + 1] = len0;
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) {
const val = getObject(arg0);
const ret = typeof(val) === 'object' && val !== null;
@ -372,6 +385,18 @@ function getImports() {
const ret = typeof(getObject(arg0)) === 'string';
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) {
const ret = getObject(arg0);
return addHeapObject(ret);
@ -380,6 +405,10 @@ function getImports() {
const ret = getStringFromWasm0(arg0, arg1);
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) {
takeObject(arg0);
};
@ -417,31 +446,15 @@ function getImports() {
wasm.__wbindgen_free(arg0, arg1);
}
};
imports.wbg.__wbg_BigInt_d0c7d465bfa30d3b = function(arg0) {
const ret = BigInt(arg0);
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;
imports.wbg.__wbindgen_jsval_loose_eq = function(arg0, arg1) {
const ret = getObject(arg0) == getObject(arg1);
return ret;
};
imports.wbg.__wbg_BigInt_06819bca5a5bedef = function(arg0) {
const ret = BigInt(getObject(arg0));
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)];
imports.wbg.__wbg_getwithrefkey_15c62c2b8546208d = function(arg0, arg1) {
const ret = getObject(arg0)[getObject(arg1)];
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);
};
imports.wbg.__wbg_debug_783a3d4910bc24c7 = function(arg0, arg1) {
@ -919,10 +932,6 @@ function getImports() {
const ret = result;
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) {
const ret = getObject(arg0).message;
return addHeapObject(ret);
@ -1000,10 +1009,6 @@ function getImports() {
const ret = result;
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) {
const ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
return ret;
@ -1012,6 +1017,12 @@ function getImports() {
const ret = JSON.stringify(getObject(arg0));
return addHeapObject(ret);
}, 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) {
const ret = debugString(getObject(arg1));
const ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
@ -1026,16 +1037,16 @@ function getImports() {
const ret = wasm.memory;
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper5843 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1415, __wbg_adapter_36);
imports.wbg.__wbindgen_closure_wrapper5891 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1425, __wbg_adapter_48);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper6004 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 1450, __wbg_adapter_39);
imports.wbg.__wbindgen_closure_wrapper6051 = function(arg0, arg1, arg2) {
const ret = makeClosure(arg0, arg1, 1460, __wbg_adapter_51);
return addHeapObject(ret);
};
imports.wbg.__wbindgen_closure_wrapper6732 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1712, __wbg_adapter_42);
imports.wbg.__wbindgen_closure_wrapper6781 = function(arg0, arg1, arg2) {
const ret = makeMutClosure(arg0, arg1, 1724, __wbg_adapter_54);
return addHeapObject(ret);
};
@ -1049,6 +1060,7 @@ function initMemory(imports, maybe_memory) {
function finalizeInit(instance, module) {
wasm = instance.exports;
init.__wbindgen_wasm_module = module;
cachedBigInt64Memory0 = new BigInt64Array();
cachedFloat64Memory0 = new Float64Array();
cachedInt32Memory0 = new Int32Array();
cachedUint32Memory0 = new Uint32Array();

View file

@ -30,6 +30,7 @@ enum State {
consent_token: String,
},
ConsentGranted(String),
AccessDenied(Option<String>),
ErrInvalidRequest,
}
@ -48,6 +49,9 @@ pub enum Oauth2Msg {
consent_token: String,
},
Redirect(String),
AccessDenied {
kopid: Option<String>,
},
Error {
emsg: String,
kopid: Option<String>,
@ -160,6 +164,8 @@ impl Oauth2App {
}
}
}
} else if status == 403 {
Ok(Oauth2Msg::AccessDenied { kopid })
} else {
let text = JsFuture::from(resp.text()?).await?;
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.
true
}
Oauth2Msg::AccessDenied { kopid } => {
console::error!(format!("{:?}", kopid).as_str());
self.state = State::AccessDenied(kopid);
true
}
Oauth2Msg::Error { emsg, kopid } => {
self.state = State::ErrInvalidRequest;
console::error!(format!("{:?}", kopid).as_str());
@ -505,6 +516,24 @@ impl Component for Oauth2App {
</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 => {
html! {
<div class="alert alert-danger" role="alert">

View file

@ -70,6 +70,7 @@ pub enum AdminRoute {
enum State {
LoginRequired,
LoggingOut,
Verifying,
Authenticated(String),
Error { emsg: String, kopid: Option<String> },
@ -91,6 +92,7 @@ pub struct ViewsApp {
pub enum ViewsMsg {
Verified(String),
Logout,
LogoutComplete,
ProfileInfoRecieved { uat: UserAuthToken },
Error { emsg: String, kopid: Option<String> },
}
@ -159,7 +161,22 @@ impl Component for ViewsApp {
true
}
ViewsMsg::Logout => {
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;
true
}
@ -199,7 +216,7 @@ impl Component for ViewsApp {
.push(Route::Login);
html! { <div></div> }
}
State::Verifying => {
State::LoggingOut | State::Verifying => {
html! {
<main class="text-center form-signin h-100">
<div class="vert-center">
@ -366,7 +383,7 @@ impl ViewsApp {
Ok(ViewsMsg::Verified(token))
} else if status == 401 {
// Not valid, re-auth
Ok(ViewsMsg::Logout)
Ok(ViewsMsg::LogoutComplete)
} else {
let headers = resp.headers();
let kopid = headers.get("x-kanidm-opid").ok().flatten();
@ -390,6 +407,38 @@ impl ViewsApp {
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 {