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":
|
"on":
|
||||||
push:
|
push:
|
||||||
|
@ -31,25 +31,33 @@ jobs:
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v3
|
uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
- name: install curl
|
||||||
run: |
|
run: |
|
||||||
apt-get update && \
|
apt-get update && apt-get install -y curl
|
||||||
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
|
|
||||||
- name: Setup sccache
|
- name: Setup sccache
|
||||||
uses: mozilla-actions/sccache-action@v0.0.3
|
uses: mozilla-actions/sccache-action@v0.0.3
|
||||||
with:
|
with:
|
||||||
version: "v0.4.2"
|
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
|
- name: Build packages
|
||||||
run: |
|
run: |
|
||||||
make -f platform/debian/Makefile debs/all
|
make -f platform/debian/Makefile debs/all
|
||||||
|
|
20
.github/workflows/wasm_test.yml
vendored
|
@ -16,21 +16,20 @@ jobs:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- name: Install dependencies
|
# - name: Check arch
|
||||||
run: |
|
# run: |
|
||||||
sudo apt-get update &&
|
# uname -a
|
||||||
sudo apt-get install -y \
|
|
||||||
libpam0g-dev \
|
|
||||||
libudev-dev \
|
|
||||||
libssl-dev \
|
|
||||||
libsqlite3-dev \
|
|
||||||
pkg-config
|
|
||||||
- name: Setup sccache
|
- name: Setup sccache
|
||||||
uses: mozilla-actions/sccache-action@v0.0.3
|
uses: mozilla-actions/sccache-action@v0.0.3
|
||||||
with:
|
with:
|
||||||
version: "v0.4.2"
|
version: "v0.4.2"
|
||||||
|
- name: Install Rust
|
||||||
|
uses: dtolnay/rust-toolchain@stable
|
||||||
- name: Install wasm-pack
|
- name: Install wasm-pack
|
||||||
run: cargo install wasm-pack
|
run: cargo install wasm-pack
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
scripts/install_ubuntu_dependencies.sh
|
||||||
# https://github.com/browser-actions/setup-chrome
|
# https://github.com/browser-actions/setup-chrome
|
||||||
- name: Install Chrome Headless
|
- name: Install Chrome Headless
|
||||||
uses: browser-actions/setup-chrome@latest
|
uses: browser-actions/setup-chrome@latest
|
||||||
|
@ -45,5 +44,6 @@ jobs:
|
||||||
# docs here:
|
# docs here:
|
||||||
# https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/browsers.html
|
# https://rustwasm.github.io/docs/wasm-bindgen/wasm-bindgen-test/browsers.html
|
||||||
- run: make webui
|
- run: make webui
|
||||||
- run: wasm-pack test --headless --chrome
|
- name: "Run wasm-pack test"
|
||||||
|
run: make webui/test
|
||||||
continue-on-error: true
|
continue-on-error: true
|
||||||
|
|
14
Cargo.lock
generated
|
@ -1215,6 +1215,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"clap_complete",
|
"clap_complete",
|
||||||
"fs2",
|
"fs2",
|
||||||
|
"is-terminal",
|
||||||
"kanidm_lib_file_permissions",
|
"kanidm_lib_file_permissions",
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
"kanidmd_core",
|
"kanidmd_core",
|
||||||
|
@ -2383,6 +2384,18 @@ version = "2.7.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "12b6ee2129af8d4fb011108c73d99a1b83a85977f23b82460c0ae2e25bb4b57f"
|
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]]
|
[[package]]
|
||||||
name = "itertools"
|
name = "itertools"
|
||||||
version = "0.10.5"
|
version = "0.10.5"
|
||||||
|
@ -2718,7 +2731,6 @@ version = "1.1.0-beta.13"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compact_jwt",
|
"compact_jwt",
|
||||||
"gloo",
|
"gloo",
|
||||||
"gloo-net",
|
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
"qrcode",
|
"qrcode",
|
||||||
|
|
6
Makefile
|
@ -122,7 +122,7 @@ codespell:
|
||||||
--skip='./book/book/*' \
|
--skip='./book/book/*' \
|
||||||
--skip='./docs/*,./.git' \
|
--skip='./docs/*,./.git' \
|
||||||
--skip='./rlm_python/mods-available/eap' \
|
--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'
|
--skip='./server/lib/src/constants/system_config.rs,./pykanidm/site,./server/lib/src/constants/*.json'
|
||||||
|
|
||||||
.PHONY: test/pykanidm/pytest
|
.PHONY: test/pykanidm/pytest
|
||||||
|
@ -255,3 +255,7 @@ cert/clean:
|
||||||
.PHONY: webui
|
.PHONY: webui
|
||||||
webui: ## Build the WASM web frontend
|
webui: ## Build the WASM web frontend
|
||||||
cd server/web_ui && ./build_wasm_release.sh
|
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.
|
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
|
#### SUSE / OpenSUSE
|
||||||
|
|
||||||
You will need to install rustup and our build dependencies with:
|
You will need to install rustup and our build dependencies with:
|
||||||
|
|
|
@ -128,8 +128,8 @@ alias kanidm="docker run ..."
|
||||||
|
|
||||||
## Initializing the configuration
|
## Initializing the configuration
|
||||||
|
|
||||||
The client requires a configuration file to connect to the server.
|
The client requires a configuration file to connect to the server. This should be at
|
||||||
This should be at `/etc/kanidm/config` or `~/.config/kanidm`, and configures the kanidm command line tool.
|
`/etc/kanidm/config` or `~/.config/kanidm`, and configures the kanidm command line tool.
|
||||||
|
|
||||||
Here is a minimal example:
|
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
|
# 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.
|
# to point at the local dev server and trust the CA security.
|
||||||
uri = "https://localhost:8443"
|
uri="https://localhost:8443"
|
||||||
verify_ca = false
|
verify_ca="/tmp/kanidm/ca.pem"
|
||||||
verify_hostnames = false
|
|
||||||
|
|
|
@ -11,8 +11,8 @@ tls_key = "/tmp/kanidm/key.pem"
|
||||||
# NOTE: this is overridden by environment variables at runtime
|
# NOTE: this is overridden by environment variables at runtime
|
||||||
# Defaults to "info"
|
# Defaults to "info"
|
||||||
#
|
#
|
||||||
log_level = "info"
|
# log_level = "info"
|
||||||
# log_level = "debug"
|
log_level = "debug"
|
||||||
# log_level = "trace"
|
# log_level = "trace"
|
||||||
|
|
||||||
domain = "localhost"
|
domain = "localhost"
|
||||||
|
|
|
@ -3,23 +3,23 @@ name = "kanidm_client"
|
||||||
description = "Kanidm Client Library"
|
description = "Kanidm Client Library"
|
||||||
documentation = "https://docs.rs/kanidm_client/latest/kanidm_client/"
|
documentation = "https://docs.rs/kanidm_client/latest/kanidm_client/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
reqwest = { workspace = true, default-features = false }
|
reqwest = { workspace = true, default-features = false }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
time = { workspace = true, features = ["serde", "std"] }
|
time = { workspace = true, features = ["serde", "std"] }
|
||||||
tokio = { workspace = true, features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
tokio = { workspace = true, features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["serde", "v4"] }
|
uuid = { workspace = true, features = ["serde", "v4"] }
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
webauthn-rs-proto = { workspace = true, features = ["wasm"] }
|
webauthn-rs-proto = { workspace = true, features = ["wasm"] }
|
||||||
|
|
|
@ -7,20 +7,20 @@ edition = "2021"
|
||||||
tpm = ["dep:tss-esapi"]
|
tpm = ["dep:tss-esapi"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
argon2.workspace = true
|
argon2 = { workspace = true }
|
||||||
base64.workspace = true
|
base64 = { workspace = true }
|
||||||
base64urlsafedata.workspace = true
|
base64urlsafedata = { workspace = true }
|
||||||
hex.workspace = true
|
hex = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
|
|
||||||
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
||||||
# into the build.rs for legacy feature checks.
|
# into the build.rs for legacy feature checks.
|
||||||
openssl-sys.workspace = true
|
openssl-sys = { workspace = true }
|
||||||
openssl.workspace = true
|
openssl = { workspace = true }
|
||||||
rand.workspace = true
|
rand = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
tss-esapi = { workspace = true, optional = true }
|
tss-esapi = { workspace = true, optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[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
|
# We do not have tests in this pkg
|
||||||
autotests = false
|
autotests = false
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "profiles"
|
name = "profiles"
|
||||||
|
@ -19,8 +19,8 @@ path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
base64.workspace = true
|
base64 = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
base64.workspace = true
|
base64 = { workspace = true }
|
||||||
|
|
|
@ -3,18 +3,18 @@ name = "sketching"
|
||||||
# We do not have tests in this pkg
|
# We do not have tests in this pkg
|
||||||
autotests = false
|
autotests = false
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait.workspace = true
|
async-trait = { workspace = true }
|
||||||
num_enum.workspace = true
|
num_enum = { workspace = true }
|
||||||
tide.workspace = true
|
tide = { workspace = true }
|
||||||
tracing = { workspace = true, features = ["attributes"] }
|
tracing = { workspace = true, features = ["attributes"] }
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
tracing-subscriber = { workspace = true, features = ["env-filter"] }
|
||||||
tracing-forest = { workspace = true, features = ["uuid", "smallvec", "tokio", "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()),
|
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
||||||
"Client error --> Response sent"
|
"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 {
|
} else {
|
||||||
request_warn!(
|
request_warn!(
|
||||||
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
status = format_args!("{} - {}", status as u16, status.canonical_reason()),
|
||||||
|
|
|
@ -3,31 +3,31 @@ name = "kanidm_proto"
|
||||||
description = "Kanidm Protocol Bindings for serde"
|
description = "Kanidm Protocol Bindings for serde"
|
||||||
documentation = "https://docs.rs/kanidm_proto/latest/kanidm_proto/"
|
documentation = "https://docs.rs/kanidm_proto/latest/kanidm_proto/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
wasm = ["webauthn-rs-proto/wasm"]
|
wasm = ["webauthn-rs-proto/wasm"]
|
||||||
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base32.workspace = true
|
base32 = { workspace = true }
|
||||||
base64urlsafedata.workspace = true
|
base64urlsafedata = { workspace = true }
|
||||||
num_enum.workspace = true
|
num_enum = { workspace = true }
|
||||||
scim_proto.workspace = true
|
scim_proto = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
time = { workspace = true, features = ["serde", "std"] }
|
time = { workspace = true, features = ["serde", "std"] }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
urlencoding.workspace = true
|
urlencoding = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["serde"] }
|
uuid = { workspace = true, features = ["serde"] }
|
||||||
webauthn-rs-proto.workspace = true
|
webauthn-rs-proto = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "wasm"))'.dependencies]
|
[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,
|
pub token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Clone, Serialize, Deserialize)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum CURequest {
|
pub enum CURequest {
|
||||||
PrimaryRemove,
|
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"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
toml = {workspace = true}
|
toml = {workspace = true}
|
||||||
tracing = { workspace = true, features = ["attributes"] }
|
tracing = { workspace = true, features = ["attributes"] }
|
||||||
urlencoding.workspace = true
|
urlencoding = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||||
|
|
||||||
[build-dependencies]
|
[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 {
|
pub enum ServerRole {
|
||||||
#[default]
|
#[default]
|
||||||
WriteReplica,
|
WriteReplica,
|
||||||
|
|
|
@ -200,6 +200,8 @@ impl<State: Clone + Send + Sync + 'static> tide::Middleware<State>
|
||||||
"base-uri 'self'",
|
"base-uri 'self'",
|
||||||
// nobody wants to be in a frame
|
// nobody wants to be in a frame
|
||||||
"frame-ancestors 'none'",
|
"frame-ancestors 'none'",
|
||||||
|
// allow inline images because bootstrap
|
||||||
|
"img-src 'self' data:",
|
||||||
]
|
]
|
||||||
.join(";"),
|
.join(";"),
|
||||||
);
|
);
|
||||||
|
|
|
@ -52,16 +52,42 @@ impl JavaScriptFile {
|
||||||
/// returns a `<script>` HTML tag
|
/// returns a `<script>` HTML tag
|
||||||
fn as_tag(self) -> String {
|
fn as_tag(self) -> String {
|
||||||
let typeattr = match self.filetype {
|
let typeattr = match self.filetype {
|
||||||
Some(val) => format!("type=\"{}\" ", val),
|
Some(val) => {
|
||||||
|
format!(" type=\"{}\"", val.as_str())
|
||||||
|
}
|
||||||
_ => String::from(""),
|
_ => String::from(""),
|
||||||
};
|
};
|
||||||
format!(
|
format!(
|
||||||
r#"<script src="/pkg/{}" integrity="{}" {}></script>"#,
|
r#"<script src="/pkg/{}" integrity="{}"{}></script>"#,
|
||||||
self.filepath, self.hash, typeattr,
|
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)]
|
#[derive(Clone)]
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub status_ref: &'static StatusActor,
|
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(
|
pub async fn create_https_server(
|
||||||
address: String,
|
address: String,
|
||||||
domain: String,
|
domain: &String,
|
||||||
// opt_tls_params: Option<SslAcceptorBuilder>,
|
|
||||||
opt_tls_params: Option<&TlsConfiguration>,
|
opt_tls_params: Option<&TlsConfiguration>,
|
||||||
role: ServerRole,
|
role: ServerRole,
|
||||||
trust_x_forward_for: bool,
|
trust_x_forward_for: bool,
|
||||||
|
|
|
@ -51,7 +51,7 @@ use tokio::sync::broadcast;
|
||||||
|
|
||||||
use crate::actors::v1_read::QueryServerReadV1;
|
use crate::actors::v1_read::QueryServerReadV1;
|
||||||
use crate::actors::v1_write::QueryServerWriteV1;
|
use crate::actors::v1_write::QueryServerWriteV1;
|
||||||
use crate::config::Configuration;
|
use crate::config::{Configuration, ServerRole};
|
||||||
use crate::interval::IntervalActor;
|
use crate::interval::IntervalActor;
|
||||||
|
|
||||||
// === internal setup helpers
|
// === internal setup helpers
|
||||||
|
@ -914,7 +914,7 @@ pub async fn create_server_core(
|
||||||
// ⚠️ only start the sockets and listeners in non-config-test modes.
|
// ⚠️ only start the sockets and listeners in non-config-test modes.
|
||||||
let h = self::https::create_https_server(
|
let h = self::https::create_https_server(
|
||||||
config.address,
|
config.address,
|
||||||
config.domain,
|
&config.domain,
|
||||||
config.tls_config.as_ref(),
|
config.tls_config.as_ref(),
|
||||||
config.role,
|
config.role,
|
||||||
config.trust_x_forward_for,
|
config.trust_x_forward_for,
|
||||||
|
@ -927,7 +927,11 @@ pub async fn create_server_core(
|
||||||
)
|
)
|
||||||
.await?;
|
.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)
|
Some(h)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@ name = "daemon"
|
||||||
description = "Kanidm Server Daemon"
|
description = "Kanidm Server Daemon"
|
||||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# 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"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
kanidmd_core.workspace = true
|
kanidmd_core = { workspace = true }
|
||||||
kanidm_lib_file_permissions.workspace = true
|
kanidm_lib_file_permissions = { workspace = true }
|
||||||
sketching.workspace = true
|
sketching = { workspace = true }
|
||||||
fs2.workspace = true
|
fs2 = { workspace = true }
|
||||||
|
|
||||||
clap = { workspace = true, features = ["env"] }
|
clap = { workspace = true, features = ["env"] }
|
||||||
reqwest = { workspace = true }
|
reqwest = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal"] }
|
tokio = { workspace = true, features = ["rt-multi-thread", "macros", "signal"] }
|
||||||
toml = { workspace = true }
|
toml = { workspace = true }
|
||||||
|
is-terminal = "0.4.7"
|
||||||
|
|
||||||
[target.'cfg(target_family = "windows")'.dependencies]
|
[target.'cfg(target_family = "windows")'.dependencies]
|
||||||
whoami.workspace = true
|
whoami = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
users.workspace = true
|
users = { workspace = true }
|
||||||
tikv-jemallocator.workspace = true
|
tikv-jemallocator = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
clap = { workspace = true, features = ["derive"] }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
clap_complete.workspace = true
|
clap_complete = { workspace = true }
|
||||||
profiles.workspace = true
|
profiles = { workspace = true }
|
||||||
|
|
|
@ -126,7 +126,7 @@ async fn main() -> ExitCode {
|
||||||
};
|
};
|
||||||
|
|
||||||
// if they specified it in the environment then that overrides everything
|
// 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,
|
Ok(val) => val,
|
||||||
Err(_e) => {
|
Err(_e) => {
|
||||||
// we couldn't get it from the env, so we'll try the config file!
|
// we couldn't get it from the env, so we'll try the config file!
|
||||||
|
@ -140,14 +140,25 @@ async fn main() -> ExitCode {
|
||||||
.into()
|
.into()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// TODO: only send to stderr when we're not in a TTY
|
||||||
tracing_forest::worker_task()
|
tracing_forest::worker_task()
|
||||||
.set_global(true)
|
.set_global(true)
|
||||||
.set_tag(sketching::event_tagger)
|
.set_tag(sketching::event_tagger)
|
||||||
// Fall back to stderr
|
// Fall back to stderr
|
||||||
.map_sender(|sender| sender.or_stderr())
|
.map_sender(|sender| sender.or_stderr())
|
||||||
.build_on(|subscriber| subscriber
|
.build_on(|subscriber|{
|
||||||
.with(log_level)
|
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 {
|
.on(async {
|
||||||
// Get information on the windows username
|
// Get information on the windows username
|
||||||
#[cfg(target_family = "windows")]
|
#[cfg(target_family = "windows")]
|
||||||
|
|
|
@ -7,7 +7,7 @@ edition = "2021"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2.workspace = true
|
proc-macro2 = { workspace = true }
|
||||||
quote.workspace = true
|
quote = { workspace = true }
|
||||||
syn.workspace = true
|
syn = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -3,13 +3,13 @@ name = "kanidmd_lib"
|
||||||
description = "Kanidm Server Backend Library"
|
description = "Kanidm Server Backend Library"
|
||||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "kanidmd_lib"
|
name = "kanidmd_lib"
|
||||||
|
@ -20,73 +20,73 @@ name = "scaling_10k"
|
||||||
harness = false
|
harness = false
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
async-trait.workspace = true
|
async-trait = { workspace = true }
|
||||||
base64.workspace = true
|
base64 = { workspace = true }
|
||||||
base64urlsafedata.workspace = true
|
base64urlsafedata = { workspace = true }
|
||||||
compact_jwt = { workspace = true, features = ["openssl"] }
|
compact_jwt = { workspace = true, features = ["openssl"] }
|
||||||
concread.workspace = true
|
concread = { workspace = true }
|
||||||
dyn-clone.workspace = true
|
dyn-clone = { workspace = true }
|
||||||
fernet = { workspace = true, features = ["fernet_danger_timestamps"] }
|
fernet = { workspace = true, features = ["fernet_danger_timestamps"] }
|
||||||
filetime.workspace = true
|
filetime = { workspace = true }
|
||||||
futures-util.workspace = true
|
futures-util = { workspace = true }
|
||||||
hashbrown.workspace = true
|
hashbrown = { workspace = true }
|
||||||
idlset.workspace = true
|
idlset = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
kanidm_lib_crypto.workspace = true
|
kanidm_lib_crypto = { workspace = true }
|
||||||
lazy_static.workspace = true
|
lazy_static = { workspace = true }
|
||||||
ldap3_proto.workspace = true
|
ldap3_proto = { workspace = true }
|
||||||
libc.workspace = true
|
libc = { workspace = true }
|
||||||
libsqlite3-sys.workspace = true
|
libsqlite3-sys = { workspace = true }
|
||||||
num_enum.workspace = true
|
num_enum = { workspace = true }
|
||||||
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
# We need to explicitly ask for openssl-sys so that we get the version propagated
|
||||||
# into the build.rs for legacy feature checks.
|
# into the build.rs for legacy feature checks.
|
||||||
openssl-sys.workspace = true
|
openssl-sys = { workspace = true }
|
||||||
openssl.workspace = true
|
openssl = { workspace = true }
|
||||||
rand.workspace = true
|
rand = { workspace = true }
|
||||||
regex = { workspace = true, features = ["std", "perf", "perf-inline", "unicode", "unicode-gencat"] }
|
regex = { workspace = true, features = ["std", "perf", "perf-inline", "unicode", "unicode-gencat"] }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_cbor.workspace = true
|
serde_cbor = { workspace = true }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
sketching.workspace = true
|
sketching = { workspace = true }
|
||||||
smartstring = { workspace = true, features = ["serde"] }
|
smartstring = { workspace = true, features = ["serde"] }
|
||||||
smolset.workspace = true
|
smolset = { workspace = true }
|
||||||
sshkeys.workspace = true
|
sshkeys = { workspace = true }
|
||||||
tide.workspace = true
|
tide = { workspace = true }
|
||||||
time = { workspace = true, features = ["serde", "std"] }
|
time = { workspace = true, features = ["serde", "std"] }
|
||||||
tokio = { workspace = true, features = ["net", "sync", "time", "rt"] }
|
tokio = { workspace = true, features = ["net", "sync", "time", "rt"] }
|
||||||
tokio-util = { workspace = true, features = ["codec"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
touch.workspace = true
|
touch = { workspace = true }
|
||||||
nonempty = { workspace = true, features = ["serialize"] }
|
nonempty = { workspace = true, features = ["serialize"] }
|
||||||
|
|
||||||
tracing = { workspace = true, features = ["attributes"] }
|
tracing = { workspace = true, features = ["attributes"] }
|
||||||
|
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
urlencoding.workspace = true
|
urlencoding = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||||
webauthn-rs = { workspace = true, features = ["resident-key-support", "preview-features", "danger-credential-internals"] }
|
webauthn-rs = { workspace = true, features = ["resident-key-support", "preview-features", "danger-credential-internals"] }
|
||||||
webauthn-rs-core.workspace = true
|
webauthn-rs-core = { workspace = true }
|
||||||
zxcvbn.workspace = true
|
zxcvbn = { workspace = true }
|
||||||
|
|
||||||
# because windows really can't build without the bundled one
|
# because windows really can't build without the bundled one
|
||||||
[target.'cfg(target_family = "windows")'.dependencies]
|
[target.'cfg(target_family = "windows")'.dependencies]
|
||||||
rusqlite = { workspace = true, features = ["bundled"] }
|
rusqlite = { workspace = true, features = ["bundled"] }
|
||||||
whoami.workspace = true
|
whoami = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
rusqlite.workspace = true
|
rusqlite = { workspace = true }
|
||||||
users.workspace = true
|
users = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# default = [ "libsqlite3-sys/bundled", "openssl/vendored" ]
|
# default = [ "libsqlite3-sys/bundled", "openssl/vendored" ]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
criterion = { workspace = true, features = ["html_reports"] }
|
criterion = { workspace = true, features = ["html_reports"] }
|
||||||
webauthn-authenticator-rs.workspace = true
|
webauthn-authenticator-rs = { workspace = true }
|
||||||
|
|
||||||
futures.workspace = true
|
futures = { workspace = true }
|
||||||
kanidmd_lib_macros.workspace = true
|
kanidmd_lib_macros = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
profiles.workspace = true
|
profiles = { workspace = true }
|
||||||
|
|
||||||
|
|
|
@ -1254,7 +1254,7 @@ impl<'a> BackendWriteTransaction<'a> {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
if entries.is_empty() {
|
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);
|
return Ok(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -815,7 +815,7 @@ impl AuthSession {
|
||||||
// of what's next, or ordering.
|
// of what's next, or ordering.
|
||||||
let valid_mechs = auth_session.valid_auth_mechs();
|
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);
|
let as_state = AuthState::Choose(valid_mechs);
|
||||||
(Some(auth_session), as_state)
|
(Some(auth_session), as_state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -39,7 +39,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
])))?;
|
])))?;
|
||||||
|
|
||||||
if rc.is_empty() {
|
if rc.is_empty() {
|
||||||
admin_info!("No recycled present - purge operation success");
|
admin_info!("No recycled items present - purge operation success");
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,8 +7,8 @@ edition = "2021"
|
||||||
proc-macro = true
|
proc-macro = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
proc-macro2.workspace = true
|
proc-macro2 = { workspace = true }
|
||||||
quote.workspace = true
|
quote = { workspace = true }
|
||||||
syn.workspace = true
|
syn = { workspace = true }
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3,40 +3,40 @@ name = "kanidmd_testkit"
|
||||||
description = "Kanidm Server Test Framework"
|
description = "Kanidm Server Test Framework"
|
||||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "kanidmd_testkit"
|
name = "kanidmd_testkit"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm_client.workspace = true
|
kanidm_client = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
kanidmd_core.workspace = true
|
kanidmd_core = { workspace = true }
|
||||||
kanidmd_lib.workspace = true
|
kanidmd_lib = { workspace = true }
|
||||||
|
|
||||||
|
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
reqwest = { workspace = true, default-features = false }
|
reqwest = { workspace = true, default-features = false }
|
||||||
sketching.workspace = true
|
sketching = { workspace = true }
|
||||||
testkit-macros.workspace = true
|
testkit-macros = { workspace = true }
|
||||||
tracing = { workspace = true, features = ["attributes"] }
|
tracing = { workspace = true, features = ["attributes"] }
|
||||||
tokio = { workspace = true, features = ["net", "sync", "io-util", "macros"] }
|
tokio = { workspace = true, features = ["net", "sync", "io-util", "macros"] }
|
||||||
|
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
profiles.workspace = true
|
profiles = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
compact_jwt.workspace = true
|
compact_jwt = { workspace = true }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
webauthn-authenticator-rs.workspace = true
|
webauthn-authenticator-rs = { workspace = true }
|
||||||
oauth2_ext = { workspace = true, default-features = false }
|
oauth2_ext = { workspace = true, default-features = false }
|
||||||
futures.workspace = true
|
futures = { workspace = true }
|
||||||
time.workspace = true
|
time = { workspace = true }
|
||||||
|
|
|
@ -22,9 +22,6 @@ repository = "https://github.com/kanidm/kanidm/"
|
||||||
# homepage = { workspace = true }
|
# homepage = { workspace = true }
|
||||||
# repository = { workspace = true }
|
# repository = { workspace = true }
|
||||||
|
|
||||||
# These are ignored because the crate is in a workspace
|
|
||||||
#[profile.release]
|
|
||||||
# less code to include into binary
|
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
crate-type = ["cdylib", "rlib"]
|
crate-type = ["cdylib", "rlib"]
|
||||||
|
@ -33,7 +30,6 @@ crate-type = ["cdylib", "rlib"]
|
||||||
compact_jwt = { workspace = true, default-features = false, features = ["unsafe_release_without_verify"] }
|
compact_jwt = { workspace = true, default-features = false, features = ["unsafe_release_without_verify"] }
|
||||||
# gloo = "^0.8.0"
|
# gloo = "^0.8.0"
|
||||||
gloo = { workspace = true }
|
gloo = { workspace = true }
|
||||||
gloo-net = { workspace = true }
|
|
||||||
js-sys = { workspace = true }
|
js-sys = { workspace = true }
|
||||||
kanidm_proto = { workspace = true, features = ["wasm"] }
|
kanidm_proto = { workspace = true, features = ["wasm"] }
|
||||||
qrcode = { workspace = true, features = ["svg"] }
|
qrcode = { workspace = true, features = ["svg"] }
|
||||||
|
|
|
@ -16,6 +16,11 @@ if [ -z "$(which rsync)" ]; then
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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
|
if [ "$(find ./pkg/ -name 'kanidmd*' | wc -l)" -gt 0 ]; then
|
||||||
echo "Cleaning up"
|
echo "Cleaning up"
|
||||||
rm pkg/kanidmd*
|
rm pkg/kanidmd*
|
||||||
|
@ -23,13 +28,10 @@ fi
|
||||||
|
|
||||||
# we can disable this since we want it to expand
|
# we can disable this since we want it to expand
|
||||||
# shellcheck disable=SC2086
|
# 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 && \
|
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 ./static/* ./pkg/ && \
|
||||||
rsync --delete-after -r --copy-links -v ./src/external/ ./pkg/external/ && \
|
|
||||||
cp ../../README.md ./pkg/
|
cp ../../README.md ./pkg/
|
||||||
cp ../../LICENSE.md ./pkg/
|
cp ../../LICENSE.md ./pkg/
|
||||||
cp ./src/style.css ./pkg/style.css && \
|
|
||||||
cp ./src/wasmloader.js ./pkg/wasmloader.js && \
|
|
||||||
rm ./pkg/.gitignore
|
rm ./pkg/.gitignore
|
||||||
|
|
|
@ -234,24 +234,24 @@ function addBorrowedObject(obj) {
|
||||||
}
|
}
|
||||||
function __wbg_adapter_48(arg0, arg1, arg2) {
|
function __wbg_adapter_48(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__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 {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
heap[stack_pointer++] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function __wbg_adapter_51(arg0, arg1, arg2) {
|
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 {
|
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 {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
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() {
|
export function run_app() {
|
||||||
|
@ -330,10 +330,6 @@ async function __wbg_load(module, imports) {
|
||||||
function __wbg_get_imports() {
|
function __wbg_get_imports() {
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
|
||||||
const ret = getObject(arg0) === undefined;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
imports.wbg.__wbindgen_string_get = function(arg0, arg1) {
|
||||||
const obj = getObject(arg1);
|
const obj = getObject(arg1);
|
||||||
const ret = typeof(obj) === 'string' ? obj : undefined;
|
const ret = typeof(obj) === 'string' ? obj : undefined;
|
||||||
|
@ -369,6 +365,10 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0);
|
const ret = getObject(arg0);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||||
|
const ret = getObject(arg0) === undefined;
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
imports.wbg.__wbindgen_in = function(arg0, arg1) {
|
||||||
const ret = getObject(arg0) in getObject(arg1);
|
const ret = getObject(arg0) in getObject(arg1);
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -643,20 +643,6 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_remove_8ae45e50cb58bb66 = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_remove_8ae45e50cb58bb66 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||||
}, arguments) };
|
}, 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) {
|
imports.wbg.__wbg_instanceof_Element_4622f5da1249a3eb = function(arg0) {
|
||||||
let result;
|
let result;
|
||||||
try {
|
try {
|
||||||
|
@ -711,10 +697,6 @@ function __wbg_get_imports() {
|
||||||
imports.wbg.__wbg_focus_dbcbbbb2a04c0e1f = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_focus_dbcbbbb2a04c0e1f = function() { return handleError(function (arg0) {
|
||||||
getObject(arg0).focus();
|
getObject(arg0).focus();
|
||||||
}, arguments) };
|
}, 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) {
|
imports.wbg.__wbg_get_2e9aab260014946d = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||||
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
const ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||||
var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
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) {
|
imports.wbg.__wbg_set_b34caba58723c454 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
}, arguments) };
|
}, 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) {
|
imports.wbg.__wbg_headers_b439dcff02e808e5 = function(arg0) {
|
||||||
const ret = getObject(arg0).headers;
|
const ret = getObject(arg0).headers;
|
||||||
return addHeapObject(ret);
|
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) {
|
imports.wbg.__wbg_newwithstrandinit_cad5cd6038c7ff5d = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, 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) {
|
imports.wbg.__wbg_create_c7e40b6b88186cbf = function() { return handleError(function (arg0, arg1) {
|
||||||
const ret = getObject(arg0).create(getObject(arg1));
|
const ret = getObject(arg0).create(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -782,10 +749,6 @@ function __wbg_get_imports() {
|
||||||
const ret = getObject(arg0).json();
|
const ret = getObject(arg0).json();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, 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) {
|
imports.wbg.__wbg_log_1d3ae0273d8f4f8a = function(arg0) {
|
||||||
console.log(getObject(arg0));
|
console.log(getObject(arg0));
|
||||||
};
|
};
|
||||||
|
@ -1090,10 +1053,6 @@ function __wbg_get_imports() {
|
||||||
const ret = Object.is(getObject(arg0), getObject(arg1));
|
const ret = Object.is(getObject(arg0), getObject(arg1));
|
||||||
return ret;
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_toString_a8e343996af880e9 = function(arg0) {
|
|
||||||
const ret = getObject(arg0).toString();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_resolve_53698b95aaf7fcf8 = function(arg0) {
|
imports.wbg.__wbg_resolve_53698b95aaf7fcf8 = function(arg0) {
|
||||||
const ret = Promise.resolve(getObject(arg0));
|
const ret = Promise.resolve(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -1159,16 +1118,16 @@ function __wbg_get_imports() {
|
||||||
const ret = wasm.memory;
|
const ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper4681 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper4628 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1097, __wbg_adapter_48);
|
const ret = makeMutClosure(arg0, arg1, 1074, __wbg_adapter_48);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper5482 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper5401 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1396, __wbg_adapter_51);
|
const ret = makeMutClosure(arg0, arg1, 1357, __wbg_adapter_51);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper5489 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper6520 = function(arg0, arg1, arg2) {
|
||||||
const ret = makeMutClosure(arg0, arg1, 1400, __wbg_adapter_54);
|
const ret = makeMutClosure(arg0, arg1, 1431, __wbg_adapter_54);
|
||||||
return addHeapObject(ret);
|
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::{
|
use crate::constants::{
|
||||||
CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_DT, CSS_TABLE,
|
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::views::AdminRoute;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
impl From<GetError> for AdminListAccountsMsg {
|
impl From<GetError> for AdminListAccountsMsg {
|
||||||
fn from(ge: GetError) -> Self {
|
fn from(ge: GetError) -> Self {
|
||||||
|
@ -93,24 +94,21 @@ pub async fn get_accounts() -> Result<AdminListAccountsMsg, GetError> {
|
||||||
];
|
];
|
||||||
|
|
||||||
for (endpoint, object_type) in endpoints {
|
for (endpoint, object_type) in endpoints {
|
||||||
let request = init_request(endpoint);
|
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||||
let response = match request.send().await {
|
Ok(val) => val,
|
||||||
Ok(value) => value,
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
err: format!("{:?}", error),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
#[allow(clippy::panic)]
|
// 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 response.json().await {
|
let data: Vec<Entity> = match serde_wasm_bindgen::from_value(value) {
|
||||||
Ok(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) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("Failed to grab the account data into JSON: {:?}", error),
|
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
|
/// pull the details for a single person by UUID
|
||||||
pub async fn get_person(uuid: &str) -> Result<AdminViewPersonMsg, GetError> {
|
pub async fn get_person(uuid: &str) -> Result<AdminViewPersonMsg, GetError> {
|
||||||
let request = init_request(format!("/v1/person/{}", uuid).as_str());
|
let (_, _, value, _) = match do_request(
|
||||||
let response = match request.send().await {
|
format!("/v1/person/{}", uuid).as_str(),
|
||||||
Ok(value) => value,
|
RequestMethod::GET,
|
||||||
|
None,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
Ok(val) => val,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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,
|
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 })
|
Ok(AdminViewPersonMsg::Responded { response: data })
|
||||||
}
|
}
|
||||||
|
|
||||||
/// pull the details for a single service_account by UUID
|
/// pull the details for a single service_account by UUID
|
||||||
pub async fn get_service_account(uuid: &str) -> Result<AdminViewServiceAccountMsg, GetError> {
|
pub async fn get_service_account(uuid: &str) -> Result<AdminViewServiceAccountMsg, GetError> {
|
||||||
let request = init_request(format!("/v1/service_account/{}", uuid).as_str());
|
let (_, _, value, _) = match do_request(
|
||||||
let response = match request.send().await {
|
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,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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 })
|
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::admin_menu::{Entity, EntityType, GetError};
|
||||||
use crate::components::alpha_warning_banner;
|
use crate::components::alpha_warning_banner;
|
||||||
use crate::constants::{CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_TABLE};
|
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::views::AdminRoute;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
impl From<GetError> for AdminListGroupsMsg {
|
impl From<GetError> for AdminListGroupsMsg {
|
||||||
fn from(ge: GetError) -> Self {
|
fn from(ge: GetError) -> Self {
|
||||||
|
@ -70,20 +71,23 @@ pub async fn get_groups() -> Result<AdminListGroupsMsg, GetError> {
|
||||||
let endpoints = [("/v1/group", EntityType::Group)];
|
let endpoints = [("/v1/group", EntityType::Group)];
|
||||||
|
|
||||||
for (endpoint, object_type) in endpoints {
|
for (endpoint, object_type) in endpoints {
|
||||||
let request = init_request(endpoint);
|
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||||
let response = match request.send().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,
|
Ok(value) => value,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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() {
|
for entity in data.iter() {
|
||||||
let mut new_entity = entity.to_owned();
|
let mut new_entity = entity.to_owned();
|
||||||
|
@ -360,19 +364,23 @@ impl Component for AdminViewGroup {
|
||||||
|
|
||||||
/// pull the details for a single group by UUID
|
/// pull the details for a single group by UUID
|
||||||
pub async fn get_group(groupid: &str) -> Result<AdminViewGroupMsg, GetError> {
|
pub async fn get_group(groupid: &str) -> Result<AdminViewGroupMsg, GetError> {
|
||||||
let request = init_request(format!("/v1/group/{}", groupid).as_str());
|
let endpoint = format!("/v1/group/{}", groupid);
|
||||||
let response = match request.send().await {
|
let (_, _, value, _) = match do_request(&endpoint, RequestMethod::GET, None).await {
|
||||||
Ok(value) => value,
|
Ok(val) => val,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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,
|
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 })
|
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::admin_menu::{Entity, EntityType, GetError};
|
||||||
use crate::components::alpha_warning_banner;
|
use crate::components::alpha_warning_banner;
|
||||||
use crate::constants::{CSS_BREADCRUMB_ITEM, CSS_BREADCRUMB_ITEM_ACTIVE, CSS_CELL, CSS_TABLE};
|
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::views::AdminRoute;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
impl From<GetError> for AdminListOAuth2Msg {
|
impl From<GetError> for AdminListOAuth2Msg {
|
||||||
fn from(ge: GetError) -> Self {
|
fn from(ge: GetError) -> Self {
|
||||||
|
@ -71,22 +72,25 @@ pub async fn get_entities() -> Result<AdminListOAuth2Msg, GetError> {
|
||||||
let endpoints = [("/v1/oauth2", EntityType::OAuth2RP)];
|
let endpoints = [("/v1/oauth2", EntityType::OAuth2RP)];
|
||||||
|
|
||||||
for (endpoint, object_type) in endpoints {
|
for (endpoint, object_type) in endpoints {
|
||||||
let request = init_request(endpoint);
|
let (_, _, value, _) = match do_request(endpoint, RequestMethod::GET, None).await {
|
||||||
let response = match request.send().await {
|
Ok(val) => val,
|
||||||
Ok(value) => value,
|
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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,
|
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();
|
let mut new_entity = entity.to_owned();
|
||||||
new_entity.object_type = object_type.clone();
|
new_entity.object_type = object_type.clone();
|
||||||
|
|
||||||
|
@ -96,8 +100,9 @@ pub async fn get_entities() -> Result<AdminListOAuth2Msg, GetError> {
|
||||||
.attrs
|
.attrs
|
||||||
.uuid
|
.uuid
|
||||||
.first()
|
.first()
|
||||||
.expect("Failed to grab the SPN for an account.");
|
.map(|e| e.to_owned())
|
||||||
oauth2_objects.insert(entity_id.to_string(), new_entity);
|
.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> {
|
pub async fn get_oauth2_rp(rs_name: &str) -> Result<AdminViewOAuth2Msg, GetError> {
|
||||||
let request = init_request(format!("/v1/oauth2/{}", rs_name).as_str());
|
let endpoint = format!("/v1/oauth2/{}", rs_name);
|
||||||
let response = match request.send().await {
|
let (_, _, value, _) = match do_request(&endpoint, RequestMethod::GET, None).await {
|
||||||
Ok(value) => value,
|
Ok(val) => val,
|
||||||
Err(error) => {
|
Err(error) => {
|
||||||
return Err(GetError {
|
return Err(GetError {
|
||||||
err: format!("{:?}", error),
|
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) => {
|
Ok(value) => {
|
||||||
console::log!(format!("{:?}", value));
|
console::log!(format!("{:?}", value));
|
||||||
value
|
value
|
||||||
|
|
|
@ -1,8 +1,7 @@
|
||||||
use kanidm_proto::v1::{SingleStringRequest, UserAuthToken};
|
use kanidm_proto::v1::{SingleStringRequest, UserAuthToken};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use web_sys::{FormData, HtmlFormElement};
|
||||||
use web_sys::{FormData, HtmlFormElement, Request, RequestInit, RequestMode, Response};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
|
@ -250,32 +249,14 @@ impl ChangeUnixPassword {
|
||||||
})
|
})
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to change request");
|
.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 uri = format!("/v1/person/{}/_unix/_credential", id);
|
||||||
|
let (kopid, status, value, _) =
|
||||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
crate::do_request(&uri, crate::RequestMethod::PUT, Some(changereq_jsvalue)).await?;
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
Ok(Msg::Success)
|
Ok(Msg::Success)
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,9 +10,6 @@ use wasm_bindgen::UnwrapThrowExt;
|
||||||
use web_sys::Node;
|
use web_sys::Node;
|
||||||
|
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use wasm_bindgen::JsCast;
|
|
||||||
use wasm_bindgen_futures::JsFuture;
|
|
||||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Valid,
|
Valid,
|
||||||
|
@ -237,35 +234,17 @@ impl Component for CreateResetCode {
|
||||||
|
|
||||||
impl CreateResetCode {
|
impl CreateResetCode {
|
||||||
async fn credential_get_update_intent_token(id: String) -> Result<Msg, FetchError> {
|
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 uri = format!("/v1/person/{}/_credential/_update_intent?ttl=0", id);
|
||||||
|
|
||||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
let (kopid, status, value, _) =
|
||||||
|
crate::do_request(&uri, crate::RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let token: CUIntentToken =
|
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 })
|
Ok(Msg::Ready { token })
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
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 jsval_json = JsFuture::from(resp.json()?).await?;
|
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
||||||
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 yew::prelude::*;
|
||||||
|
|
||||||
use super::reset::{EventBusMsg, ModalProps};
|
use super::reset::{EventBusMsg, ModalProps};
|
||||||
|
use crate::do_request;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use crate::RequestMethod;
|
||||||
|
|
||||||
enum State {
|
enum State {
|
||||||
Init,
|
Init,
|
||||||
|
@ -50,37 +50,21 @@ impl DeleteApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_update",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
|
Some(req_jsvalue),
|
||||||
opts.body(Some(&req_jsvalue));
|
)
|
||||||
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let custatus: CUStatus =
|
||||||
let status: CUStatus =
|
serde_wasm_bindgen::from_value(value).expect_throw("Invalid response type");
|
||||||
serde_wasm_bindgen::from_value(jsval).expect_throw("Invalid response type");
|
|
||||||
|
|
||||||
cb.emit(EventBusMsg::UpdateStatus { status });
|
cb.emit(EventBusMsg::UpdateStatus { status: custatus });
|
||||||
|
|
||||||
Ok(Msg::Success)
|
Ok(Msg::Success)
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,13 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
||||||
use kanidm_proto::webauthn::{CreationChallengeResponse, RegisterPublicKeyCredential};
|
use kanidm_proto::webauthn::{CreationChallengeResponse, RegisterPublicKeyCredential};
|
||||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use wasm_bindgen_futures::JsFuture;
|
||||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use super::reset::{EventBusMsg, ModalProps};
|
use super::reset::{EventBusMsg, ModalProps};
|
||||||
use crate::error::*;
|
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use crate::{do_request, error::*, RequestMethod};
|
||||||
|
|
||||||
pub struct PasskeyModalApp {
|
pub struct PasskeyModalApp {
|
||||||
state: State,
|
state: State,
|
||||||
|
@ -61,30 +60,16 @@ impl PasskeyModalApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_update",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
|
Some(req_jsvalue),
|
||||||
opts.body(Some(&req_jsvalue));
|
)
|
||||||
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: CUStatus =
|
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 {
|
cb.emit(EventBusMsg::UpdateStatus {
|
||||||
status: status.clone(),
|
status: status.clone(),
|
||||||
|
@ -102,8 +87,7 @@ impl PasskeyModalApp {
|
||||||
CURegState::None => Msg::Success,
|
CURegState::None => Msg::Success,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,13 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
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 yew::prelude::*;
|
||||||
|
|
||||||
use super::reset::{EventBusMsg, PasskeyRemoveModalProps};
|
use super::reset::{EventBusMsg, PasskeyRemoveModalProps};
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
pub struct PasskeyRemoveModalApp {
|
pub struct PasskeyRemoveModalApp {
|
||||||
state: State,
|
state: State,
|
||||||
|
@ -70,30 +69,17 @@ impl PasskeyRemoveModalApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
// this really should require a DELETE not a post!
|
||||||
opts.method("POST");
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.mode(RequestMode::SameOrigin);
|
"/v1/credential/_update",
|
||||||
|
RequestMethod::POST,
|
||||||
opts.body(Some(&req_jsvalue));
|
Some(req_jsvalue),
|
||||||
|
)
|
||||||
let request = Request::new_with_str_and_init("/v1/credential/_update", &opts)?;
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: CUStatus =
|
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 {
|
cb.emit(EventBusMsg::UpdateStatus {
|
||||||
status: status.clone(),
|
status: status.clone(),
|
||||||
|
@ -111,8 +97,7 @@ impl PasskeyRemoveModalApp {
|
||||||
CURegState::None => Msg::Success,
|
CURegState::None => Msg::Success,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus, OperationError, PasswordFeedback};
|
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus, OperationError, PasswordFeedback};
|
||||||
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 yew::prelude::*;
|
||||||
|
|
||||||
use super::reset::{EventBusMsg, ModalProps};
|
use super::reset::{EventBusMsg, ModalProps};
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
enum PwState {
|
enum PwState {
|
||||||
Init,
|
Init,
|
||||||
|
@ -57,38 +57,24 @@ impl PwModalApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn submit_password_update(token: CUSessionToken, pw: String) -> Result<Msg, FetchError> {
|
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))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_update",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
|
Some(req_jsvalue),
|
||||||
opts.body(Some(&intentreq_jsvalue));
|
)
|
||||||
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: CUStatus =
|
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 })
|
Ok(Msg::PasswordResponseSuccess { status })
|
||||||
} else if status == 400 {
|
} else if status == 400 {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: OperationError =
|
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 {
|
match status {
|
||||||
OperationError::PasswordQuality(feedback) => {
|
OperationError::PasswordQuality(feedback) => {
|
||||||
Ok(Msg::PasswordResponseQuality { feedback })
|
Ok(Msg::PasswordResponseQuality { feedback })
|
||||||
|
@ -99,9 +85,7 @@ impl PwModalApp {
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,9 +3,7 @@ use kanidm_proto::v1::{
|
||||||
CUIntentToken, CUSessionToken, CUStatus, CredentialDetail, CredentialDetailType,
|
CUIntentToken, CUSessionToken, CUStatus, CredentialDetail, CredentialDetailType,
|
||||||
};
|
};
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
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 yew::prelude::*;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
|
@ -15,7 +13,7 @@ use super::passkeyremove::PasskeyRemoveModalApp;
|
||||||
use super::pwmodal::PwModalApp;
|
use super::pwmodal::PwModalApp;
|
||||||
use super::totpmodal::TotpModalApp;
|
use super::totpmodal::TotpModalApp;
|
||||||
use super::totpremove::TotpRemoveComp;
|
use super::totpremove::TotpRemoveComp;
|
||||||
use crate::error::*;
|
use crate::{do_request, error::*, RequestMethod};
|
||||||
use crate::{models, utils};
|
use crate::{models, utils};
|
||||||
|
|
||||||
// use std::rc::Rc;
|
// use std::rc::Rc;
|
||||||
|
@ -577,37 +575,23 @@ impl CredentialResetApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn exchange_intent_token(token: String) -> Result<Msg, FetchError> {
|
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))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise intent request");
|
.expect_throw("Failed to serialise intent request");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_exchange_intent",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
|
Some(req_jsvalue),
|
||||||
opts.body(Some(&intentreq_jsvalue));
|
)
|
||||||
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let (token, status): (CUSessionToken, CUStatus) =
|
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 })
|
Ok(Msg::BeginSession { token, status })
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -617,30 +601,13 @@ impl CredentialResetApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise session token");
|
.expect_throw("Failed to serialise session token");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("POST");
|
do_request(url, RequestMethod::POST, Some(req_jsvalue)).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
Ok(Msg::Success)
|
Ok(Msg::Success)
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,14 +3,14 @@ use gloo::console;
|
||||||
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus, TotpSecret};
|
use kanidm_proto::v1::{CURegState, CURequest, CUSessionToken, CUStatus, TotpSecret};
|
||||||
use qrcode::render::svg;
|
use qrcode::render::svg;
|
||||||
use qrcode::QrCode;
|
use qrcode::QrCode;
|
||||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
use web_sys::Node;
|
||||||
use web_sys::{Node, Request, RequestCredentials, RequestInit, RequestMode, Response};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
use super::reset::{EventBusMsg, ModalProps};
|
use super::reset::{EventBusMsg, ModalProps};
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::utils;
|
use crate::utils;
|
||||||
|
use crate::{do_request, RequestMethod};
|
||||||
|
|
||||||
enum TotpState {
|
enum TotpState {
|
||||||
Init,
|
Init,
|
||||||
|
@ -74,31 +74,15 @@ impl TotpModalApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_update",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
opts.credentials(RequestCredentials::SameOrigin);
|
Some(req_jsvalue),
|
||||||
|
)
|
||||||
opts.body(Some(&req_jsvalue));
|
.await?;
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: CUStatus =
|
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 {
|
cb.emit(EventBusMsg::UpdateStatus {
|
||||||
status: status.clone(),
|
status: status.clone(),
|
||||||
|
@ -115,8 +99,7 @@ impl TotpModalApp {
|
||||||
CURegState::TotpInvalidSha1 => Msg::TotpInvalidSha1,
|
CURegState::TotpInvalidSha1 => Msg::TotpInvalidSha1,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,12 +2,11 @@ use super::reset::{EventBusMsg, TotpRemoveProps};
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
use kanidm_proto::v1::{CURequest, CUSessionToken, CUStatus};
|
||||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
use wasm_bindgen::{JsValue, UnwrapThrowExt};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
|
||||||
use web_sys::{Request, RequestInit, RequestMode, Response};
|
|
||||||
|
|
||||||
|
use crate::do_request;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::utils;
|
use crate::RequestMethod;
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
pub enum Msg {
|
pub enum Msg {
|
||||||
|
@ -108,37 +107,21 @@ impl TotpRemoveComp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise pw curequest");
|
.expect_throw("Failed to serialise pw curequest");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request(
|
||||||
opts.method("POST");
|
"/v1/credential/_update",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
|
Some(req_jsvalue),
|
||||||
opts.body(Some(&req_jsvalue));
|
)
|
||||||
|
.await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let status: CUStatus =
|
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 });
|
cb.emit(EventBusMsg::UpdateStatus { status });
|
||||||
|
|
||||||
Ok(Msg::Success)
|
Ok(Msg::Success)
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,11 @@
|
||||||
#![deny(clippy::needless_pass_by_value)]
|
#![deny(clippy::needless_pass_by_value)]
|
||||||
#![deny(clippy::trivially_copy_pass_by_ref)]
|
#![deny(clippy::trivially_copy_pass_by_ref)]
|
||||||
|
|
||||||
|
use error::FetchError;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
|
use wasm_bindgen_futures::JsFuture;
|
||||||
|
use web_sys::{Headers, Request, RequestInit, RequestMode, Response};
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod macros;
|
mod macros;
|
||||||
|
@ -35,3 +39,57 @@ pub fn run_app() -> Result<(), JsValue> {
|
||||||
gloo::console::debug!(kanidm_proto::utils::get_version("kanidmd_web_ui"));
|
gloo::console::debug!(kanidm_proto::utils::get_version("kanidmd_web_ui"));
|
||||||
Ok(())
|
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 kanidm_proto::webauthn::PublicKeyCredential;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::JsCast;
|
|
||||||
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
use wasm_bindgen_futures::{spawn_local, JsFuture};
|
||||||
use web_sys::{
|
use web_sys::CredentialRequestOptions;
|
||||||
CredentialRequestOptions, Request, RequestCredentials, RequestInit, RequestMode, Response,
|
|
||||||
};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew::virtual_dom::VNode;
|
use yew::virtual_dom::VNode;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
use crate::constants::{CLASS_BUTTON_DARK, CLASS_DIV_LOGIN_BUTTON, CLASS_DIV_LOGIN_FIELD};
|
use crate::constants::{CLASS_BUTTON_DARK, CLASS_DIV_LOGIN_BUTTON, CLASS_DIV_LOGIN_FIELD};
|
||||||
use crate::error::FetchError;
|
use crate::error::FetchError;
|
||||||
use crate::{models, utils};
|
use crate::{do_request, models, utils, RequestMethod};
|
||||||
|
|
||||||
pub struct LoginApp {
|
pub struct LoginApp {
|
||||||
state: LoginState,
|
state: LoginState,
|
||||||
|
@ -105,48 +102,26 @@ impl LoginApp {
|
||||||
issue: AuthIssueSession::Cookie,
|
issue: AuthIssueSession::Cookie,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
let authreq_jsvalue = serde_json::to_string(&authreq)
|
let req_jsvalue = serde_json::to_string(&authreq)
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise authreq");
|
.expect_throw("Failed to serialise authreq");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("POST");
|
do_request("/v1/auth", RequestMethod::POST, Some(req_jsvalue)).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||||
Ok(LoginAppMsg::Start(state))
|
Ok(LoginAppMsg::Start(state))
|
||||||
} else if status == 404 {
|
} else if status == 404 {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
console::error!(format!(
|
console::error!(format!(
|
||||||
"User not found: {:?}. Operation ID: {:?}",
|
"User not found: {:?}. Operation ID: {:?}",
|
||||||
text, kopid
|
value.as_string().unwrap_or_default(),
|
||||||
|
kopid
|
||||||
));
|
));
|
||||||
Ok(LoginAppMsg::UnknownUser)
|
Ok(LoginAppMsg::UnknownUser)
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(LoginAppMsg::Error { emsg, kopid })
|
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,45 +131,23 @@ impl LoginApp {
|
||||||
let authreq_jsvalue = serde_json::to_string(&issue)
|
let authreq_jsvalue = serde_json::to_string(&issue)
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise authreq");
|
.expect_throw("Failed to serialise authreq");
|
||||||
|
let url = "/v1/reauth";
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("POST");
|
do_request(url, RequestMethod::POST, Some(authreq_jsvalue)).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||||
Ok(LoginAppMsg::Next(state))
|
Ok(LoginAppMsg::Next(state))
|
||||||
} else if status == 404 {
|
} else if status == 404 {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
console::error!(format!(
|
console::error!(format!(
|
||||||
"User not found: {:?}. Operation ID: {:?}",
|
"User not found: {:?}. Operation ID: {:?}",
|
||||||
text, kopid
|
value.as_string(),
|
||||||
|
kopid
|
||||||
));
|
));
|
||||||
Ok(LoginAppMsg::UnknownUser)
|
Ok(LoginAppMsg::UnknownUser)
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(LoginAppMsg::Error { emsg, kopid })
|
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -204,30 +157,11 @@ impl LoginApp {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise authreq");
|
.expect_throw("Failed to serialise authreq");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("POST");
|
do_request("/v1/auth", RequestMethod::POST, Some(authreq_jsvalue)).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let state: AuthResponse = serde_wasm_bindgen::from_value(value)
|
||||||
let state: AuthResponse = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
console::error!(format!("auth_step::AuthResponse: {:?}", e));
|
console::error!(format!("auth_step::AuthResponse: {:?}", e));
|
||||||
e
|
e
|
||||||
|
@ -235,9 +169,7 @@ impl LoginApp {
|
||||||
.expect_throw("Invalid response type - auth_step::AuthResponse");
|
.expect_throw("Invalid response type - auth_step::AuthResponse");
|
||||||
Ok(LoginAppMsg::Next(state))
|
Ok(LoginAppMsg::Next(state))
|
||||||
} else {
|
} else {
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
let emsg = value.as_string()
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string()
|
|
||||||
.unwrap_or_else(|| "Unhandled error, please report this along with the operation ID below to your administrator. 😔".to_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 })
|
Ok(LoginAppMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
|
@ -247,6 +179,7 @@ impl LoginApp {
|
||||||
fn button_start_again(&self, ctx: &Context<Self>) -> VNode {
|
fn button_start_again(&self, ctx: &Context<Self>) -> VNode {
|
||||||
html! {
|
html! {
|
||||||
<div class="col-md-auto text-center">
|
<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>
|
<button type="button" class={CLASS_BUTTON_DARK} onclick={ ctx.link().callback(|_| LoginAppMsg::Restart) } >{" Start Again "}</button>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,3 @@
|
||||||
// use anyhow::Error;
|
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
pub use kanidm_proto::oauth2::{
|
pub use kanidm_proto::oauth2::{
|
||||||
AccessTokenRequest, AccessTokenResponse, AuthorisationRequest, AuthorisationResponse,
|
AccessTokenRequest, AccessTokenResponse, AuthorisationRequest, AuthorisationResponse,
|
||||||
|
@ -6,12 +5,12 @@ pub use kanidm_proto::oauth2::{
|
||||||
};
|
};
|
||||||
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
use wasm_bindgen::{JsCast, JsValue, UnwrapThrowExt};
|
||||||
use wasm_bindgen_futures::JsFuture;
|
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::prelude::*;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
use crate::error::*;
|
|
||||||
use crate::manager::Route;
|
use crate::manager::Route;
|
||||||
|
use crate::{do_request, error::*, RequestMethod};
|
||||||
use crate::{models, utils};
|
use crate::{models, utils};
|
||||||
|
|
||||||
use std::collections::BTreeSet;
|
use std::collections::BTreeSet;
|
||||||
|
@ -70,31 +69,15 @@ impl From<FetchError> for Oauth2Msg {
|
||||||
|
|
||||||
impl Oauth2App {
|
impl Oauth2App {
|
||||||
async fn fetch_session_valid() -> Result<Oauth2Msg, FetchError> {
|
async fn fetch_session_valid() -> Result<Oauth2Msg, FetchError> {
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("GET");
|
do_request("/v1/auth/valid", RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
Ok(Oauth2Msg::TokenValid)
|
Ok(Oauth2Msg::TokenValid)
|
||||||
} else if status == 401 {
|
} else if status == 401 {
|
||||||
Ok(Oauth2Msg::LoginRequired)
|
Ok(Oauth2Msg::LoginRequired)
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
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 jsval_json = JsFuture::from(resp.json()?).await?;
|
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||||
Ok(Oauth2Msg::Error { emsg, kopid })
|
Ok(Oauth2Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
|
@ -105,29 +88,15 @@ impl Oauth2App {
|
||||||
.map(|s| JsValue::from(&s))
|
.map(|s| JsValue::from(&s))
|
||||||
.expect_throw("Failed to serialise authreq");
|
.expect_throw("Failed to serialise authreq");
|
||||||
|
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, headers) = do_request(
|
||||||
opts.method("POST");
|
"/oauth2/authorise",
|
||||||
opts.mode(RequestMode::SameOrigin);
|
RequestMethod::POST,
|
||||||
opts.credentials(RequestCredentials::SameOrigin);
|
Some(authreq_jsvalue),
|
||||||
|
)
|
||||||
opts.body(Some(&authreq_jsvalue));
|
.await?;
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let state: AuthorisationResponse = serde_wasm_bindgen::from_value(value)
|
||||||
let state: AuthorisationResponse = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e_msg = format!("serde error -> {:?}", e);
|
let e_msg = format!("serde error -> {:?}", e);
|
||||||
console::error!(e_msg.as_str());
|
console::error!(e_msg.as_str());
|
||||||
|
@ -159,8 +128,7 @@ impl Oauth2App {
|
||||||
} else if status == 403 {
|
} else if status == 403 {
|
||||||
Ok(Oauth2Msg::AccessDenied { kopid })
|
Ok(Oauth2Msg::AccessDenied { kopid })
|
||||||
} else {
|
} else {
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Oauth2Msg::Error { emsg, kopid })
|
Ok(Oauth2Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -173,8 +141,7 @@ impl Oauth2App {
|
||||||
let mut opts = RequestInit::new();
|
let mut opts = RequestInit::new();
|
||||||
opts.method("POST");
|
opts.method("POST");
|
||||||
opts.mode(RequestMode::SameOrigin);
|
opts.mode(RequestMode::SameOrigin);
|
||||||
opts.redirect(RequestRedirect::Manual);
|
opts.redirect(RequestRedirect::Manual); // can't replace with do_request because of this
|
||||||
opts.credentials(RequestCredentials::SameOrigin);
|
|
||||||
|
|
||||||
opts.body(Some(&consentreq_jsvalue));
|
opts.body(Some(&consentreq_jsvalue));
|
||||||
|
|
||||||
|
|
|
@ -1,10 +1,9 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use gloo_net::http::Request;
|
|
||||||
use url::Url;
|
use url::Url;
|
||||||
use wasm_bindgen::prelude::*;
|
use wasm_bindgen::prelude::*;
|
||||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
||||||
pub use web_sys::InputEvent;
|
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::virtual_dom::VNode;
|
||||||
use yew::{html, Html};
|
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 {
|
pub fn do_alert_error(alert_title: &str, alert_message: Option<&str>) -> Html {
|
||||||
html! {
|
html! {
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
|
|
@ -4,11 +4,8 @@ use yew::prelude::*;
|
||||||
|
|
||||||
use crate::constants::{CSS_CARD, CSS_LINK_DARK_STRETCHED, CSS_PAGE_HEADER};
|
use crate::constants::{CSS_CARD, CSS_LINK_DARK_STRETCHED, CSS_PAGE_HEADER};
|
||||||
use crate::error::FetchError;
|
use crate::error::FetchError;
|
||||||
use crate::utils;
|
use crate::{do_request, RequestMethod};
|
||||||
use wasm_bindgen::prelude::*;
|
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;
|
use kanidm_proto::internal::AppLink;
|
||||||
|
|
||||||
|
@ -182,33 +179,15 @@ impl AppsApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_user_apps() -> Result<Msg, FetchError> {
|
async fn fetch_user_apps() -> Result<Msg, FetchError> {
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("GET");
|
do_request("/v1/self/_applinks", RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let apps: Vec<AppLink> = serde_wasm_bindgen::from_value(value)
|
||||||
let apps: Vec<AppLink> = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
.expect_throw("Invalid response type - auth_init::AuthResponse");
|
||||||
Ok(Msg::Ready { apps })
|
Ok(Msg::Ready { apps })
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(Msg::Error { emsg, kopid })
|
Ok(Msg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,16 +1,14 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{UiHint, UserAuthToken};
|
use kanidm_proto::v1::{UiHint, UserAuthToken};
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
|
||||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
use crate::components::{admin_accounts, admin_groups, admin_menu, admin_oauth2};
|
use crate::components::{admin_accounts, admin_groups, admin_menu, admin_oauth2};
|
||||||
use crate::error::*;
|
|
||||||
use crate::manager::Route;
|
use crate::manager::Route;
|
||||||
use crate::{models, utils};
|
use crate::models;
|
||||||
|
use crate::{do_request, error::*, RequestMethod};
|
||||||
|
|
||||||
mod apps;
|
mod apps;
|
||||||
mod profile;
|
mod profile;
|
||||||
|
@ -328,62 +326,25 @@ impl ViewsApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn check_session_valid() -> Result<ViewsMsg, FetchError> {
|
async fn check_session_valid() -> Result<ViewsMsg, FetchError> {
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("GET");
|
do_request("/v1/auth/valid", RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
Ok(ViewsMsg::Verified)
|
Ok(ViewsMsg::Verified)
|
||||||
} else if status == 401 {
|
} else if status == 401 {
|
||||||
Ok(ViewsMsg::LogoutComplete)
|
Ok(ViewsMsg::LogoutComplete)
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(ViewsMsg::Error { emsg, kopid })
|
Ok(ViewsMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_user_data() -> Result<ViewsMsg, FetchError> {
|
async fn fetch_user_data() -> Result<ViewsMsg, FetchError> {
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) =
|
||||||
opts.method("GET");
|
do_request("/v1/self/_uat", RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
let uat: UserAuthToken = serde_wasm_bindgen::from_value(value)
|
||||||
let uat: UserAuthToken = serde_wasm_bindgen::from_value(jsval)
|
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
let e_msg = format!("serde error -> {:?}", e);
|
let e_msg = format!("serde error -> {:?}", e);
|
||||||
console::error!(e_msg.as_str());
|
console::error!(e_msg.as_str());
|
||||||
|
@ -392,39 +353,18 @@ impl ViewsApp {
|
||||||
|
|
||||||
Ok(ViewsMsg::ProfileInfoReceived { uat })
|
Ok(ViewsMsg::ProfileInfoReceived { uat })
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(ViewsMsg::Error { emsg, kopid })
|
Ok(ViewsMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn fetch_logout() -> Result<ViewsMsg, FetchError> {
|
async fn fetch_logout() -> Result<ViewsMsg, FetchError> {
|
||||||
let mut opts = RequestInit::new();
|
let (kopid, status, value, _) = do_request("/v1/logout", RequestMethod::GET, None).await?;
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
Ok(ViewsMsg::LogoutComplete)
|
Ok(ViewsMsg::LogoutComplete)
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
let kopid = headers.get("x-kanidm-opid").ok().flatten();
|
|
||||||
let text = JsFuture::from(resp.text()?).await?;
|
|
||||||
let emsg = text.as_string().unwrap_or_default();
|
|
||||||
Ok(ViewsMsg::Error { emsg, kopid })
|
Ok(ViewsMsg::Error { emsg, kopid })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,9 +2,7 @@
|
||||||
use gloo::console;
|
use gloo::console;
|
||||||
use kanidm_proto::v1::{CUSessionToken, CUStatus, UiHint, UserAuthToken};
|
use kanidm_proto::v1::{CUSessionToken, CUStatus, UiHint, UserAuthToken};
|
||||||
use time::format_description::well_known::Rfc3339;
|
use time::format_description::well_known::Rfc3339;
|
||||||
use wasm_bindgen::{JsCast, UnwrapThrowExt};
|
use wasm_bindgen::UnwrapThrowExt;
|
||||||
use wasm_bindgen_futures::JsFuture;
|
|
||||||
use web_sys::{Request, RequestCredentials, RequestInit, RequestMode, Response};
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
use yew_router::prelude::*;
|
use yew_router::prelude::*;
|
||||||
|
|
||||||
|
@ -13,8 +11,8 @@ use crate::components::create_reset_code::CreateResetCode;
|
||||||
use crate::constants::CSS_PAGE_HEADER;
|
use crate::constants::CSS_PAGE_HEADER;
|
||||||
use crate::error::*;
|
use crate::error::*;
|
||||||
use crate::manager::Route;
|
use crate::manager::Route;
|
||||||
|
use crate::models;
|
||||||
use crate::views::{ViewProps, ViewRoute};
|
use crate::views::{ViewProps, ViewRoute};
|
||||||
use crate::{models, utils};
|
|
||||||
|
|
||||||
#[allow(clippy::large_enum_variant)]
|
#[allow(clippy::large_enum_variant)]
|
||||||
// Page state
|
// Page state
|
||||||
|
@ -240,35 +238,16 @@ impl ProfileApp {
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn request_credential_update(id: String) -> Result<Msg, FetchError> {
|
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 uri = format!("/v1/person/{}/_credential/_update", id);
|
||||||
|
let (kopid, status, value, _headers) =
|
||||||
let request = Request::new_with_str_and_init(uri.as_str(), &opts)?;
|
crate::do_request(&uri, crate::RequestMethod::GET, None).await?;
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
if status == 200 {
|
if status == 200 {
|
||||||
let jsval = JsFuture::from(resp.json()?).await?;
|
|
||||||
let (token, status): (CUSessionToken, CUStatus) =
|
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 })
|
Ok(Msg::BeginCredentialUpdate { token, status })
|
||||||
} else {
|
} else {
|
||||||
let headers = resp.headers();
|
let emsg = value.as_string().unwrap_or_default();
|
||||||
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 jsval_json = JsFuture::from(resp.json()?).await?;
|
// let jsval_json = JsFuture::from(resp.json()?).await?;
|
||||||
Ok(Msg::Error { emsg, kopid })
|
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"
|
description = "Kanidm Client Tools"
|
||||||
documentation = "https://kanidm.github.io/kanidm/stable/"
|
documentation = "https://kanidm.github.io/kanidm/stable/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64urlsafedata.workspace = true
|
base64urlsafedata = { workspace = true }
|
||||||
clap = { workspace = true, features = ["derive", "env"] }
|
clap = { workspace = true, features = ["derive", "env"] }
|
||||||
chrono.workspace = true
|
chrono = { workspace = true }
|
||||||
cron.workspace = true
|
cron = { workspace = true }
|
||||||
kanidm_client.workspace = true
|
kanidm_client = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
||||||
|
|
||||||
|
|
||||||
ldap3_client.workspace = true
|
ldap3_client = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
uuid = { workspace = true, features = ["serde"] }
|
uuid = { workspace = true, features = ["serde"] }
|
||||||
|
|
||||||
# For file metadata, should this me moved out?
|
# For file metadata, should this me moved out?
|
||||||
kanidmd_lib.workspace = true
|
kanidmd_lib = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_family = "unix")'.dependencies]
|
[target.'cfg(target_family = "unix")'.dependencies]
|
||||||
users.workspace = true
|
users = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
clap = { workspace = true, features = ["derive"] }
|
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"
|
description = "Kanidm Client Tools"
|
||||||
documentation = "https://kanidm.github.io/kanidm/stable/"
|
documentation = "https://kanidm.github.io/kanidm/stable/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
base64urlsafedata.workspace = true
|
base64urlsafedata = { workspace = true }
|
||||||
clap = { workspace = true, features = ["derive", "env"] }
|
clap = { workspace = true, features = ["derive", "env"] }
|
||||||
chrono.workspace = true
|
chrono = { workspace = true }
|
||||||
cron.workspace = true
|
cron = { workspace = true }
|
||||||
kanidm_client.workspace = true
|
kanidm_client = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
tokio = { workspace = true, features = ["rt", "macros", "net"] }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
tracing-subscriber = { workspace = true, features = ["env-filter", "fmt"] }
|
||||||
|
|
||||||
|
|
||||||
ldap3_client.workspace = true
|
ldap3_client = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
url = { workspace = true, features = ["serde"] }
|
url = { workspace = true, features = ["serde"] }
|
||||||
uuid = { workspace = true, features = ["serde"] }
|
uuid = { workspace = true, features = ["serde"] }
|
||||||
|
|
||||||
# For file metadata, should this me moved out?
|
# For file metadata, should this me moved out?
|
||||||
kanidmd_lib.workspace = true
|
kanidmd_lib = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(target_family = "unix")'.dependencies]
|
[target.'cfg(target_family = "unix")'.dependencies]
|
||||||
users.workspace = true
|
users = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
clap = { workspace = true, features = ["derive"] }
|
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"
|
description = "Orca - load testing for LDAP and Kanidm"
|
||||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[[bin]]
|
[[bin]]
|
||||||
name = "orca"
|
name = "orca"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
clap.workspace = true
|
clap = { workspace = true }
|
||||||
crossbeam.workspace = true
|
crossbeam = { workspace = true }
|
||||||
csv.workspace = true
|
csv = { workspace = true }
|
||||||
dialoguer.workspace = true
|
dialoguer = { workspace = true }
|
||||||
futures-util = { workspace = true, features = ["sink"] }
|
futures-util = { workspace = true, features = ["sink"] }
|
||||||
kanidm_client.workspace = true
|
kanidm_client = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
ldap3_proto.workspace = true
|
ldap3_proto = { workspace = true }
|
||||||
mathru.workspace = true
|
mathru = { workspace = true }
|
||||||
openssl.workspace = true
|
openssl = { workspace = true }
|
||||||
rand.workspace = true
|
rand = { workspace = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["rt-multi-thread"] }
|
tokio = { workspace = true, features = ["rt-multi-thread"] }
|
||||||
tokio-openssl.workspace = true
|
tokio-openssl = { workspace = true }
|
||||||
tokio-util = { workspace = true, features = ["codec"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
tracing-subscriber.workspace = true
|
tracing-subscriber = { workspace = true }
|
||||||
uuid = { workspace = true, features = ["serde", "v4" ] }
|
uuid = { workspace = true, features = ["serde", "v4" ] }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
tikv-jemallocator.workspace = true
|
tikv-jemallocator = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
profiles.workspace = true
|
profiles = { workspace = true }
|
||||||
|
|
|
@ -3,13 +3,13 @@ name = "kanidm_unix_int"
|
||||||
description = "Kanidm Unix Integration Clients"
|
description = "Kanidm Unix Integration Clients"
|
||||||
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
documentation = "https://docs.rs/kanidm/latest/kanidm/"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["unix"]
|
default = ["unix"]
|
||||||
|
@ -42,40 +42,40 @@ name = "kanidm_unix_common"
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
bytes.workspace = true
|
bytes = { workspace = true }
|
||||||
clap = { workspace = true, features = ["derive", "env"] }
|
clap = { workspace = true, features = ["derive", "env"] }
|
||||||
csv.workspace = true
|
csv = { workspace = true }
|
||||||
futures.workspace = true
|
futures = { workspace = true }
|
||||||
libc.workspace = true
|
libc = { workspace = true }
|
||||||
libsqlite3-sys.workspace = true
|
libsqlite3-sys = { workspace = true }
|
||||||
lru.workspace = true
|
lru = { workspace = true }
|
||||||
kanidm_client.workspace = true
|
kanidm_client = { workspace = true }
|
||||||
kanidm_proto.workspace = true
|
kanidm_proto = { workspace = true }
|
||||||
kanidm_lib_crypto.workspace = true
|
kanidm_lib_crypto = { workspace = true }
|
||||||
kanidm_lib_file_permissions.workspace = true
|
kanidm_lib_file_permissions = { workspace = true }
|
||||||
notify-debouncer-full.workspace = true
|
notify-debouncer-full = { workspace = true }
|
||||||
rpassword.workspace = true
|
rpassword = { workspace = true }
|
||||||
rusqlite.workspace = true
|
rusqlite = { workspace = true }
|
||||||
selinux = { workspace = true, optional = true }
|
selinux = { workspace = true, optional = true }
|
||||||
serde = { workspace = true, features = ["derive"] }
|
serde = { workspace = true, features = ["derive"] }
|
||||||
serde_json.workspace = true
|
serde_json = { workspace = true }
|
||||||
sketching.workspace = true
|
sketching = { workspace = true }
|
||||||
|
|
||||||
toml.workspace = true
|
toml = { workspace = true }
|
||||||
tokio = { workspace = true, features = ["rt", "fs", "macros", "sync", "time", "net", "io-util"] }
|
tokio = { workspace = true, features = ["rt", "fs", "macros", "sync", "time", "net", "io-util"] }
|
||||||
tokio-util = { workspace = true, features = ["codec"] }
|
tokio-util = { workspace = true, features = ["codec"] }
|
||||||
tracing.workspace = true
|
tracing = { workspace = true }
|
||||||
tss-esapi = { workspace = true, optional = true }
|
tss-esapi = { workspace = true, optional = true }
|
||||||
reqwest = { workspace = true, default-features = false }
|
reqwest = { workspace = true, default-features = false }
|
||||||
walkdir.workspace = true
|
walkdir = { workspace = true }
|
||||||
|
|
||||||
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
[target.'cfg(not(target_family = "windows"))'.dependencies]
|
||||||
users.workspace = true
|
users = { workspace = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
kanidmd_core.workspace = true
|
kanidmd_core = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
clap = { workspace = true, features = ["derive"] }
|
clap = { workspace = true, features = ["derive"] }
|
||||||
clap_complete.workspace = true
|
clap_complete = { workspace = true }
|
||||||
profiles.workspace = true
|
profiles = { workspace = true }
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
name = "pam_kanidm"
|
name = "pam_kanidm"
|
||||||
links = "pam"
|
links = "pam"
|
||||||
|
|
||||||
version.workspace = true
|
version = { workspace = true }
|
||||||
authors.workspace = true
|
authors = { workspace = true }
|
||||||
rust-version.workspace = true
|
rust-version = { workspace = true }
|
||||||
edition.workspace = true
|
edition = { workspace = true }
|
||||||
license.workspace = true
|
license = { workspace = true }
|
||||||
homepage.workspace = true
|
homepage = { workspace = true }
|
||||||
repository.workspace = true
|
repository = { workspace = true }
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "pam_kanidm"
|
name = "pam_kanidm"
|
||||||
|
@ -16,8 +16,8 @@ crate-type = [ "cdylib" ]
|
||||||
path = "src/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm_unix_int.workspace = true
|
kanidm_unix_int = { workspace = true }
|
||||||
libc.workspace = true
|
libc = { workspace = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
pkg-config.workspace = true
|
pkg-config = { workspace = true }
|
||||||
|
|