mirror of
https://github.com/kanidm/kanidm.git
synced 2025-02-23 12:37:00 +01:00
383 170 164 authentication updates 2 (#716)
Add foundations for credential update sessions.
This commit is contained in:
parent
61d7000870
commit
9ade567a52
39
Cargo.lock
generated
39
Cargo.lock
generated
|
@ -601,21 +601,6 @@ dependencies = [
|
||||||
"unicode-width",
|
"unicode-width",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "compact_jwt"
|
|
||||||
version = "0.1.9"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "41e359e67b8bb65fdcdc67e506f65b4aec4a97c7e731f321ed1b4b86c443ca6e"
|
|
||||||
dependencies = [
|
|
||||||
"base64 0.13.0",
|
|
||||||
"openssl",
|
|
||||||
"serde",
|
|
||||||
"serde_json",
|
|
||||||
"tracing",
|
|
||||||
"url",
|
|
||||||
"uuid",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "compact_jwt"
|
name = "compact_jwt"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
@ -1891,7 +1876,7 @@ dependencies = [
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"base64 0.13.0",
|
"base64 0.13.0",
|
||||||
"chrono",
|
"chrono",
|
||||||
"compact_jwt 0.2.0",
|
"compact_jwt",
|
||||||
"compiled-uuid",
|
"compiled-uuid",
|
||||||
"concread",
|
"concread",
|
||||||
"criterion",
|
"criterion",
|
||||||
|
@ -1945,24 +1930,15 @@ dependencies = [
|
||||||
name = "kanidm_client"
|
name = "kanidm_client"
|
||||||
version = "1.1.0-alpha.7"
|
version = "1.1.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
|
||||||
"base64 0.13.0",
|
|
||||||
"compact_jwt 0.1.9",
|
|
||||||
"futures",
|
|
||||||
"kanidm",
|
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
"oauth2",
|
|
||||||
"reqwest",
|
"reqwest",
|
||||||
"score",
|
|
||||||
"serde",
|
"serde",
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"tokio",
|
"tokio",
|
||||||
"toml",
|
"toml",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-subscriber",
|
|
||||||
"url",
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
"webauthn-authenticator-rs",
|
|
||||||
"webauthn-rs",
|
"webauthn-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1983,7 +1959,7 @@ dependencies = [
|
||||||
name = "kanidm_tools"
|
name = "kanidm_tools"
|
||||||
version = "1.1.0-alpha.7"
|
version = "1.1.0-alpha.7"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"compact_jwt 0.2.0",
|
"compact_jwt",
|
||||||
"dialoguer",
|
"dialoguer",
|
||||||
"kanidm_client",
|
"kanidm_client",
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
|
@ -3193,22 +3169,31 @@ version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"async-std",
|
"async-std",
|
||||||
"async-trait",
|
"async-trait",
|
||||||
"compact_jwt 0.2.0",
|
"base64 0.13.0",
|
||||||
|
"compact_jwt",
|
||||||
|
"futures",
|
||||||
"futures-util",
|
"futures-util",
|
||||||
"kanidm",
|
"kanidm",
|
||||||
|
"kanidm_client",
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
"ldap3_proto",
|
"ldap3_proto",
|
||||||
"libc",
|
"libc",
|
||||||
|
"oauth2",
|
||||||
"openssl",
|
"openssl",
|
||||||
"profiles",
|
"profiles",
|
||||||
|
"reqwest",
|
||||||
"serde",
|
"serde",
|
||||||
|
"serde_json",
|
||||||
"tide",
|
"tide",
|
||||||
"tide-openssl",
|
"tide-openssl",
|
||||||
"tokio",
|
"tokio",
|
||||||
"tokio-openssl",
|
"tokio-openssl",
|
||||||
"tokio-util",
|
"tokio-util",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
"url",
|
||||||
"uuid",
|
"uuid",
|
||||||
|
"webauthn-authenticator-rs",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -6,7 +6,7 @@ lto = "thin"
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [
|
members = [
|
||||||
"kanidm_proto",
|
"kanidm_proto",
|
||||||
"kanidmd",
|
"kanidmd/idm",
|
||||||
"kanidmd/score",
|
"kanidmd/score",
|
||||||
"kanidmd/daemon",
|
"kanidmd/daemon",
|
||||||
"kanidmd_web_ui",
|
"kanidmd_web_ui",
|
||||||
|
|
2
Makefile
2
Makefile
|
@ -4,7 +4,7 @@ IMAGE_BASE ?= kanidm
|
||||||
IMAGE_VERSION ?= devel
|
IMAGE_VERSION ?= devel
|
||||||
EXT_OPTS ?=
|
EXT_OPTS ?=
|
||||||
IMAGE_ARCH ?= "linux/amd64,linux/arm64"
|
IMAGE_ARCH ?= "linux/amd64,linux/arm64"
|
||||||
ARGS ?= --build-arg "SCCACHE_REDIS=redis://172.24.20.4:6379"
|
ARGS ?= --build-arg "SCCACHE_REDIS=redis://redis.dev.blackhats.net.au:6379"
|
||||||
|
|
||||||
BOOK_VERSION ?= master
|
BOOK_VERSION ?= master
|
||||||
|
|
||||||
|
|
|
@ -22,15 +22,3 @@ url = { version = "2", features = ["serde"] }
|
||||||
webauthn-rs = "0.3"
|
webauthn-rs = "0.3"
|
||||||
tokio = { version = "1", features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
tokio = { version = "1", features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tracing-subscriber = "0.3"
|
|
||||||
tokio = { version = "1", features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
|
||||||
kanidm = { path = "../kanidmd" }
|
|
||||||
score = { path = "../kanidmd/score" }
|
|
||||||
futures = "0.3"
|
|
||||||
async-std = { version = "1.6", features = ["tokio1"] }
|
|
||||||
|
|
||||||
webauthn-authenticator-rs = "0.3.0-alpha.12"
|
|
||||||
oauth2_ext = { package = "oauth2", version = "4.0", default-features = false }
|
|
||||||
base64 = "0.13"
|
|
||||||
compact_jwt = "^0.1.5"
|
|
||||||
|
|
|
@ -58,6 +58,43 @@ pub enum ConsistencyError {
|
||||||
BackendIndexSync,
|
BackendIndexSync,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum PasswordFeedback {
|
||||||
|
// https://docs.rs/zxcvbn/latest/zxcvbn/feedback/enum.Suggestion.html
|
||||||
|
UseAFewWordsAvoidCommonPhrases,
|
||||||
|
NoNeedForSymbolsDigitsOrUppercaseLetters,
|
||||||
|
AddAnotherWordOrTwo,
|
||||||
|
CapitalizationDoesntHelpVeryMuch,
|
||||||
|
AllUppercaseIsAlmostAsEasyToGuessAsAllLowercase,
|
||||||
|
ReversedWordsArentMuchHarderToGuess,
|
||||||
|
PredictableSubstitutionsDontHelpVeryMuch,
|
||||||
|
UseALongerKeyboardPatternWithMoreTurns,
|
||||||
|
AvoidRepeatedWordsAndCharacters,
|
||||||
|
AvoidSequences,
|
||||||
|
AvoidRecentYears,
|
||||||
|
AvoidYearsThatAreAssociatedWithYou,
|
||||||
|
AvoidDatesAndYearsThatAreAssociatedWithYou,
|
||||||
|
// https://docs.rs/zxcvbn/latest/zxcvbn/feedback/enum.Warning.html
|
||||||
|
StraightRowsOfKeysAreEasyToGuess,
|
||||||
|
ShortKeyboardPatternsAreEasyToGuess,
|
||||||
|
RepeatsLikeAaaAreEasyToGuess,
|
||||||
|
RepeatsLikeAbcAbcAreOnlySlightlyHarderToGuess,
|
||||||
|
ThisIsATop10Password,
|
||||||
|
ThisIsATop100Password,
|
||||||
|
ThisIsACommonPassword,
|
||||||
|
ThisIsSimilarToACommonlyUsedPassword,
|
||||||
|
SequencesLikeAbcAreEasyToGuess,
|
||||||
|
RecentYearsAreEasyToGuess,
|
||||||
|
AWordByItselfIsEasyToGuess,
|
||||||
|
DatesAreOftenEasyToGuess,
|
||||||
|
NamesAndSurnamesByThemselvesAreEasyToGuess,
|
||||||
|
CommonNamesAndSurnamesAreEasyToGuess,
|
||||||
|
// Custom
|
||||||
|
TooShort(usize),
|
||||||
|
BadListed,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
#[serde(rename_all = "lowercase")]
|
#[serde(rename_all = "lowercase")]
|
||||||
pub enum OperationError {
|
pub enum OperationError {
|
||||||
|
@ -94,18 +131,17 @@ pub enum OperationError {
|
||||||
SerdeCborError,
|
SerdeCborError,
|
||||||
AccessDenied,
|
AccessDenied,
|
||||||
NotAuthenticated,
|
NotAuthenticated,
|
||||||
|
NotAuthorised,
|
||||||
InvalidAuthState(String),
|
InvalidAuthState(String),
|
||||||
InvalidSessionState,
|
InvalidSessionState,
|
||||||
SystemProtectedObject,
|
SystemProtectedObject,
|
||||||
SystemProtectedAttribute,
|
SystemProtectedAttribute,
|
||||||
PasswordTooWeak,
|
PasswordQuality(Vec<PasswordFeedback>),
|
||||||
PasswordTooShort(usize),
|
|
||||||
PasswordEmpty,
|
|
||||||
PasswordBadListed,
|
|
||||||
CryptographyError,
|
CryptographyError,
|
||||||
ResourceLimit,
|
ResourceLimit,
|
||||||
QueueDisconnected,
|
QueueDisconnected,
|
||||||
Webauthn,
|
Webauthn,
|
||||||
|
Wait(time::OffsetDateTime),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for OperationError {
|
impl PartialEq for OperationError {
|
||||||
|
|
|
@ -12,7 +12,7 @@ use webauthn_authenticator_rs::{u2fhid::U2FHid, WebauthnAuthenticator};
|
||||||
|
|
||||||
use kanidm_client::ClientError;
|
use kanidm_client::ClientError;
|
||||||
use kanidm_client::ClientError::Http as ClientErrorHttp;
|
use kanidm_client::ClientError::Http as ClientErrorHttp;
|
||||||
use kanidm_proto::v1::OperationError::{PasswordBadListed, PasswordTooShort, PasswordTooWeak};
|
use kanidm_proto::v1::OperationError::PasswordQuality;
|
||||||
|
|
||||||
impl AccountOpt {
|
impl AccountOpt {
|
||||||
pub fn debug(&self) -> bool {
|
pub fn debug(&self) -> bool {
|
||||||
|
@ -81,10 +81,10 @@ impl AccountOpt {
|
||||||
) {
|
) {
|
||||||
match e {
|
match e {
|
||||||
// TODO: once the password length is configurable at a system level (#498), pull from the configuration.
|
// TODO: once the password length is configurable at a system level (#498), pull from the configuration.
|
||||||
ClientErrorHttp(_, Some(PasswordBadListed), _) => error!("Password is banned by the administrator of this system, please try a different one."),
|
ClientErrorHttp(_, Some(PasswordQuality(feedback)), _) => {
|
||||||
ClientErrorHttp(_, Some(PasswordTooShort(pwminlength)), _) => error!("Password was too short (needs to be at least {} characters), please try again.", pwminlength),
|
error!("{:?}", feedback)
|
||||||
ClientErrorHttp(_, Some(PasswordTooWeak), _) => error!("The supplied password did not match configured complexity requirements, please use a password with upper/lower case letters, symbols and digits."),
|
}
|
||||||
_ => error!("Error setting password -> {:?}", e)
|
_ => error!("Error setting password -> {:?}", e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ path = "src/test_auth.rs"
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm_client = { path = "../kanidm_client", version = "1.1.0-alpha" }
|
kanidm_client = { path = "../kanidm_client", version = "1.1.0-alpha" }
|
||||||
kanidm_proto = { path = "../kanidm_proto", version = "1.1.0-alpha" }
|
kanidm_proto = { path = "../kanidm_proto", version = "1.1.0-alpha" }
|
||||||
kanidm = { path = "../kanidmd", version = "1.1.0-alpha" }
|
kanidm = { path = "../kanidmd/idm", version = "1.1.0-alpha" }
|
||||||
|
|
||||||
tracing = "0.1"
|
tracing = "0.1"
|
||||||
tracing-subscriber = "0.3"
|
tracing-subscriber = "0.3"
|
||||||
|
@ -80,7 +80,7 @@ lru = "0.7"
|
||||||
# default = [ "libsqlite3-sys/bundled" ]
|
# default = [ "libsqlite3-sys/bundled" ]
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
kanidm = { path = "../kanidmd" }
|
# kanidm = { path = "../kanidmd/idm" }
|
||||||
score = { path = "../kanidmd/score" }
|
score = { path = "../kanidmd/score" }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
|
|
|
@ -17,7 +17,7 @@ name = "kanidmd"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm = { path = "../" }
|
kanidm = { path = "../idm" }
|
||||||
score = { path = "../score" }
|
score = { path = "../score" }
|
||||||
structopt = { version = "0.3", default-features = false }
|
structopt = { version = "0.3", default-features = false }
|
||||||
users = "0.11"
|
users = "0.11"
|
||||||
|
|
|
@ -8,7 +8,7 @@ use structopt::StructOpt;
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
include!("../src/lib/audit_loglevel.rs");
|
include!("../idm/src/audit_loglevel.rs");
|
||||||
include!("src/opt.rs");
|
include!("src/opt.rs");
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
|
|
|
@ -12,10 +12,10 @@ repository = "https://github.com/kanidm/kanidm/"
|
||||||
|
|
||||||
[lib]
|
[lib]
|
||||||
name = "kanidm"
|
name = "kanidm"
|
||||||
path = "src/lib/lib.rs"
|
path = "src/lib.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm_proto = { path = "../kanidm_proto", version = "1.1.0-alpha" }
|
kanidm_proto = { path = "../../kanidm_proto", version = "1.1.0-alpha" }
|
||||||
tracing = { version = "0.1", features = ["attributes"] }
|
tracing = { version = "0.1", features = ["attributes"] }
|
||||||
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
tracing-subscriber = { version = "0.3", features = ["env-filter"] }
|
||||||
tracing-serde = "0.1"
|
tracing-serde = "0.1"
|
||||||
|
@ -97,7 +97,7 @@ criterion = { version = "0.3", features = ["html_reports"] }
|
||||||
webauthn-authenticator-rs = "0.3.0-alpha.12"
|
webauthn-authenticator-rs = "0.3.0-alpha.12"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
profiles = { path = "../profiles" }
|
profiles = { path = "../../profiles" }
|
||||||
|
|
||||||
[[bench]]
|
[[bench]]
|
||||||
name = "scaling_10k"
|
name = "scaling_10k"
|
|
@ -3,7 +3,6 @@ use criterion::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use kanidm;
|
use kanidm;
|
||||||
use kanidm::audit::AuditScope;
|
|
||||||
use kanidm::entry::{Entry, EntryInit, EntryNew};
|
use kanidm::entry::{Entry, EntryInit, EntryNew};
|
||||||
use kanidm::entry_init;
|
use kanidm::entry_init;
|
||||||
use kanidm::idm::server::{IdmServer, IdmServerDelayed};
|
use kanidm::idm::server::{IdmServer, IdmServerDelayed};
|
||||||
|
@ -30,10 +29,7 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
kanidm::macros::run_idm_test_no_logging(
|
kanidm::macros::run_idm_test_no_logging(
|
||||||
|_qs: &QueryServer,
|
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
||||||
idms: &IdmServer,
|
|
||||||
_idms_delayed: &IdmServerDelayed,
|
|
||||||
au: &mut AuditScope| {
|
|
||||||
let ct = duration_from_epoch_now();
|
let ct = duration_from_epoch_now();
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
@ -50,10 +46,10 @@ pub fn scaling_user_create_single(c: &mut Criterion) {
|
||||||
("displayname", Value::new_utf8s(&name))
|
("displayname", Value::new_utf8s(&name))
|
||||||
);
|
);
|
||||||
|
|
||||||
let cr = idms_prox_write.qs_write.internal_create(au, vec![e1]);
|
let cr = idms_prox_write.qs_write.internal_create(vec![e1]);
|
||||||
assert!(cr.is_ok());
|
assert!(cr.is_ok());
|
||||||
|
|
||||||
idms_prox_write.commit(au).expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
}
|
}
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
||||||
},
|
},
|
||||||
|
@ -97,19 +93,16 @@ pub fn scaling_user_create_batched(c: &mut Criterion) {
|
||||||
|
|
||||||
for _i in 0..iters {
|
for _i in 0..iters {
|
||||||
kanidm::macros::run_idm_test_no_logging(
|
kanidm::macros::run_idm_test_no_logging(
|
||||||
|_qs: &QueryServer,
|
|_qs: &QueryServer, idms: &IdmServer, _idms_delayed: &IdmServerDelayed| {
|
||||||
idms: &IdmServer,
|
|
||||||
_idms_delayed: &IdmServerDelayed,
|
|
||||||
au: &mut AuditScope| {
|
|
||||||
let ct = duration_from_epoch_now();
|
let ct = duration_from_epoch_now();
|
||||||
|
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
|
|
||||||
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
let idms_prox_write = task::block_on(idms.proxy_write_async(ct));
|
||||||
let cr = idms_prox_write.qs_write.internal_create(au, data.clone());
|
let cr = idms_prox_write.qs_write.internal_create(data.clone());
|
||||||
assert!(cr.is_ok());
|
assert!(cr.is_ok());
|
||||||
|
|
||||||
idms_prox_write.commit(au).expect("Must not fail");
|
idms_prox_write.commit().expect("Must not fail");
|
||||||
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
elapsed = elapsed.checked_add(start.elapsed()).unwrap();
|
||||||
},
|
},
|
||||||
);
|
);
|
|
@ -367,6 +367,17 @@ impl AccessControlProfile {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
|
pub struct AccessEffectivePermission {
|
||||||
|
// I don't think we need this? The ident is implied by the requestor.
|
||||||
|
// ident: Uuid,
|
||||||
|
pub target: Uuid,
|
||||||
|
pub search: BTreeSet<AttrString>,
|
||||||
|
pub modify_pres: BTreeSet<AttrString>,
|
||||||
|
pub modify_rem: BTreeSet<AttrString>,
|
||||||
|
pub modify_class: BTreeSet<AttrString>,
|
||||||
|
}
|
||||||
|
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
// ACP transactions and management for server bits.
|
// ACP transactions and management for server bits.
|
||||||
// =========================================================================
|
// =========================================================================
|
||||||
|
@ -400,8 +411,8 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
fn search_related_acp<'b>(
|
fn search_related_acp<'b>(
|
||||||
&'b self,
|
&'b self,
|
||||||
rec_entry: &Entry<EntrySealed, EntryCommitted>,
|
rec_entry: &Entry<EntrySealed, EntryCommitted>,
|
||||||
se: &SearchEvent,
|
ident: &Identity,
|
||||||
) -> Vec<&'b AccessControlSearch> {
|
) -> Vec<(&'b AccessControlSearch, Filter<FilterValidResolved>)> {
|
||||||
let search_state = self.get_search();
|
let search_state = self.get_search();
|
||||||
// let acp_related_search_cache = self.get_acp_related_search_cache();
|
// let acp_related_search_cache = self.get_acp_related_search_cache();
|
||||||
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
||||||
|
@ -432,12 +443,11 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
} else {
|
} else {
|
||||||
*/
|
*/
|
||||||
// else, we calculate this, and then stash/cache the uuids.
|
// else, we calculate this, and then stash/cache the uuids.
|
||||||
let related_acp: Vec<&AccessControlSearch> =
|
let related_acp: Vec<(&AccessControlSearch, Filter<FilterValidResolved>)> =
|
||||||
spanned!("access::search_related_acp<uncached>", {
|
spanned!("access::search_related_acp<uncached>", {
|
||||||
search_state
|
search_state
|
||||||
.iter()
|
.iter()
|
||||||
// .filter_map(|(_, acs)| {
|
.filter_map(|acs| {
|
||||||
.filter(|acs| {
|
|
||||||
// Now resolve the receiver filter
|
// Now resolve the receiver filter
|
||||||
// Okay, so in filter resolution, the primary error case
|
// Okay, so in filter resolution, the primary error case
|
||||||
// is that we have a non-user in the event. We have already
|
// is that we have a non-user in the event. We have already
|
||||||
|
@ -454,17 +464,35 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
// such that it takes an entry, rather than an event, but that
|
// such that it takes an entry, rather than an event, but that
|
||||||
// would create issues in search.
|
// would create issues in search.
|
||||||
match (&acs.acp.receiver).resolve(
|
match (&acs.acp.receiver).resolve(
|
||||||
&se.ident,
|
ident,
|
||||||
None,
|
None,
|
||||||
Some(acp_resolve_filter_cache),
|
Some(acp_resolve_filter_cache),
|
||||||
) {
|
) {
|
||||||
Ok(f_res) => rec_entry.entry_match_no_index(&f_res),
|
Ok(f_res) => {
|
||||||
|
if rec_entry.entry_match_no_index(&f_res) {
|
||||||
|
// Now, for each of the acp's that apply to our receiver, resolve their
|
||||||
|
// related target filters.
|
||||||
|
(&acs.acp.targetscope)
|
||||||
|
.resolve(ident, None, Some(acp_resolve_filter_cache))
|
||||||
|
.map_err(|e| {
|
||||||
|
admin_error!(
|
||||||
|
?e,
|
||||||
|
"A internal filter/event was passed for resolution!?!?"
|
||||||
|
);
|
||||||
|
e
|
||||||
|
})
|
||||||
|
.ok()
|
||||||
|
.map(|f_res| (acs, f_res))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
admin_error!(
|
admin_error!(
|
||||||
?e,
|
?e,
|
||||||
"A internal filter/event was passed for resolution!?!?"
|
"A internal filter/event was passed for resolution!?!?"
|
||||||
);
|
);
|
||||||
false
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
@ -501,25 +529,8 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
trace!(event = %se.ident, "Access check for search (filter) event");
|
trace!(event = %se.ident, "Access check for search (filter) event");
|
||||||
|
|
||||||
// First get the set of acps that apply to this receiver
|
// First get the set of acps that apply to this receiver
|
||||||
let related_acp = self.search_related_acp(rec_entry, se);
|
let related_acp: Vec<(&AccessControlSearch, _)> =
|
||||||
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
self.search_related_acp(rec_entry, &se.ident);
|
||||||
|
|
||||||
let related_acp: Vec<(&AccessControlSearch, _)> = related_acp
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|acs| {
|
|
||||||
(&acs.acp.targetscope)
|
|
||||||
.resolve(&se.ident, None, Some(acp_resolve_filter_cache))
|
|
||||||
.map_err(|e| {
|
|
||||||
admin_error!(
|
|
||||||
?e,
|
|
||||||
"A internal filter/event was passed for resolution!?!?"
|
|
||||||
);
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.map(|f_res| (acs, f_res))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
related_acp.iter().for_each(|racp| {
|
related_acp.iter().for_each(|racp| {
|
||||||
|
@ -619,37 +630,19 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
trace!("Access check for search (reduce) event: {}", se.ident);
|
trace!("Access check for search (reduce) event: {}", se.ident);
|
||||||
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
|
||||||
|
|
||||||
// Get the relevant acps for this receiver.
|
// Get the relevant acps for this receiver.
|
||||||
let related_acp = self.search_related_acp(rec_entry, se);
|
let related_acp: Vec<(&AccessControlSearch, _)> =
|
||||||
|
self.search_related_acp(rec_entry, &se.ident);
|
||||||
let related_acp: Vec<&AccessControlSearch> = if let Some(r_attrs) = se.attrs.as_ref() {
|
let related_acp: Vec<(&AccessControlSearch, _)> =
|
||||||
related_acp
|
if let Some(r_attrs) = se.attrs.as_ref() {
|
||||||
.into_iter()
|
related_acp
|
||||||
.filter(|acs| !acs.attrs.is_disjoint(r_attrs))
|
.into_iter()
|
||||||
.collect()
|
.filter(|(acs, _)| !acs.attrs.is_disjoint(r_attrs))
|
||||||
} else {
|
.collect()
|
||||||
related_acp
|
} else {
|
||||||
};
|
related_acp
|
||||||
|
};
|
||||||
// Compile all the target filters in one pass.
|
|
||||||
let related_acp: Vec<(&AccessControlSearch, _)> = related_acp
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|acs| {
|
|
||||||
(&acs.acp.targetscope)
|
|
||||||
.resolve(&se.ident, None, Some(acp_resolve_filter_cache))
|
|
||||||
.map_err(|e| {
|
|
||||||
admin_error!(
|
|
||||||
?e,
|
|
||||||
"A internal filter/event was passed for resolution!?!?"
|
|
||||||
);
|
|
||||||
e
|
|
||||||
})
|
|
||||||
.ok()
|
|
||||||
.map(|f_res| (acs, f_res))
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
related_acp.iter().for_each(|racp| {
|
related_acp.iter().for_each(|racp| {
|
||||||
|
@ -729,48 +722,28 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::cognitive_complexity)]
|
fn modify_related_acp<'b>(
|
||||||
fn modify_allow_operation(
|
&'b self,
|
||||||
&self,
|
rec_entry: &Entry<EntrySealed, EntryCommitted>,
|
||||||
me: &ModifyEvent,
|
ident: &Identity,
|
||||||
entries: &[Arc<EntrySealedCommitted>],
|
) -> Vec<(&'b AccessControlModify, Filter<FilterValidResolved>)> {
|
||||||
) -> Result<bool, OperationError> {
|
// Some useful references we'll use for the remainder of the operation
|
||||||
let rec_entry: &Entry<EntrySealed, EntryCommitted> = match &me.ident.origin {
|
let modify_state = self.get_modify();
|
||||||
IdentType::Internal => {
|
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
||||||
trace!("Internal operation, bypassing access check");
|
|
||||||
// No need to check ACS
|
|
||||||
return Ok(true);
|
|
||||||
}
|
|
||||||
IdentType::User(u) => &u.entry,
|
|
||||||
};
|
|
||||||
spanned!("access::modify_allow_operation", {
|
|
||||||
trace!("Access check for modify event: {}", me.ident);
|
|
||||||
|
|
||||||
// Some useful references we'll use for the remainder of the operation
|
// Find the acps that relate to the caller, and compile their related
|
||||||
let modify_state = self.get_modify();
|
// target filters.
|
||||||
let acp_resolve_filter_cache = self.get_acp_resolve_filter_cache();
|
let related_acp: Vec<(&AccessControlModify, _)> = spanned!(
|
||||||
|
"access::modify_related_acp<uncached>",
|
||||||
// Pre-check if the no-no purge class is present
|
{
|
||||||
let disallow = me
|
modify_state
|
||||||
.modlist
|
|
||||||
.iter()
|
|
||||||
.any(|m| matches!(m, Modify::Purged(a) if a == "class"));
|
|
||||||
|
|
||||||
if disallow {
|
|
||||||
security_access!("Disallowing purge class in modification");
|
|
||||||
return Ok(false);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Find the acps that relate to the caller, and compile their related
|
|
||||||
// target filters.
|
|
||||||
let related_acp: Vec<(&AccessControlModify, _)> = modify_state
|
|
||||||
.iter()
|
.iter()
|
||||||
.filter_map(|acs| {
|
.filter_map(|acs| {
|
||||||
match (&acs.acp.receiver).resolve(&me.ident, None, Some(acp_resolve_filter_cache)) {
|
match (&acs.acp.receiver).resolve(ident, None, Some(acp_resolve_filter_cache)) {
|
||||||
Ok(f_res) => {
|
Ok(f_res) => {
|
||||||
if rec_entry.entry_match_no_index(&f_res) {
|
if rec_entry.entry_match_no_index(&f_res) {
|
||||||
(&acs.acp.targetscope)
|
(&acs.acp.targetscope)
|
||||||
.resolve(&me.ident, None, Some(acp_resolve_filter_cache))
|
.resolve(ident, None, Some(acp_resolve_filter_cache))
|
||||||
.map_err(|e| {
|
.map_err(|e| {
|
||||||
admin_error!(
|
admin_error!(
|
||||||
"A internal filter/event was passed for resolution!?!? {:?}",
|
"A internal filter/event was passed for resolution!?!? {:?}",
|
||||||
|
@ -793,7 +766,45 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect();
|
.collect()
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
related_acp
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::cognitive_complexity)]
|
||||||
|
fn modify_allow_operation(
|
||||||
|
&self,
|
||||||
|
me: &ModifyEvent,
|
||||||
|
entries: &[Arc<EntrySealedCommitted>],
|
||||||
|
) -> Result<bool, OperationError> {
|
||||||
|
let rec_entry: &Entry<EntrySealed, EntryCommitted> = match &me.ident.origin {
|
||||||
|
IdentType::Internal => {
|
||||||
|
trace!("Internal operation, bypassing access check");
|
||||||
|
// No need to check ACS
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
IdentType::User(u) => &u.entry,
|
||||||
|
};
|
||||||
|
spanned!("access::modify_allow_operation", {
|
||||||
|
trace!("Access check for modify event: {}", me.ident);
|
||||||
|
|
||||||
|
// Pre-check if the no-no purge class is present
|
||||||
|
let disallow = me
|
||||||
|
.modlist
|
||||||
|
.iter()
|
||||||
|
.any(|m| matches!(m, Modify::Purged(a) if a == "class"));
|
||||||
|
|
||||||
|
if disallow {
|
||||||
|
security_access!("Disallowing purge class in modification");
|
||||||
|
return Ok(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the acps that relate to the caller, and compile their related
|
||||||
|
// target filters.
|
||||||
|
let related_acp: Vec<(&AccessControlModify, _)> =
|
||||||
|
self.modify_related_acp(&rec_entry, &me.ident);
|
||||||
|
|
||||||
related_acp.iter().for_each(|racp| {
|
related_acp.iter().for_each(|racp| {
|
||||||
trace!("Related acs -> {:?}", racp.0.acp.name);
|
trace!("Related acs -> {:?}", racp.0.acp.name);
|
||||||
|
@ -1137,6 +1148,143 @@ pub trait AccessControlsTransaction<'a> {
|
||||||
Ok(r)
|
Ok(r)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn effective_permission_check(
|
||||||
|
&self,
|
||||||
|
ident: &Identity,
|
||||||
|
attrs: Option<BTreeSet<AttrString>>,
|
||||||
|
entries: &[Arc<EntrySealedCommitted>],
|
||||||
|
) -> Result<Vec<AccessEffectivePermission>, OperationError> {
|
||||||
|
// I think we need a structure like " CheckResult, which is in the order of the
|
||||||
|
// entries, but also stashes the uuid. Then it has search, mod, create, delete,
|
||||||
|
// as seperate attrs to describe what is capable.
|
||||||
|
|
||||||
|
// Does create make sense here? I don't think it does. Create requires you to
|
||||||
|
// have an entry template. I think james was right about the create being
|
||||||
|
// a template copy op ...
|
||||||
|
|
||||||
|
let rec_entry: &Entry<EntrySealed, EntryCommitted> = match &ident.origin {
|
||||||
|
IdentType::Internal => {
|
||||||
|
// In production we can't risk leaking data here, so we return
|
||||||
|
// empty sets.
|
||||||
|
security_critical!("IMPOSSIBLE STATE: Internal search in external interface?! Returning empty for safety.");
|
||||||
|
// No need to check ACS
|
||||||
|
return Err(OperationError::InvalidState);
|
||||||
|
}
|
||||||
|
IdentType::User(u) => &u.entry,
|
||||||
|
};
|
||||||
|
|
||||||
|
spanned!("access::effective_permission_check", {
|
||||||
|
trace!(ident = %ident, "Effective permission check");
|
||||||
|
// I think we seperate this to multiple checks ...?
|
||||||
|
|
||||||
|
// == search ==
|
||||||
|
// Get the relevant acps for this receiver.
|
||||||
|
let search_related_acp: Vec<(&AccessControlSearch, _)> =
|
||||||
|
self.search_related_acp(rec_entry, ident);
|
||||||
|
let search_related_acp: Vec<(&AccessControlSearch, _)> =
|
||||||
|
if let Some(r_attrs) = attrs.as_ref() {
|
||||||
|
search_related_acp
|
||||||
|
.into_iter()
|
||||||
|
.filter(|(acs, _)| !acs.attrs.is_disjoint(r_attrs))
|
||||||
|
.collect()
|
||||||
|
} else {
|
||||||
|
search_related_acp
|
||||||
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
search_related_acp.iter().for_each(|(racp, _)| {
|
||||||
|
trace!("Related acs -> {:?}", racp.acp.name);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
// == modify ==
|
||||||
|
|
||||||
|
let modify_related_acp: Vec<(&AccessControlModify, _)> =
|
||||||
|
self.modify_related_acp(rec_entry, ident);
|
||||||
|
|
||||||
|
/*
|
||||||
|
modify_related_acp.iter().for_each(|(racp, _)| {
|
||||||
|
trace!("Related acm -> {:?}", racp.acp.name);
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
let effective_permissions: Vec<_> = entries
|
||||||
|
.iter()
|
||||||
|
.map(|e| {
|
||||||
|
// == search ==
|
||||||
|
let allowed_attrs: BTreeSet<AttrString> = search_related_acp
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(acs, f_res)| {
|
||||||
|
// if it applies
|
||||||
|
if e.entry_match_no_index(f_res) {
|
||||||
|
// security_access!(entry = ?e.get_uuid(), acs = %acs.acp.name, "entry matches acs");
|
||||||
|
Some(acs.attrs.iter().map(|s| s.clone()))
|
||||||
|
} else {
|
||||||
|
trace!(entry = ?e.get_uuid(), acs = %acs.acp.name, "entry DOES NOT match acs"); // should this be `security_access`?
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
security_access!(
|
||||||
|
requested = ?attrs,
|
||||||
|
allows = ?allowed_attrs,
|
||||||
|
"attributes",
|
||||||
|
);
|
||||||
|
|
||||||
|
// intersect?
|
||||||
|
let search_effective = if let Some(r_attrs) = attrs.as_ref() {
|
||||||
|
r_attrs & &allowed_attrs
|
||||||
|
} else {
|
||||||
|
allowed_attrs
|
||||||
|
};
|
||||||
|
|
||||||
|
// == modify ==
|
||||||
|
let modify_scoped_acp: Vec<&AccessControlModify> = modify_related_acp
|
||||||
|
.iter()
|
||||||
|
.filter_map(|(acm, f_res)| {
|
||||||
|
if e.entry_match_no_index(f_res) {
|
||||||
|
Some(*acm)
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let modify_pres: BTreeSet<AttrString> = modify_scoped_acp
|
||||||
|
.iter()
|
||||||
|
.flat_map(|acp| acp.presattrs.iter().map(|v| v.clone()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let modify_rem: BTreeSet<AttrString> = modify_scoped_acp
|
||||||
|
.iter()
|
||||||
|
.flat_map(|acp| acp.remattrs.iter().map(|v| v.clone()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let modify_class: BTreeSet<AttrString> = modify_scoped_acp
|
||||||
|
.iter()
|
||||||
|
.flat_map(|acp| acp.classes.iter().map(|v| v.clone()))
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
AccessEffectivePermission {
|
||||||
|
target: *e.get_uuid(),
|
||||||
|
search: search_effective,
|
||||||
|
modify_pres,
|
||||||
|
modify_rem,
|
||||||
|
modify_class,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
effective_permissions.iter().for_each(|ep| {
|
||||||
|
trace!(?ep);
|
||||||
|
});
|
||||||
|
|
||||||
|
Ok(effective_permissions)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct AccessControlsWriteTransaction<'a> {
|
pub struct AccessControlsWriteTransaction<'a> {
|
||||||
|
@ -1359,10 +1507,12 @@ impl AccessControls {
|
||||||
mod tests {
|
mod tests {
|
||||||
use crate::access::{
|
use crate::access::{
|
||||||
AccessControlCreate, AccessControlDelete, AccessControlModify, AccessControlProfile,
|
AccessControlCreate, AccessControlDelete, AccessControlModify, AccessControlProfile,
|
||||||
AccessControlSearch, AccessControls, AccessControlsTransaction,
|
AccessControlSearch, AccessControls, AccessControlsTransaction, AccessEffectivePermission,
|
||||||
};
|
};
|
||||||
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
|
use crate::event::{CreateEvent, DeleteEvent, ModifyEvent, SearchEvent};
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
use compiled_uuid::uuid;
|
||||||
|
use std::collections::BTreeSet;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
macro_rules! acp_from_entry_err {
|
macro_rules! acp_from_entry_err {
|
||||||
|
@ -2332,4 +2482,110 @@ mod tests {
|
||||||
// Test reject delete
|
// Test reject delete
|
||||||
test_acp_delete!(&de_anon, vec![acp], &r_set, false);
|
test_acp_delete!(&de_anon, vec![acp], &r_set, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
macro_rules! test_acp_effective_permissions {
|
||||||
|
(
|
||||||
|
$ident:expr,
|
||||||
|
$attrs:expr,
|
||||||
|
$search_controls:expr,
|
||||||
|
$modify_controls:expr,
|
||||||
|
$entries:expr,
|
||||||
|
$expect:expr
|
||||||
|
) => {{
|
||||||
|
let ac = AccessControls::new();
|
||||||
|
let mut acw = ac.write();
|
||||||
|
acw.update_search($search_controls)
|
||||||
|
.expect("Failed to update");
|
||||||
|
acw.update_modify($modify_controls)
|
||||||
|
.expect("Failed to update");
|
||||||
|
let acw = acw;
|
||||||
|
|
||||||
|
let res = acw
|
||||||
|
.effective_permission_check($ident, $attrs, $entries)
|
||||||
|
.expect("Failed to apply effective_permission_check");
|
||||||
|
|
||||||
|
debug!("result --> {:?}", res);
|
||||||
|
debug!("expect --> {:?}", $expect);
|
||||||
|
// should be ok, and same as expect.
|
||||||
|
assert!(res == $expect);
|
||||||
|
}};
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_access_effective_permission_check_1() {
|
||||||
|
let _ = crate::tracing_tree::test_init();
|
||||||
|
|
||||||
|
let admin = unsafe { Identity::from_impersonate_entry_ser(JSON_ADMIN_V1) };
|
||||||
|
|
||||||
|
let e1: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(JSON_TESTPERSON1);
|
||||||
|
let ev1 = unsafe { e1.into_sealed_committed() };
|
||||||
|
|
||||||
|
let r_set = vec![Arc::new(ev1.clone())];
|
||||||
|
|
||||||
|
test_acp_effective_permissions!(
|
||||||
|
&admin,
|
||||||
|
None,
|
||||||
|
vec![unsafe {
|
||||||
|
AccessControlSearch::from_raw(
|
||||||
|
"test_acp",
|
||||||
|
"d38640c4-0254-49f9-99b7-8ba7d0233f3d",
|
||||||
|
// apply to admin only
|
||||||
|
filter_valid!(f_eq("name", PartialValue::new_iname("admin"))),
|
||||||
|
// Allow admin to read only testperson1
|
||||||
|
filter_valid!(f_eq("name", PartialValue::new_iname("testperson1"))),
|
||||||
|
// They can read "name".
|
||||||
|
"name",
|
||||||
|
)
|
||||||
|
}],
|
||||||
|
vec![],
|
||||||
|
&r_set,
|
||||||
|
vec![AccessEffectivePermission {
|
||||||
|
target: uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"),
|
||||||
|
search: btreeset![AttrString::from("name")],
|
||||||
|
modify_pres: BTreeSet::new(),
|
||||||
|
modify_rem: BTreeSet::new(),
|
||||||
|
modify_class: BTreeSet::new(),
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_access_effective_permission_check_2() {
|
||||||
|
let _ = crate::tracing_tree::test_init();
|
||||||
|
|
||||||
|
let admin = unsafe { Identity::from_impersonate_entry_ser(JSON_ADMIN_V1) };
|
||||||
|
|
||||||
|
let e1: Entry<EntryInit, EntryNew> = Entry::unsafe_from_entry_str(JSON_TESTPERSON1);
|
||||||
|
let ev1 = unsafe { e1.into_sealed_committed() };
|
||||||
|
|
||||||
|
let r_set = vec![Arc::new(ev1.clone())];
|
||||||
|
|
||||||
|
test_acp_effective_permissions!(
|
||||||
|
&admin,
|
||||||
|
None,
|
||||||
|
vec![],
|
||||||
|
vec![unsafe {
|
||||||
|
AccessControlModify::from_raw(
|
||||||
|
"test_acp",
|
||||||
|
"d38640c4-0254-49f9-99b7-8ba7d0233f3d",
|
||||||
|
// apply to admin only
|
||||||
|
filter_valid!(f_eq("name", PartialValue::new_iname("admin"))),
|
||||||
|
// Allow admin to read only testperson1
|
||||||
|
filter_valid!(f_eq("name", PartialValue::new_iname("testperson1"))),
|
||||||
|
// They can read "name".
|
||||||
|
"name",
|
||||||
|
"name",
|
||||||
|
"object",
|
||||||
|
)
|
||||||
|
}],
|
||||||
|
&r_set,
|
||||||
|
vec![AccessEffectivePermission {
|
||||||
|
target: uuid!("cc8e95b4-c24f-4d68-ba54-8bed76f63930"),
|
||||||
|
search: BTreeSet::new(),
|
||||||
|
modify_pres: btreeset![AttrString::from("name")],
|
||||||
|
modify_rem: btreeset![AttrString::from("name")],
|
||||||
|
modify_class: btreeset![AttrString::from("object")],
|
||||||
|
}]
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -30,6 +30,16 @@ impl std::fmt::Debug for DbPasswordV1 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
|
pub enum DbValueIntentTokenStateV1 {
|
||||||
|
#[serde(rename = "v")]
|
||||||
|
Valid,
|
||||||
|
#[serde(rename = "p")]
|
||||||
|
InProgress(Uuid, Duration),
|
||||||
|
#[serde(rename = "c")]
|
||||||
|
Consumed,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize, Debug)]
|
#[derive(Serialize, Deserialize, Debug)]
|
||||||
pub enum DbTotpAlgoV1 {
|
pub enum DbTotpAlgoV1 {
|
||||||
S1,
|
S1,
|
||||||
|
@ -231,6 +241,15 @@ pub enum DbValueV1 {
|
||||||
PublicBinary(String, Vec<u8>),
|
PublicBinary(String, Vec<u8>),
|
||||||
#[serde(rename = "RS")]
|
#[serde(rename = "RS")]
|
||||||
RestrictedString(String),
|
RestrictedString(String),
|
||||||
|
#[serde(rename = "IT")]
|
||||||
|
IntentToken {
|
||||||
|
u: Uuid,
|
||||||
|
s: DbValueIntentTokenStateV1,
|
||||||
|
},
|
||||||
|
#[serde(rename = "TE")]
|
||||||
|
TrustedDeviceEnrollment { u: Uuid },
|
||||||
|
#[serde(rename = "AS")]
|
||||||
|
AuthSession { u: Uuid },
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
|
@ -112,7 +112,7 @@ pub const JSON_IDM_SELF_ACP_WRITE_V1: &str = r#"{
|
||||||
"uuid": ["00000000-0000-0000-0000-ffffff000021"],
|
"uuid": ["00000000-0000-0000-0000-ffffff000021"],
|
||||||
"description": ["Builtin IDM Control for self write - required for people to update their own identities and credentials in line with best practices."],
|
"description": ["Builtin IDM Control for self write - required for people to update their own identities and credentials in line with best practices."],
|
||||||
"acp_receiver": [
|
"acp_receiver": [
|
||||||
"{\"and\": [\"self\", {\"andnot\": {\"or\": [{\"eq\": [\"class\", \"tombstone\"]}, {\"eq\": [\"class\", \"recycled\"]}, {\"eq\": [\"uuid\", \"00000000-0000-0000-0000-ffffffffffff\"]}]}}]}"
|
"{\"and\": [\"self\", {\"eq\": [\"class\", \"person\"]}, {\"eq\": [\"class\", \"account\"]}, {\"andnot\": {\"or\": [{\"eq\": [\"class\", \"tombstone\"]}, {\"eq\": [\"class\", \"recycled\"]}, {\"eq\": [\"uuid\", \"00000000-0000-0000-0000-ffffffffffff\"]}]}}]}"
|
||||||
],
|
],
|
||||||
"acp_targetscope": [
|
"acp_targetscope": [
|
||||||
"{\"and\": [{\"eq\": [\"class\",\"person\"]}, {\"eq\": [\"class\",\"account\"]}, \"self\"]}"
|
"{\"and\": [{\"eq\": [\"class\",\"person\"]}, {\"eq\": [\"class\",\"account\"]}, \"self\"]}"
|
|
@ -836,6 +836,35 @@ pub const JSON_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE: &str = r#"{
|
||||||
}
|
}
|
||||||
}"#;
|
}"#;
|
||||||
|
|
||||||
|
pub const JSON_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: &str = r#"{
|
||||||
|
"attrs": {
|
||||||
|
"class": [
|
||||||
|
"object",
|
||||||
|
"system",
|
||||||
|
"attributetype"
|
||||||
|
],
|
||||||
|
"description": [
|
||||||
|
"The status of a credential update intent token"
|
||||||
|
],
|
||||||
|
"index": [],
|
||||||
|
"unique": [
|
||||||
|
"false"
|
||||||
|
],
|
||||||
|
"multivalue": [
|
||||||
|
"true"
|
||||||
|
],
|
||||||
|
"attributename": [
|
||||||
|
"credential_update_intent_token"
|
||||||
|
],
|
||||||
|
"syntax": [
|
||||||
|
"INTENT_TOKEN"
|
||||||
|
],
|
||||||
|
"uuid": [
|
||||||
|
"00000000-0000-0000-0000-ffff00000096"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}"#;
|
||||||
|
|
||||||
// === classes ===
|
// === classes ===
|
||||||
|
|
||||||
pub const JSON_SCHEMA_CLASS_PERSON: &str = r#"
|
pub const JSON_SCHEMA_CLASS_PERSON: &str = r#"
|
||||||
|
@ -939,6 +968,7 @@ pub const JSON_SCHEMA_CLASS_ACCOUNT: &str = r#"
|
||||||
],
|
],
|
||||||
"systemmay": [
|
"systemmay": [
|
||||||
"primary_credential",
|
"primary_credential",
|
||||||
|
"credential_update_intent_token",
|
||||||
"ssh_publickey",
|
"ssh_publickey",
|
||||||
"radius_secret",
|
"radius_secret",
|
||||||
"account_expire",
|
"account_expire",
|
|
@ -165,6 +165,8 @@ pub const _UUID_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER: Uuid =
|
||||||
pub const _UUID_SCHEMA_CLASS_ORGPERSON: Uuid = uuid!("00000000-0000-0000-0000-ffff00000094");
|
pub const _UUID_SCHEMA_CLASS_ORGPERSON: Uuid = uuid!("00000000-0000-0000-0000-ffff00000094");
|
||||||
pub const UUID_SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR: Uuid =
|
pub const UUID_SCHEMA_ATTR_FERNET_PRIVATE_KEY_STR: Uuid =
|
||||||
uuid!("00000000-0000-0000-0000-ffff00000095");
|
uuid!("00000000-0000-0000-0000-ffff00000095");
|
||||||
|
pub const _UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: Uuid =
|
||||||
|
uuid!("00000000-0000-0000-0000-ffff00000096");
|
||||||
|
|
||||||
// System and domain infos
|
// System and domain infos
|
||||||
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
// I'd like to strongly criticise william of the past for making poor choices about these allocations.
|
|
@ -308,7 +308,7 @@ impl From<&Credential> for CredentialDetail {
|
||||||
CredentialDetailType::PasswordMfa(
|
CredentialDetailType::PasswordMfa(
|
||||||
totp.is_some(),
|
totp.is_some(),
|
||||||
labels,
|
labels,
|
||||||
backup_code.iter().count(),
|
backup_code.as_ref().map(|c| c.code_set.len()).unwrap_or(0),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
},
|
},
|
|
@ -32,7 +32,7 @@ use crate::prelude::*;
|
||||||
use crate::repl::cid::Cid;
|
use crate::repl::cid::Cid;
|
||||||
use crate::schema::{SchemaAttribute, SchemaClass, SchemaTransaction};
|
use crate::schema::{SchemaAttribute, SchemaClass, SchemaTransaction};
|
||||||
use crate::value::{IndexType, SyntaxType};
|
use crate::value::{IndexType, SyntaxType};
|
||||||
use crate::value::{PartialValue, Value};
|
use crate::value::{IntentTokenState, PartialValue, Value};
|
||||||
use crate::valueset::ValueSet;
|
use crate::valueset::ValueSet;
|
||||||
use kanidm_proto::v1::Entry as ProtoEntry;
|
use kanidm_proto::v1::Entry as ProtoEntry;
|
||||||
use kanidm_proto::v1::Filter as ProtoFilter;
|
use kanidm_proto::v1::Filter as ProtoFilter;
|
||||||
|
@ -1605,6 +1605,14 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
||||||
self.attrs.get(attr).and_then(|vs| vs.as_oauthscopemap())
|
self.attrs.get(attr).and_then(|vs| vs.as_oauthscopemap())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline(always)]
|
||||||
|
pub fn get_ava_as_intenttokens(
|
||||||
|
&self,
|
||||||
|
attr: &str,
|
||||||
|
) -> Option<&std::collections::BTreeMap<Uuid, IntentTokenState>> {
|
||||||
|
self.attrs.get(attr).and_then(|vs| vs.as_intenttoken())
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
/// If possible, return an iterator over the set of values transformed into a `&str`.
|
/// If possible, return an iterator over the set of values transformed into a `&str`.
|
||||||
pub fn get_ava_as_str(&self, attr: &str) -> Option<impl Iterator<Item = &str>> {
|
pub fn get_ava_as_str(&self, attr: &str) -> Option<impl Iterator<Item = &str>> {
|
||||||
|
@ -1795,6 +1803,7 @@ impl<VALID, STATE> Entry<VALID, STATE> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
/// Test if the following filter applies to and matches this entry.
|
/// Test if the following filter applies to and matches this entry.
|
||||||
pub fn entry_match_no_index(&self, filter: &Filter<FilterValidResolved>) -> bool {
|
pub fn entry_match_no_index(&self, filter: &Filter<FilterValidResolved>) -> bool {
|
||||||
|
let _entered = trace_span!("entry::entry_match_no_index").entered();
|
||||||
self.entry_match_no_index_inner(filter.to_inner())
|
self.entry_match_no_index_inner(filter.to_inner())
|
||||||
}
|
}
|
||||||
|
|
|
@ -748,6 +748,22 @@ impl AuthEventStep {
|
||||||
cred: AuthCredential::Password(pw.to_string()),
|
cred: AuthCredential::Password(pw.to_string()),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn cred_step_totp(sid: Uuid, totp: u32) -> Self {
|
||||||
|
AuthEventStep::Cred(AuthEventStepCred {
|
||||||
|
sessionid: sid,
|
||||||
|
cred: AuthCredential::Totp(totp),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn cred_step_backup_code(sid: Uuid, code: &str) -> Self {
|
||||||
|
AuthEventStep::Cred(AuthEventStepCred {
|
||||||
|
sessionid: sid,
|
||||||
|
cred: AuthCredential::BackupCode(code.to_string()),
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
@ -804,6 +820,22 @@ impl AuthEvent {
|
||||||
step: AuthEventStep::cred_step_password(sid, pw),
|
step: AuthEventStep::cred_step_password(sid, pw),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn cred_step_totp(sid: Uuid, totp: u32) -> Self {
|
||||||
|
AuthEvent {
|
||||||
|
ident: None,
|
||||||
|
step: AuthEventStep::cred_step_totp(sid, totp),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub fn cred_step_backup_code(sid: Uuid, code: &str) -> Self {
|
||||||
|
AuthEvent {
|
||||||
|
ident: None,
|
||||||
|
step: AuthEventStep::cred_step_backup_code(sid, code),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Probably should be a struct with the session id present.
|
// Probably should be a struct with the session id present.
|
|
@ -12,8 +12,9 @@ use crate::credential::totp::Totp;
|
||||||
use crate::credential::{softlock::CredSoftLockPolicy, Credential};
|
use crate::credential::{softlock::CredSoftLockPolicy, Credential};
|
||||||
use crate::idm::group::Group;
|
use crate::idm::group::Group;
|
||||||
use crate::modify::{ModifyInvalid, ModifyList};
|
use crate::modify::{ModifyInvalid, ModifyList};
|
||||||
use crate::value::{PartialValue, Value};
|
use crate::value::{IntentTokenState, PartialValue, Value};
|
||||||
|
|
||||||
|
use std::collections::BTreeMap;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use time::OffsetDateTime;
|
use time::OffsetDateTime;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
@ -76,6 +77,11 @@ macro_rules! try_from_entry {
|
||||||
|
|
||||||
let uuid = $value.get_uuid().clone();
|
let uuid = $value.get_uuid().clone();
|
||||||
|
|
||||||
|
let credential_update_intent_tokens = $value
|
||||||
|
.get_ava_as_intenttokens("credential_update_intent_token")
|
||||||
|
.cloned()
|
||||||
|
.unwrap_or_else(|| BTreeMap::new());
|
||||||
|
|
||||||
Ok(Account {
|
Ok(Account {
|
||||||
uuid,
|
uuid,
|
||||||
name,
|
name,
|
||||||
|
@ -88,6 +94,7 @@ macro_rules! try_from_entry {
|
||||||
spn,
|
spn,
|
||||||
mail_primary,
|
mail_primary,
|
||||||
mail,
|
mail,
|
||||||
|
credential_update_intent_tokens,
|
||||||
})
|
})
|
||||||
}};
|
}};
|
||||||
}
|
}
|
||||||
|
@ -110,14 +117,12 @@ pub(crate) struct Account {
|
||||||
pub valid_from: Option<OffsetDateTime>,
|
pub valid_from: Option<OffsetDateTime>,
|
||||||
pub expire: Option<OffsetDateTime>,
|
pub expire: Option<OffsetDateTime>,
|
||||||
pub radius_secret: Option<String>,
|
pub radius_secret: Option<String>,
|
||||||
// primary: Credential
|
|
||||||
// app_creds: Vec<Credential>
|
|
||||||
// account expiry? (as opposed to cred expiry)
|
|
||||||
pub spn: String,
|
pub spn: String,
|
||||||
// TODO #256: When you add mail, you should update the check to zxcvbn
|
// TODO #256: When you add mail, you should update the check to zxcvbn
|
||||||
// to include these.
|
// to include these.
|
||||||
pub mail_primary: Option<String>,
|
pub mail_primary: Option<String>,
|
||||||
pub mail: Vec<String>,
|
pub mail: Vec<String>,
|
||||||
|
pub credential_update_intent_tokens: BTreeMap<Uuid, IntentTokenState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Account {
|
impl Account {
|
|
@ -585,6 +585,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");
|
||||||
let as_state = AuthState::Choose(valid_mechs);
|
let as_state = AuthState::Choose(valid_mechs);
|
||||||
(Some(auth_session), as_state)
|
(Some(auth_session), as_state)
|
||||||
}
|
}
|
||||||
|
@ -629,6 +630,7 @@ impl AuthSession {
|
||||||
let allowed: Vec<_> = allowed_handler.next_auth_allowed();
|
let allowed: Vec<_> = allowed_handler.next_auth_allowed();
|
||||||
|
|
||||||
if allowed.is_empty() {
|
if allowed.is_empty() {
|
||||||
|
security_info!("Unable to negotiate credentials");
|
||||||
(
|
(
|
||||||
None,
|
None,
|
||||||
Err(OperationError::InvalidAuthState(
|
Err(OperationError::InvalidAuthState(
|
||||||
|
@ -642,6 +644,7 @@ impl AuthSession {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
security_error!("Unable to select a credential for authentication");
|
||||||
(
|
(
|
||||||
Some(AuthSessionState::Denied(BAD_CREDENTIALS)),
|
Some(AuthSessionState::Denied(BAD_CREDENTIALS)),
|
||||||
Ok(AuthState::Denied(BAD_CREDENTIALS.to_string())),
|
Ok(AuthState::Denied(BAD_CREDENTIALS.to_string())),
|
1702
kanidmd/idm/src/idm/credupdatesession.rs
Normal file
1702
kanidmd/idm/src/idm/credupdatesession.rs
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,7 +1,5 @@
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
|
|
||||||
use uuid::Uuid;
|
|
||||||
|
|
||||||
use kanidm_proto::v1::OperationError;
|
use kanidm_proto::v1::OperationError;
|
||||||
use webauthn_rs::proto::RegisterPublicKeyCredential;
|
use webauthn_rs::proto::RegisterPublicKeyCredential;
|
||||||
|
|
||||||
|
@ -25,11 +23,11 @@ impl PasswordChangeEvent {
|
||||||
cleartext: String,
|
cleartext: String,
|
||||||
// qs: &QueryServerWriteTransaction,
|
// qs: &QueryServerWriteTransaction,
|
||||||
) -> Result<Self, OperationError> {
|
) -> Result<Self, OperationError> {
|
||||||
let u = ident.get_uuid().ok_or(OperationError::InvalidState)?;
|
let target = ident.get_uuid().ok_or(OperationError::InvalidState)?;
|
||||||
|
|
||||||
Ok(PasswordChangeEvent {
|
Ok(PasswordChangeEvent {
|
||||||
ident,
|
ident,
|
||||||
target: u,
|
target,
|
||||||
cleartext,
|
cleartext,
|
||||||
})
|
})
|
||||||
}
|
}
|
|
@ -5,6 +5,7 @@
|
||||||
|
|
||||||
pub(crate) mod account;
|
pub(crate) mod account;
|
||||||
pub(crate) mod authsession;
|
pub(crate) mod authsession;
|
||||||
|
pub(crate) mod credupdatesession;
|
||||||
pub(crate) mod delayed;
|
pub(crate) mod delayed;
|
||||||
pub(crate) mod event;
|
pub(crate) mod event;
|
||||||
pub(crate) mod group;
|
pub(crate) mod group;
|
|
@ -6,6 +6,7 @@ use crate::event::{AuthEvent, AuthEventStep, AuthResult};
|
||||||
use crate::identity::{IdentType, IdentUser, Limits};
|
use crate::identity::{IdentType, IdentUser, Limits};
|
||||||
use crate::idm::account::Account;
|
use crate::idm::account::Account;
|
||||||
use crate::idm::authsession::AuthSession;
|
use crate::idm::authsession::AuthSession;
|
||||||
|
use crate::idm::credupdatesession::CredentialUpdateSessionMutex;
|
||||||
use crate::idm::event::{
|
use crate::idm::event::{
|
||||||
AcceptSha1TotpEvent, CredentialStatusEvent, GeneratePasswordEvent, GenerateTotpEvent,
|
AcceptSha1TotpEvent, CredentialStatusEvent, GeneratePasswordEvent, GenerateTotpEvent,
|
||||||
LdapAuthEvent, PasswordChangeEvent, RadiusAuthTokenEvent, RegenerateRadiusSecretEvent,
|
LdapAuthEvent, PasswordChangeEvent, RadiusAuthTokenEvent, RegenerateRadiusSecretEvent,
|
||||||
|
@ -38,8 +39,8 @@ use crate::idm::delayed::{
|
||||||
|
|
||||||
use hashbrown::HashSet;
|
use hashbrown::HashSet;
|
||||||
use kanidm_proto::v1::{
|
use kanidm_proto::v1::{
|
||||||
AuthType, BackupCodesView, CredentialStatus, RadiusAuthToken, SetCredentialResponse,
|
AuthType, BackupCodesView, CredentialStatus, PasswordFeedback, RadiusAuthToken,
|
||||||
UnixGroupToken, UnixUserToken, UserAuthToken,
|
SetCredentialResponse, UnixGroupToken, UnixUserToken, UserAuthToken,
|
||||||
};
|
};
|
||||||
|
|
||||||
use compact_jwt::{Jws, JwsSigner, JwsUnverified, JwsValidator};
|
use compact_jwt::{Jws, JwsSigner, JwsUnverified, JwsValidator};
|
||||||
|
@ -56,7 +57,7 @@ use core::task::{Context, Poll};
|
||||||
use futures::task as futures_task;
|
use futures::task as futures_task;
|
||||||
|
|
||||||
use concread::{
|
use concread::{
|
||||||
bptree::{BptreeMap, BptreeMapWriteTxn},
|
bptree::{BptreeMap, BptreeMapReadTxn, BptreeMapWriteTxn},
|
||||||
cowcell::{CowCellReadTxn, CowCellWriteTxn},
|
cowcell::{CowCellReadTxn, CowCellWriteTxn},
|
||||||
hashmap::HashMap,
|
hashmap::HashMap,
|
||||||
CowCell,
|
CowCell,
|
||||||
|
@ -79,8 +80,6 @@ use tracing::trace;
|
||||||
type AuthSessionMutex = Arc<Mutex<AuthSession>>;
|
type AuthSessionMutex = Arc<Mutex<AuthSession>>;
|
||||||
type CredSoftLockMutex = Arc<Mutex<CredSoftLock>>;
|
type CredSoftLockMutex = Arc<Mutex<CredSoftLock>>;
|
||||||
|
|
||||||
// type CredUpdateSessionMutex = Arc<Mutex<CredUpdateSession>>;
|
|
||||||
|
|
||||||
pub struct IdmServer {
|
pub struct IdmServer {
|
||||||
// There is a good reason to keep this single thread - it
|
// There is a good reason to keep this single thread - it
|
||||||
// means that limits to sessions can be easily applied and checked to
|
// means that limits to sessions can be easily applied and checked to
|
||||||
|
@ -91,7 +90,7 @@ pub struct IdmServer {
|
||||||
softlocks: HashMap<Uuid, CredSoftLockMutex>,
|
softlocks: HashMap<Uuid, CredSoftLockMutex>,
|
||||||
/// A set of in progress MFA registrations
|
/// A set of in progress MFA registrations
|
||||||
mfareg_sessions: BptreeMap<Uuid, MfaRegSession>,
|
mfareg_sessions: BptreeMap<Uuid, MfaRegSession>,
|
||||||
// cred_update_sessions: BptreeMap<Uuid, CredUpdateSessionMutex>,
|
cred_update_sessions: BptreeMap<Uuid, CredentialUpdateSessionMutex>,
|
||||||
/// Reference to the query server.
|
/// Reference to the query server.
|
||||||
qs: QueryServer,
|
qs: QueryServer,
|
||||||
/// The configured crypto policy for the IDM server. Later this could be transactional and loaded from the db similar to access. But today it's just to allow dynamic pbkdf2rounds
|
/// The configured crypto policy for the IDM server. Later this could be transactional and loaded from the db similar to access. But today it's just to allow dynamic pbkdf2rounds
|
||||||
|
@ -124,6 +123,16 @@ pub struct IdmServerAuthTransaction<'a> {
|
||||||
uat_jwt_validator: CowCellReadTxn<JwsValidator>,
|
uat_jwt_validator: CowCellReadTxn<JwsValidator>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub(crate) struct IdmServerCredUpdateTransaction<'a> {
|
||||||
|
pub _qs_read: QueryServerReadTransaction<'a>,
|
||||||
|
// sid: Sid,
|
||||||
|
pub _webauthn: &'a Webauthn<WebauthnDomainConfig>,
|
||||||
|
pub pw_badlist_cache: CowCellReadTxn<HashSet<String>>,
|
||||||
|
pub cred_update_sessions: BptreeMapReadTxn<'a, Uuid, CredentialUpdateSessionMutex>,
|
||||||
|
pub token_enc_key: CowCellReadTxn<Fernet>,
|
||||||
|
pub crypto_policy: &'a CryptoPolicy,
|
||||||
|
}
|
||||||
|
|
||||||
/// This contains read-only methods, like getting users, groups and other structured content.
|
/// This contains read-only methods, like getting users, groups and other structured content.
|
||||||
pub struct IdmServerProxyReadTransaction<'a> {
|
pub struct IdmServerProxyReadTransaction<'a> {
|
||||||
pub qs_read: QueryServerReadTransaction<'a>,
|
pub qs_read: QueryServerReadTransaction<'a>,
|
||||||
|
@ -137,13 +146,14 @@ pub struct IdmServerProxyWriteTransaction<'a> {
|
||||||
pub qs_write: QueryServerWriteTransaction<'a>,
|
pub qs_write: QueryServerWriteTransaction<'a>,
|
||||||
/// Associate to an event origin ID, which has a TS and a UUID instead
|
/// Associate to an event origin ID, which has a TS and a UUID instead
|
||||||
mfareg_sessions: BptreeMapWriteTxn<'a, Uuid, MfaRegSession>,
|
mfareg_sessions: BptreeMapWriteTxn<'a, Uuid, MfaRegSession>,
|
||||||
sid: Sid,
|
pub(crate) cred_update_sessions: BptreeMapWriteTxn<'a, Uuid, CredentialUpdateSessionMutex>,
|
||||||
|
pub(crate) sid: Sid,
|
||||||
crypto_policy: &'a CryptoPolicy,
|
crypto_policy: &'a CryptoPolicy,
|
||||||
webauthn: &'a Webauthn<WebauthnDomainConfig>,
|
webauthn: &'a Webauthn<WebauthnDomainConfig>,
|
||||||
pw_badlist_cache: CowCellWriteTxn<'a, HashSet<String>>,
|
pw_badlist_cache: CowCellWriteTxn<'a, HashSet<String>>,
|
||||||
uat_jwt_signer: CowCellWriteTxn<'a, JwsSigner>,
|
uat_jwt_signer: CowCellWriteTxn<'a, JwsSigner>,
|
||||||
uat_jwt_validator: CowCellWriteTxn<'a, JwsValidator>,
|
uat_jwt_validator: CowCellWriteTxn<'a, JwsValidator>,
|
||||||
token_enc_key: CowCellWriteTxn<'a, Fernet>,
|
pub(crate) token_enc_key: CowCellWriteTxn<'a, Fernet>,
|
||||||
oauth2rs: Oauth2ResourceServersWriteTransaction<'a>,
|
oauth2rs: Oauth2ResourceServersWriteTransaction<'a>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,6 +256,7 @@ impl IdmServer {
|
||||||
sessions: BptreeMap::new(),
|
sessions: BptreeMap::new(),
|
||||||
softlocks: HashMap::new(),
|
softlocks: HashMap::new(),
|
||||||
mfareg_sessions: BptreeMap::new(),
|
mfareg_sessions: BptreeMap::new(),
|
||||||
|
cred_update_sessions: BptreeMap::new(),
|
||||||
qs,
|
qs,
|
||||||
crypto_policy,
|
crypto_policy,
|
||||||
async_tx,
|
async_tx,
|
||||||
|
@ -312,6 +323,7 @@ impl IdmServer {
|
||||||
|
|
||||||
IdmServerProxyWriteTransaction {
|
IdmServerProxyWriteTransaction {
|
||||||
mfareg_sessions: self.mfareg_sessions.write(),
|
mfareg_sessions: self.mfareg_sessions.write(),
|
||||||
|
cred_update_sessions: self.cred_update_sessions.write(),
|
||||||
qs_write,
|
qs_write,
|
||||||
sid,
|
sid,
|
||||||
crypto_policy: &self.crypto_policy,
|
crypto_policy: &self.crypto_policy,
|
||||||
|
@ -324,6 +336,23 @@ impl IdmServer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn cred_update_transaction(&self) -> IdmServerCredUpdateTransaction<'_> {
|
||||||
|
task::block_on(self.cred_update_transaction_async())
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) async fn cred_update_transaction_async(&self) -> IdmServerCredUpdateTransaction<'_> {
|
||||||
|
IdmServerCredUpdateTransaction {
|
||||||
|
_qs_read: self.qs.read_async().await,
|
||||||
|
// sid: Sid,
|
||||||
|
_webauthn: &self.webauthn,
|
||||||
|
pw_badlist_cache: self.pw_badlist_cache.read(),
|
||||||
|
cred_update_sessions: self.cred_update_sessions.read(),
|
||||||
|
token_enc_key: self.token_enc_key.read(),
|
||||||
|
crypto_policy: &self.crypto_policy,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub(crate) async fn delayed_action(
|
pub(crate) async fn delayed_action(
|
||||||
&self,
|
&self,
|
||||||
|
@ -574,6 +603,8 @@ impl<'a> IdmServerAuthTransaction<'a> {
|
||||||
// out of the session tree.
|
// out of the session tree.
|
||||||
let account = Account::try_from_entry_ro(entry.as_ref(), &mut self.qs_read)?;
|
let account = Account::try_from_entry_ro(entry.as_ref(), &mut self.qs_read)?;
|
||||||
|
|
||||||
|
trace!(?account.primary);
|
||||||
|
|
||||||
// Intent to take both trees to write.
|
// Intent to take both trees to write.
|
||||||
let _session_ticket = self.session_ticket.acquire().await;
|
let _session_ticket = self.session_ticket.acquire().await;
|
||||||
|
|
||||||
|
@ -1247,14 +1278,16 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
|
|
||||||
// is the password at least 10 char?
|
// is the password at least 10 char?
|
||||||
if cleartext.len() < PW_MIN_LENGTH {
|
if cleartext.len() < PW_MIN_LENGTH {
|
||||||
return Err(OperationError::PasswordTooShort(PW_MIN_LENGTH));
|
return Err(OperationError::PasswordQuality(vec![
|
||||||
|
PasswordFeedback::TooShort(PW_MIN_LENGTH),
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// does the password pass zxcvbn?
|
// does the password pass zxcvbn?
|
||||||
|
|
||||||
let entropy = zxcvbn::zxcvbn(cleartext, related_inputs).map_err(|e| {
|
let entropy = zxcvbn::zxcvbn(cleartext, related_inputs).map_err(|e| {
|
||||||
admin_error!("zxcvbn check failure (password empty?) {:?}", e);
|
admin_error!("zxcvbn check failure (password empty?) {:?}", e);
|
||||||
OperationError::PasswordEmpty
|
OperationError::PasswordQuality(vec![PasswordFeedback::TooShort(PW_MIN_LENGTH)])
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
// check account pwpolicy (for 3 or 4)? Do we need pw strength beyond this
|
// check account pwpolicy (for 3 or 4)? Do we need pw strength beyond this
|
||||||
|
@ -1275,7 +1308,10 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
security_info!(?feedback, "pw quality feedback");
|
security_info!(?feedback, "pw quality feedback");
|
||||||
|
|
||||||
// return Err(OperationError::PasswordTooWeak(feedback))
|
// return Err(OperationError::PasswordTooWeak(feedback))
|
||||||
return Err(OperationError::PasswordTooWeak);
|
// return Err(OperationError::PasswordTooWeak);
|
||||||
|
return Err(OperationError::PasswordQuality(vec![
|
||||||
|
PasswordFeedback::BadListed,
|
||||||
|
]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// check a password badlist to eliminate more content
|
// check a password badlist to eliminate more content
|
||||||
|
@ -1283,7 +1319,9 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
// also, when pw_badlist_cache is read from DB, it is read as Value (iutf8 lowercase)
|
// also, when pw_badlist_cache is read from DB, it is read as Value (iutf8 lowercase)
|
||||||
if (&*self.pw_badlist_cache).contains(&cleartext.to_lowercase()) {
|
if (&*self.pw_badlist_cache).contains(&cleartext.to_lowercase()) {
|
||||||
security_info!("Password found in badlist, rejecting");
|
security_info!("Password found in badlist, rejecting");
|
||||||
Err(OperationError::PasswordBadListed)
|
Err(OperationError::PasswordQuality(vec![
|
||||||
|
PasswordFeedback::BadListed,
|
||||||
|
]))
|
||||||
} else {
|
} else {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -2073,6 +2111,7 @@ impl<'a> IdmServerProxyWriteTransaction<'a> {
|
||||||
self.token_enc_key.commit();
|
self.token_enc_key.commit();
|
||||||
self.pw_badlist_cache.commit();
|
self.pw_badlist_cache.commit();
|
||||||
self.mfareg_sessions.commit();
|
self.mfareg_sessions.commit();
|
||||||
|
self.cred_update_sessions.commit();
|
||||||
self.qs_write.commit()
|
self.qs_write.commit()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -3801,7 +3840,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_idm_bundy_uat_expiry() {
|
fn test_idm_jwt_uat_expiry() {
|
||||||
run_idm_test!(
|
run_idm_test!(
|
||||||
|qs: &QueryServer, idms: &IdmServer, _idms_delayed: &mut IdmServerDelayed| {
|
|qs: &QueryServer, idms: &IdmServer, _idms_delayed: &mut IdmServerDelayed| {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
||||||
|
@ -3931,7 +3970,7 @@ mod tests {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_idm_bundy_uat_token_key_reload() {
|
fn test_idm_jwt_uat_token_key_reload() {
|
||||||
run_idm_test!(
|
run_idm_test!(
|
||||||
|qs: &QueryServer, idms: &IdmServer, _idms_delayed: &mut IdmServerDelayed| {
|
|qs: &QueryServer, idms: &IdmServer, _idms_delayed: &mut IdmServerDelayed| {
|
||||||
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
let ct = Duration::from_secs(TEST_CURRENT_TIME);
|
|
@ -2,7 +2,7 @@
|
||||||
//! which is used to process authentication, store identities and enforce access controls.
|
//! which is used to process authentication, store identities and enforce access controls.
|
||||||
|
|
||||||
#![recursion_limit = "512"]
|
#![recursion_limit = "512"]
|
||||||
#![deny(warnings)]
|
// #![deny(warnings)]
|
||||||
#![warn(unused_extern_crates)]
|
#![warn(unused_extern_crates)]
|
||||||
#![deny(clippy::todo)]
|
#![deny(clippy::todo)]
|
||||||
#![deny(clippy::unimplemented)]
|
#![deny(clippy::unimplemented)]
|
||||||
|
@ -43,8 +43,8 @@ pub mod identity;
|
||||||
pub mod interval;
|
pub mod interval;
|
||||||
pub mod ldap;
|
pub mod ldap;
|
||||||
mod modify;
|
mod modify;
|
||||||
pub(crate) mod value;
|
pub mod value;
|
||||||
pub(crate) mod valueset;
|
pub mod valueset;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
mod plugins;
|
mod plugins;
|
||||||
mod access;
|
mod access;
|
|
@ -171,8 +171,6 @@ macro_rules! run_idm_test_inner {
|
||||||
use crate::prelude::*;
|
use crate::prelude::*;
|
||||||
#[allow(unused_imports)]
|
#[allow(unused_imports)]
|
||||||
use crate::schema::Schema;
|
use crate::schema::Schema;
|
||||||
|
|
||||||
let _ = crate::tracing_tree::test_init();
|
|
||||||
/*
|
/*
|
||||||
use env_logger;
|
use env_logger;
|
||||||
::std::env::set_var("RUST_LOG", "actix_web=debug,kanidm=debug");
|
::std::env::set_var("RUST_LOG", "actix_web=debug,kanidm=debug");
|
||||||
|
@ -213,6 +211,7 @@ where
|
||||||
&crate::idm::server::IdmServerDelayed,
|
&crate::idm::server::IdmServerDelayed,
|
||||||
),
|
),
|
||||||
{
|
{
|
||||||
|
let _ = crate::tracing_tree::test_level(tracing::Level::ERROR);
|
||||||
let _ = run_idm_test_inner!(test_fn);
|
let _ = run_idm_test_inner!(test_fn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -196,6 +196,7 @@ impl SchemaAttribute {
|
||||||
SyntaxType::OauthScope => v.is_oauthscope(),
|
SyntaxType::OauthScope => v.is_oauthscope(),
|
||||||
SyntaxType::OauthScopeMap => v.is_oauthscopemap() || v.is_refer(),
|
SyntaxType::OauthScopeMap => v.is_oauthscopemap() || v.is_refer(),
|
||||||
SyntaxType::PrivateBinary => v.is_privatebinary(),
|
SyntaxType::PrivateBinary => v.is_privatebinary(),
|
||||||
|
SyntaxType::IntentToken => matches!(v, PartialValue::IntentToken(_)),
|
||||||
};
|
};
|
||||||
if r {
|
if r {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -235,6 +236,7 @@ impl SchemaAttribute {
|
||||||
SyntaxType::OauthScope => v.is_oauthscope(),
|
SyntaxType::OauthScope => v.is_oauthscope(),
|
||||||
SyntaxType::OauthScopeMap => v.is_oauthscopemap() || v.is_refer(),
|
SyntaxType::OauthScopeMap => v.is_oauthscopemap() || v.is_refer(),
|
||||||
SyntaxType::PrivateBinary => v.is_privatebinary(),
|
SyntaxType::PrivateBinary => v.is_privatebinary(),
|
||||||
|
SyntaxType::IntentToken => matches!(v, Value::IntentToken(_, _)),
|
||||||
};
|
};
|
||||||
if r {
|
if r {
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -281,6 +283,7 @@ impl SchemaAttribute {
|
||||||
SyntaxType::OauthScope => ava.is_oauthscope(),
|
SyntaxType::OauthScope => ava.is_oauthscope(),
|
||||||
SyntaxType::OauthScopeMap => ava.is_oauthscopemap(),
|
SyntaxType::OauthScopeMap => ava.is_oauthscopemap(),
|
||||||
SyntaxType::PrivateBinary => ava.is_privatebinary(),
|
SyntaxType::PrivateBinary => ava.is_privatebinary(),
|
||||||
|
SyntaxType::IntentToken => ava.is_intenttoken(),
|
||||||
};
|
};
|
||||||
if valid && ava.validate() {
|
if valid && ava.validate() {
|
||||||
Ok(())
|
Ok(())
|
|
@ -514,6 +514,7 @@ pub trait QueryServerTransaction<'a> {
|
||||||
.ok_or_else(|| OperationError::InvalidAttribute("Invalid Oauth Scope syntax".to_string())),
|
.ok_or_else(|| OperationError::InvalidAttribute("Invalid Oauth Scope syntax".to_string())),
|
||||||
SyntaxType::OauthScopeMap => Err(OperationError::InvalidAttribute("Oauth Scope Maps can not be supplied through modification - please use the IDM api".to_string())),
|
SyntaxType::OauthScopeMap => Err(OperationError::InvalidAttribute("Oauth Scope Maps can not be supplied through modification - please use the IDM api".to_string())),
|
||||||
SyntaxType::PrivateBinary => Err(OperationError::InvalidAttribute("Private Binary Values can not be supplied through modification".to_string())),
|
SyntaxType::PrivateBinary => Err(OperationError::InvalidAttribute("Private Binary Values can not be supplied through modification".to_string())),
|
||||||
|
SyntaxType::IntentToken => Err(OperationError::InvalidAttribute("Intent Token Values can not be supplied through modification".to_string())),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -634,6 +635,13 @@ pub trait QueryServerTransaction<'a> {
|
||||||
}),
|
}),
|
||||||
SyntaxType::OauthScope => Ok(PartialValue::new_oauthscope(value)),
|
SyntaxType::OauthScope => Ok(PartialValue::new_oauthscope(value)),
|
||||||
SyntaxType::PrivateBinary => Ok(PartialValue::PrivateBinary),
|
SyntaxType::PrivateBinary => Ok(PartialValue::PrivateBinary),
|
||||||
|
SyntaxType::IntentToken => {
|
||||||
|
PartialValue::new_intenttoken_s(value).ok_or_else(|| {
|
||||||
|
OperationError::InvalidAttribute(
|
||||||
|
"Invalid Intent Token ID (uuid) syntax".to_string(),
|
||||||
|
)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
|
@ -2295,6 +2303,7 @@ impl<'a> QueryServerWriteTransaction<'a> {
|
||||||
JSON_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE,
|
JSON_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE,
|
||||||
JSON_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE,
|
JSON_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE,
|
||||||
JSON_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER,
|
JSON_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER,
|
||||||
|
JSON_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
|
||||||
JSON_SCHEMA_CLASS_PERSON,
|
JSON_SCHEMA_CLASS_PERSON,
|
||||||
JSON_SCHEMA_CLASS_ORGPERSON,
|
JSON_SCHEMA_CLASS_ORGPERSON,
|
||||||
JSON_SCHEMA_CLASS_GROUP,
|
JSON_SCHEMA_CLASS_GROUP,
|
|
@ -8,4 +8,6 @@ mod timings;
|
||||||
|
|
||||||
pub use event_tag::EventTag;
|
pub use event_tag::EventTag;
|
||||||
pub use middleware::TreeMiddleware;
|
pub use middleware::TreeMiddleware;
|
||||||
pub use subscriber::{main_init, operation_id, test_init, TreePreProcessed, TreeSubscriber};
|
pub use subscriber::{
|
||||||
|
main_init, operation_id, test_init, test_level, TreePreProcessed, TreeSubscriber,
|
||||||
|
};
|
|
@ -556,10 +556,27 @@ pub fn main_init() -> JoinHandle<()> {
|
||||||
// and then getting dropped, making the global subscriber panic on further attempts to send logs.
|
// and then getting dropped, making the global subscriber panic on further attempts to send logs.
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
pub fn test_init() -> Result<(), SetGlobalDefaultError> {
|
pub fn test_init() -> Result<(), SetGlobalDefaultError> {
|
||||||
tracing::subscriber::set_global_default(TreeSubscriber {
|
let subscriber = TreeSubscriber {
|
||||||
inner: Registry::default().with(TreeLayer {
|
inner: Registry::default().with(TreeLayer {
|
||||||
fmt: LogFmt::Pretty,
|
fmt: LogFmt::Pretty,
|
||||||
processor: TestProcessor {},
|
processor: TestProcessor {},
|
||||||
}),
|
}),
|
||||||
})
|
};
|
||||||
|
|
||||||
|
tracing::subscriber::set_global_default(subscriber)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
pub fn test_level(level: tracing::Level) -> Result<(), SetGlobalDefaultError> {
|
||||||
|
let subscriber = TreeSubscriber {
|
||||||
|
inner: Registry::default().with(TreeLayer {
|
||||||
|
fmt: LogFmt::Pretty,
|
||||||
|
processor: TestProcessor {},
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
|
let subscriber =
|
||||||
|
tracing_subscriber::filter::LevelFilter::from_level(level).with_subscriber(subscriber);
|
||||||
|
|
||||||
|
tracing::subscriber::set_global_default(subscriber)
|
||||||
}
|
}
|
|
@ -68,6 +68,13 @@ pub enum IndexType {
|
||||||
SubString,
|
SubString,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
|
pub enum IntentTokenState {
|
||||||
|
Valid,
|
||||||
|
InProgress(Uuid, Duration),
|
||||||
|
Consumed,
|
||||||
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for IndexType {
|
impl TryFrom<&str> for IndexType {
|
||||||
type Error = ();
|
type Error = ();
|
||||||
|
|
||||||
|
@ -154,6 +161,7 @@ pub enum SyntaxType {
|
||||||
OauthScope,
|
OauthScope,
|
||||||
OauthScopeMap,
|
OauthScopeMap,
|
||||||
PrivateBinary,
|
PrivateBinary,
|
||||||
|
IntentToken,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TryFrom<&str> for SyntaxType {
|
impl TryFrom<&str> for SyntaxType {
|
||||||
|
@ -185,6 +193,7 @@ impl TryFrom<&str> for SyntaxType {
|
||||||
"OAUTH_SCOPE" => Ok(SyntaxType::OauthScope),
|
"OAUTH_SCOPE" => Ok(SyntaxType::OauthScope),
|
||||||
"OAUTH_SCOPE_MAP" => Ok(SyntaxType::OauthScopeMap),
|
"OAUTH_SCOPE_MAP" => Ok(SyntaxType::OauthScopeMap),
|
||||||
"PRIVATE_BINARY" => Ok(SyntaxType::PrivateBinary),
|
"PRIVATE_BINARY" => Ok(SyntaxType::PrivateBinary),
|
||||||
|
"INTENT_TOKEN" => Ok(SyntaxType::IntentToken),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -217,6 +226,7 @@ impl TryFrom<usize> for SyntaxType {
|
||||||
19 => Ok(SyntaxType::OauthScope),
|
19 => Ok(SyntaxType::OauthScope),
|
||||||
20 => Ok(SyntaxType::OauthScopeMap),
|
20 => Ok(SyntaxType::OauthScopeMap),
|
||||||
21 => Ok(SyntaxType::PrivateBinary),
|
21 => Ok(SyntaxType::PrivateBinary),
|
||||||
|
22 => Ok(SyntaxType::IntentToken),
|
||||||
_ => Err(()),
|
_ => Err(()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -247,6 +257,7 @@ impl SyntaxType {
|
||||||
SyntaxType::OauthScope => 19,
|
SyntaxType::OauthScope => 19,
|
||||||
SyntaxType::OauthScopeMap => 20,
|
SyntaxType::OauthScopeMap => 20,
|
||||||
SyntaxType::PrivateBinary => 21,
|
SyntaxType::PrivateBinary => 21,
|
||||||
|
SyntaxType::IntentToken => 22,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -276,6 +287,7 @@ impl fmt::Display for SyntaxType {
|
||||||
SyntaxType::OauthScope => "OAUTH_SCOPE",
|
SyntaxType::OauthScope => "OAUTH_SCOPE",
|
||||||
SyntaxType::OauthScopeMap => "OAUTH_SCOPE_MAP",
|
SyntaxType::OauthScopeMap => "OAUTH_SCOPE_MAP",
|
||||||
SyntaxType::PrivateBinary => "PRIVATE_BINARY",
|
SyntaxType::PrivateBinary => "PRIVATE_BINARY",
|
||||||
|
SyntaxType::IntentToken => "INTENT_TOKEN",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -320,6 +332,9 @@ pub enum PartialValue {
|
||||||
// Enumeration(String),
|
// Enumeration(String),
|
||||||
// Float64(f64),
|
// Float64(f64),
|
||||||
RestrictedString(String),
|
RestrictedString(String),
|
||||||
|
IntentToken(Uuid),
|
||||||
|
TrustedDeviceEnrollment(Uuid),
|
||||||
|
AuthSession(Uuid),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<SyntaxType> for PartialValue {
|
impl From<SyntaxType> for PartialValue {
|
||||||
|
@ -631,6 +646,13 @@ impl PartialValue {
|
||||||
PartialValue::RestrictedString(s.to_string())
|
PartialValue::RestrictedString(s.to_string())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn new_intenttoken_s(us: &str) -> Option<Self> {
|
||||||
|
match Uuid::parse_str(us) {
|
||||||
|
Ok(u) => Some(PartialValue::IntentToken(u)),
|
||||||
|
Err(_) => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_str(&self) -> Option<&str> {
|
pub fn to_str(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
PartialValue::Utf8(s) => Some(s.as_str()),
|
PartialValue::Utf8(s) => Some(s.as_str()),
|
||||||
|
@ -682,6 +704,9 @@ impl PartialValue {
|
||||||
PartialValue::OauthScopeMap(u) => u.to_hyphenated_ref().to_string(),
|
PartialValue::OauthScopeMap(u) => u.to_hyphenated_ref().to_string(),
|
||||||
PartialValue::Address(a) => a.to_string(),
|
PartialValue::Address(a) => a.to_string(),
|
||||||
PartialValue::PhoneNumber(a) => a.to_string(),
|
PartialValue::PhoneNumber(a) => a.to_string(),
|
||||||
|
PartialValue::IntentToken(u) => u.to_hyphenated_ref().to_string(),
|
||||||
|
PartialValue::TrustedDeviceEnrollment(u) => u.to_hyphenated_ref().to_string(),
|
||||||
|
PartialValue::AuthSession(u) => u.to_hyphenated_ref().to_string(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -726,6 +751,9 @@ pub enum Value {
|
||||||
// Enumeration(String),
|
// Enumeration(String),
|
||||||
// Float64(f64),
|
// Float64(f64),
|
||||||
RestrictedString(String),
|
RestrictedString(String),
|
||||||
|
IntentToken(Uuid, IntentTokenState),
|
||||||
|
TrustedDeviceEnrollment(Uuid),
|
||||||
|
AuthSession(Uuid),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for Value {
|
impl PartialEq for Value {
|
||||||
|
@ -1411,6 +1439,27 @@ impl Value {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn to_intenttoken(self) -> Option<(Uuid, IntentTokenState)> {
|
||||||
|
match self {
|
||||||
|
Value::IntentToken(u, s) => Some((u, s)),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_trusteddeviceenrollment(self) -> Option<(Uuid, ())> {
|
||||||
|
match self {
|
||||||
|
Value::TrustedDeviceEnrollment(u) => Some((u, ())),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_authsession(self) -> Option<(Uuid, ())> {
|
||||||
|
match self {
|
||||||
|
Value::AuthSession(u) => Some((u, ())),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn migrate_iutf8_iname(self) -> Option<Self> {
|
pub fn migrate_iutf8_iname(self) -> Option<Self> {
|
||||||
match self {
|
match self {
|
||||||
Value::Iutf8(v) => Some(Value::Iname(v)),
|
Value::Iutf8(v) => Some(Value::Iname(v)),
|
|
@ -13,10 +13,10 @@ use time::OffsetDateTime;
|
||||||
use tracing::trace;
|
use tracing::trace;
|
||||||
|
|
||||||
use crate::be::dbvalue::{
|
use crate::be::dbvalue::{
|
||||||
DbCidV1, DbValueAddressV1, DbValueCredV1, DbValueEmailAddressV1, DbValueOauthScopeMapV1,
|
DbCidV1, DbValueAddressV1, DbValueCredV1, DbValueEmailAddressV1, DbValueIntentTokenStateV1,
|
||||||
DbValuePhoneNumberV1, DbValueTaggedStringV1, DbValueV1,
|
DbValueOauthScopeMapV1, DbValuePhoneNumberV1, DbValueTaggedStringV1, DbValueV1,
|
||||||
};
|
};
|
||||||
use crate::value::{Address, INAME_RE, NSUNIQUEID_RE, OAUTHSCOPE_RE};
|
use crate::value::{Address, IntentTokenState, INAME_RE, NSUNIQUEID_RE, OAUTHSCOPE_RE};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
enum I {
|
enum I {
|
||||||
|
@ -34,6 +34,9 @@ enum I {
|
||||||
SecretValue(SmolSet<[String; 1]>),
|
SecretValue(SmolSet<[String; 1]>),
|
||||||
Spn(BTreeSet<(String, String)>),
|
Spn(BTreeSet<(String, String)>),
|
||||||
Uint32(SmolSet<[u32; 1]>),
|
Uint32(SmolSet<[u32; 1]>),
|
||||||
|
// Uint64(SmolSet<[u64; 1]>),
|
||||||
|
// Int64(SmolSet<[i64; 1]>),
|
||||||
|
// Float64(Vec<[f64; 1]>),
|
||||||
Cid(SmolSet<[Cid; 1]>),
|
Cid(SmolSet<[Cid; 1]>),
|
||||||
Nsuniqueid(BTreeSet<String>),
|
Nsuniqueid(BTreeSet<String>),
|
||||||
DateTime(SmolSet<[OffsetDateTime; 1]>),
|
DateTime(SmolSet<[OffsetDateTime; 1]>),
|
||||||
|
@ -53,9 +56,10 @@ enum I {
|
||||||
OauthScopeMap(BTreeMap<Uuid, BTreeSet<String>>),
|
OauthScopeMap(BTreeMap<Uuid, BTreeSet<String>>),
|
||||||
PrivateBinary(SmolSet<[Vec<u8>; 1]>),
|
PrivateBinary(SmolSet<[Vec<u8>; 1]>),
|
||||||
PublicBinary(BTreeMap<String, Vec<u8>>),
|
PublicBinary(BTreeMap<String, Vec<u8>>),
|
||||||
// Enumeration(SmolSet<[String; 1]>),
|
|
||||||
// Float64(Vec<[f64; 1]>),
|
|
||||||
RestrictedString(BTreeSet<String>),
|
RestrictedString(BTreeSet<String>),
|
||||||
|
IntentToken(BTreeMap<Uuid, IntentTokenState>),
|
||||||
|
TrustedDeviceEnrollment(BTreeMap<Uuid, ()>),
|
||||||
|
AuthSession(BTreeMap<Uuid, ()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ValueSet {
|
pub struct ValueSet {
|
||||||
|
@ -126,6 +130,9 @@ impl From<Value> for ValueSet {
|
||||||
Value::Address(a) => I::Address { set: btreeset![a] },
|
Value::Address(a) => I::Address { set: btreeset![a] },
|
||||||
Value::PublicBinary(tag, bin) => I::PublicBinary(btreemap![(tag, bin)]),
|
Value::PublicBinary(tag, bin) => I::PublicBinary(btreemap![(tag, bin)]),
|
||||||
Value::RestrictedString(s) => I::RestrictedString(btreeset![s]),
|
Value::RestrictedString(s) => I::RestrictedString(btreeset![s]),
|
||||||
|
Value::IntentToken(u, t) => I::IntentToken(btreemap![(u, t)]),
|
||||||
|
Value::TrustedDeviceEnrollment(u) => I::TrustedDeviceEnrollment(btreemap![(u, ())]),
|
||||||
|
Value::AuthSession(u) => I::AuthSession(btreemap![(u, ())]),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -216,6 +223,20 @@ impl TryFrom<DbValueV1> for ValueSet {
|
||||||
// I::Address { set: btreeset![a] },
|
// I::Address { set: btreeset![a] },
|
||||||
DbValueV1::PublicBinary(tag, bin) => I::PublicBinary(btreemap![(tag, bin)]),
|
DbValueV1::PublicBinary(tag, bin) => I::PublicBinary(btreemap![(tag, bin)]),
|
||||||
DbValueV1::RestrictedString(s) => I::RestrictedString(btreeset![s]),
|
DbValueV1::RestrictedString(s) => I::RestrictedString(btreeset![s]),
|
||||||
|
DbValueV1::IntentToken { u, s } => {
|
||||||
|
let ts = match s {
|
||||||
|
DbValueIntentTokenStateV1::Valid => IntentTokenState::Valid,
|
||||||
|
DbValueIntentTokenStateV1::InProgress(pu, pd) => {
|
||||||
|
IntentTokenState::InProgress(pu, pd)
|
||||||
|
}
|
||||||
|
DbValueIntentTokenStateV1::Consumed => IntentTokenState::Consumed,
|
||||||
|
};
|
||||||
|
I::IntentToken(btreemap![(u, ts)])
|
||||||
|
}
|
||||||
|
DbValueV1::TrustedDeviceEnrollment { u } => {
|
||||||
|
I::TrustedDeviceEnrollment(btreemap![(u, ())])
|
||||||
|
}
|
||||||
|
DbValueV1::AuthSession { u } => I::AuthSession(btreemap![(u, ())]),
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -305,6 +326,30 @@ impl ValueSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(I::RestrictedString(set), Value::RestrictedString(s)) => Ok(set.insert(s)),
|
(I::RestrictedString(set), Value::RestrictedString(s)) => Ok(set.insert(s)),
|
||||||
|
(I::IntentToken(map), Value::IntentToken(u, ts)) => {
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(ts);
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::TrustedDeviceEnrollment(map), Value::TrustedDeviceEnrollment(u)) => {
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(());
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::AuthSession(map), Value::AuthSession(u)) => {
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(());
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
(_, _) => Err(OperationError::InvalidValueState),
|
(_, _) => Err(OperationError::InvalidValueState),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -419,6 +464,38 @@ impl ValueSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(I::RestrictedString(set), DbValueV1::RestrictedString(s)) => Ok(set.insert(s)),
|
(I::RestrictedString(set), DbValueV1::RestrictedString(s)) => Ok(set.insert(s)),
|
||||||
|
(I::IntentToken(map), DbValueV1::IntentToken { u, s }) => {
|
||||||
|
let ts = match s {
|
||||||
|
DbValueIntentTokenStateV1::Valid => IntentTokenState::Valid,
|
||||||
|
DbValueIntentTokenStateV1::InProgress(i, d) => {
|
||||||
|
IntentTokenState::InProgress(i, d)
|
||||||
|
}
|
||||||
|
DbValueIntentTokenStateV1::Consumed => IntentTokenState::Consumed,
|
||||||
|
};
|
||||||
|
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(ts);
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::TrustedDeviceEnrollment(map), DbValueV1::TrustedDeviceEnrollment { u }) => {
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(());
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::AuthSession(map), DbValueV1::AuthSession { u }) => {
|
||||||
|
if let BTreeEntry::Vacant(e) = map.entry(u) {
|
||||||
|
e.insert(());
|
||||||
|
Ok(true)
|
||||||
|
} else {
|
||||||
|
Ok(false)
|
||||||
|
}
|
||||||
|
}
|
||||||
(_, _) => Err(()),
|
(_, _) => Err(()),
|
||||||
}
|
}
|
||||||
.and_then(|is_new| {
|
.and_then(|is_new| {
|
||||||
|
@ -542,6 +619,15 @@ impl ValueSet {
|
||||||
(I::RestrictedString(a), I::RestrictedString(b)) => {
|
(I::RestrictedString(a), I::RestrictedString(b)) => {
|
||||||
mergesets!(a, b)
|
mergesets!(a, b)
|
||||||
}
|
}
|
||||||
|
(I::IntentToken(a), I::IntentToken(b)) => {
|
||||||
|
mergemaps!(a, b)
|
||||||
|
}
|
||||||
|
(I::TrustedDeviceEnrollment(a), I::TrustedDeviceEnrollment(b)) => {
|
||||||
|
mergemaps!(a, b)
|
||||||
|
}
|
||||||
|
(I::AuthSession(a), I::AuthSession(b)) => {
|
||||||
|
mergemaps!(a, b)
|
||||||
|
}
|
||||||
// I think that in this case, we need to specify self / everything as we are changing
|
// I think that in this case, we need to specify self / everything as we are changing
|
||||||
// type and we need to potentially purge everything, so we just return the left side.
|
// type and we need to potentially purge everything, so we just return the left side.
|
||||||
_ => Err(OperationError::InvalidValueState),
|
_ => Err(OperationError::InvalidValueState),
|
||||||
|
@ -652,6 +738,15 @@ impl ValueSet {
|
||||||
I::RestrictedString(set) => {
|
I::RestrictedString(set) => {
|
||||||
set.extend(iter.filter_map(|v| v.to_restrictedstring()));
|
set.extend(iter.filter_map(|v| v.to_restrictedstring()));
|
||||||
}
|
}
|
||||||
|
I::IntentToken(map) => {
|
||||||
|
map.extend(iter.filter_map(|v| v.to_intenttoken()));
|
||||||
|
}
|
||||||
|
I::TrustedDeviceEnrollment(map) => {
|
||||||
|
map.extend(iter.filter_map(|v| v.to_trusteddeviceenrollment()));
|
||||||
|
}
|
||||||
|
I::AuthSession(map) => {
|
||||||
|
map.extend(iter.filter_map(|v| v.to_authsession()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -737,6 +832,15 @@ impl ValueSet {
|
||||||
I::RestrictedString(set) => {
|
I::RestrictedString(set) => {
|
||||||
set.clear();
|
set.clear();
|
||||||
}
|
}
|
||||||
|
I::IntentToken(map) => {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
I::TrustedDeviceEnrollment(map) => {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
I::AuthSession(map) => {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
};
|
};
|
||||||
debug_assert!(self.is_empty());
|
debug_assert!(self.is_empty());
|
||||||
}
|
}
|
||||||
|
@ -831,6 +935,15 @@ impl ValueSet {
|
||||||
(I::RestrictedString(set), PartialValue::RestrictedString(s)) => {
|
(I::RestrictedString(set), PartialValue::RestrictedString(s)) => {
|
||||||
set.remove(s);
|
set.remove(s);
|
||||||
}
|
}
|
||||||
|
(I::IntentToken(map), PartialValue::IntentToken(t)) => {
|
||||||
|
map.remove(t);
|
||||||
|
}
|
||||||
|
(I::TrustedDeviceEnrollment(map), PartialValue::TrustedDeviceEnrollment(t)) => {
|
||||||
|
map.remove(t);
|
||||||
|
}
|
||||||
|
(I::AuthSession(map), PartialValue::AuthSession(t)) => {
|
||||||
|
map.remove(t);
|
||||||
|
}
|
||||||
(_, _) => {
|
(_, _) => {
|
||||||
debug_assert!(false)
|
debug_assert!(false)
|
||||||
}
|
}
|
||||||
|
@ -873,6 +986,11 @@ impl ValueSet {
|
||||||
(I::RestrictedString(set), PartialValue::RestrictedString(s)) => {
|
(I::RestrictedString(set), PartialValue::RestrictedString(s)) => {
|
||||||
set.contains(s.as_str())
|
set.contains(s.as_str())
|
||||||
}
|
}
|
||||||
|
(I::IntentToken(map), PartialValue::IntentToken(u)) => map.contains_key(u),
|
||||||
|
(I::TrustedDeviceEnrollment(map), PartialValue::TrustedDeviceEnrollment(u)) => {
|
||||||
|
map.contains_key(u)
|
||||||
|
}
|
||||||
|
(I::AuthSession(map), PartialValue::AuthSession(u)) => map.contains_key(u),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -925,6 +1043,9 @@ impl ValueSet {
|
||||||
I::PrivateBinary(set) => set.len(),
|
I::PrivateBinary(set) => set.len(),
|
||||||
I::PublicBinary(map) => map.len(),
|
I::PublicBinary(map) => map.len(),
|
||||||
I::RestrictedString(set) => set.len(),
|
I::RestrictedString(set) => set.len(),
|
||||||
|
I::IntentToken(map) => map.len(),
|
||||||
|
I::TrustedDeviceEnrollment(map) => map.len(),
|
||||||
|
I::AuthSession(map) => map.len(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -986,6 +1107,18 @@ impl ValueSet {
|
||||||
I::PrivateBinary(_set) => vec![],
|
I::PrivateBinary(_set) => vec![],
|
||||||
I::PublicBinary(map) => map.keys().cloned().collect(),
|
I::PublicBinary(map) => map.keys().cloned().collect(),
|
||||||
I::RestrictedString(set) => set.iter().cloned().collect(),
|
I::RestrictedString(set) => set.iter().cloned().collect(),
|
||||||
|
I::IntentToken(map) => map
|
||||||
|
.keys()
|
||||||
|
.map(|u| u.to_hyphenated_ref().to_string())
|
||||||
|
.collect(),
|
||||||
|
I::TrustedDeviceEnrollment(map) => map
|
||||||
|
.keys()
|
||||||
|
.map(|u| u.to_hyphenated_ref().to_string())
|
||||||
|
.collect(),
|
||||||
|
I::AuthSession(map) => map
|
||||||
|
.keys()
|
||||||
|
.map(|u| u.to_hyphenated_ref().to_string())
|
||||||
|
.collect(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1263,6 +1396,48 @@ impl ValueSet {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
(I::IntentToken(a), I::IntentToken(b)) => {
|
||||||
|
let x: BTreeMap<_, _> = a
|
||||||
|
.iter()
|
||||||
|
.filter(|(k, _)| b.contains_key(k))
|
||||||
|
.map(|(k, v)| (*k, v.clone()))
|
||||||
|
.collect();
|
||||||
|
if x.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ValueSet {
|
||||||
|
inner: I::IntentToken(x),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::TrustedDeviceEnrollment(a), I::TrustedDeviceEnrollment(b)) => {
|
||||||
|
let x: BTreeMap<_, _> = a
|
||||||
|
.iter()
|
||||||
|
.filter(|(k, _)| b.contains_key(k))
|
||||||
|
.map(|(k, v)| (*k, v.clone()))
|
||||||
|
.collect();
|
||||||
|
if x.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ValueSet {
|
||||||
|
inner: I::TrustedDeviceEnrollment(x),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
(I::AuthSession(a), I::AuthSession(b)) => {
|
||||||
|
let x: BTreeMap<_, _> = a
|
||||||
|
.iter()
|
||||||
|
.filter(|(k, _)| b.contains_key(k))
|
||||||
|
.map(|(k, v)| (*k, v.clone()))
|
||||||
|
.collect();
|
||||||
|
if x.is_empty() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
Some(ValueSet {
|
||||||
|
inner: I::AuthSession(x),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
// I think that in this case, we need to specify self / everything as we are changing
|
// I think that in this case, we need to specify self / everything as we are changing
|
||||||
// type and we need to potentially purge everything, so we just return the left side.
|
// type and we need to potentially purge everything, so we just return the left side.
|
||||||
_ => Some(self.clone()),
|
_ => Some(self.clone()),
|
||||||
|
@ -1550,6 +1725,13 @@ impl ValueSet {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn as_intenttoken(&self) -> Option<&BTreeMap<Uuid, IntentTokenState>> {
|
||||||
|
match &self.inner {
|
||||||
|
I::IntentToken(map) => Some(map),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn to_proto_string_clone_iter(&self) -> ProtoIter<'_> {
|
pub fn to_proto_string_clone_iter(&self) -> ProtoIter<'_> {
|
||||||
// to_proto_string_clone
|
// to_proto_string_clone
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
|
@ -1579,6 +1761,9 @@ impl ValueSet {
|
||||||
I::PrivateBinary(set) => ProtoIter::PrivateBinary(set.iter()),
|
I::PrivateBinary(set) => ProtoIter::PrivateBinary(set.iter()),
|
||||||
I::PublicBinary(set) => ProtoIter::PublicBinary(set.iter()),
|
I::PublicBinary(set) => ProtoIter::PublicBinary(set.iter()),
|
||||||
I::RestrictedString(set) => ProtoIter::RestrictedString(set.iter()),
|
I::RestrictedString(set) => ProtoIter::RestrictedString(set.iter()),
|
||||||
|
I::IntentToken(map) => ProtoIter::IntentToken(map.iter()),
|
||||||
|
I::TrustedDeviceEnrollment(map) => ProtoIter::TrustedDeviceEnrollment(map.iter()),
|
||||||
|
I::AuthSession(map) => ProtoIter::AuthSession(map.iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1614,6 +1799,9 @@ impl ValueSet {
|
||||||
I::PrivateBinary(set) => DbValueV1Iter::PrivateBinary(set.iter()),
|
I::PrivateBinary(set) => DbValueV1Iter::PrivateBinary(set.iter()),
|
||||||
I::PublicBinary(set) => DbValueV1Iter::PublicBinary(set.iter()),
|
I::PublicBinary(set) => DbValueV1Iter::PublicBinary(set.iter()),
|
||||||
I::RestrictedString(set) => DbValueV1Iter::RestrictedString(set.iter()),
|
I::RestrictedString(set) => DbValueV1Iter::RestrictedString(set.iter()),
|
||||||
|
I::IntentToken(map) => DbValueV1Iter::IntentToken(map.iter()),
|
||||||
|
I::TrustedDeviceEnrollment(map) => DbValueV1Iter::TrustedDeviceEnrollment(map.iter()),
|
||||||
|
I::AuthSession(map) => DbValueV1Iter::AuthSession(map.iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1645,6 +1833,11 @@ impl ValueSet {
|
||||||
I::PrivateBinary(set) => PartialValueIter::PrivateBinary(set.iter()),
|
I::PrivateBinary(set) => PartialValueIter::PrivateBinary(set.iter()),
|
||||||
I::PublicBinary(set) => PartialValueIter::PublicBinary(set.iter()),
|
I::PublicBinary(set) => PartialValueIter::PublicBinary(set.iter()),
|
||||||
I::RestrictedString(set) => PartialValueIter::RestrictedString(set.iter()),
|
I::RestrictedString(set) => PartialValueIter::RestrictedString(set.iter()),
|
||||||
|
I::IntentToken(map) => PartialValueIter::IntentToken(map.iter()),
|
||||||
|
I::TrustedDeviceEnrollment(map) => {
|
||||||
|
PartialValueIter::TrustedDeviceEnrollment(map.iter())
|
||||||
|
}
|
||||||
|
I::AuthSession(map) => PartialValueIter::AuthSession(map.iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1676,6 +1869,9 @@ impl ValueSet {
|
||||||
I::PrivateBinary(set) => ValueIter::PrivateBinary(set.iter()),
|
I::PrivateBinary(set) => ValueIter::PrivateBinary(set.iter()),
|
||||||
I::PublicBinary(set) => ValueIter::PublicBinary(set.iter()),
|
I::PublicBinary(set) => ValueIter::PublicBinary(set.iter()),
|
||||||
I::RestrictedString(set) => ValueIter::RestrictedString(set.iter()),
|
I::RestrictedString(set) => ValueIter::RestrictedString(set.iter()),
|
||||||
|
I::IntentToken(map) => ValueIter::IntentToken(map.iter()),
|
||||||
|
I::TrustedDeviceEnrollment(map) => ValueIter::TrustedDeviceEnrollment(map.iter()),
|
||||||
|
I::AuthSession(map) => ValueIter::AuthSession(map.iter()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1808,6 +2004,10 @@ impl ValueSet {
|
||||||
matches!(self.inner, I::PrivateBinary(_))
|
matches!(self.inner, I::PrivateBinary(_))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_intenttoken(&self) -> bool {
|
||||||
|
matches!(self.inner, I::IntentToken(_))
|
||||||
|
}
|
||||||
|
|
||||||
pub fn validate(&self) -> bool {
|
pub fn validate(&self) -> bool {
|
||||||
match &self.inner {
|
match &self.inner {
|
||||||
I::Iname(set) => set.iter().all(|s| {
|
I::Iname(set) => set.iter().all(|s| {
|
||||||
|
@ -1906,6 +2106,9 @@ impl PartialEq for ValueSet {
|
||||||
(I::PrivateBinary(a), I::PrivateBinary(b)) => a.eq(b),
|
(I::PrivateBinary(a), I::PrivateBinary(b)) => a.eq(b),
|
||||||
(I::PublicBinary(a), I::PublicBinary(b)) => a.eq(b),
|
(I::PublicBinary(a), I::PublicBinary(b)) => a.eq(b),
|
||||||
(I::RestrictedString(a), I::RestrictedString(b)) => a.eq(b),
|
(I::RestrictedString(a), I::RestrictedString(b)) => a.eq(b),
|
||||||
|
(I::IntentToken(a), I::IntentToken(b)) => a.eq(b),
|
||||||
|
(I::TrustedDeviceEnrollment(a), I::TrustedDeviceEnrollment(b)) => a.eq(b),
|
||||||
|
(I::AuthSession(a), I::AuthSession(b)) => a.eq(b),
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1973,6 +2176,9 @@ pub enum ValueIter<'a> {
|
||||||
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
||||||
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
||||||
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
||||||
|
IntentToken(std::collections::btree_map::Iter<'a, Uuid, IntentTokenState>),
|
||||||
|
TrustedDeviceEnrollment(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
|
AuthSession(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for ValueIter<'a> {
|
impl<'a> Iterator for ValueIter<'a> {
|
||||||
|
@ -2032,6 +2238,13 @@ impl<'a> Iterator for ValueIter<'a> {
|
||||||
ValueIter::RestrictedString(iter) => {
|
ValueIter::RestrictedString(iter) => {
|
||||||
iter.next().map(|i| Value::new_restrictedstring(i.clone()))
|
iter.next().map(|i| Value::new_restrictedstring(i.clone()))
|
||||||
}
|
}
|
||||||
|
ValueIter::IntentToken(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, ts)| Value::IntentToken(*u, ts.clone())),
|
||||||
|
ValueIter::TrustedDeviceEnrollment(iter) => {
|
||||||
|
iter.next().map(|(u, _)| Value::TrustedDeviceEnrollment(*u))
|
||||||
|
}
|
||||||
|
ValueIter::AuthSession(iter) => iter.next().map(|(u, _)| Value::AuthSession(*u)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2063,6 +2276,9 @@ pub enum PartialValueIter<'a> {
|
||||||
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
||||||
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
||||||
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
||||||
|
IntentToken(std::collections::btree_map::Iter<'a, Uuid, IntentTokenState>),
|
||||||
|
TrustedDeviceEnrollment(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
|
AuthSession(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for PartialValueIter<'a> {
|
impl<'a> Iterator for PartialValueIter<'a> {
|
||||||
|
@ -2135,6 +2351,15 @@ impl<'a> Iterator for PartialValueIter<'a> {
|
||||||
PartialValueIter::RestrictedString(iter) => iter
|
PartialValueIter::RestrictedString(iter) => iter
|
||||||
.next()
|
.next()
|
||||||
.map(|i| PartialValue::new_restrictedstring_s(i.as_str())),
|
.map(|i| PartialValue::new_restrictedstring_s(i.as_str())),
|
||||||
|
PartialValueIter::IntentToken(iter) => {
|
||||||
|
iter.next().map(|(u, _state)| PartialValue::IntentToken(*u))
|
||||||
|
}
|
||||||
|
PartialValueIter::TrustedDeviceEnrollment(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, _)| PartialValue::TrustedDeviceEnrollment(*u)),
|
||||||
|
PartialValueIter::AuthSession(iter) => {
|
||||||
|
iter.next().map(|(u, _)| PartialValue::AuthSession(*u))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2172,6 +2397,9 @@ pub enum DbValueV1Iter<'a> {
|
||||||
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
||||||
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
||||||
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
||||||
|
IntentToken(std::collections::btree_map::Iter<'a, Uuid, IntentTokenState>),
|
||||||
|
TrustedDeviceEnrollment(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
|
AuthSession(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for DbValueV1Iter<'a> {
|
impl<'a> Iterator for DbValueV1Iter<'a> {
|
||||||
|
@ -2267,6 +2495,22 @@ impl<'a> Iterator for DbValueV1Iter<'a> {
|
||||||
DbValueV1Iter::RestrictedString(iter) => {
|
DbValueV1Iter::RestrictedString(iter) => {
|
||||||
iter.next().map(|i| DbValueV1::RestrictedString(i.clone()))
|
iter.next().map(|i| DbValueV1::RestrictedString(i.clone()))
|
||||||
}
|
}
|
||||||
|
DbValueV1Iter::IntentToken(iter) => iter.next().map(|(u, s)| DbValueV1::IntentToken {
|
||||||
|
u: *u,
|
||||||
|
s: match s {
|
||||||
|
IntentTokenState::Valid => DbValueIntentTokenStateV1::Valid,
|
||||||
|
IntentTokenState::InProgress(i, d) => {
|
||||||
|
DbValueIntentTokenStateV1::InProgress(*i, *d)
|
||||||
|
}
|
||||||
|
IntentTokenState::Consumed => DbValueIntentTokenStateV1::Consumed,
|
||||||
|
},
|
||||||
|
}),
|
||||||
|
DbValueV1Iter::TrustedDeviceEnrollment(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, _)| DbValueV1::TrustedDeviceEnrollment { u: *u }),
|
||||||
|
DbValueV1Iter::AuthSession(iter) => {
|
||||||
|
iter.next().map(|(u, _)| DbValueV1::AuthSession { u: *u })
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2298,6 +2542,9 @@ pub enum ProtoIter<'a> {
|
||||||
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
PrivateBinary(SmolSetIter<'a, [Vec<u8>; 1]>),
|
||||||
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
PublicBinary(std::collections::btree_map::Iter<'a, String, Vec<u8>>),
|
||||||
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
RestrictedString(std::collections::btree_set::Iter<'a, String>),
|
||||||
|
IntentToken(std::collections::btree_map::Iter<'a, Uuid, IntentTokenState>),
|
||||||
|
TrustedDeviceEnrollment(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
|
AuthSession(std::collections::btree_map::Iter<'a, Uuid, ()>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Iterator for ProtoIter<'a> {
|
impl<'a> Iterator for ProtoIter<'a> {
|
||||||
|
@ -2357,6 +2604,15 @@ impl<'a> Iterator for ProtoIter<'a> {
|
||||||
.next()
|
.next()
|
||||||
.map(|(t, b)| format!("{}: {}", t, base64::encode_config(&b, base64::URL_SAFE))),
|
.map(|(t, b)| format!("{}: {}", t, base64::encode_config(&b, base64::URL_SAFE))),
|
||||||
ProtoIter::RestrictedString(iter) => iter.next().cloned(),
|
ProtoIter::RestrictedString(iter) => iter.next().cloned(),
|
||||||
|
ProtoIter::IntentToken(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, m)| format!("{}: {:?}", ValueSet::uuid_to_proto_string(u), m)),
|
||||||
|
ProtoIter::TrustedDeviceEnrollment(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, _)| format!("{}", ValueSet::uuid_to_proto_string(u))),
|
||||||
|
ProtoIter::AuthSession(iter) => iter
|
||||||
|
.next()
|
||||||
|
.map(|(u, _)| format!("{}", ValueSet::uuid_to_proto_string(u))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -13,7 +13,7 @@ repository = "https://github.com/kanidm/kanidm/"
|
||||||
# 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
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
kanidm = { path = "../" }
|
kanidm = { path = "../idm" }
|
||||||
kanidm_proto = { path = "../../kanidm_proto" }
|
kanidm_proto = { path = "../../kanidm_proto" }
|
||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
|
|
||||||
|
@ -37,3 +37,21 @@ compact_jwt = "^0.2.0"
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
profiles = { path = "../../profiles" }
|
profiles = { path = "../../profiles" }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
tracing-subscriber = "0.3"
|
||||||
|
# tokio = { version = "1", features = ["rt", "net", "time", "macros", "sync", "signal"] }
|
||||||
|
# kanidm = { path = "../kanidmd" }
|
||||||
|
# score = { path = "../kanidmd/score" }
|
||||||
|
futures = "0.3"
|
||||||
|
serde_json = "1.0"
|
||||||
|
# async-std = { version = "1.6", features = ["tokio1"] }
|
||||||
|
|
||||||
|
webauthn-authenticator-rs = "0.3.0-alpha.12"
|
||||||
|
oauth2_ext = { package = "oauth2", version = "4.0", default-features = false }
|
||||||
|
base64 = "0.13"
|
||||||
|
# compact_jwt = "^0.1.5"
|
||||||
|
|
||||||
|
kanidm_client = { path = "../../kanidm_client" }
|
||||||
|
url = { version = "2", features = ["serde"] }
|
||||||
|
reqwest = { version = "0.11", features=["cookies", "json", "native-tls"] }
|
||||||
|
|
|
@ -374,27 +374,45 @@ fn test_server_radius_credential_lifecycle() {
|
||||||
.idm_account_person_extend("admin", None, None)
|
.idm_account_person_extend("admin", None, None)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let f = Filter::Eq("name".to_string(), "idm_admins".to_string());
|
||||||
|
let m = ModifyList::new_list(vec![Modify::Present(
|
||||||
|
"member".to_string(),
|
||||||
|
"system_admins".to_string(),
|
||||||
|
)]);
|
||||||
|
let res = rsclient.modify(f, m);
|
||||||
|
assert!(res.is_ok());
|
||||||
|
|
||||||
|
rsclient
|
||||||
|
.idm_account_create("demo_account", "Deeeeemo")
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
// Should have no radius secret
|
// Should have no radius secret
|
||||||
let n_sec = rsclient.idm_account_radius_credential_get("admin").unwrap();
|
let n_sec = rsclient
|
||||||
|
.idm_account_radius_credential_get("demo_account")
|
||||||
|
.unwrap();
|
||||||
assert!(n_sec.is_none());
|
assert!(n_sec.is_none());
|
||||||
|
|
||||||
// Set one
|
// Set one
|
||||||
let sec1 = rsclient
|
let sec1 = rsclient
|
||||||
.idm_account_radius_credential_regenerate("admin")
|
.idm_account_radius_credential_regenerate("demo_account")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Should be able to get it.
|
// Should be able to get it.
|
||||||
let r_sec = rsclient.idm_account_radius_credential_get("admin").unwrap();
|
let r_sec = rsclient
|
||||||
|
.idm_account_radius_credential_get("demo_account")
|
||||||
|
.unwrap();
|
||||||
assert!(sec1 == r_sec.unwrap());
|
assert!(sec1 == r_sec.unwrap());
|
||||||
|
|
||||||
// test getting the token - we can do this as self or the radius server
|
// test getting the token - we can do this as self or the radius server
|
||||||
let r_tok = rsclient.idm_account_radius_token_get("admin").unwrap();
|
let r_tok = rsclient
|
||||||
|
.idm_account_radius_token_get("demo_account")
|
||||||
|
.unwrap();
|
||||||
assert!(sec1 == r_tok.secret);
|
assert!(sec1 == r_tok.secret);
|
||||||
assert!(r_tok.name == "admin");
|
assert!(r_tok.name == "demo_account");
|
||||||
|
|
||||||
// Reset it
|
// Reset it
|
||||||
let sec2 = rsclient
|
let sec2 = rsclient
|
||||||
.idm_account_radius_credential_regenerate("admin")
|
.idm_account_radius_credential_regenerate("demo_account")
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
// Should be different
|
// Should be different
|
||||||
|
@ -402,11 +420,13 @@ fn test_server_radius_credential_lifecycle() {
|
||||||
assert!(sec1 != sec2);
|
assert!(sec1 != sec2);
|
||||||
|
|
||||||
// Delete it
|
// Delete it
|
||||||
let res = rsclient.idm_account_radius_credential_delete("admin");
|
let res = rsclient.idm_account_radius_credential_delete("demo_account");
|
||||||
assert!(res.is_ok());
|
assert!(res.is_ok());
|
||||||
|
|
||||||
// No secret
|
// No secret
|
||||||
let n_sec = rsclient.idm_account_radius_credential_get("admin").unwrap();
|
let n_sec = rsclient
|
||||||
|
.idm_account_radius_credential_get("demo_account")
|
||||||
|
.unwrap();
|
||||||
assert!(n_sec.is_none());
|
assert!(n_sec.is_none());
|
||||||
});
|
});
|
||||||
}
|
}
|
31
kanidmd_web_ui/pkg/kanidmd_web_ui.d.ts
vendored
Normal file
31
kanidmd_web_ui/pkg/kanidmd_web_ui.d.ts
vendored
Normal file
|
@ -0,0 +1,31 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
/**
|
||||||
|
*/
|
||||||
|
export function run_app(): void;
|
||||||
|
|
||||||
|
export type InitInput = RequestInfo | URL | Response | BufferSource | WebAssembly.Module;
|
||||||
|
|
||||||
|
export interface InitOutput {
|
||||||
|
readonly memory: WebAssembly.Memory;
|
||||||
|
readonly run_app: (a: number) => void;
|
||||||
|
readonly __wbindgen_malloc: (a: number) => number;
|
||||||
|
readonly __wbindgen_realloc: (a: number, b: number, c: number) => number;
|
||||||
|
readonly __wbindgen_export_2: WebAssembly.Table;
|
||||||
|
readonly _dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h79af8eb94e22cb43: (a: number, b: number, c: number) => void;
|
||||||
|
readonly _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1c17030d49aa8a7b: (a: number, b: number, c: number) => void;
|
||||||
|
readonly _dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb210817f7291cc2b: (a: number, b: number, c: number) => void;
|
||||||
|
readonly __wbindgen_add_to_stack_pointer: (a: number) => number;
|
||||||
|
readonly __wbindgen_free: (a: number, b: number) => void;
|
||||||
|
readonly __wbindgen_exn_store: (a: number) => void;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If `module_or_path` is {RequestInfo} or {URL}, makes a request and
|
||||||
|
* for everything else, calls `WebAssembly.instantiate` directly.
|
||||||
|
*
|
||||||
|
* @param {InitInput | Promise<InitInput>} module_or_path
|
||||||
|
*
|
||||||
|
* @returns {Promise<InitOutput>}
|
||||||
|
*/
|
||||||
|
export default function init (module_or_path?: InitInput | Promise<InitInput>): Promise<InitOutput>;
|
|
@ -7,32 +7,7 @@ heap.push(undefined, null, true, false);
|
||||||
|
|
||||||
function getObject(idx) { return heap[idx]; }
|
function getObject(idx) { return heap[idx]; }
|
||||||
|
|
||||||
let heap_next = heap.length;
|
let WASM_VECTOR_LEN = 0;
|
||||||
|
|
||||||
function dropObject(idx) {
|
|
||||||
if (idx < 36) return;
|
|
||||||
heap[idx] = heap_next;
|
|
||||||
heap_next = idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
function takeObject(idx) {
|
|
||||||
const ret = getObject(idx);
|
|
||||||
dropObject(idx);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
function addHeapObject(obj) {
|
|
||||||
if (heap_next === heap.length) heap.push(heap.length + 1);
|
|
||||||
const idx = heap_next;
|
|
||||||
heap_next = heap[idx];
|
|
||||||
|
|
||||||
heap[idx] = obj;
|
|
||||||
return idx;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
|
||||||
|
|
||||||
cachedTextDecoder.decode();
|
|
||||||
|
|
||||||
let cachegetUint8Memory0 = null;
|
let cachegetUint8Memory0 = null;
|
||||||
function getUint8Memory0() {
|
function getUint8Memory0() {
|
||||||
|
@ -42,12 +17,6 @@ function getUint8Memory0() {
|
||||||
return cachegetUint8Memory0;
|
return cachegetUint8Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getStringFromWasm0(ptr, len) {
|
|
||||||
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
|
||||||
}
|
|
||||||
|
|
||||||
let WASM_VECTOR_LEN = 0;
|
|
||||||
|
|
||||||
let cachedTextEncoder = new TextEncoder('utf-8');
|
let cachedTextEncoder = new TextEncoder('utf-8');
|
||||||
|
|
||||||
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
||||||
|
@ -65,6 +34,8 @@ const encodeString = (typeof cachedTextEncoder.encodeInto === 'function'
|
||||||
|
|
||||||
function passStringToWasm0(arg, malloc, realloc) {
|
function passStringToWasm0(arg, malloc, realloc) {
|
||||||
|
|
||||||
|
if (typeof(arg) !== 'string') throw new Error('expected a string argument');
|
||||||
|
|
||||||
if (realloc === undefined) {
|
if (realloc === undefined) {
|
||||||
const buf = cachedTextEncoder.encode(arg);
|
const buf = cachedTextEncoder.encode(arg);
|
||||||
const ptr = malloc(buf.length);
|
const ptr = malloc(buf.length);
|
||||||
|
@ -93,7 +64,7 @@ function passStringToWasm0(arg, malloc, realloc) {
|
||||||
ptr = realloc(ptr, len, len = offset + arg.length * 3);
|
ptr = realloc(ptr, len, len = offset + arg.length * 3);
|
||||||
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
const view = getUint8Memory0().subarray(ptr + offset, ptr + len);
|
||||||
const ret = encodeString(arg, view);
|
const ret = encodeString(arg, view);
|
||||||
|
if (ret.read !== arg.length) throw new Error('failed to pass whole string');
|
||||||
offset += ret.written;
|
offset += ret.written;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,10 +72,6 @@ function passStringToWasm0(arg, malloc, realloc) {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
function isLikeNone(x) {
|
|
||||||
return x === undefined || x === null;
|
|
||||||
}
|
|
||||||
|
|
||||||
let cachegetInt32Memory0 = null;
|
let cachegetInt32Memory0 = null;
|
||||||
function getInt32Memory0() {
|
function getInt32Memory0() {
|
||||||
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
if (cachegetInt32Memory0 === null || cachegetInt32Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
@ -113,6 +80,41 @@ function getInt32Memory0() {
|
||||||
return cachegetInt32Memory0;
|
return cachegetInt32Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });
|
||||||
|
|
||||||
|
cachedTextDecoder.decode();
|
||||||
|
|
||||||
|
function getStringFromWasm0(ptr, len) {
|
||||||
|
return cachedTextDecoder.decode(getUint8Memory0().subarray(ptr, ptr + len));
|
||||||
|
}
|
||||||
|
|
||||||
|
let heap_next = heap.length;
|
||||||
|
|
||||||
|
function addHeapObject(obj) {
|
||||||
|
if (heap_next === heap.length) heap.push(heap.length + 1);
|
||||||
|
const idx = heap_next;
|
||||||
|
heap_next = heap[idx];
|
||||||
|
|
||||||
|
if (typeof(heap_next) !== 'number') throw new Error('corrupt heap');
|
||||||
|
|
||||||
|
heap[idx] = obj;
|
||||||
|
return idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isLikeNone(x) {
|
||||||
|
return x === undefined || x === null;
|
||||||
|
}
|
||||||
|
|
||||||
|
function _assertNum(n) {
|
||||||
|
if (typeof(n) !== 'number') throw new Error('expected a number argument');
|
||||||
|
}
|
||||||
|
|
||||||
|
function _assertBoolean(n) {
|
||||||
|
if (typeof(n) !== 'boolean') {
|
||||||
|
throw new Error('expected a boolean argument');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
let cachegetFloat64Memory0 = null;
|
let cachegetFloat64Memory0 = null;
|
||||||
function getFloat64Memory0() {
|
function getFloat64Memory0() {
|
||||||
if (cachegetFloat64Memory0 === null || cachegetFloat64Memory0.buffer !== wasm.memory.buffer) {
|
if (cachegetFloat64Memory0 === null || cachegetFloat64Memory0.buffer !== wasm.memory.buffer) {
|
||||||
|
@ -121,6 +123,18 @@ function getFloat64Memory0() {
|
||||||
return cachegetFloat64Memory0;
|
return cachegetFloat64Memory0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function dropObject(idx) {
|
||||||
|
if (idx < 36) return;
|
||||||
|
heap[idx] = heap_next;
|
||||||
|
heap_next = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
function takeObject(idx) {
|
||||||
|
const ret = getObject(idx);
|
||||||
|
dropObject(idx);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
function debugString(val) {
|
function debugString(val) {
|
||||||
// primitive types
|
// primitive types
|
||||||
const type = typeof val;
|
const type = typeof val;
|
||||||
|
@ -186,6 +200,49 @@ function debugString(val) {
|
||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeClosure(arg0, arg1, dtor, f) {
|
||||||
|
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
||||||
|
const real = (...args) => {
|
||||||
|
// First up with a closure we increment the internal reference
|
||||||
|
// count. This ensures that the Rust closure environment won't
|
||||||
|
// be deallocated while we're invoking it.
|
||||||
|
state.cnt++;
|
||||||
|
try {
|
||||||
|
return f(state.a, state.b, ...args);
|
||||||
|
} finally {
|
||||||
|
if (--state.cnt === 0) {
|
||||||
|
wasm.__wbindgen_export_2.get(state.dtor)(state.a, state.b);
|
||||||
|
state.a = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
real.original = state;
|
||||||
|
|
||||||
|
return real;
|
||||||
|
}
|
||||||
|
|
||||||
|
function logError(f, args) {
|
||||||
|
try {
|
||||||
|
return f.apply(this, args);
|
||||||
|
} catch (e) {
|
||||||
|
let error = (function () {
|
||||||
|
try {
|
||||||
|
return e instanceof Error ? `${e.message}\n\nStack:\n${e.stack}` : e.toString();
|
||||||
|
} catch(_) {
|
||||||
|
return "<failed to stringify thrown value>";
|
||||||
|
}
|
||||||
|
}());
|
||||||
|
console.error("wasm-bindgen: imported JS function that was not marked as `catch` threw an error:", error);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function __wbg_adapter_30(arg0, arg1, arg2) {
|
||||||
|
_assertNum(arg0);
|
||||||
|
_assertNum(arg1);
|
||||||
|
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h79af8eb94e22cb43(arg0, arg1, addHeapObject(arg2));
|
||||||
|
}
|
||||||
|
|
||||||
function makeMutClosure(arg0, arg1, dtor, f) {
|
function makeMutClosure(arg0, arg1, dtor, f) {
|
||||||
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
||||||
const real = (...args) => {
|
const real = (...args) => {
|
||||||
|
@ -210,6 +267,11 @@ function makeMutClosure(arg0, arg1, dtor, f) {
|
||||||
|
|
||||||
return real;
|
return real;
|
||||||
}
|
}
|
||||||
|
function __wbg_adapter_33(arg0, arg1, arg2) {
|
||||||
|
_assertNum(arg0);
|
||||||
|
_assertNum(arg1);
|
||||||
|
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1c17030d49aa8a7b(arg0, arg1, addHeapObject(arg2));
|
||||||
|
}
|
||||||
|
|
||||||
let stack_pointer = 32;
|
let stack_pointer = 32;
|
||||||
|
|
||||||
|
@ -218,43 +280,16 @@ function addBorrowedObject(obj) {
|
||||||
heap[--stack_pointer] = obj;
|
heap[--stack_pointer] = obj;
|
||||||
return stack_pointer;
|
return stack_pointer;
|
||||||
}
|
}
|
||||||
function __wbg_adapter_30(arg0, arg1, arg2) {
|
function __wbg_adapter_36(arg0, arg1, arg2) {
|
||||||
try {
|
try {
|
||||||
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h044f18bcb347ffd0(arg0, arg1, addBorrowedObject(arg2));
|
_assertNum(arg0);
|
||||||
|
_assertNum(arg1);
|
||||||
|
wasm._dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb210817f7291cc2b(arg0, arg1, addBorrowedObject(arg2));
|
||||||
} finally {
|
} finally {
|
||||||
heap[stack_pointer++] = undefined;
|
heap[stack_pointer++] = undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function makeClosure(arg0, arg1, dtor, f) {
|
|
||||||
const state = { a: arg0, b: arg1, cnt: 1, dtor };
|
|
||||||
const real = (...args) => {
|
|
||||||
// First up with a closure we increment the internal reference
|
|
||||||
// count. This ensures that the Rust closure environment won't
|
|
||||||
// be deallocated while we're invoking it.
|
|
||||||
state.cnt++;
|
|
||||||
try {
|
|
||||||
return f(state.a, state.b, ...args);
|
|
||||||
} finally {
|
|
||||||
if (--state.cnt === 0) {
|
|
||||||
wasm.__wbindgen_export_2.get(state.dtor)(state.a, state.b);
|
|
||||||
state.a = 0;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
real.original = state;
|
|
||||||
|
|
||||||
return real;
|
|
||||||
}
|
|
||||||
function __wbg_adapter_33(arg0, arg1, arg2) {
|
|
||||||
wasm._dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__ha821c5ee02284a59(arg0, arg1, addHeapObject(arg2));
|
|
||||||
}
|
|
||||||
|
|
||||||
function __wbg_adapter_36(arg0, arg1, arg2) {
|
|
||||||
wasm._dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb14a7cff63e25e7d(arg0, arg1, addHeapObject(arg2));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*/
|
*/
|
||||||
export function run_app() {
|
export function run_app() {
|
||||||
|
@ -334,12 +369,13 @@ async function init(input) {
|
||||||
}
|
}
|
||||||
const imports = {};
|
const imports = {};
|
||||||
imports.wbg = {};
|
imports.wbg = {};
|
||||||
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
imports.wbg.__wbindgen_json_serialize = function(arg0, arg1) {
|
||||||
takeObject(arg0);
|
const obj = getObject(arg1);
|
||||||
};
|
var ret = JSON.stringify(obj === undefined ? null : obj);
|
||||||
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var ret = getObject(arg0);
|
var len0 = WASM_VECTOR_LEN;
|
||||||
return addHeapObject(ret);
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
imports.wbg.__wbindgen_string_new = function(arg0, arg1) {
|
||||||
var ret = getStringFromWasm0(arg0, arg1);
|
var ret = getStringFromWasm0(arg0, arg1);
|
||||||
|
@ -353,36 +389,25 @@ async function init(input) {
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_json_serialize = function(arg0, arg1) {
|
imports.wbg.__wbindgen_object_clone_ref = function(arg0) {
|
||||||
const obj = getObject(arg1);
|
var ret = getObject(arg0);
|
||||||
var ret = JSON.stringify(obj === undefined ? null : obj);
|
return addHeapObject(ret);
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_cb_drop = function(arg0) {
|
|
||||||
const obj = takeObject(arg0).original;
|
|
||||||
if (obj.cnt-- == 1) {
|
|
||||||
obj.a = 0;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
var ret = false;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_boolean_get = function(arg0) {
|
|
||||||
const v = getObject(arg0);
|
|
||||||
var ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
|
||||||
var ret = getObject(arg0) === undefined;
|
|
||||||
return ret;
|
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_json_parse = function(arg0, arg1) {
|
imports.wbg.__wbindgen_json_parse = function(arg0, arg1) {
|
||||||
var ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
var ret = JSON.parse(getStringFromWasm0(arg0, arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
|
imports.wbg.__wbindgen_boolean_get = function(arg0) {
|
||||||
|
const v = getObject(arg0);
|
||||||
|
var ret = typeof(v) === 'boolean' ? (v ? 1 : 0) : 2;
|
||||||
|
_assertNum(ret);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
|
imports.wbg.__wbindgen_is_undefined = function(arg0) {
|
||||||
|
var ret = getObject(arg0) === undefined;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
|
};
|
||||||
imports.wbg.__wbindgen_number_new = function(arg0) {
|
imports.wbg.__wbindgen_number_new = function(arg0) {
|
||||||
var ret = arg0;
|
var ret = arg0;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -390,57 +415,74 @@ async function init(input) {
|
||||||
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
imports.wbg.__wbindgen_number_get = function(arg0, arg1) {
|
||||||
const obj = getObject(arg1);
|
const obj = getObject(arg1);
|
||||||
var ret = typeof(obj) === 'number' ? obj : undefined;
|
var ret = typeof(obj) === 'number' ? obj : undefined;
|
||||||
|
if (!isLikeNone(ret)) {
|
||||||
|
_assertNum(ret);
|
||||||
|
}
|
||||||
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
getFloat64Memory0()[arg0 / 8 + 1] = isLikeNone(ret) ? 0 : ret;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
getInt32Memory0()[arg0 / 4 + 0] = !isLikeNone(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_new_693216e109162396 = function() {
|
imports.wbg.__wbindgen_object_drop_ref = function(arg0) {
|
||||||
var ret = new Error();
|
takeObject(arg0);
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_stack_0ddaca5d1abfb52f = function(arg0, arg1) {
|
imports.wbg.__wbg_error_09919627ac0992f5 = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg1).stack;
|
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_error_09919627ac0992f5 = function(arg0, arg1) {
|
|
||||||
try {
|
try {
|
||||||
console.error(getStringFromWasm0(arg0, arg1));
|
console.error(getStringFromWasm0(arg0, arg1));
|
||||||
} finally {
|
} finally {
|
||||||
wasm.__wbindgen_free(arg0, arg1);
|
wasm.__wbindgen_free(arg0, arg1);
|
||||||
}
|
}
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_new_693216e109162396 = function() { return logError(function () {
|
||||||
|
var ret = new Error();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_stack_0ddaca5d1abfb52f = function() { return logError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg1).stack;
|
||||||
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbindgen_cb_drop = function(arg0) {
|
||||||
|
const obj = takeObject(arg0).original;
|
||||||
|
if (obj.cnt-- == 1) {
|
||||||
|
obj.a = 0;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
var ret = false;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
};
|
};
|
||||||
imports.wbg.__wbg_log_06b7ffc63a0f8bee = function(arg0, arg1) {
|
imports.wbg.__wbg_log_06b7ffc63a0f8bee = function() { return logError(function (arg0, arg1) {
|
||||||
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
|
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
|
||||||
wasm.__wbindgen_free(arg0, arg1 * 4);
|
wasm.__wbindgen_free(arg0, arg1 * 4);
|
||||||
console.log(...v0);
|
console.log(...v0);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_warn_2aa0e7178e1d35f6 = function(arg0, arg1) {
|
imports.wbg.__wbg_warn_2aa0e7178e1d35f6 = function() { return logError(function (arg0, arg1) {
|
||||||
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
|
var v0 = getArrayJsValueFromWasm0(arg0, arg1).slice();
|
||||||
wasm.__wbindgen_free(arg0, arg1 * 4);
|
wasm.__wbindgen_free(arg0, arg1 * 4);
|
||||||
console.warn(...v0);
|
console.warn(...v0);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_instanceof_Window_434ce1849eb4e0fc = function(arg0) {
|
imports.wbg.__wbg_instanceof_Window_434ce1849eb4e0fc = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0) instanceof Window;
|
var ret = getObject(arg0) instanceof Window;
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_document_5edd43643d1060d9 = function(arg0) {
|
imports.wbg.__wbg_document_5edd43643d1060d9 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).document;
|
var ret = getObject(arg0).document;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_location_11472bb76bf5bbca = function(arg0) {
|
imports.wbg.__wbg_location_11472bb76bf5bbca = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).location;
|
var ret = getObject(arg0).location;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_history_52cfc93c824e772b = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_history_52cfc93c824e772b = function() { return handleError(function (arg0) {
|
||||||
var ret = getObject(arg0).history;
|
var ret = getObject(arg0).history;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_navigator_0e0588c949560476 = function(arg0) {
|
imports.wbg.__wbg_navigator_0e0588c949560476 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).navigator;
|
var ret = getObject(arg0).navigator;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_localStorage_2b7091e6919605e2 = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_localStorage_2b7091e6919605e2 = function() { return handleError(function (arg0) {
|
||||||
var ret = getObject(arg0).localStorage;
|
var ret = getObject(arg0).localStorage;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
@ -449,14 +491,14 @@ async function init(input) {
|
||||||
var ret = getObject(arg0).sessionStorage;
|
var ret = getObject(arg0).sessionStorage;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_fetch_427498e0ccea81f4 = function(arg0, arg1) {
|
imports.wbg.__wbg_fetch_427498e0ccea81f4 = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg0).fetch(getObject(arg1));
|
var ret = getObject(arg0).fetch(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_body_7538539844356c1c = function(arg0) {
|
imports.wbg.__wbg_body_7538539844356c1c = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).body;
|
var ret = getObject(arg0).body;
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_createElement_d017b8d2af99bab9 = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_createElement_d017b8d2af99bab9 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
|
var ret = getObject(arg0).createElement(getStringFromWasm0(arg1, arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -465,89 +507,102 @@ async function init(input) {
|
||||||
var ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
var ret = getObject(arg0).createElementNS(arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_createTextNode_39a0de25d14bcde5 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_createTextNode_39a0de25d14bcde5 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
|
var ret = getObject(arg0).createTextNode(getStringFromWasm0(arg1, arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_getElementById_b30e88aff96f66a1 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_getElementById_b30e88aff96f66a1 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
|
var ret = getObject(arg0).getElementById(getStringFromWasm0(arg1, arg2));
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_querySelector_cc714d0aa0b868ed = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_querySelector_cc714d0aa0b868ed = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
|
var ret = getObject(arg0).querySelector(getStringFromWasm0(arg1, arg2));
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_pathname_7affbcff36f35c0e = function() { return logError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg1).pathname;
|
||||||
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_new_4473c9af1cac368b = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = new URL(getStringFromWasm0(arg0, arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_value_d3a30bc2c7caf357 = function() { return logError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg1).value;
|
||||||
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_setvalue_6a34bab301f38bf2 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_get_5835a17331a9d8f2 = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg0).get(getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_add_c1e566b20be6badb = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_add_c1e566b20be6badb = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
getObject(arg0).add(getStringFromWasm0(arg1, arg2));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_remove_b4d29ca5eb7db54e = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_remove_b4d29ca5eb7db54e = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
getObject(arg0).remove(getStringFromWasm0(arg1, arg2));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_href_cad8f02caf39f2fb = function(arg0, arg1) {
|
imports.wbg.__wbg_href_cad8f02caf39f2fb = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg1).href;
|
var ret = getObject(arg1).href;
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_getClientExtensionResults_37549795564cd9d3 = function(arg0) {
|
imports.wbg.__wbg_headers_1a60dec7fbd28a3b = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).getClientExtensionResults();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_headers_1a60dec7fbd28a3b = function(arg0) {
|
|
||||||
var ret = getObject(arg0).headers;
|
var ret = getObject(arg0).headers;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_newwithstrandinit_c07f0662ece15bc6 = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_newwithstrandinit_c07f0662ece15bc6 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
var ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
var ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_instanceof_HtmlInputElement_8969541a2a0bded0 = function(arg0) {
|
imports.wbg.__wbg_instanceof_Event_39e54e1fe6593f4c = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0) instanceof HTMLInputElement;
|
var ret = getObject(arg0) instanceof Event;
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_setchecked_f6ead3490df88a7f = function(arg0, arg1) {
|
imports.wbg.__wbg_target_e560052e31e4567c = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).target;
|
||||||
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_cancelBubble_17d7988ab2fbe4c9 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).cancelBubble;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_preventDefault_fa00541ff125b78c = function() { return logError(function (arg0) {
|
||||||
|
getObject(arg0).preventDefault();
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_getClientExtensionResults_37549795564cd9d3 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).getClientExtensionResults();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_instanceof_HtmlInputElement_8969541a2a0bded0 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0) instanceof HTMLInputElement;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_setchecked_f6ead3490df88a7f = function() { return logError(function (arg0, arg1) {
|
||||||
getObject(arg0).checked = arg1 !== 0;
|
getObject(arg0).checked = arg1 !== 0;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_value_fc1c354d1a0e9714 = function(arg0, arg1) {
|
imports.wbg.__wbg_value_fc1c354d1a0e9714 = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg1).value;
|
var ret = getObject(arg1).value;
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setvalue_ce4a23f487065c07 = function(arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_get_5835a17331a9d8f2 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
var ret = getObject(arg0).get(getObject(arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_instanceof_Event_39e54e1fe6593f4c = function(arg0) {
|
imports.wbg.__wbg_setvalue_ce4a23f487065c07 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0) instanceof Event;
|
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_target_e560052e31e4567c = function(arg0) {
|
|
||||||
var ret = getObject(arg0).target;
|
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_cancelBubble_17d7988ab2fbe4c9 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).cancelBubble;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_preventDefault_fa00541ff125b78c = function(arg0) {
|
|
||||||
getObject(arg0).preventDefault();
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_instanceof_HtmlDocument_395ec6365cabde6c = function(arg0) {
|
|
||||||
var ret = getObject(arg0) instanceof HTMLDocument;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_cookie_66f4449cc764fcb2 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
var ret = getObject(arg1).cookie;
|
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_addEventListener_55682f77717d7665 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_addEventListener_55682f77717d7665 = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), getObject(arg4));
|
||||||
|
@ -555,64 +610,55 @@ async function init(input) {
|
||||||
imports.wbg.__wbg_removeEventListener_9cd36e5806463d5d = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_removeEventListener_9cd36e5806463d5d = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3), arg4 !== 0);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_credentials_403bf2de10e8f1c3 = function(arg0) {
|
imports.wbg.__wbg_instanceof_HtmlDocument_395ec6365cabde6c = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).credentials;
|
var ret = getObject(arg0) instanceof HTMLDocument;
|
||||||
return addHeapObject(ret);
|
_assertBoolean(ret);
|
||||||
};
|
|
||||||
imports.wbg.__wbg_instanceof_Element_c9423704dd5d9b1d = function(arg0) {
|
|
||||||
var ret = getObject(arg0) instanceof Element;
|
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_namespaceURI_e9a971e6c1ce68db = function(arg0, arg1) {
|
imports.wbg.__wbg_cookie_66f4449cc764fcb2 = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg1).cookie;
|
||||||
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_instanceof_Element_c9423704dd5d9b1d = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0) instanceof Element;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_namespaceURI_e9a971e6c1ce68db = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg1).namespaceURI;
|
var ret = getObject(arg1).namespaceURI;
|
||||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
var len0 = WASM_VECTOR_LEN;
|
var len0 = WASM_VECTOR_LEN;
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_classList_5086913f676eb3f3 = function(arg0) {
|
imports.wbg.__wbg_classList_5086913f676eb3f3 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).classList;
|
var ret = getObject(arg0).classList;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_removeAttribute_1adaecf6b4d35a09 = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_removeAttribute_1adaecf6b4d35a09 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
|
getObject(arg0).removeAttribute(getStringFromWasm0(arg1, arg2));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_setAttribute_1776fcc9b98d464e = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_setAttribute_1776fcc9b98d464e = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
getObject(arg0).setAttribute(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_instanceof_HtmlElement_d3e8f1c1d6788b24 = function(arg0) {
|
imports.wbg.__wbg_instanceof_HtmlElement_d3e8f1c1d6788b24 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0) instanceof HTMLElement;
|
var ret = getObject(arg0) instanceof HTMLElement;
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_focus_4434360545ac99cf = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_focus_4434360545ac99cf = function() { return handleError(function (arg0) {
|
||||||
getObject(arg0).focus();
|
getObject(arg0).focus();
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_credentials_403bf2de10e8f1c3 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).credentials;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_pushState_89ce908020e1d6aa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
imports.wbg.__wbg_pushState_89ce908020e1d6aa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4, arg5) {
|
||||||
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
getObject(arg0).pushState(getObject(arg1), getStringFromWasm0(arg2, arg3), arg4 === 0 ? undefined : getStringFromWasm0(arg4, arg5));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_parentElement_96e1e07348340043 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).parentElement;
|
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_lastChild_e2b014abab089e08 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).lastChild;
|
|
||||||
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setnodeValue_f175b74a390f8fda = function(arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_appendChild_3fe5090c665d3bb4 = function() { return handleError(function (arg0, arg1) {
|
|
||||||
var ret = getObject(arg0).appendChild(getObject(arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_insertBefore_4f09909023feac91 = function() { return handleError(function (arg0, arg1, arg2) {
|
|
||||||
var ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_removeChild_f4a83c9698136bbb = function() { return handleError(function (arg0, arg1) {
|
|
||||||
var ret = getObject(arg0).removeChild(getObject(arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_pathname_d0014089875ea691 = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_pathname_d0014089875ea691 = function() { return handleError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg1).pathname;
|
var ret = getObject(arg1).pathname;
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -630,6 +676,39 @@ async function init(input) {
|
||||||
imports.wbg.__wbg_replace_ec236a3e3182c4da = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_replace_ec236a3e3182c4da = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
getObject(arg0).replace(getStringFromWasm0(arg1, arg2));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_parentElement_96e1e07348340043 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).parentElement;
|
||||||
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_lastChild_e2b014abab089e08 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).lastChild;
|
||||||
|
return isLikeNone(ret) ? 0 : addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_setnodeValue_f175b74a390f8fda = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).nodeValue = arg1 === 0 ? undefined : getStringFromWasm0(arg1, arg2);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_appendChild_3fe5090c665d3bb4 = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg0).appendChild(getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_insertBefore_4f09909023feac91 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
|
var ret = getObject(arg0).insertBefore(getObject(arg1), getObject(arg2));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_removeChild_f4a83c9698136bbb = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = getObject(arg0).removeChild(getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_get_bee69a0c35eec41c = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||||
|
var ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
||||||
|
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
var len0 = WASM_VECTOR_LEN;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
||||||
|
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_set_f9448486a94c9aef = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
|
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_getItem_f92ef607397e96b1 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
imports.wbg.__wbg_getItem_f92ef607397e96b1 = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
||||||
var ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
var ret = getObject(arg1).getItem(getStringFromWasm0(arg2, arg3));
|
||||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
||||||
|
@ -643,49 +722,20 @@ async function init(input) {
|
||||||
imports.wbg.__wbg_setItem_279b13e5ad0b82cb = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
imports.wbg.__wbg_setItem_279b13e5ad0b82cb = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
||||||
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
getObject(arg0).setItem(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_get_bee69a0c35eec41c = function() { return handleError(function (arg0, arg1, arg2, arg3) {
|
imports.wbg.__wbg_instanceof_Response_ea36d565358a42f7 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg1).get(getStringFromWasm0(arg2, arg3));
|
|
||||||
var ptr0 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_set_f9448486a94c9aef = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {
|
|
||||||
getObject(arg0).set(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_pathname_7affbcff36f35c0e = function(arg0, arg1) {
|
|
||||||
var ret = getObject(arg1).pathname;
|
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_new_4473c9af1cac368b = function() { return handleError(function (arg0, arg1) {
|
|
||||||
var ret = new URL(getStringFromWasm0(arg0, arg1));
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_value_d3a30bc2c7caf357 = function(arg0, arg1) {
|
|
||||||
var ret = getObject(arg1).value;
|
|
||||||
var ptr0 = passStringToWasm0(ret, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
|
|
||||||
var len0 = WASM_VECTOR_LEN;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 1] = len0;
|
|
||||||
getInt32Memory0()[arg0 / 4 + 0] = ptr0;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_setvalue_6a34bab301f38bf2 = function(arg0, arg1, arg2) {
|
|
||||||
getObject(arg0).value = getStringFromWasm0(arg1, arg2);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_instanceof_Response_ea36d565358a42f7 = function(arg0) {
|
|
||||||
var ret = getObject(arg0) instanceof Response;
|
var ret = getObject(arg0) instanceof Response;
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_status_3a55bb50e744b834 = function(arg0) {
|
imports.wbg.__wbg_status_3a55bb50e744b834 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).status;
|
var ret = getObject(arg0).status;
|
||||||
|
_assertNum(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_headers_e4204c6775f7b3b4 = function(arg0) {
|
imports.wbg.__wbg_headers_e4204c6775f7b3b4 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).headers;
|
var ret = getObject(arg0).headers;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_json_4ab99130d1a5b3a9 = function() { return handleError(function (arg0) {
|
imports.wbg.__wbg_json_4ab99130d1a5b3a9 = function() { return handleError(function (arg0) {
|
||||||
var ret = getObject(arg0).json();
|
var ret = getObject(arg0).json();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -694,66 +744,69 @@ async function init(input) {
|
||||||
var ret = getObject(arg0).text();
|
var ret = getObject(arg0).text();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_new_16f24b0728c5e67b = function() {
|
imports.wbg.__wbg_new_16f24b0728c5e67b = function() { return logError(function () {
|
||||||
var ret = new Array();
|
var ret = new Array();
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_newnoargs_f579424187aa1717 = function(arg0, arg1) {
|
imports.wbg.__wbg_push_a72df856079e6930 = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = new Function(getStringFromWasm0(arg0, arg1));
|
var ret = getObject(arg0).push(getObject(arg1));
|
||||||
|
_assertNum(ret);
|
||||||
|
return ret;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_instanceof_Error_4287ce7d75f0e3a2 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0) instanceof Error;
|
||||||
|
_assertBoolean(ret);
|
||||||
|
return ret;
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_message_1dfe93b595be8811 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).message;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_get_8bbb82393651dd9c = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_name_66305ab387468967 = function() { return logError(function (arg0) {
|
||||||
var ret = Reflect.get(getObject(arg0), getObject(arg1));
|
var ret = getObject(arg0).name;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_toString_3e854a6a919f2996 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).toString();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_newnoargs_f579424187aa1717 = function() { return logError(function (arg0, arg1) {
|
||||||
|
var ret = new Function(getStringFromWasm0(arg0, arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_call_89558c3e96703ca1 = function() { return handleError(function (arg0, arg1) {
|
imports.wbg.__wbg_call_89558c3e96703ca1 = function() { return handleError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg0).call(getObject(arg1));
|
var ret = getObject(arg0).call(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_new_d3138911a89329b0 = function() {
|
imports.wbg.__wbg_valueOf_39e0d6bc7e4232b9 = function() { return logError(function (arg0) {
|
||||||
var ret = new Object();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_push_a72df856079e6930 = function(arg0, arg1) {
|
|
||||||
var ret = getObject(arg0).push(getObject(arg1));
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_instanceof_Error_4287ce7d75f0e3a2 = function(arg0) {
|
|
||||||
var ret = getObject(arg0) instanceof Error;
|
|
||||||
return ret;
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_message_1dfe93b595be8811 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).message;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_name_66305ab387468967 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).name;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_toString_3e854a6a919f2996 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).toString();
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_valueOf_39e0d6bc7e4232b9 = function(arg0) {
|
|
||||||
var ret = getObject(arg0).valueOf();
|
var ret = getObject(arg0).valueOf();
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_is_3d73f4d91adacc37 = function(arg0, arg1) {
|
imports.wbg.__wbg_is_3d73f4d91adacc37 = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = Object.is(getObject(arg0), getObject(arg1));
|
var ret = Object.is(getObject(arg0), getObject(arg1));
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_resolve_4f8f547f26b30b27 = function(arg0) {
|
imports.wbg.__wbg_new_d3138911a89329b0 = function() { return logError(function () {
|
||||||
|
var ret = new Object();
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_resolve_4f8f547f26b30b27 = function() { return logError(function (arg0) {
|
||||||
var ret = Promise.resolve(getObject(arg0));
|
var ret = Promise.resolve(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_then_a6860c82b90816ca = function(arg0, arg1) {
|
imports.wbg.__wbg_then_a6860c82b90816ca = function() { return logError(function (arg0, arg1) {
|
||||||
var ret = getObject(arg0).then(getObject(arg1));
|
var ret = getObject(arg0).then(getObject(arg1));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_then_58a04e42527f52c6 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_then_58a04e42527f52c6 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
|
var ret = getObject(arg0).then(getObject(arg1), getObject(arg2));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_globalThis_d61b1f48a57191ae = function() { return handleError(function () {
|
||||||
|
var ret = globalThis.globalThis;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_self_e23d74ae45fb17d1 = function() { return handleError(function () {
|
imports.wbg.__wbg_self_e23d74ae45fb17d1 = function() { return handleError(function () {
|
||||||
var ret = self.self;
|
var ret = self.self;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
|
@ -762,35 +815,37 @@ async function init(input) {
|
||||||
var ret = window.window;
|
var ret = window.window;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_globalThis_d61b1f48a57191ae = function() { return handleError(function () {
|
|
||||||
var ret = globalThis.globalThis;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
}, arguments) };
|
|
||||||
imports.wbg.__wbg_global_e7669da72fd7f239 = function() { return handleError(function () {
|
imports.wbg.__wbg_global_e7669da72fd7f239 = function() { return handleError(function () {
|
||||||
var ret = global.global;
|
var ret = global.global;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbg_buffer_5e74a88a1424a2e0 = function(arg0) {
|
imports.wbg.__wbg_new_e3b800e570795b3c = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).buffer;
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_newwithbyteoffsetandlength_278ec7532799393a = function(arg0, arg1, arg2) {
|
|
||||||
var ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
|
||||||
return addHeapObject(ret);
|
|
||||||
};
|
|
||||||
imports.wbg.__wbg_new_e3b800e570795b3c = function(arg0) {
|
|
||||||
var ret = new Uint8Array(getObject(arg0));
|
var ret = new Uint8Array(getObject(arg0));
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbg_set_5b8081e9d002f0df = function(arg0, arg1, arg2) {
|
imports.wbg.__wbg_newwithbyteoffsetandlength_278ec7532799393a = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
var ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);
|
||||||
};
|
return addHeapObject(ret);
|
||||||
imports.wbg.__wbg_length_30803400a8f15c59 = function(arg0) {
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_length_30803400a8f15c59 = function() { return logError(function (arg0) {
|
||||||
var ret = getObject(arg0).length;
|
var ret = getObject(arg0).length;
|
||||||
|
_assertNum(ret);
|
||||||
return ret;
|
return ret;
|
||||||
};
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_set_5b8081e9d002f0df = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
|
getObject(arg0).set(getObject(arg1), arg2 >>> 0);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_buffer_5e74a88a1424a2e0 = function() { return logError(function (arg0) {
|
||||||
|
var ret = getObject(arg0).buffer;
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
|
imports.wbg.__wbg_get_8bbb82393651dd9c = function() { return handleError(function (arg0, arg1) {
|
||||||
|
var ret = Reflect.get(getObject(arg0), getObject(arg1));
|
||||||
|
return addHeapObject(ret);
|
||||||
|
}, arguments) };
|
||||||
imports.wbg.__wbg_set_c42875065132a932 = function() { return handleError(function (arg0, arg1, arg2) {
|
imports.wbg.__wbg_set_c42875065132a932 = function() { return handleError(function (arg0, arg1, arg2) {
|
||||||
var ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
var ret = Reflect.set(getObject(arg0), getObject(arg1), getObject(arg2));
|
||||||
|
_assertBoolean(ret);
|
||||||
return ret;
|
return ret;
|
||||||
}, arguments) };
|
}, arguments) };
|
||||||
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
imports.wbg.__wbindgen_debug_string = function(arg0, arg1) {
|
||||||
|
@ -807,18 +862,18 @@ async function init(input) {
|
||||||
var ret = wasm.memory;
|
var ret = wasm.memory;
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
};
|
||||||
imports.wbg.__wbindgen_closure_wrapper1345 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper12230 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 563, __wbg_adapter_30);
|
var ret = makeClosure(arg0, arg1, 856, __wbg_adapter_30);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbindgen_closure_wrapper1575 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper15845 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = makeClosure(arg0, arg1, 609, __wbg_adapter_33);
|
var ret = makeMutClosure(arg0, arg1, 884, __wbg_adapter_33);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
imports.wbg.__wbindgen_closure_wrapper1700 = function(arg0, arg1, arg2) {
|
imports.wbg.__wbindgen_closure_wrapper16308 = function() { return logError(function (arg0, arg1, arg2) {
|
||||||
var ret = makeMutClosure(arg0, arg1, 648, __wbg_adapter_36);
|
var ret = makeMutClosure(arg0, arg1, 913, __wbg_adapter_36);
|
||||||
return addHeapObject(ret);
|
return addHeapObject(ret);
|
||||||
};
|
}, arguments) };
|
||||||
|
|
||||||
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
if (typeof input === 'string' || (typeof Request === 'function' && input instanceof Request) || (typeof URL === 'function' && input instanceof URL)) {
|
||||||
input = fetch(input);
|
input = fetch(input);
|
||||||
|
|
Binary file not shown.
13
kanidmd_web_ui/pkg/kanidmd_web_ui_bg.wasm.d.ts
vendored
Normal file
13
kanidmd_web_ui/pkg/kanidmd_web_ui_bg.wasm.d.ts
vendored
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
/* tslint:disable */
|
||||||
|
/* eslint-disable */
|
||||||
|
export const memory: WebAssembly.Memory;
|
||||||
|
export function run_app(a: number): void;
|
||||||
|
export function __wbindgen_malloc(a: number): number;
|
||||||
|
export function __wbindgen_realloc(a: number, b: number, c: number): number;
|
||||||
|
export const __wbindgen_export_2: WebAssembly.Table;
|
||||||
|
export function _dyn_core__ops__function__Fn__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h79af8eb94e22cb43(a: number, b: number, c: number): void;
|
||||||
|
export function _dyn_core__ops__function__FnMut__A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__h1c17030d49aa8a7b(a: number, b: number, c: number): void;
|
||||||
|
export function _dyn_core__ops__function__FnMut___A____Output___R_as_wasm_bindgen__closure__WasmClosure___describe__invoke__hb210817f7291cc2b(a: number, b: number, c: number): void;
|
||||||
|
export function __wbindgen_add_to_stack_pointer(a: number): number;
|
||||||
|
export function __wbindgen_free(a: number, b: number): void;
|
||||||
|
export function __wbindgen_exn_store(a: number): void;
|
|
@ -14,9 +14,11 @@
|
||||||
"files": [
|
"files": [
|
||||||
"kanidmd_web_ui_bg.wasm",
|
"kanidmd_web_ui_bg.wasm",
|
||||||
"kanidmd_web_ui.js",
|
"kanidmd_web_ui.js",
|
||||||
|
"kanidmd_web_ui.d.ts",
|
||||||
"LICENSE.md"
|
"LICENSE.md"
|
||||||
],
|
],
|
||||||
"module": "kanidmd_web_ui.js",
|
"module": "kanidmd_web_ui.js",
|
||||||
"homepage": "https://github.com/kanidm/kanidm/",
|
"homepage": "https://github.com/kanidm/kanidm/",
|
||||||
|
"types": "kanidmd_web_ui.d.ts",
|
||||||
"sideEffects": false
|
"sideEffects": false
|
||||||
}
|
}
|
Loading…
Reference in a new issue