Started chasing noise, found some code to delete... (#1768)
logging changes: * Offering auth mechanisms -> debug * 404's aren't really warnings * double tombstone message, one goes to debug other changes: * CSP changes to allow the bootstrap images to load * more testing javascriptfile things, I R * it's nice to know where things are * putting non-rust web things in static/ instead of src/ * RequestCredentials::SameOrigin is the default, also adding a utility function to save dupe code. Wow this saved... kilobytes. * removing commented code, fixing up codespell config * clippyisms * wtf, gha * dee-gloo-ing some things * adding some ubuntu build test things * sigh rustwasm/wasm-pack/issues/1138 * more do_request things * packaging things * hilarious dev env setup script * updated script works, all the UI works, including the experimental UI for naughty crabs * deb package fixes * fixed some notes * setup experimental UI tweaks
38
.github/workflows/debian_package_kanidm.yml
vendored
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
name: "Build Debian Packages"
|
||||
name: "Build Deb Packages"
|
||||
|
||||
"on":
|
||||
push:
|
||||
|
@ -31,25 +31,33 @@ jobs:
|
|||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
- name: install curl
|
||||
run: |
|
||||
apt-get update && \
|
||||
apt-get install -y \
|
||||
lsb-release \
|
||||
libpam0g-dev \
|
||||
libudev-dev \
|
||||
libssl-dev \
|
||||
libsqlite3-dev \
|
||||
pkg-config \
|
||||
make \
|
||||
curl \
|
||||
sudo
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
apt-get update && apt-get install -y curl
|
||||
- name: Setup sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.3
|
||||
with:
|
||||
version: "v0.4.2"
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
scripts/install_ubuntu_dependencies.sh
|
||||
# apt-get update && \
|
||||
# apt-get install -y \
|
||||
# lsb-release \
|
||||
# libpam0g-dev \
|
||||
# libudev-dev \
|
||||
# libssl-dev \
|
||||
# libsqlite3-dev \
|
||||
# pkg-config \
|
||||
# make \
|
||||
# curl \
|
||||
# sudo \
|
||||
# build-essential \
|
||||
# rsync
|
||||
- name: Install wasm-pack
|
||||
run: cargo install wasm-pack
|
||||
- name: Build packages
|
||||
run: |
|
||||
make -f platform/debian/Makefile debs/all
|
||||
|
|
20
.github/workflows/wasm_test.yml
vendored
|
@ -16,21 +16,20 @@ jobs:
|
|||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
sudo apt-get update &&
|
||||
sudo apt-get install -y \
|
||||
libpam0g-dev \
|
||||
libudev-dev \
|
||||
libssl-dev \
|
||||
libsqlite3-dev \
|
||||
pkg-config
|
||||
# - name: Check arch
|
||||
# run: |
|
||||
# uname -a
|
||||
- name: Setup sccache
|
||||
uses: mozilla-actions/sccache-action@v0.0.3
|
||||
with:
|
||||
version: "v0.4.2"
|
||||
- name: Install Rust
|
||||
uses: dtolnay/rust-toolchain@stable
|
||||
- name: Install wasm-pack
|
||||
run: cargo install wasm-pack
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
scripts/install_ubuntu_dependencies.sh
|
||||
# https://github.com/browser-actions/setup-chrome
|
||||
- name: Install Chrome Headless
|
||||
uses: browser-actions/setup-chrome@latest
|
||||
|
@ -45,5 +44,6 @@ jobs:
|
|||
# docs here:
|
||||
# https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/browsers.html
|
||||
- run: make webui
|
||||
- run: wasm-pack test --headless --chrome
|
||||
- name: "Run wasm-pack test"
|
||||
run: make webui/test
|
||||
continue-on-error: true
|
||||
|
|
14
Cargo.lock
generated
|
@ -1215,6 +1215,7 @@ dependencies = [
|
|||
"clap",
|
||||
"clap_complete",
|
||||
"fs2",
|
||||
"is-terminal",
|
||||
"kanidm_lib_file_permissions",
|
||||
"kanidm_proto",
|
||||
"kanidmd_core",
|
||||
|
@ -2383,6 +2384,18 @@ version = "2.7.2"
|
|||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
|
||||
|
||||
[[package]]
|
||||
name = "is-terminal"
|
||||
version = "0.4.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "adcf93614601c8129ddf72e2d5633df827ba6551541c6d8c59520a371475be1f"
|
||||
dependencies = [
|
||||
"hermit-abi 0.3.1",
|
||||
"io-lifetimes",
|
||||
"rustix",
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.10.5"
|
||||
|
@ -2718,7 +2731,6 @@ version = "1.1.0-beta.13"
|
|||
dependencies = [
|
||||
"compact_jwt",
|
||||
"gloo",
|
||||
"gloo-net",
|
||||
"js-sys",
|
||||
"kanidm_proto",
|
||||
"qrcode",
|
||||
|
|
6
Makefile
|
@ -122,7 +122,7 @@ codespell:
|
|||
--skip='./book/book/*' \
|
||||
--skip='./docs/*,./.git' \
|
||||
--skip='./rlm_python/mods-available/eap' \
|
||||
--skip='./server/web_ui/src/external,./server/web_ui/pkg/external' \
|
||||
--skip='./server/web_ui/static/external,./server/web_ui/pkg/external' \
|
||||
--skip='./server/lib/src/constants/system_config.rs,./pykanidm/site,./server/lib/src/constants/*.json'
|
||||
|
||||
.PHONY: test/pykanidm/pytest
|
||||
|
@ -255,3 +255,7 @@ cert/clean:
|
|||
.PHONY: webui
|
||||
webui: ## Build the WASM web frontend
|
||||
cd server/web_ui && ./build_wasm_release.sh
|
||||
|
||||
.PHONY: webui/test
|
||||
webui/test: ## Run wasm-pack test
|
||||
cd server/web_ui && wasm-pack test --headless --chrome
|
||||
|
|
|
@ -19,6 +19,8 @@ git and compiler tools. You should install this first.
|
|||
|
||||
You will need [rustup](https://rustup.rs/) to install a Rust toolchain.
|
||||
|
||||
To build the Web UI you'll need [wasm-pack](https://rustwasm.github.io/wasm-pack/) (`cargo install wasm-pack`).
|
||||
|
||||
#### SUSE / OpenSUSE
|
||||
|
||||
You will need to install rustup and our build dependencies with:
|
||||
|
|
|
@ -128,8 +128,8 @@ alias kanidm="docker run ..."
|
|||
|
||||
## Initializing the configuration
|
||||
|
||||
The client requires a configuration file to connect to the server.
|
||||
This should be at `/etc/kanidm/config` or `~/.config/kanidm`, and configures the kanidm command line tool.
|
||||
The client requires a configuration file to connect to the server. This should be at
|
||||
`/etc/kanidm/config` or `~/.config/kanidm`, and configures the kanidm command line tool.
|
||||
|
||||
Here is a minimal example:
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# This should be at /etc/kanidm/config or ~/.config/kanidm, and configures the kanidm command line tool
|
||||
# to point at the local dev server and ignore TLS security.
|
||||
uri = "https://localhost:8443"
|
||||
verify_ca = false
|
||||
verify_hostnames = false
|
||||
# to point at the local dev server and trust the CA security.
|
||||
uri="https://localhost:8443"
|
||||
verify_ca="/tmp/kanidm/ca.pem"
|
||||
|
|
|
@ -11,8 +11,8 @@ tls_key = "/tmp/kanidm/key.pem"
|
|||
# NOTE: this is overridden by environment variables at runtime
|
||||
# Defaults to "info"
|
||||
#
|
||||
log_level = "info"
|
||||
# log_level = "debug"
|
||||
# log_level = "info"
|
||||
log_level = "debug"
|
||||
# log_level = "trace"
|
||||
|
||||
domain = "localhost"
|
||||
|
|
|
@ -3,23 +3,23 @@ name = "kanidm_client"
|
|||
description = "Kanidm Client Library"
|
||||
documentation = "https://docs.rs/kanidm_client/latest/kanidm_client/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
reqwest = { workspace = true, default-features = false }
|
||||
kanidm_proto.workspace = true
|
||||
kanidm_proto = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
time = { workspace = true, features = ["serde", "std"] }
|
||||
tokio = { workspace = true, features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
||||
toml.workspace = true
|
||||
toml = { workspace = true }
|
||||
uuid = { workspace = true, features = ["serde", "v4"] }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
webauthn-rs-proto = { workspace = true, features = ["wasm"] }
|
||||
|
|
|
@ -7,20 +7,20 @@ edition = "2021"
|
|||
tpm = ["dep:tss-esapi"]
|
||||
|
||||
[dependencies]
|
||||
argon2.workspace = true
|
||||
base64.workspace = true
|
||||
base64urlsafedata.workspace = true
|
||||
hex.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
argon2 = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
base64urlsafedata = { workspace = true }
|
||||
hex = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
|
||||
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
||||
# into the build.rs for legacy feature checks.
|
||||
openssl-sys.workspace = true
|
||||
openssl.workspace = true
|
||||
rand.workspace = true
|
||||
openssl-sys = { workspace = true }
|
||||
openssl = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
tss-esapi = { workspace = true, optional = true }
|
||||
|
||||
[dev-dependencies]
|
||||
sketching.workspace = true
|
||||
sketching = { workspace = true }
|
||||
|
|
|
@ -5,13 +5,13 @@ documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
|||
# We do not have tests in this pkg
|
||||
autotests = false
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[lib]
|
||||
name = "profiles"
|
||||
|
@ -19,8 +19,8 @@ path = "src/lib.rs"
|
|||
|
||||
[dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
toml.workspace = true
|
||||
base64.workspace = true
|
||||
toml = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
base64.workspace = true
|
||||
base64 = { workspace = true }
|
||||
|
|
|
@ -3,18 +3,18 @@ name = "sketching"
|
|||
# We do not have tests in this pkg
|
||||
autotests = false
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
num_enum.workspace = true
|
||||
tide.workspace = true
|
||||
async-trait = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
tide = { workspace = true }
|
||||
tracing = { workspace = true, features = ["attributes"] }
|
||||
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
||||
tracing-forest = { workspace = true, features = ["uuid", "smallvec", "tokio", "env-filter"] }
|
||||
|
|
|
@ -76,6 +76,12 @@ impl TreeMiddleware {
|
|||
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
||||
"Client error --> Response sent"
|
||||
);
|
||||
} else if status == 404 {
|
||||
// because not-found isn't really an error, is it?
|
||||
request_info!(
|
||||
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
||||
"--> Response sent"
|
||||
);
|
||||
} else {
|
||||
request_warn!(
|
||||
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
||||
|
|
|
@ -3,31 +3,31 @@ name = "kanidm_proto"
|
|||
description = "Kanidm Protocol Bindings for serde"
|
||||
documentation = "https://docs.rs/kanidm_proto/latest/kanidm_proto/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[features]
|
||||
wasm = ["webauthn-rs-proto/wasm"]
|
||||
|
||||
|
||||
[dependencies]
|
||||
base32.workspace = true
|
||||
base64urlsafedata.workspace = true
|
||||
num_enum.workspace = true
|
||||
scim_proto.workspace = true
|
||||
base32 = { workspace = true }
|
||||
base64urlsafedata = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
scim_proto = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
time = { workspace = true, features = ["serde", "std"] }
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
urlencoding.workspace = true
|
||||
urlencoding = { workspace = true }
|
||||
uuid = { workspace = true, features = ["serde"] }
|
||||
webauthn-rs-proto.workspace = true
|
||||
webauthn-rs-proto = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
||||
last-git-commit.workspace = true
|
||||
last-git-commit = { workspace = true }
|
||||
|
|
|
@ -1099,7 +1099,7 @@ pub struct CUSessionToken {
|
|||
pub token: String,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize)]
|
||||
#[derive(Clone, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum CURequest {
|
||||
PrimaryRemove,
|
||||
|
|
19
scripts/install_macos_dependencies.sh
Executable file
|
@ -0,0 +1,19 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
ERROR=0
|
||||
if [ -z "$(which cargo)" ]; then
|
||||
echo "You don't have cargo / rust installed!"
|
||||
echo "Go to <https://www.rust-lang.org/tools/install> for instructions!"
|
||||
ERROR=1
|
||||
fi
|
||||
|
||||
if [ -z "$(which wasm-pack)" ]; then
|
||||
echo "You don't have wasm-pack installed! Installing it now..."
|
||||
cargo install wasm-pack
|
||||
fi
|
||||
|
||||
if [ $ERROR -eq 1 ]; then
|
||||
exit 1
|
||||
fi
|
60
scripts/install_ubuntu_dependencies.sh
Executable file
|
@ -0,0 +1,60 @@
|
|||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
if [ "$(whoami)" == "root" ]; then
|
||||
SUDOCMD=""
|
||||
else
|
||||
SUDOCMD="sudo "
|
||||
fi
|
||||
|
||||
${SUDOCMD} apt-get update &&
|
||||
${SUDOCMD} apt-get install -y \
|
||||
libpam0g-dev \
|
||||
libudev-dev \
|
||||
libssl-dev \
|
||||
libsqlite3-dev \
|
||||
pkg-config \
|
||||
curl \
|
||||
rsync \
|
||||
build-essential
|
||||
|
||||
if [ -z "$(which cargo)" ]; then
|
||||
if [ -f "$HOME/.cargo/env" ]; then
|
||||
#shellcheck disable=SC1091
|
||||
source "$HOME/.cargo/env"
|
||||
elif [ "${INSTALL_RUST}" == "1" ]; then
|
||||
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
|
||||
#shellcheck disable=SC1091
|
||||
source "$HOME/.cargo/env"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
ERROR=0
|
||||
if [ -z "$(which cargo)" ]; then
|
||||
echo "You don't have cargo / rust installed!"
|
||||
echo "Go to <https://www.rust-lang.org/tools/install> for instructions!"
|
||||
echo ""
|
||||
echo "Or run this script with INSTALL_RUST=1 to install it for you."
|
||||
ERROR=1
|
||||
fi
|
||||
|
||||
if [ $ERROR -eq 0 ] && [ -z "$(which wasm-pack)" ]; then
|
||||
echo "You don't have wasm-pack installed! Installing it now..."
|
||||
cargo install wasm-pack
|
||||
fi
|
||||
if [ $ERROR -eq 0 ] && [ -z "$(which wasm-bindgen)" ]; then
|
||||
echo "You don't have wasm-bindgen installed! Installing it now..."
|
||||
cargo install -f wasm-bindgen-cli
|
||||
fi
|
||||
|
||||
|
||||
if [ $ERROR -eq 1 ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Woo, all ready to go!"
|
||||
|
||||
#shellcheck disable=SC2016
|
||||
echo 'You might need to load the env: source "$HOME/.cargo/env"'
|
125
scripts/setup_dev_environment.sh
Executable file
|
@ -0,0 +1,125 @@
|
|||
#!/bin/bash
|
||||
|
||||
# run this, it'll set up a bunch of default stuff
|
||||
# - reset the admin and idm_admin users
|
||||
# - set up a test user
|
||||
# - set up a test group
|
||||
# - set up a test oauth2 rp (https://kanidm.com)
|
||||
# - prompt to reset testuser's creds online
|
||||
|
||||
set -e
|
||||
|
||||
# if they passed --help then output the help
|
||||
if [ "${1}" == "--help" ]; then
|
||||
echo "Usage: $0 [--remove-db]"
|
||||
echo " --remove-db: remove the existing DB before running"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# if --remove-db is in the command line args then remove the DB
|
||||
if [ -z "${REMOVE_TEST_DB}" ]; then
|
||||
if [ "${1}" == "--remove-db" ]; then
|
||||
REMOVE_TEST_DB=1
|
||||
else
|
||||
REMOVE_TEST_DB=0
|
||||
fi
|
||||
fi
|
||||
|
||||
|
||||
if [ ! -f run_insecure_dev_server.sh ]; then
|
||||
echo "Please run from the server/daemon dir!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# wait for them to shut down the server if it's running...
|
||||
while true
|
||||
do
|
||||
if [ "$(pgrep kanidmd | wc -l )" -eq 0 ]; then
|
||||
break
|
||||
fi
|
||||
echo "Stop the kanidmd server first please!"
|
||||
sleep 1
|
||||
done
|
||||
|
||||
# defaults
|
||||
KANIDM_CONFIG="../../examples/insecure_server.toml"
|
||||
KANIDM_URL="$(rg origin "${KANIDM_CONFIG}" | awk '{print $NF}' | tr -d '"')"
|
||||
KANIDM_CA_PATH="/tmp/kanidm/ca.pem"
|
||||
|
||||
# needed for the CLI tools to do their thing
|
||||
export KANIDM_URL
|
||||
export KANIDM_CA_PATH
|
||||
export KANIDM_CONFIG
|
||||
|
||||
# string things
|
||||
TEST_USER_NAME="testuser"
|
||||
TEST_USER_DISPLAY="Test Crab"
|
||||
TEST_GROUP="test_users"
|
||||
OAUTH2_RP_ID="test_oauth2"
|
||||
OAUTH2_RP_DISPLAY="test_oauth2"
|
||||
|
||||
# commands to run things
|
||||
KANIDM="cargo run --manifest-path ../../Cargo.toml --bin kanidm -- "
|
||||
KANIDMD="cargo run -p daemon --bin kanidmd -- "
|
||||
|
||||
if [ "${REMOVE_TEST_DB}" -eq 1 ]; then
|
||||
echo "Removing the existing DB!"
|
||||
rm /tmp/kanidm/kanidm.db || true
|
||||
fi
|
||||
|
||||
echo "Reset the admin user"
|
||||
ADMIN_PASS=$(${KANIDMD} recover-account admin -o json 2>&1 | rg recovery | rg result | jq -r .result )
|
||||
echo "admin pass: '${ADMIN_PASS}'"
|
||||
echo "Reset the idm_admin user"
|
||||
IDM_ADMIN_PASS=$(${KANIDMD} recover-account idm_admin -o json 2>&1 | rg recovery | rg result | jq -r .result)
|
||||
echo "idm_admin pass: '${IDM_ADMIN_PASS}'"
|
||||
|
||||
while true
|
||||
do
|
||||
echo "Waiting for you to start the server... testing ${KANIDM_URL}"
|
||||
curl --cacert "${KANIDM_CA_PATH}" -fs "${KANIDM_URL}" > /dev/null && break
|
||||
sleep 2
|
||||
done
|
||||
|
||||
echo "login with admin"
|
||||
${KANIDM} login -D admin --password "${ADMIN_PASS}"
|
||||
echo "login with idm_admin"
|
||||
${KANIDM} login -D idm_admin --password "${IDM_ADMIN_PASS}"
|
||||
|
||||
# create group test_users
|
||||
${KANIDM} group create "${TEST_GROUP}" -D idm_admin
|
||||
|
||||
# create testuser (person)
|
||||
${KANIDM} person create "${TEST_USER_NAME}" "${TEST_USER_DISPLAY}" -D idm_admin
|
||||
|
||||
echo "Adding ${TEST_USER_NAME} to ${TEST_GROUP}"
|
||||
${KANIDM} group add-members "${TEST_GROUP}" "${TEST_USER_NAME}" -D idm_admin
|
||||
|
||||
echo "Enable experimental UI for admin idm_admin ${TEST_USER_NAME}"
|
||||
${KANIDM} group add-members idm_ui_enable_experimental_features admin idm_admin "${TEST_USER_NAME}"
|
||||
|
||||
# create oauth2 rp
|
||||
echo "Creating the OAuth2 RP"
|
||||
${KANIDM} system oauth2 create "${OAUTH2_RP_ID}" "${OAUTH2_RP_DISPLAY}" "https://kanidm.com" -D admin
|
||||
|
||||
echo "Creating the OAuth2 RP Scope Map"
|
||||
${KANIDM} system oauth2 update-scope-map "${OAUTH2_RP_ID}" "${TEST_GROUP}" openid -D admin
|
||||
echo "Creating the OAuth2 RP Supplemental Scope Map"
|
||||
${KANIDM} system oauth2 update-sup-scope-map "${OAUTH2_RP_ID}" "${TEST_GROUP}" admin -D admin
|
||||
echo "Creating the OAuth2 RP Secondary Supplemental Crab-baite Scope Map.... wait, no that's not a thing."
|
||||
|
||||
|
||||
# config auth2
|
||||
echo "Pulling secret for the OAuth2 RP"
|
||||
${KANIDM} system oauth2 show-basic-secret -o json "${OAUTH2_RP_ID}" -D admin
|
||||
|
||||
echo "Creating cred reset link for ${TEST_USER_NAME}"
|
||||
${KANIDM} person credential create-reset-token "${TEST_USER_NAME}" -D idm_admin
|
||||
|
||||
echo "Done!"
|
||||
|
||||
echo "###################################"
|
||||
echo "admin password: ${ADMIN_PASS}"
|
||||
echo "idm_admin password: ${IDM_ADMIN_PASS}"
|
||||
echo "UI URL: ${KANIDM_URL}"
|
||||
echo "###################################"
|
|
@ -38,7 +38,7 @@ tokio-openssl = { workspace = true }
|
|||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
toml = {workspace = true}
|
||||
tracing = { workspace = true, features = ["attributes"] }
|
||||
urlencoding.workspace = true
|
||||
urlencoding = { workspace = true }
|
||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||
|
||||
[build-dependencies]
|
||||
|
|
|
@ -77,7 +77,7 @@ impl ServerConfig {
|
|||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default)]
|
||||
#[derive(Debug, Serialize, Deserialize, Clone, Copy, Default, Eq, PartialEq)]
|
||||
pub enum ServerRole {
|
||||
#[default]
|
||||
WriteReplica,
|
||||
|
|
|
@ -200,6 +200,8 @@ impl<State: Clone + Send + Sync + 'static> tide::Middleware<State>
|
|||
"base-uri 'self'",
|
||||
// nobody wants to be in a frame
|
||||
"frame-ancestors 'none'",
|
||||
// allow inline images because bootstrap
|
||||
"img-src 'self' data:",
|
||||
]
|
||||
.join(";"),
|
||||
);
|
||||
|
|
|
@ -52,16 +52,42 @@ impl JavaScriptFile {
|
|||
/// returns a `<script>` HTML tag
|
||||
fn as_tag(self) -> String {
|
||||
let typeattr = match self.filetype {
|
||||
Some(val) => format!("type=\"{}\" ", val),
|
||||
Some(val) => {
|
||||
format!(" type=\"{}\"", val.as_str())
|
||||
}
|
||||
_ => String::from(""),
|
||||
};
|
||||
format!(
|
||||
r#"<script src="/pkg/{}" integrity="{}" {}></script>"#,
|
||||
self.filepath, self.hash, typeattr,
|
||||
r#"<script src="/pkg/{}" integrity="{}"{}></script>"#,
|
||||
self.filepath, &self.hash, &typeattr,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_javscriptfile() {
|
||||
// make sure it outputs what we think it does
|
||||
use JavaScriptFile;
|
||||
let jsf = JavaScriptFile {
|
||||
filepath: "wasmloader.js",
|
||||
hash: "sha384-1234567890".to_string(),
|
||||
filetype: Some("module".to_string()),
|
||||
};
|
||||
assert_eq!(
|
||||
jsf.as_tag(),
|
||||
r#"<script src="/pkg/wasmloader.js" integrity="sha384-1234567890" type="module"></script>"#
|
||||
);
|
||||
let jsf = JavaScriptFile {
|
||||
filepath: "wasmloader.js",
|
||||
hash: "sha384-1234567890".to_string(),
|
||||
filetype: None,
|
||||
};
|
||||
assert_eq!(
|
||||
jsf.as_tag(),
|
||||
r#"<script src="/pkg/wasmloader.js" integrity="sha384-1234567890"></script>"#
|
||||
);
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct AppState {
|
||||
pub status_ref: &'static StatusActor,
|
||||
|
@ -352,8 +378,7 @@ pub fn generate_integrity_hash(filename: String) -> Result<String, String> {
|
|||
|
||||
pub async fn create_https_server(
|
||||
address: String,
|
||||
domain: String,
|
||||
// opt_tls_params: Option<SslAcceptorBuilder>,
|
||||
domain: &String,
|
||||
opt_tls_params: Option<&TlsConfiguration>,
|
||||
role: ServerRole,
|
||||
trust_x_forward_for: bool,
|
||||
|
|
|
@ -51,7 +51,7 @@ use tokio::sync::broadcast;
|
|||
|
||||
use crate::actors::v1_read::QueryServerReadV1;
|
||||
use crate::actors::v1_write::QueryServerWriteV1;
|
||||
use crate::config::Configuration;
|
||||
use crate::config::{Configuration, ServerRole};
|
||||
use crate::interval::IntervalActor;
|
||||
|
||||
// === internal setup helpers
|
||||
|
@ -914,7 +914,7 @@ pub async fn create_server_core(
|
|||
// ⚠️ only start the sockets and listeners in non-config-test modes.
|
||||
let h = self::https::create_https_server(
|
||||
config.address,
|
||||
config.domain,
|
||||
&config.domain,
|
||||
config.tls_config.as_ref(),
|
||||
config.role,
|
||||
config.trust_x_forward_for,
|
||||
|
@ -927,7 +927,11 @@ pub async fn create_server_core(
|
|||
)
|
||||
.await?;
|
||||
|
||||
admin_info!("ready to rock! 🪨 ");
|
||||
if config.role != ServerRole::WriteReplicaNoUI {
|
||||
admin_info!("ready to rock! 🪨 UI available at: {}", config.origin);
|
||||
} else {
|
||||
admin_info!("ready to rock! 🪨");
|
||||
}
|
||||
Some(h)
|
||||
};
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ name = "daemon"
|
|||
description = "Kanidm Server Daemon"
|
||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
|
@ -18,27 +18,28 @@ name = "kanidmd"
|
|||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
kanidm_proto.workspace = true
|
||||
kanidmd_core.workspace = true
|
||||
kanidm_lib_file_permissions.workspace = true
|
||||
sketching.workspace = true
|
||||
fs2.workspace = true
|
||||
kanidm_proto = { workspace = true }
|
||||
kanidmd_core = { workspace = true }
|
||||
kanidm_lib_file_permissions = { workspace = true }
|
||||
sketching = { workspace = true }
|
||||
fs2 = { workspace = true }
|
||||
|
||||
clap = { workspace = true, features = ["env"] }
|
||||
reqwest = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal"] }
|
||||
toml = { workspace = true }
|
||||
is-terminal = "0.4.7"
|
||||
|
||||
[target.'cfg(target_family = "windows")'.dependencies]
|
||||
whoami.workspace = true
|
||||
whoami = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||
users.workspace = true
|
||||
tikv-jemallocator.workspace = true
|
||||
users = { workspace = true }
|
||||
tikv-jemallocator = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
clap_complete.workspace = true
|
||||
profiles.workspace = true
|
||||
clap_complete = { workspace = true }
|
||||
profiles = { workspace = true }
|
||||
|
|
|
@ -126,7 +126,7 @@ async fn main() -> ExitCode {
|
|||
};
|
||||
|
||||
// if they specified it in the environment then that overrides everything
|
||||
let log_level = match EnvFilter::try_from_default_env() {
|
||||
let log_filter = match EnvFilter::try_from_default_env() {
|
||||
Ok(val) => val,
|
||||
Err(_e) => {
|
||||
// we couldn't get it from the env, so we'll try the config file!
|
||||
|
@ -140,14 +140,25 @@ async fn main() -> ExitCode {
|
|||
.into()
|
||||
}
|
||||
};
|
||||
|
||||
// TODO: only send to stderr when we're not in a TTY
|
||||
tracing_forest::worker_task()
|
||||
.set_global(true)
|
||||
.set_tag(sketching::event_tagger)
|
||||
// Fall back to stderr
|
||||
.map_sender(|sender| sender.or_stderr())
|
||||
.build_on(|subscriber| subscriber
|
||||
.with(log_level)
|
||||
)
|
||||
.build_on(|subscriber|{
|
||||
let sub = subscriber.with(log_filter);
|
||||
// this does NOT work, it just adds a layer.
|
||||
// if std::io::stdout().is_terminal() {
|
||||
// println!("Stdout is a terminal");
|
||||
// sub.with(sketching::tracing_subscriber::fmt::layer().with_writer(std::io::stderr))
|
||||
// } else {
|
||||
// println!("Stdout is not a terminal");
|
||||
// sub.with(sketching::tracing_subscriber::fmt::layer().with_writer(std::io::stderr))
|
||||
// }
|
||||
sub
|
||||
})
|
||||
.on(async {
|
||||
// Get information on the windows username
|
||||
#[cfg(target_family = "windows")]
|
||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
proc-macro2 = { workspace = true }
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
||||
|
||||
|
|
|
@ -3,13 +3,13 @@ name = "kanidmd_lib"
|
|||
description = "Kanidm Server Backend Library"
|
||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[lib]
|
||||
name = "kanidmd_lib"
|
||||
|
@ -20,73 +20,73 @@ name = "scaling_10k"
|
|||
harness = false
|
||||
|
||||
[dependencies]
|
||||
async-trait.workspace = true
|
||||
base64.workspace = true
|
||||
base64urlsafedata.workspace = true
|
||||
async-trait = { workspace = true }
|
||||
base64 = { workspace = true }
|
||||
base64urlsafedata = { workspace = true }
|
||||
compact_jwt = { workspace = true, features = ["openssl"] }
|
||||
concread.workspace = true
|
||||
dyn-clone.workspace = true
|
||||
concread = { workspace = true }
|
||||
dyn-clone = { workspace = true }
|
||||
fernet = { workspace = true, features = ["fernet_danger_timestamps"] }
|
||||
filetime.workspace = true
|
||||
futures-util.workspace = true
|
||||
hashbrown.workspace = true
|
||||
idlset.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
kanidm_lib_crypto.workspace = true
|
||||
lazy_static.workspace = true
|
||||
ldap3_proto.workspace = true
|
||||
libc.workspace = true
|
||||
libsqlite3-sys.workspace = true
|
||||
num_enum.workspace = true
|
||||
filetime = { workspace = true }
|
||||
futures-util = { workspace = true }
|
||||
hashbrown = { workspace = true }
|
||||
idlset = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
kanidm_lib_crypto = { workspace = true }
|
||||
lazy_static = { workspace = true }
|
||||
ldap3_proto = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
libsqlite3-sys = { workspace = true }
|
||||
num_enum = { workspace = true }
|
||||
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
||||
# into the build.rs for legacy feature checks.
|
||||
openssl-sys.workspace = true
|
||||
openssl.workspace = true
|
||||
rand.workspace = true
|
||||
openssl-sys = { workspace = true }
|
||||
openssl = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
regex = { workspace = true, features = ["std", "perf", "perf-inline", "unicode", "unicode-gencat"] }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_cbor.workspace = true
|
||||
serde_json.workspace = true
|
||||
sketching.workspace = true
|
||||
serde_cbor = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
sketching = { workspace = true }
|
||||
smartstring = { workspace = true, features = ["serde"] }
|
||||
smolset.workspace = true
|
||||
sshkeys.workspace = true
|
||||
tide.workspace = true
|
||||
smolset = { workspace = true }
|
||||
sshkeys = { workspace = true }
|
||||
tide = { workspace = true }
|
||||
time = { workspace = true, features = ["serde", "std"] }
|
||||
tokio = { workspace = true, features = ["net", "sync", "time", "rt"] }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
toml.workspace = true
|
||||
touch.workspace = true
|
||||
toml = { workspace = true }
|
||||
touch = { workspace = true }
|
||||
nonempty = { workspace = true, features = ["serialize"] }
|
||||
|
||||
tracing = { workspace = true, features = ["attributes"] }
|
||||
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
urlencoding.workspace = true
|
||||
urlencoding = { workspace = true }
|
||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||
webauthn-rs = { workspace = true, features = ["resident-key-support", "preview-features", "danger-credential-internals"] }
|
||||
webauthn-rs-core.workspace = true
|
||||
zxcvbn.workspace = true
|
||||
webauthn-rs-core = { workspace = true }
|
||||
zxcvbn = { workspace = true }
|
||||
|
||||
# because windows really can't build without the bundled one
|
||||
[target.'cfg(target_family = "windows")'.dependencies]
|
||||
rusqlite = { workspace = true, features = ["bundled"] }
|
||||
whoami.workspace = true
|
||||
whoami = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||
rusqlite.workspace = true
|
||||
users.workspace = true
|
||||
rusqlite = { workspace = true }
|
||||
users = { workspace = true }
|
||||
|
||||
[features]
|
||||
# default = [ "libsqlite3-sys/bundled", "openssl/vendored" ]
|
||||
|
||||
[dev-dependencies]
|
||||
criterion = { workspace = true, features = ["html_reports"] }
|
||||
webauthn-authenticator-rs.workspace = true
|
||||
webauthn-authenticator-rs = { workspace = true }
|
||||
|
||||
futures.workspace = true
|
||||
kanidmd_lib_macros.workspace = true
|
||||
futures = { workspace = true }
|
||||
kanidmd_lib_macros = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
profiles.workspace = true
|
||||
profiles = { workspace = true }
|
||||
|
||||
|
|
|
@ -1254,7 +1254,7 @@ impl<'a> BackendWriteTransaction<'a> {
|
|||
})?;
|
||||
|
||||
if entries.is_empty() {
|
||||
admin_info!("No entries affected - reap_tombstones operation success");
|
||||
admin_debug!("No entries affected - reap_tombstones operation success");
|
||||
return Ok(0);
|
||||
}
|
||||
|
||||
|
|
|
@ -815,7 +815,7 @@ impl AuthSession {
|
|||
// of what's next, or ordering.
|
||||
let valid_mechs = auth_session.valid_auth_mechs();
|
||||
|
||||
security_info!(?valid_mechs, "Offering auth mechanisms");
|
||||
security_debug!(?valid_mechs, "Offering auth mechanisms");
|
||||
let as_state = AuthState::Choose(valid_mechs);
|
||||
(Some(auth_session), as_state)
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
|||
])))?;
|
||||
|
||||
if rc.is_empty() {
|
||||
admin_info!("No recycled present - purge operation success");
|
||||
admin_info!("No recycled items present - purge operation success");
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
|||
proc-macro = true
|
||||
|
||||
[dependencies]
|
||||
proc-macro2.workspace = true
|
||||
quote.workspace = true
|
||||
syn.workspace = true
|
||||
proc-macro2 = { workspace = true }
|
||||
quote = { workspace = true }
|
||||
syn = { workspace = true }
|
||||
|
||||
|
||||
|
|
|
@ -3,40 +3,40 @@ name = "kanidmd_testkit"
|
|||
description = "Kanidm Server Test Framework"
|
||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[lib]
|
||||
name = "kanidmd_testkit"
|
||||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
kanidm_client.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
kanidmd_core.workspace = true
|
||||
kanidmd_lib.workspace = true
|
||||
kanidm_client = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
kanidmd_core = { workspace = true }
|
||||
kanidmd_lib = { workspace = true }
|
||||
|
||||
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
reqwest = { workspace = true, default-features = false }
|
||||
sketching.workspace = true
|
||||
testkit-macros.workspace = true
|
||||
sketching = { workspace = true }
|
||||
testkit-macros = { workspace = true }
|
||||
tracing = { workspace = true, features = ["attributes"] }
|
||||
tokio = { workspace = true, features = ["net", "sync", "io-util", "macros"] }
|
||||
|
||||
|
||||
[build-dependencies]
|
||||
profiles.workspace = true
|
||||
profiles = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
compact_jwt.workspace = true
|
||||
serde_json.workspace = true
|
||||
webauthn-authenticator-rs.workspace = true
|
||||
compact_jwt = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
webauthn-authenticator-rs = { workspace = true }
|
||||
oauth2_ext = { workspace = true, default-features = false }
|
||||
futures.workspace = true
|
||||
time.workspace = true
|
||||
futures = { workspace = true }
|
||||
time = { workspace = true }
|
||||
|
|
|
@ -22,9 +22,6 @@ repository = "https://github.com/kanidm/kanidm/"
|
|||
# homepage = { workspace = true }
|
||||
# repository = { workspace = true }
|
||||
|
||||
# These are ignored because the crate is in a workspace
|
||||
#[profile.release]
|
||||
# less code to include into binary
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib", "rlib"]
|
||||
|
@ -33,7 +30,6 @@ crate-type = ["cdylib", "rlib"]
|
|||
compact_jwt = { workspace = true, default-features = false, features = ["unsafe_release_without_verify"] }
|
||||
# gloo = "^0.8.0"
|
||||
gloo = { workspace = true }
|
||||
gloo-net = { workspace = true }
|
||||
js-sys = { workspace = true }
|
||||
kanidm_proto = { workspace = true, features = ["wasm"] }
|
||||
qrcode = { workspace = true, features = ["svg"] }
|
||||
|
|
|
@ -16,6 +16,11 @@ if [ -z "$(which rsync)" ]; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
if [ -z "$(which wasm-pack)" ]; then
|
||||
echo "Cannot find wasm-pack which is needed to build the UI, quitting!"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [ "$(find ./pkg/ -name 'kanidmd*' | wc -l)" -gt 0 ]; then
|
||||
echo "Cleaning up"
|
||||
rm pkg/kanidmd*
|
||||
|
@ -23,13 +28,10 @@ fi
|
|||
|
||||
# we can disable this since we want it to expand
|
||||
# shellcheck disable=SC2086
|
||||
wasm-pack build ${BUILD_FLAGS} --target web || exit 1
|
||||
wasm-pack build ${BUILD_FLAGS} --target web --mode no-install --no-pack || exit 1
|
||||
|
||||
touch ./pkg/ANYTHING_HERE_WILL_BE_DELETED_ADD_TO_SRC && \
|
||||
rsync --delete-after -r --copy-links -v ./src/img/ ./pkg/img/ && \
|
||||
rsync --delete-after -r --copy-links -v ./src/external/ ./pkg/external/ && \
|
||||
rsync --delete-after -r --copy-links -v ./static/* ./pkg/ && \
|
||||
cp ../../README.md ./pkg/
|
||||
cp ../../LICENSE.md ./pkg/
|
||||
cp ./src/style.css ./pkg/style.css && \
|
||||
cp ./src/wasmloader.js ./pkg/wasmloader.js && \
|
||||
rm ./pkg/.gitignore
|
||||
|
|
|
@ -234,24 +234,24 @@ 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__hd63bd1cb9b35210b(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hd11765386bfbbb1b(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__h4a4d23d6ebf5b8fa(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__hf7e9e605a1806538(arg0, arg1, addBorrowedObject(arg2));
|
||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h13182848512d5ace(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__h9e05cfbc2276f207(arg0, arg1, addHeapObject(arg2));
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
export function run_app() {
|
||||
|
@ -330,10 +330,6 @@ async function __wbg_load(module, imports) {
|
|||
function __wbg_get_imports() {
|
||||
const imports = {};
|
||||
imports.wbg = {};
|
||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||
const ret = getObject(arg0) === undefined;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
||||
const obj = getObject(arg1);
|
||||
const ret = typeof(obj) === 'string' ? obj : undefined;
|
||||
|
@ -369,6 +365,10 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0);
|
||||
return addHeapObject(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;
|
||||
|
@ -643,20 +643,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_remove_8ae45e50cb58bb66 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_instanceof_WorkerGlobalScope_d9d741da0fb130ce = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
result = getObject(arg0) instanceof WorkerGlobalScope;
|
||||
} catch {
|
||||
result = false;
|
||||
}
|
||||
const ret = result;
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_fetch_8eaf01857a5bb21f = function(arg0, arg1) {
|
||||
const ret = getObject(arg0).fetch(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_instanceof_Element_4622f5da1249a3eb = function(arg0) {
|
||||
let result;
|
||||
try {
|
||||
|
@ -711,10 +697,6 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_focus_dbcbbbb2a04c0e1f = function() { return handleError(function (arg0) {
|
||||
getObject(arg0).focus();
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_new_1eead62f64ca15ce = function() { return handleError(function () {
|
||||
const ret = new Headers();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_get_2e9aab260014946d = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||
|
@ -725,29 +707,14 @@ function __wbg_get_imports() {
|
|||
imports.wbg.__wbg_set_b34caba58723c454 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_url_fda63503ced387ff = function(arg0, arg1) {
|
||||
const ret = getObject(arg1).url;
|
||||
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_b439dcff02e808e5 = function(arg0) {
|
||||
const ret = getObject(arg0).headers;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_newwithstr_3d9bc779603a93c7 = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = new Request(getStringFromWasm0(arg0, arg1));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_newwithstrandinit_cad5cd6038c7ff5d = function() { return handleError(function (arg0, arg1, arg2) {
|
||||
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_new_2a98b9c4a51bdc04 = function() { return handleError(function () {
|
||||
const ret = new URLSearchParams();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_create_c7e40b6b88186cbf = function() { return handleError(function (arg0, arg1) {
|
||||
const ret = getObject(arg0).create(getObject(arg1));
|
||||
return addHeapObject(ret);
|
||||
|
@ -782,10 +749,6 @@ function __wbg_get_imports() {
|
|||
const ret = getObject(arg0).json();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_text_a667ac1770538491 = function() { return handleError(function (arg0) {
|
||||
const ret = getObject(arg0).text();
|
||||
return addHeapObject(ret);
|
||||
}, arguments) };
|
||||
imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function(arg0) {
|
||||
console.log(getObject(arg0));
|
||||
};
|
||||
|
@ -1090,10 +1053,6 @@ function __wbg_get_imports() {
|
|||
const ret = Object.is(getObject(arg0), getObject(arg1));
|
||||
return ret;
|
||||
};
|
||||
imports.wbg.__wbg_toString_a8e343996af880e9 = function(arg0) {
|
||||
const ret = getObject(arg0).toString();
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbg_resolve_53698b95aaf7fcf8 = function(arg0) {
|
||||
const ret = Promise.resolve(getObject(arg0));
|
||||
return addHeapObject(ret);
|
||||
|
@ -1159,16 +1118,16 @@ function __wbg_get_imports() {
|
|||
const ret = wasm.memory;
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper4681 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1097, __wbg_adapter_48);
|
||||
imports.wbg.__wbindgen_closure_wrapper4628 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1074, __wbg_adapter_48);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper5482 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1396, __wbg_adapter_51);
|
||||
imports.wbg.__wbindgen_closure_wrapper5401 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1357, __wbg_adapter_51);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
imports.wbg.__wbindgen_closure_wrapper5489 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1400, __wbg_adapter_54);
|
||||
imports.wbg.__wbindgen_closure_wrapper6520 = function(arg0, arg1, arg2) {
|
||||
const ret = makeMutClosure(arg0, arg1, 1431, __wbg_adapter_54);
|
||||
return addHeapObject(ret);
|
||||
};
|
||||
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
{
|
||||
"name": "kanidmd_web_ui",
|
||||
"collaborators": [
|
||||
"William Brown <william@blackhats.net.au>",
|
||||
"James Hodgkinson <james@terminaloutcomes.com>"
|
||||
],
|
||||
"description": "Kanidm Server Web User Interface",
|
||||
"version": "1.1.0-beta.13",
|
||||
"license": "MPL-2.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/kanidm/kanidm/"
|
||||
},
|
||||
"files": [
|
||||
"kanidmd_web_ui_bg.wasm",
|
||||
"kanidmd_web_ui.js",
|
||||
"LICENSE.md"
|
||||
],
|
||||
"module": "kanidmd_web_ui.js",
|
||||
"homepage": "https://github.com/kanidm/kanidm/",
|
||||
"sideEffects": [
|
||||
"./snippets/*"
|
||||
]
|
||||
}
|
|
@ -9,8 +9,9 @@ use crate::components::alpha_warning_banner;
|
|||
use crate::constants::{
|
||||
CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_DT, CSS_TABLE,
|
||||
};
|
||||
use crate::utils::{do_alert_error, do_page_header, init_request};
|
||||
use crate::utils::{do_alert_error, do_page_header};
|
||||
use crate::views::AdminRoute;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
impl From<GetError> for AdminListAccountsMsg {
|
||||
fn from(ge: GetError) -> Self {
|
||||
|
@ -93,24 +94,21 @@ pub async fn get_accounts() -> Result<AdminListAccountsMsg, GetError> {
|
|||
];
|
||||
|
||||
for (endpoint, object_type) in endpoints {
|
||||
let request = init_request(endpoint);
|
||||
let response = match request.send().await {
|
||||
Ok(value) => value,
|
||||
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Vec<Entity> = match response.json().await {
|
||||
// TODO: this kind of thing comes back when you're logged out: SerdeError(Error("invalid type: string \"sessionexpired\", expected a sequence", line: 1, column: 16))', server/web_ui/src/components/admin_accounts.rs:107:27
|
||||
let data: Vec<Entity> = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
|
||||
// TODO: this kind of thing comes back when you're logged out: SerdeError(Error("invalid type: string \"sessionexpired\", expected a sequence", line: 1, column: 16))', server/web_ui/src/components/admin_accounts.rs:107:27
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("Failed to grab the account data into JSON: {:?}", error),
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -544,41 +542,59 @@ impl Component for AdminViewServiceAccount {
|
|||
|
||||
/// pull the details for a single person by UUID
|
||||
pub async fn get_person(uuid: &str) -> Result<AdminViewPersonMsg, GetError> {
|
||||
let request = init_request(format!("/v1/person/{}", uuid).as_str());
|
||||
let response = match request.send().await {
|
||||
Ok(value) => value,
|
||||
let (_, _, value, _) = match do_request(
|
||||
format!("/v1/person/{}", uuid).as_str(),
|
||||
RequestMethod::GET,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Entity = match response.json().await {
|
||||
|
||||
let data: Entity = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
Err(error) => panic!("Failed to grab the person data into JSON: {:?}", error),
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
});
|
||||
}
|
||||
};
|
||||
Ok(AdminViewPersonMsg::Responded { response: data })
|
||||
}
|
||||
|
||||
/// pull the details for a single service_account by UUID
|
||||
pub async fn get_service_account(uuid: &str) -> Result<AdminViewServiceAccountMsg, GetError> {
|
||||
let request = init_request(format!("/v1/service_account/{}", uuid).as_str());
|
||||
let response = match request.send().await {
|
||||
let (_, _, value, _) = match do_request(
|
||||
format!("/v1/service_account/{}", uuid).as_str(),
|
||||
RequestMethod::GET,
|
||||
None,
|
||||
)
|
||||
.await
|
||||
{
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!(
|
||||
"Failed to grab the service_account data into JSON: {:?}",
|
||||
error
|
||||
),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let data: Entity = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Entity = match response.json().await {
|
||||
Ok(value) => value,
|
||||
Err(error) => panic!(
|
||||
"Failed to grab the service account data into JSON: {:?}",
|
||||
error
|
||||
),
|
||||
};
|
||||
Ok(AdminViewServiceAccountMsg::Responded { response: data })
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@ use yew_router::prelude::Link;
|
|||
use crate::components::admin_menu::{Entity, EntityType, GetError};
|
||||
use crate::components::alpha_warning_banner;
|
||||
use crate::constants::{CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_TABLE};
|
||||
use crate::utils::{do_alert_error, do_page_header, init_request};
|
||||
use crate::utils::{do_alert_error, do_page_header};
|
||||
use crate::views::AdminRoute;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
impl From<GetError> for AdminListGroupsMsg {
|
||||
fn from(ge: GetError) -> Self {
|
||||
|
@ -70,20 +71,23 @@ pub async fn get_groups() -> Result<AdminListGroupsMsg, GetError> {
|
|||
let endpoints = [("/v1/group", EntityType::Group)];
|
||||
|
||||
for (endpoint, object_type) in endpoints {
|
||||
let request = init_request(endpoint);
|
||||
let response = match request.send().await {
|
||||
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("Failed to grab the group data into JSON: {:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
|
||||
let data: Vec<Entity> = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
});
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Vec<Entity> = match response.json().await {
|
||||
Ok(value) => value,
|
||||
Err(error) => panic!("Failed to grab the group data into JSON: {:?}", error),
|
||||
};
|
||||
|
||||
for entity in data.iter() {
|
||||
let mut new_entity = entity.to_owned();
|
||||
|
@ -360,19 +364,23 @@ impl Component for AdminViewGroup {
|
|||
|
||||
/// pull the details for a single group by UUID
|
||||
pub async fn get_group(groupid: &str) -> Result<AdminViewGroupMsg, GetError> {
|
||||
let request = init_request(format!("/v1/group/{}", groupid).as_str());
|
||||
let response = match request.send().await {
|
||||
Ok(value) => value,
|
||||
let endpoint = format!("/v1/group/{}", groupid);
|
||||
let (_, _, value, _) = match do_request(&endpoint, RequestMethod::GET, None).await {
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Entity = match response.json().await {
|
||||
|
||||
let data: Entity = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
Err(error) => panic!("Failed to grab the group data into JSON: {:?}", error),
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
});
|
||||
}
|
||||
};
|
||||
Ok(AdminViewGroupMsg::Responded { response: data })
|
||||
}
|
||||
|
|
|
@ -7,8 +7,9 @@ use yew_router::prelude::Link;
|
|||
use crate::components::admin_menu::{Entity, EntityType, GetError};
|
||||
use crate::components::alpha_warning_banner;
|
||||
use crate::constants::{CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_TABLE};
|
||||
use crate::utils::{do_alert_error, do_page_header, init_request};
|
||||
use crate::utils::{do_alert_error, do_page_header};
|
||||
use crate::views::AdminRoute;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
impl From<GetError> for AdminListOAuth2Msg {
|
||||
fn from(ge: GetError) -> Self {
|
||||
|
@ -71,22 +72,25 @@ pub async fn get_entities() -> Result<AdminListOAuth2Msg, GetError> {
|
|||
let endpoints = [("/v1/oauth2", EntityType::OAuth2RP)];
|
||||
|
||||
for (endpoint, object_type) in endpoints {
|
||||
let request = init_request(endpoint);
|
||||
let response = match request.send().await {
|
||||
Ok(value) => value,
|
||||
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Vec<Entity> = match response.json().await {
|
||||
|
||||
let data: Vec<Entity> = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => value,
|
||||
Err(error) => panic!("Failed to grab the OAuth2 RP data into JSON: {:?}", error),
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("Failed to grab the oauth2 data into JSON: {:?}", error),
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
for entity in data.iter() {
|
||||
for entity in data.into_iter() {
|
||||
let mut new_entity = entity.to_owned();
|
||||
new_entity.object_type = object_type.clone();
|
||||
|
||||
|
@ -96,8 +100,9 @@ pub async fn get_entities() -> Result<AdminListOAuth2Msg, GetError> {
|
|||
.attrs
|
||||
.uuid
|
||||
.first()
|
||||
.expect("Failed to grab the SPN for an account.");
|
||||
oauth2_objects.insert(entity_id.to_string(), new_entity);
|
||||
.map(|e| e.to_owned())
|
||||
.unwrap_or(String::from("Unknown entity name!"));
|
||||
oauth2_objects.insert(entity_id, new_entity);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -401,17 +406,17 @@ impl Component for AdminViewOAuth2 {
|
|||
}
|
||||
|
||||
pub async fn get_oauth2_rp(rs_name: &str) -> Result<AdminViewOAuth2Msg, GetError> {
|
||||
let request = init_request(format!("/v1/oauth2/{}", rs_name).as_str());
|
||||
let response = match request.send().await {
|
||||
Ok(value) => value,
|
||||
let endpoint = format!("/v1/oauth2/{}", rs_name);
|
||||
let (_, _, value, _) = match do_request(&endpoint, RequestMethod::GET, None).await {
|
||||
Ok(val) => val,
|
||||
Err(error) => {
|
||||
return Err(GetError {
|
||||
err: format!("{:?}", error),
|
||||
})
|
||||
}
|
||||
};
|
||||
#[allow(clippy::panic)]
|
||||
let data: Entity = match response.json().await {
|
||||
|
||||
let data: Entity = match serde_wasm_bindgen::from_value(value) {
|
||||
Ok(value) => {
|
||||
console::log!(format!("{:?}", value));
|
||||
value
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
use kanidm_proto::v1::{SingleStringRequest, UserAuthToken};
|
||||
use uuid::Uuid;
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{FormData, HtmlFormElement, Request, RequestInit, RequestMode, Response};
|
||||
use web_sys::{FormData, HtmlFormElement};
|
||||
use yew::prelude::*;
|
||||
|
||||
use crate::error::*;
|
||||
|
@ -250,32 +249,14 @@ impl ChangeUnixPassword {
|
|||
})
|
||||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to change request");
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("PUT");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.body(Some(&changereq_jsvalue));
|
||||
|
||||
let uri = format!("/v1/person/{}/_unix/_credential", id);
|
||||
|
||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _) =
|
||||
crate::do_request(&uri, crate::RequestMethod::PUT, Some(changereq_jsvalue)).await?;
|
||||
|
||||
if status == 200 {
|
||||
Ok(Msg::Success)
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,9 +10,6 @@ use wasm_bindgen::UnwrapThrowExt;
|
|||
use web_sys::Node;
|
||||
|
||||
use crate::error::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
||||
|
||||
enum State {
|
||||
Valid,
|
||||
|
@ -237,35 +234,17 @@ impl Component for CreateResetCode {
|
|||
|
||||
impl CreateResetCode {
|
||||
async fn credential_get_update_intent_token(id: String) -> Result<Msg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
let uri = format!("/v1/person/{}/_credential/_update_intent?ttl=0", id);
|
||||
|
||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _) =
|
||||
crate::do_request(&uri, crate::RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let token: CUIntentToken =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
Ok(Msg::Ready { token })
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
#[cfg(debug_assertions)]
|
||||
use gloo::console;
|
||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::reset::{EventBusMsg, ModalProps};
|
||||
use crate::do_request;
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::RequestMethod;
|
||||
|
||||
enum State {
|
||||
Init,
|
||||
|
@ -50,37 +50,21 @@ impl DeleteApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
let custatus: CUStatus =
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
|
||||
cb.emit(EventBusMsg::UpdateStatus { status });
|
||||
cb.emit(EventBusMsg::UpdateStatus { status: custatus });
|
||||
|
||||
Ok(Msg::Success)
|
||||
} else {
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,14 +1,13 @@
|
|||
use gloo::console;
|
||||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
||||
use kanidm_proto::webauthn::{CreationChallengeResponse, RegisterPublicKeyCredential};
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::reset::{EventBusMsg, ModalProps};
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::{do_request, error::*, RequestMethod};
|
||||
|
||||
pub struct PasskeyModalApp {
|
||||
state: State,
|
||||
|
@ -61,30 +60,16 @@ impl PasskeyModalApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
|
||||
cb.emit(EventBusMsg::UpdateStatus {
|
||||
status: status.clone(),
|
||||
|
@ -102,8 +87,7 @@ impl PasskeyModalApp {
|
|||
CURegState::None => Msg::Success,
|
||||
})
|
||||
} else {
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,14 +2,13 @@
|
|||
use gloo::console;
|
||||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
||||
use uuid::Uuid;
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::reset::{EventBusMsg, PasskeyRemoveModalProps};
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
pub struct PasskeyRemoveModalApp {
|
||||
state: State,
|
||||
|
@ -70,30 +69,17 @@ impl PasskeyRemoveModalApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
// this really should require a DELETE not a post!
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
|
||||
cb.emit(EventBusMsg::UpdateStatus {
|
||||
status: status.clone(),
|
||||
|
@ -111,8 +97,7 @@ impl PasskeyRemoveModalApp {
|
|||
CURegState::None => Msg::Success,
|
||||
})
|
||||
} else {
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use gloo::console;
|
||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus, OperationError, PasswordFeedback};
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::reset::{EventBusMsg, ModalProps};
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
enum PwState {
|
||||
Init,
|
||||
|
@ -57,38 +57,24 @@ impl PwModalApp {
|
|||
}
|
||||
|
||||
async fn submit_password_update(token: CUSessionToken, pw: String) -> Result<Msg, FetchError> {
|
||||
let intentreq_jsvalue = serde_json::to_string(&(CURequest::Password(pw), token))
|
||||
let req_jsvalue = serde_json::to_string(&(CURequest::Password(pw), token))
|
||||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&intentreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
Ok(Msg::PasswordResponseSuccess { status })
|
||||
} else if status == 400 {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: OperationError =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
match status {
|
||||
OperationError::PasswordQuality(feedback) => {
|
||||
Ok(Msg::PasswordResponseQuality { feedback })
|
||||
|
@ -99,9 +85,7 @@ impl PwModalApp {
|
|||
}),
|
||||
}
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,9 +3,7 @@ use kanidm_proto::v1::{
|
|||
CUIntentToken, CUSessionToken, CUStatus, CredentialDetail, CredentialDetailType,
|
||||
};
|
||||
use uuid::Uuid;
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
|
@ -15,7 +13,7 @@ use super::passkeyremove::PasskeyRemoveModalApp;
|
|||
use super::pwmodal::PwModalApp;
|
||||
use super::totpmodal::TotpModalApp;
|
||||
use super::totpremove::TotpRemoveComp;
|
||||
use crate::error::*;
|
||||
use crate::{do_request, error::*, RequestMethod};
|
||||
use crate::{models, utils};
|
||||
|
||||
// use std::rc::Rc;
|
||||
|
@ -577,37 +575,23 @@ impl CredentialResetApp {
|
|||
}
|
||||
|
||||
async fn exchange_intent_token(token: String) -> Result<Msg, FetchError> {
|
||||
let intentreq_jsvalue = serde_json::to_string(&CUIntentToken { token })
|
||||
let req_jsvalue = serde_json::to_string(&CUIntentToken { token })
|
||||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise intent request");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&intentreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_exchange_intent", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_exchange_intent",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let (token, status): (CUSessionToken, CUStatus) =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
Ok(Msg::BeginSession { token, status })
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
@ -617,30 +601,13 @@ impl CredentialResetApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise session token");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init(url, &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
let (kopid, status, value, _) =
|
||||
do_request(url, RequestMethod::POST, Some(req_jsvalue)).await?;
|
||||
|
||||
if status == 200 {
|
||||
Ok(Msg::Success)
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -3,14 +3,14 @@ use gloo::console;
|
|||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus, TotpSecret};
|
||||
use qrcode::render::svg;
|
||||
use qrcode::QrCode;
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Node, Request, RequestCredentials, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
use web_sys::Node;
|
||||
use yew::prelude::*;
|
||||
|
||||
use super::reset::{EventBusMsg, ModalProps};
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::{do_request, RequestMethod};
|
||||
|
||||
enum TotpState {
|
||||
Init,
|
||||
|
@ -74,31 +74,15 @@ impl TotpModalApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
|
||||
cb.emit(EventBusMsg::UpdateStatus {
|
||||
status: status.clone(),
|
||||
|
@ -115,8 +99,7 @@ impl TotpModalApp {
|
|||
CURegState::TotpInvalidSha1 => Msg::TotpInvalidSha1,
|
||||
})
|
||||
} else {
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,12 +2,11 @@ use super::reset::{EventBusMsg, TotpRemoveProps};
|
|||
#[cfg(debug_assertions)]
|
||||
use gloo::console;
|
||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||
|
||||
use crate::do_request;
|
||||
use crate::error::*;
|
||||
use crate::utils;
|
||||
use crate::RequestMethod;
|
||||
use yew::prelude::*;
|
||||
|
||||
pub enum Msg {
|
||||
|
@ -108,37 +107,21 @@ impl TotpRemoveComp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise pw curequest");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
|
||||
opts.body(Some(&req_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
|
||||
let (kopid, status, value, _) = do_request(
|
||||
"/v1/credential/_update",
|
||||
RequestMethod::POST,
|
||||
Some(req_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let status: CUStatus =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
|
||||
cb.emit(EventBusMsg::UpdateStatus { status });
|
||||
|
||||
Ok(Msg::Success)
|
||||
} else {
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,11 @@
|
|||
#![deny(clippy::needless_pass_by_value)]
|
||||
#![deny(clippy::trivially_copy_pass_by_ref)]
|
||||
|
||||
use error::FetchError;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Headers, Request, RequestInit, RequestMode, Response};
|
||||
|
||||
#[macro_use]
|
||||
mod macros;
|
||||
|
@ -35,3 +39,57 @@ pub fn run_app() -> Result<(), JsValue> {
|
|||
gloo::console::debug!(kanidm_proto::utils::get_version("kanidmd_web_ui"));
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[derive(Serialize, Deserialize, Eq, PartialEq)]
|
||||
#[serde(rename_all = "lowercase")]
|
||||
pub enum RequestMethod {
|
||||
GET,
|
||||
POST,
|
||||
PUT,
|
||||
}
|
||||
|
||||
impl ToString for RequestMethod {
|
||||
fn to_string(&self) -> String {
|
||||
match self {
|
||||
RequestMethod::PUT => "PUT".to_string(),
|
||||
RequestMethod::POST => "POST".to_string(),
|
||||
RequestMethod::GET => "GET".to_string(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Build and send a request to the backend, with some standard headers and pull back
|
||||
/// (kopid, status, json, headers)
|
||||
pub async fn do_request(
|
||||
uri: &str,
|
||||
method: RequestMethod,
|
||||
body: Option<JsValue>,
|
||||
) -> Result<(Option<String>, u16, JsValue, Headers), FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method(&method.to_string());
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(web_sys::RequestCredentials::SameOrigin);
|
||||
if let Some(body) = body {
|
||||
#[cfg(debug_assertions)]
|
||||
if method == RequestMethod::GET {
|
||||
gloo::console::debug!("This seems odd, you've supplied a body with a GET request?")
|
||||
}
|
||||
opts.body(Some(&body));
|
||||
}
|
||||
|
||||
let request = Request::new_with_str_and_init(uri, &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers: Headers = resp.headers();
|
||||
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
|
||||
Ok((kopid, status, JsFuture::from(resp.json()?).await?, headers))
|
||||
}
|
||||
|
|
|
@ -6,18 +6,15 @@ use kanidm_proto::v1::{
|
|||
};
|
||||
use kanidm_proto::webauthn::PublicKeyCredential;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
||||
use web_sys::{
|
||||
CredentialRequestOptions, Request, RequestCredentials, RequestInit, RequestMode, Response,
|
||||
};
|
||||
use web_sys::CredentialRequestOptions;
|
||||
use yew::prelude::*;
|
||||
use yew::virtual_dom::VNode;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::constants::{CLASS_BUTTON_DARK, CLASS_DIV_LOGIN_BUTTON, CLASS_DIV_LOGIN_FIELD};
|
||||
use crate::error::FetchError;
|
||||
use crate::{models, utils};
|
||||
use crate::{do_request, models, utils, RequestMethod};
|
||||
|
||||
pub struct LoginApp {
|
||||
state: LoginState,
|
||||
|
@ -105,48 +102,26 @@ impl LoginApp {
|
|||
issue: AuthIssueSession::Cookie,
|
||||
},
|
||||
};
|
||||
let authreq_jsvalue = serde_json::to_string(&authreq)
|
||||
let req_jsvalue = serde_json::to_string(&authreq)
|
||||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise authreq");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
opts.body(Some(&authreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/auth", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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 - auth_init::Response");
|
||||
let status = resp.status();
|
||||
let headers = resp.headers();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/auth", RequestMethod::POST, Some(req_jsvalue)).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||
Ok(LoginAppMsg::Start(state))
|
||||
} else if status == 404 {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
console::error!(format!(
|
||||
"User not found: {:?}. Operation ID: {:?}",
|
||||
text, kopid
|
||||
value.as_string().unwrap_or_default(),
|
||||
kopid
|
||||
));
|
||||
Ok(LoginAppMsg::UnknownUser)
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
@ -156,45 +131,23 @@ impl LoginApp {
|
|||
let authreq_jsvalue = serde_json::to_string(&issue)
|
||||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise authreq");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
opts.body(Some(&authreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/reauth", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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 - reauth_init::Response");
|
||||
let status = resp.status();
|
||||
let headers = resp.headers();
|
||||
let url = "/v1/reauth";
|
||||
let (kopid, status, value, _) =
|
||||
do_request(url, RequestMethod::POST, Some(authreq_jsvalue)).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||
Ok(LoginAppMsg::Next(state))
|
||||
} else if status == 404 {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
console::error!(format!(
|
||||
"User not found: {:?}. Operation ID: {:?}",
|
||||
text, kopid
|
||||
value.as_string(),
|
||||
kopid
|
||||
));
|
||||
Ok(LoginAppMsg::UnknownUser)
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string().unwrap_or_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
@ -204,30 +157,11 @@ impl LoginApp {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise authreq");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
opts.body(Some(&authreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/auth", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.expect_throw("failed to set content-type 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 - auth_step::Response");
|
||||
let status = resp.status();
|
||||
let headers = resp.headers();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/auth", RequestMethod::POST, Some(authreq_jsvalue)).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
||||
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||
.map_err(|e| {
|
||||
console::error!(format!("auth_step::AuthResponse: {:?}", e));
|
||||
e
|
||||
|
@ -235,9 +169,7 @@ impl LoginApp {
|
|||
.expect_throw("Invalid response type - auth_step::AuthResponse");
|
||||
Ok(LoginAppMsg::Next(state))
|
||||
} else {
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let text = JsFuture::from(resp.text()?).await?;
|
||||
let emsg = text.as_string()
|
||||
let emsg = value.as_string()
|
||||
.unwrap_or_else(|| "Unhandled error, please report this along with the operation ID below to your administrator. 😔".to_string());
|
||||
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||
}
|
||||
|
@ -247,6 +179,7 @@ impl LoginApp {
|
|||
fn button_start_again(&self, ctx: &Context<Self>) -> VNode {
|
||||
html! {
|
||||
<div class="col-md-auto text-center">
|
||||
// TODO: this doesn't seem to work if you failed to login
|
||||
<button type="button" class={CLASS_BUTTON_DARK} onclick={ ctx.link().callback(|_| LoginAppMsg::Restart) } >{" Start Again "}</button>
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
// use anyhow::Error;
|
||||
use gloo::console;
|
||||
pub use kanidm_proto::oauth2::{
|
||||
AccessTokenRequest, AccessTokenResponse, AuthorisationRequest, AuthorisationResponse,
|
||||
|
@ -6,12 +5,12 @@ pub use kanidm_proto::oauth2::{
|
|||
};
|
||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, RequestRedirect, Response};
|
||||
use web_sys::{Request, RequestInit, RequestMode, RequestRedirect, Response};
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::error::*;
|
||||
use crate::manager::Route;
|
||||
use crate::{do_request, error::*, RequestMethod};
|
||||
use crate::{models, utils};
|
||||
|
||||
use std::collections::BTreeSet;
|
||||
|
@ -70,31 +69,15 @@ impl From<FetchError> for Oauth2Msg {
|
|||
|
||||
impl Oauth2App {
|
||||
async fn fetch_session_valid() -> Result<Oauth2Msg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
let request = Request::new_with_str_and_init("/v1/auth/valid", &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/auth/valid", RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
Ok(Oauth2Msg::TokenValid)
|
||||
} else if status == 401 {
|
||||
Ok(Oauth2Msg::LoginRequired)
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||
Ok(Oauth2Msg::Error { emsg, kopid })
|
||||
}
|
||||
|
@ -105,29 +88,15 @@ impl Oauth2App {
|
|||
.map(|s| JsValue::from(&s))
|
||||
.expect_throw("Failed to serialise authreq");
|
||||
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
opts.body(Some(&authreq_jsvalue));
|
||||
|
||||
let request = Request::new_with_str_and_init("/oauth2/authorise", &opts)?;
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let headers = resp.headers();
|
||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
||||
let (kopid, status, value, headers) = do_request(
|
||||
"/oauth2/authorise",
|
||||
RequestMethod::POST,
|
||||
Some(authreq_jsvalue),
|
||||
)
|
||||
.await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let state: AuthorisationResponse = serde_wasm_bindgen::from_value(jsval)
|
||||
let state: AuthorisationResponse = serde_wasm_bindgen::from_value(value)
|
||||
.map_err(|e| {
|
||||
let e_msg = format!("serde error -> {:?}", e);
|
||||
console::error!(e_msg.as_str());
|
||||
|
@ -159,8 +128,7 @@ 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Oauth2Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
@ -173,8 +141,7 @@ impl Oauth2App {
|
|||
let mut opts = RequestInit::new();
|
||||
opts.method("POST");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.redirect(RequestRedirect::Manual);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
opts.redirect(RequestRedirect::Manual); // can't replace with do_request because of this
|
||||
|
||||
opts.body(Some(&consentreq_jsvalue));
|
||||
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
use gloo::console;
|
||||
use gloo_net::http::Request;
|
||||
use url::Url;
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
pub use web_sys::InputEvent;
|
||||
use web_sys::{Document, HtmlElement, HtmlInputElement, RequestCredentials, RequestMode, Window};
|
||||
use web_sys::{Document, HtmlElement, HtmlInputElement, Window};
|
||||
use yew::virtual_dom::VNode;
|
||||
use yew::{html, Html};
|
||||
|
||||
|
@ -94,14 +93,6 @@ pub fn do_footer() -> VNode {
|
|||
}
|
||||
}
|
||||
|
||||
/// Builds a request object to a server-local endpoint with the usual requirements
|
||||
pub fn init_request(endpoint: &str) -> gloo_net::http::Request {
|
||||
Request::new(endpoint)
|
||||
.mode(RequestMode::SameOrigin)
|
||||
.credentials(RequestCredentials::SameOrigin)
|
||||
.header("content-type", "application/json")
|
||||
}
|
||||
|
||||
pub fn do_alert_error(alert_title: &str, alert_message: Option<&str>) -> Html {
|
||||
html! {
|
||||
<div class="container">
|
||||
|
|
|
@ -4,11 +4,8 @@ use yew::prelude::*;
|
|||
|
||||
use crate::constants::{CSS_CARD, CSS_LINK_DARK_STRETCHED, CSS_PAGE_HEADER};
|
||||
use crate::error::FetchError;
|
||||
use crate::utils;
|
||||
use crate::{do_request, RequestMethod};
|
||||
use wasm_bindgen::prelude::*;
|
||||
use wasm_bindgen::JsCast;
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
||||
|
||||
use kanidm_proto::internal::AppLink;
|
||||
|
||||
|
@ -182,33 +179,15 @@ impl AppsApp {
|
|||
}
|
||||
|
||||
async fn fetch_user_apps() -> Result<Msg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/self/_applinks", &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/self/_applinks", RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let apps: Vec<AppLink> = serde_wasm_bindgen::from_value(jsval)
|
||||
let apps: Vec<AppLink> = serde_wasm_bindgen::from_value(value)
|
||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||
Ok(Msg::Ready { apps })
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,16 +1,14 @@
|
|||
use gloo::console;
|
||||
use kanidm_proto::v1::{UiHint, UserAuthToken};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
use crate::components::{admin_accounts, admin_groups, admin_menu, admin_oauth2};
|
||||
use crate::error::*;
|
||||
use crate::manager::Route;
|
||||
use crate::{models, utils};
|
||||
use crate::models;
|
||||
use crate::{do_request, error::*, RequestMethod};
|
||||
|
||||
mod apps;
|
||||
mod profile;
|
||||
|
@ -328,62 +326,25 @@ impl ViewsApp {
|
|||
}
|
||||
|
||||
async fn check_session_valid() -> Result<ViewsMsg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/auth/valid", &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.expect_throw("failed to set header");
|
||||
|
||||
let window = utils::window();
|
||||
let resp_value = JsFuture::from(window.fetch_with_request(&request))
|
||||
.await
|
||||
.map_err(|e| {
|
||||
console::error!(&format!("fetch request failed {:?}", e));
|
||||
e
|
||||
})?;
|
||||
let resp: Response = resp_value.dyn_into().expect_throw("Invalid response type");
|
||||
let status = resp.status();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/auth/valid", RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
Ok(ViewsMsg::Verified)
|
||||
} else if status == 401 {
|
||||
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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(ViewsMsg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch_user_data() -> Result<ViewsMsg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
let request = Request::new_with_str_and_init("/v1/self/_uat", &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _) =
|
||||
do_request("/v1/self/_uat", RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let uat: UserAuthToken = serde_wasm_bindgen::from_value(jsval)
|
||||
let uat: UserAuthToken = serde_wasm_bindgen::from_value(value)
|
||||
.map_err(|e| {
|
||||
let e_msg = format!("serde error -> {:?}", e);
|
||||
console::error!(e_msg.as_str());
|
||||
|
@ -392,39 +353,18 @@ impl ViewsApp {
|
|||
|
||||
Ok(ViewsMsg::ProfileInfoReceived { uat })
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(ViewsMsg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
||||
async fn fetch_logout() -> Result<ViewsMsg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::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");
|
||||
|
||||
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();
|
||||
let (kopid, status, value, _) = do_request("/v1/logout", RequestMethod::GET, None).await?;
|
||||
|
||||
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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
Ok(ViewsMsg::Error { emsg, kopid })
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
use gloo::console;
|
||||
use kanidm_proto::v1::{CUSessionToken, CUStatus, UiHint, UserAuthToken};
|
||||
use time::format_description::well_known::Rfc3339;
|
||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||
use wasm_bindgen_futures::JsFuture;
|
||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
||||
use wasm_bindgen::UnwrapThrowExt;
|
||||
use yew::prelude::*;
|
||||
use yew_router::prelude::*;
|
||||
|
||||
|
@ -13,8 +11,8 @@ use crate::components::create_reset_code::CreateResetCode;
|
|||
use crate::constants::CSS_PAGE_HEADER;
|
||||
use crate::error::*;
|
||||
use crate::manager::Route;
|
||||
use crate::models;
|
||||
use crate::views::{ViewProps, ViewRoute};
|
||||
use crate::{models, utils};
|
||||
|
||||
#[allow(clippy::large_enum_variant)]
|
||||
// Page state
|
||||
|
@ -240,35 +238,16 @@ impl ProfileApp {
|
|||
}
|
||||
|
||||
async fn request_credential_update(id: String) -> Result<Msg, FetchError> {
|
||||
let mut opts = RequestInit::new();
|
||||
opts.method("GET");
|
||||
opts.mode(RequestMode::SameOrigin);
|
||||
opts.credentials(RequestCredentials::SameOrigin);
|
||||
|
||||
let uri = format!("/v1/person/{}/_credential/_update", id);
|
||||
|
||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
||||
|
||||
request
|
||||
.headers()
|
||||
.set("content-type", "application/json")
|
||||
.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();
|
||||
let (kopid, status, value, _headers) =
|
||||
crate::do_request(&uri, crate::RequestMethod::GET, None).await?;
|
||||
|
||||
if status == 200 {
|
||||
let jsval = JsFuture::from(resp.json()?).await?;
|
||||
let (token, status): (CUSessionToken, CUStatus) =
|
||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
||||
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||
Ok(Msg::BeginCredentialUpdate { token, status })
|
||||
} 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_default();
|
||||
let emsg = value.as_string().unwrap_or_default();
|
||||
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||
Ok(Msg::Error { emsg, kopid })
|
||||
}
|
||||
|
|
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 1.4 KiB After Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 53 KiB After Width: | Height: | Size: 53 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 39 KiB After Width: | Height: | Size: 39 KiB |
Before Width: | Height: | Size: 9.7 KiB After Width: | Height: | Size: 9.7 KiB |
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 14 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 48 KiB After Width: | Height: | Size: 48 KiB |
Before Width: | Height: | Size: 16 KiB After Width: | Height: | Size: 16 KiB |
|
@ -3,39 +3,39 @@ name = "kanidm-ipa-sync"
|
|||
description = "Kanidm Client Tools"
|
||||
documentation = "https://kanidm.github.io/kanidm/stable/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
base64urlsafedata.workspace = true
|
||||
base64urlsafedata = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
chrono.workspace = true
|
||||
cron.workspace = true
|
||||
kanidm_client.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
chrono = { workspace = true }
|
||||
cron = { workspace = true }
|
||||
kanidm_client = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
||||
|
||||
|
||||
ldap3_client.workspace = true
|
||||
ldap3_client = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
toml.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
uuid = { workspace = true, features = ["serde"] }
|
||||
|
||||
# For file metadata, should this me moved out?
|
||||
kanidmd_lib.workspace = true
|
||||
kanidmd_lib = { workspace = true }
|
||||
|
||||
[target.'cfg(target_family = "unix")'.dependencies]
|
||||
users.workspace = true
|
||||
users = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
clap_complete.workspace = true
|
||||
clap_complete = { workspace = true }
|
||||
|
|
|
@ -3,39 +3,39 @@ name = "kanidm-ldap-sync"
|
|||
description = "Kanidm Client Tools"
|
||||
documentation = "https://kanidm.github.io/kanidm/stable/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[dependencies]
|
||||
base64urlsafedata.workspace = true
|
||||
base64urlsafedata = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
chrono.workspace = true
|
||||
cron.workspace = true
|
||||
kanidm_client.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
chrono = { workspace = true }
|
||||
cron = { workspace = true }
|
||||
kanidm_client = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
||||
|
||||
|
||||
ldap3_client.workspace = true
|
||||
ldap3_client = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
toml.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
toml = { workspace = true }
|
||||
url = { workspace = true, features = ["serde"] }
|
||||
uuid = { workspace = true, features = ["serde"] }
|
||||
|
||||
# For file metadata, should this me moved out?
|
||||
kanidmd_lib.workspace = true
|
||||
kanidmd_lib = { workspace = true }
|
||||
|
||||
[target.'cfg(target_family = "unix")'.dependencies]
|
||||
users.workspace = true
|
||||
users = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
clap_complete.workspace = true
|
||||
clap_complete = { workspace = true }
|
||||
|
|
|
@ -3,42 +3,42 @@ name = "orca"
|
|||
description = "Orca - load testing for LDAP and Kanidm"
|
||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[[bin]]
|
||||
name = "orca"
|
||||
path = "src/main.rs"
|
||||
|
||||
[dependencies]
|
||||
clap.workspace = true
|
||||
crossbeam.workspace = true
|
||||
csv.workspace = true
|
||||
dialoguer.workspace = true
|
||||
clap = { workspace = true }
|
||||
crossbeam = { workspace = true }
|
||||
csv = { workspace = true }
|
||||
dialoguer = { workspace = true }
|
||||
futures-util = { workspace = true, features = ["sink"] }
|
||||
kanidm_client.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
ldap3_proto.workspace = true
|
||||
mathru.workspace = true
|
||||
openssl.workspace = true
|
||||
rand.workspace = true
|
||||
kanidm_client = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
ldap3_proto = { workspace = true }
|
||||
mathru = { workspace = true }
|
||||
openssl = { workspace = true }
|
||||
rand = { workspace = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt-multi-thread"] }
|
||||
tokio-openssl.workspace = true
|
||||
tokio-openssl = { workspace = true }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
toml.workspace = true
|
||||
tracing.workspace = true
|
||||
tracing-subscriber.workspace = true
|
||||
toml = { workspace = true }
|
||||
tracing = { workspace = true }
|
||||
tracing-subscriber = { workspace = true }
|
||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||
|
||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||
tikv-jemallocator.workspace = true
|
||||
tikv-jemallocator = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
profiles.workspace = true
|
||||
profiles = { workspace = true }
|
||||
|
|
|
@ -3,13 +3,13 @@ name = "kanidm_unix_int"
|
|||
description = "Kanidm Unix Integration Clients"
|
||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[features]
|
||||
default = ["unix"]
|
||||
|
@ -42,40 +42,40 @@ name = "kanidm_unix_common"
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
bytes.workspace = true
|
||||
bytes = { workspace = true }
|
||||
clap = { workspace = true, features = ["derive", "env"] }
|
||||
csv.workspace = true
|
||||
futures.workspace = true
|
||||
libc.workspace = true
|
||||
libsqlite3-sys.workspace = true
|
||||
lru.workspace = true
|
||||
kanidm_client.workspace = true
|
||||
kanidm_proto.workspace = true
|
||||
kanidm_lib_crypto.workspace = true
|
||||
kanidm_lib_file_permissions.workspace = true
|
||||
notify-debouncer-full.workspace = true
|
||||
rpassword.workspace = true
|
||||
rusqlite.workspace = true
|
||||
csv = { workspace = true }
|
||||
futures = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
libsqlite3-sys = { workspace = true }
|
||||
lru = { workspace = true }
|
||||
kanidm_client = { workspace = true }
|
||||
kanidm_proto = { workspace = true }
|
||||
kanidm_lib_crypto = { workspace = true }
|
||||
kanidm_lib_file_permissions = { workspace = true }
|
||||
notify-debouncer-full = { workspace = true }
|
||||
rpassword = { workspace = true }
|
||||
rusqlite = { workspace = true }
|
||||
selinux = { workspace = true, optional = true }
|
||||
serde = { workspace = true, features = ["derive"] }
|
||||
serde_json.workspace = true
|
||||
sketching.workspace = true
|
||||
serde_json = { workspace = true }
|
||||
sketching = { workspace = true }
|
||||
|
||||
toml.workspace = true
|
||||
toml = { workspace = true }
|
||||
tokio = { workspace = true, features = ["rt", "fs", "macros", "sync", "time", "net", "io-util"] }
|
||||
tokio-util = { workspace = true, features = ["codec"] }
|
||||
tracing.workspace = true
|
||||
tracing = { workspace = true }
|
||||
tss-esapi = { workspace = true, optional = true }
|
||||
reqwest = { workspace = true, default-features = false }
|
||||
walkdir.workspace = true
|
||||
walkdir = { workspace = true }
|
||||
|
||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||
users.workspace = true
|
||||
users = { workspace = true }
|
||||
|
||||
[dev-dependencies]
|
||||
kanidmd_core.workspace = true
|
||||
kanidmd_core = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
clap = { workspace = true, features = ["derive"] }
|
||||
clap_complete.workspace = true
|
||||
profiles.workspace = true
|
||||
clap_complete = { workspace = true }
|
||||
profiles = { workspace = true }
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
name = "pam_kanidm"
|
||||
links = "pam"
|
||||
|
||||
version.workspace = true
|
||||
authors.workspace = true
|
||||
rust-version.workspace = true
|
||||
edition.workspace = true
|
||||
license.workspace = true
|
||||
homepage.workspace = true
|
||||
repository.workspace = true
|
||||
version = { workspace = true }
|
||||
authors = { workspace = true }
|
||||
rust-version = { workspace = true }
|
||||
edition = { workspace = true }
|
||||
license = { workspace = true }
|
||||
homepage = { workspace = true }
|
||||
repository = { workspace = true }
|
||||
|
||||
[lib]
|
||||
name = "pam_kanidm"
|
||||
|
@ -16,8 +16,8 @@ crate-type = [ "cdylib" ]
|
|||
path = "src/lib.rs"
|
||||
|
||||
[dependencies]
|
||||
kanidm_unix_int.workspace = true
|
||||
libc.workspace = true
|
||||
kanidm_unix_int = { workspace = true }
|
||||
libc = { workspace = true }
|
||||
|
||||
[build-dependencies]
|
||||
pkg-config.workspace = true
|
||||
pkg-config = { workspace = true }
|
||||
|
|