Compare commits

...

10 commits

Author SHA1 Message Date
William Brown 0e484a6801 update 2025-03-26 14:40:59 +10:00
William Brown 9534d257e5 Allow versioning of server configs
This allows our server configuration to be versioned, in preparation
for a change related to the proxy protocol additions.
2025-03-26 14:37:43 +10:00
dependabot[bot] 5edc6be51c
Bump the all group in /pykanidm with 5 updates ()
Bumps the all group in /pykanidm with 5 updates:

| Package | From | To |
| --- | --- | --- |
| [aiohttp](https://github.com/aio-libs/aiohttp) | `3.11.13` | `3.11.14` |
| [ruff](https://github.com/astral-sh/ruff) | `0.11.0` | `0.11.2` |
| [coverage](https://github.com/nedbat/coveragepy) | `7.7.0` | `7.7.1` |
| [mkdocs-material](https://github.com/squidfunk/mkdocs-material) | `9.6.8` | `9.6.9` |
| [mkdocstrings-python](https://github.com/mkdocstrings/python) | `1.16.5` | `1.16.7` |


Updates `aiohttp` from 3.11.13 to 3.11.14
- [Release notes](https://github.com/aio-libs/aiohttp/releases)
- [Changelog](https://github.com/aio-libs/aiohttp/blob/master/CHANGES.rst)
- [Commits](https://github.com/aio-libs/aiohttp/compare/v3.11.13...v3.11.14)

Updates `ruff` from 0.11.0 to 0.11.2
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/0.11.0...0.11.2)

Updates `coverage` from 7.7.0 to 7.7.1
- [Release notes](https://github.com/nedbat/coveragepy/releases)
- [Changelog](https://github.com/nedbat/coveragepy/blob/master/CHANGES.rst)
- [Commits](https://github.com/nedbat/coveragepy/compare/7.7.0...7.7.1)

Updates `mkdocs-material` from 9.6.8 to 9.6.9
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.6.8...9.6.9)

Updates `mkdocstrings-python` from 1.16.5 to 1.16.7
- [Release notes](https://github.com/mkdocstrings/python/releases)
- [Changelog](https://github.com/mkdocstrings/python/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mkdocstrings/python/compare/1.16.5...1.16.7)

---
updated-dependencies:
- dependency-name: aiohttp
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: coverage
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
- dependency-name: mkdocstrings-python
  dependency-type: direct:development
  update-type: version-update:semver-patch
  dependency-group: all
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-03-24 11:59:26 +10:00
William Brown c75c97893e Update Concread 2025-03-22 12:47:18 +10:00
Peter Todd Decker ("Todd") 638904f12c
Update developer_ethics.md () 2025-03-22 01:58:54 +00:00
Jeff Scrum e1b9063b99
Update examples.md ()
fix command in OAuth2 Proxy example
2025-03-21 23:18:16 +00:00
Firstyear bf1e9b0989
Make schema indexing a boolean instead of index types ()
Previously on schema definitions for attributes, the list of index
types was manually set on attributes. The issue with this approach is
that not all index types apply to all attribute syntaxes. This made it
error prone not just to Kanidm developers, but to future users who
want to define custom attributes and may incorrectly index those
attributes.

Instead, this changes the index value to be a boolean to indicate
if this attribute should or should not be indexed. Internally Kanidm
has a list of appropriate indexes to apply to these syntax types.

As part of this change, the tests were reviewed to find missing index
types for syntaxes, and other causes of unindexed searches which led
to some changes around the dyngroup plugin (which pushes the boundaries
of a lot of things in Kani due to how it works).
2025-03-21 02:13:54 +00:00
Foosec 11c7266ff3
Add missing lld dependency and fix syntax typo ()
* Add missing lld dependency and fix syntax typo in devcontainer_postcreate.sh
* replace pushd/popd with shell agnostic solution and do not throw away std out/err
---------
Co-authored-by: foobar <foobar>
2025-03-21 01:51:58 +00:00
Katherina Walshe-Grey ef638a62e9
Update shell.nix to work with stable nixpkgs ()
The existing shell.nix uses whatever versions of rustc and cargo are in
the system nixpkgs. In the current stable nixpkgs version (24.11), this
is rustc 1.82.0. Unfortunately, we depend on the `strict_provenance`
feature, which was unstable before 1.84.0. (See: )

This patch makes minimal changes to shell.nix to overlay nixpkgs with
the rustc version defined in rust-toolchain.toml, enabling Kanidm to
build locally on stable versions of NixOS.

Co-authored-by: Firstyear <william@blackhats.net.au>
2025-03-20 13:06:51 +10:00
Firstyear f86bc03a93
Improve unixd tasks channel comments () 2025-03-19 00:57:39 +00:00
40 changed files with 1782 additions and 2037 deletions

259
Cargo.lock generated
View file

@ -232,9 +232,9 @@ dependencies = [
[[package]]
name = "async-compression"
version = "0.4.20"
version = "0.4.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "310c9bcae737a48ef5cdee3174184e6d548b292739ede61a1f955ef76a738861"
checksum = "59a194f9d963d8099596278594b3107448656ba73831c9d8c783e613ce86da64"
dependencies = [
"flate2",
"futures-core",
@ -267,9 +267,9 @@ dependencies = [
[[package]]
name = "async-trait"
version = "0.1.87"
version = "0.1.88"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d556ec1359574147ec0c4fc5eb525f3f23263a592b1a9c07e0a75b427de55c97"
checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5"
dependencies = [
"proc-macro2",
"quote",
@ -299,7 +299,7 @@ dependencies = [
"memoffset",
"openssl",
"openssl-sys",
"rand",
"rand 0.8.5",
"runloop",
"serde",
"serde_bytes",
@ -425,20 +425,17 @@ dependencies = [
[[package]]
name = "axum-server"
version = "0.7.1"
version = "0.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56bac90848f6a9393ac03c63c640925c4b7c8ca21654de40d53f55964667c7d8"
checksum = "495c05f60d6df0093e8fb6e74aa5846a0ad06abaf96d76166283720bf740f8ab"
dependencies = [
"bytes",
"futures-util",
"fs-err",
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
"hyper 1.6.0",
"hyper-util",
"pin-project-lite",
"tokio",
"tower 0.4.13",
"tower-service",
]
@ -665,9 +662,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a"
[[package]]
name = "cc"
version = "1.2.16"
version = "1.2.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c"
checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a"
dependencies = [
"shlex",
]
@ -749,9 +746,9 @@ dependencies = [
[[package]]
name = "clap_complete"
version = "4.5.46"
version = "4.5.47"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5c5508ea23c5366f77e53f5a0070e5a84e51687ec3ef9e0464c86dc8d13ce98"
checksum = "c06f5378ea264ad4f82bbc826628b5aad714a75abf6ece087e923010eb937fb6"
dependencies = [
"clap",
]
@ -812,9 +809,9 @@ dependencies = [
[[package]]
name = "concread"
version = "0.5.4"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a06c26e76cd1d7a88a44324d0cf18b11589be552e97af09bee345f7e7334c6d"
checksum = "cdefc169c45893a578093c2f90733e3c56b60e67b0a8670a16ade3437b2fe392"
dependencies = [
"ahash",
"arc-swap",
@ -1044,7 +1041,7 @@ dependencies = [
"kanidmd_core",
"mimalloc",
"prctl",
"reqwest 0.12.14",
"reqwest 0.12.15",
"sd-notify",
"serde_json",
"sketching",
@ -1170,9 +1167,9 @@ dependencies = [
[[package]]
name = "deranged"
version = "0.3.11"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058"
dependencies = [
"powerfmt",
"serde",
@ -1444,13 +1441,12 @@ dependencies = [
[[package]]
name = "fantoccini"
version = "0.21.4"
version = "0.21.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7722aeee9c2be6fa131166990295089d73d973012b758a2208b9ba51af5dd024"
checksum = "e3a6a7a9a454c24453f9807c7f12b37e31ae43f3eb41888ae1f79a9a3e3be3f5"
dependencies = [
"base64 0.22.1",
"cookie 0.18.1",
"futures-core",
"futures-util",
"http 1.3.1",
"http-body-util",
@ -1554,9 +1550,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.4"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foreign-types"
@ -1592,6 +1588,16 @@ dependencies = [
"num",
]
[[package]]
name = "fs-err"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1f89bda4c2a21204059a977ed3bfe746677dfd137b83c339e702b0ac91d482aa"
dependencies = [
"autocfg",
"tokio",
]
[[package]]
name = "fs4"
version = "0.12.0"
@ -1725,14 +1731,16 @@ dependencies = [
[[package]]
name = "getrandom"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8"
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"wasi 0.13.3+wasi-0.2.2",
"windows-targets 0.52.6",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasm-bindgen",
]
[[package]]
@ -2524,14 +2532,15 @@ dependencies = [
[[package]]
name = "iana-time-zone"
version = "0.1.61"
version = "0.1.62"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220"
checksum = "b2fd658b06e56721792c5df4475705b6cda790e9298d19d2f8af083457bcd127"
dependencies = [
"android_system_properties",
"core-foundation-sys",
"iana-time-zone-haiku",
"js-sys",
"log",
"wasm-bindgen",
"windows-core",
]
@ -2851,7 +2860,7 @@ dependencies = [
"percent-encoding",
"referencing",
"regex-syntax 0.8.5",
"reqwest 0.12.14",
"reqwest 0.12.15",
"serde",
"serde_json",
"uuid-simd",
@ -2942,7 +2951,7 @@ dependencies = [
"hyper 1.6.0",
"kanidm_lib_file_permissions",
"kanidm_proto",
"reqwest 0.12.14",
"reqwest 0.12.15",
"serde",
"serde_json",
"serde_urlencoded",
@ -2962,7 +2971,7 @@ dependencies = [
"anyhow",
"kanidm_proto",
"oauth2 5.0.0",
"reqwest 0.12.14",
"reqwest 0.12.15",
"sketching",
"tokio",
"tracing",
@ -2981,7 +2990,7 @@ dependencies = [
"md-5",
"openssl",
"openssl-sys",
"rand",
"rand 0.8.5",
"serde",
"sha-crypt",
"sha2",
@ -3207,7 +3216,7 @@ dependencies = [
"num_enum",
"openssl",
"openssl-sys",
"rand",
"rand 0.8.5",
"regex",
"rusqlite",
"serde",
@ -3258,7 +3267,7 @@ dependencies = [
"oauth2 4.4.2",
"openssl",
"petgraph",
"reqwest 0.12.14",
"reqwest 0.12.15",
"serde",
"serde_json",
"sketching",
@ -3376,9 +3385,9 @@ checksum = "8355be11b20d696c8f18f6cc018c4e372165b1fa8126cef092399c9951984ffa"
[[package]]
name = "libmimalloc-sys"
version = "0.1.39"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "23aa6811d3bd4deb8a84dde645f943476d13b248d818edcf8ce0b2f37f036b44"
checksum = "07d0e07885d6a754b9c7993f2625187ad694ee985d60f23355ff0e7077261502"
dependencies = [
"cc",
"libc",
@ -3444,9 +3453,9 @@ checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]]
name = "linux-raw-sys"
version = "0.9.2"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6db9c683daf087dc577b7506e9695b3d556a9f3849903fa28186283afd6809e9"
checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413"
[[package]]
name = "litemap"
@ -3484,9 +3493,9 @@ dependencies = [
[[package]]
name = "log"
version = "0.4.26"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e"
checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "lru"
@ -3533,7 +3542,7 @@ version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9a42bf938e4c9a6ad581cf528d5606eb50c5458ac759ca23719291e2f6499bec"
dependencies = [
"rand",
"rand 0.8.5",
]
[[package]]
@ -3572,9 +3581,9 @@ dependencies = [
[[package]]
name = "mimalloc"
version = "0.1.43"
version = "0.1.44"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "68914350ae34959d83f732418d51e2427a794055d0b9529f48259ac07af65633"
checksum = "99585191385958383e13f6b822e6b6d8d9cf928e7d286ceb092da92b43c87bc1"
dependencies = [
"libmimalloc-sys",
]
@ -3899,7 +3908,7 @@ dependencies = [
"chrono",
"getrandom 0.2.15",
"http 0.2.12",
"rand",
"rand 0.8.5",
"reqwest 0.11.27",
"serde",
"serde_json",
@ -3919,8 +3928,8 @@ dependencies = [
"chrono",
"getrandom 0.2.15",
"http 1.3.1",
"rand",
"reqwest 0.12.14",
"rand 0.8.5",
"reqwest 0.12.15",
"serde",
"serde_json",
"serde_path_to_error",
@ -4083,7 +4092,7 @@ dependencies = [
"glob",
"opentelemetry",
"percent-encoding",
"rand",
"rand 0.8.5",
"serde_json",
"thiserror 1.0.69",
"tokio",
@ -4106,8 +4115,8 @@ dependencies = [
"kanidm_client",
"mathru",
"mimalloc",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_json",
"tokio",
@ -4170,7 +4179,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "346f04948ba92c43e8469c1ee6736c7563d71012b17d40745260fe106aac2166"
dependencies = [
"base64ct",
"rand_core",
"rand_core 0.6.4",
"subtle",
]
@ -4324,7 +4333,7 @@ version = "0.2.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9"
dependencies = [
"zerocopy 0.8.23",
"zerocopy 0.8.24",
]
[[package]]
@ -4453,11 +4462,12 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
[[package]]
name = "quinn"
version = "0.11.6"
version = "0.11.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62e96808277ec6f97351a2380e6c25114bc9e67037775464979f3037c92d05ef"
checksum = "c3bd15a6f2967aef83887dcb9fec0014580467e33720d073560cf015a5683012"
dependencies = [
"bytes",
"cfg_aliases",
"pin-project-lite",
"quinn-proto",
"quinn-udp",
@ -4467,17 +4477,18 @@ dependencies = [
"thiserror 2.0.12",
"tokio",
"tracing",
"web-time",
]
[[package]]
name = "quinn-proto"
version = "0.11.9"
version = "0.11.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2fe5ef3495d7d2e377ff17b1a8ce2ee2ec2a18cde8b6ad6619d65d0701c135d"
checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc"
dependencies = [
"bytes",
"getrandom 0.2.15",
"rand",
"getrandom 0.3.2",
"rand 0.9.0",
"ring",
"rustc-hash 2.1.1",
"rustls",
@ -4491,9 +4502,9 @@ dependencies = [
[[package]]
name = "quinn-udp"
version = "0.5.10"
version = "0.5.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e46f3055866785f6b92bc6164b76be02ca8f2eb4b002c0354b28cf4c119e5944"
checksum = "541d0f57c6ec747a90738a52741d3221f7960e8ac2f0ff4b1a63680e033b4ab5"
dependencies = [
"cfg_aliases",
"libc",
@ -4512,6 +4523,12 @@ dependencies = [
"proc-macro2",
]
[[package]]
name = "r-efi"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
[[package]]
name = "rand"
version = "0.8.5"
@ -4519,8 +4536,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
dependencies = [
"libc",
"rand_chacha",
"rand_core",
"rand_chacha 0.3.1",
"rand_core 0.6.4",
]
[[package]]
name = "rand"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
"zerocopy 0.8.24",
]
[[package]]
@ -4530,7 +4558,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
dependencies = [
"ppv-lite86",
"rand_core",
"rand_core 0.6.4",
]
[[package]]
name = "rand_chacha"
version = "0.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
dependencies = [
"ppv-lite86",
"rand_core 0.9.3",
]
[[package]]
@ -4542,6 +4580,15 @@ dependencies = [
"getrandom 0.2.15",
]
[[package]]
name = "rand_core"
version = "0.9.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
dependencies = [
"getrandom 0.3.2",
]
[[package]]
name = "redox_syscall"
version = "0.5.10"
@ -4684,9 +4731,9 @@ dependencies = [
[[package]]
name = "reqwest"
version = "0.12.14"
version = "0.12.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "989e327e510263980e231de548a33e63d34962d29ae61b467389a1a09627a254"
checksum = "d19c46a6fdd48bc4dab94b6103fccc55d34c67cc0ad04653aad4ea2a07cd7bbb"
dependencies = [
"async-compression",
"base64 0.22.1",
@ -4862,22 +4909,22 @@ dependencies = [
[[package]]
name = "rustix"
version = "1.0.2"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f7178faa4b75a30e269c71e61c353ce2748cf3d76f0c44c393f4e60abf49b825"
checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96"
dependencies = [
"bitflags 2.9.0",
"errno",
"libc",
"linux-raw-sys 0.9.2",
"linux-raw-sys 0.9.3",
"windows-sys 0.59.0",
]
[[package]]
name = "rustls"
version = "0.23.23"
version = "0.23.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395"
checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c"
dependencies = [
"once_cell",
"ring",
@ -4919,9 +4966,9 @@ dependencies = [
[[package]]
name = "rustls-webpki"
version = "0.102.8"
version = "0.103.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9"
checksum = "fef8b8769aaccf73098557a87cd1816b4f9c7c16811c9c77142aa695c16f2c03"
dependencies = [
"ring",
"rustls-pki-types",
@ -5178,7 +5225,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88e79009728d8311d42d754f2f319a975f9e38f156fd5e422d2451486c78b286"
dependencies = [
"base64ct",
"rand",
"rand 0.8.5",
"sha2",
"subtle",
]
@ -5470,14 +5517,14 @@ checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1"
[[package]]
name = "tempfile"
version = "3.19.0"
version = "3.19.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488960f40a3fd53d72c2a29a58722561dee8afdd175bd88e3db4677d7b2ba600"
checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf"
dependencies = [
"fastrand",
"getrandom 0.3.1",
"getrandom 0.3.2",
"once_cell",
"rustix 1.0.2",
"rustix 1.0.3",
"windows-sys 0.59.0",
]
@ -5548,9 +5595,9 @@ dependencies = [
[[package]]
name = "time"
version = "0.3.39"
version = "0.3.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8"
checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40"
dependencies = [
"deranged",
"itoa",
@ -5565,15 +5612,15 @@ dependencies = [
[[package]]
name = "time-core"
version = "0.1.3"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef"
checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c"
[[package]]
name = "time-macros"
version = "0.2.20"
version = "0.2.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c"
checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49"
dependencies = [
"num-conv",
"time-core",
@ -5777,7 +5824,7 @@ dependencies = [
"indexmap 1.9.3",
"pin-project",
"pin-project-lite",
"rand",
"rand 0.8.5",
"slab",
"tokio",
"tokio-util",
@ -6111,11 +6158,11 @@ dependencies = [
[[package]]
name = "uuid"
version = "1.15.1"
version = "1.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0f540e3240398cce6128b64ba83fdbdd86129c16a3aa1a3a252efd66eb3d587"
checksum = "458f7a779bf54acc9f347480ac654f68407d3aab21269a6e3c9f922acd9e2da9"
dependencies = [
"getrandom 0.3.1",
"getrandom 0.3.2",
"serde",
]
@ -6181,9 +6228,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
[[package]]
name = "wasi"
version = "0.13.3+wasi-0.2.2"
version = "0.14.2+wasi-0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2"
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
dependencies = [
"wit-bindgen-rt",
]
@ -6359,8 +6406,8 @@ dependencies = [
"hex",
"nom",
"openssl",
"rand",
"rand_chacha",
"rand 0.8.5",
"rand_chacha 0.3.1",
"serde",
"serde_cbor_2",
"serde_json",
@ -6435,9 +6482,9 @@ dependencies = [
[[package]]
name = "whoami"
version = "1.5.2"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d"
checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7"
dependencies = [
"redox_syscall",
"wasite",
@ -6501,9 +6548,9 @@ dependencies = [
[[package]]
name = "windows-link"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dccfd733ce2b1753b03b6d3c65edf020262ea35e20ccdf3e288043e6dd620e3"
checksum = "76840935b766e1b0a05c0066835fb9ec80071d4c09a16f6bd5f7e655e3c14c38"
[[package]]
name = "windows-registry"
@ -6518,9 +6565,9 @@ dependencies = [
[[package]]
name = "windows-result"
version = "0.3.1"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "06374efe858fab7e4f881500e6e86ec8bc28f9462c47e5a9941a0142ad86b189"
checksum = "c64fd11a4fd95df68efcfee5f44a294fe71b8bc6a91993e2791938abcc712252"
dependencies = [
"windows-link",
]
@ -6818,9 +6865,9 @@ dependencies = [
[[package]]
name = "wit-bindgen-rt"
version = "0.33.0"
version = "0.39.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c"
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
dependencies = [
"bitflags 2.9.0",
]
@ -6901,11 +6948,11 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.8.23"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd97444d05a4328b90e75e503a34bad781f14e28a823ad3557f0750df1ebcbc6"
checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879"
dependencies = [
"zerocopy-derive 0.8.23",
"zerocopy-derive 0.8.24",
]
[[package]]
@ -6921,9 +6968,9 @@ dependencies = [
[[package]]
name = "zerocopy-derive"
version = "0.8.23"
version = "0.8.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6352c01d0edd5db859a63e2605f4ea3183ddbd15e2c4a9e7d32184df75e4f154"
checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be"
dependencies = [
"proc-macro2",
"quote",

View file

@ -164,7 +164,7 @@ clap_complete = "^4.5.42"
# Forced by saffron/cron
chrono = "^0.4.39"
compact_jwt = { version = "^0.4.2", default-features = false }
concread = "^0.5.3"
concread = "^0.5.5"
cron = "0.15.0"
crossbeam = "0.8.4"
csv = "1.3.1"

View file

@ -45,6 +45,7 @@ can take many forms such as.
- firstname firstname lastname
- firstname lastname lastname
- firstname
- middlename lastname
- lastname firstname
And many many more that are not listed here. This is why our names are displayName as a freetext

View file

@ -566,7 +566,7 @@ Due to a [lack of public client support](https://github.com/oauth2-proxy/oauth2-
```bash
kanidm system oauth2 create webapp 'webapp.example.com' 'https://webapp.example.com'
kanidm system add-redirect-url webapp 'https://webapp.example.com/oauth2/callback'
kanidm system oauth2 add-redirect-url webapp 'https://webapp.example.com/oauth2/callback'
kanidm system oauth2 update-scope-map webapp email openid
kanidm system oauth2 get webapp
kanidm system oauth2 show-basic-secret webapp

View file

@ -1,3 +1,6 @@
# The server configuration file version.
version = "2"
# The webserver bind address. Requires TLS certificates.
# If the port is set to 443 you may require the
# NET_BIND_SERVICE capability.

View file

@ -1,3 +1,6 @@
# The server configuration file version.
version = "2"
# The webserver bind address. Requires TLS certificates.
# If the port is set to 443 you may require the
# NET_BIND_SERVICE capability.

View file

@ -80,6 +80,7 @@ pub enum Attribute {
IdVerificationEcKey,
Image,
Index,
Indexed,
IpaNtHash,
IpaSshPubKey,
JwsEs256PrivateKey,
@ -311,6 +312,7 @@ impl Attribute {
Attribute::IdVerificationEcKey => ATTR_ID_VERIFICATION_ECKEY,
Attribute::Image => ATTR_IMAGE,
Attribute::Index => ATTR_INDEX,
Attribute::Indexed => ATTR_INDEXED,
Attribute::IpaNtHash => ATTR_IPANTHASH,
Attribute::IpaSshPubKey => ATTR_IPASSHPUBKEY,
Attribute::JwsEs256PrivateKey => ATTR_JWS_ES256_PRIVATE_KEY,
@ -495,6 +497,7 @@ impl Attribute {
ATTR_ID_VERIFICATION_ECKEY => Attribute::IdVerificationEcKey,
ATTR_IMAGE => Attribute::Image,
ATTR_INDEX => Attribute::Index,
ATTR_INDEXED => Attribute::Indexed,
ATTR_IPANTHASH => Attribute::IpaNtHash,
ATTR_IPASSHPUBKEY => Attribute::IpaSshPubKey,
ATTR_JWS_ES256_PRIVATE_KEY => Attribute::JwsEs256PrivateKey,

View file

@ -124,6 +124,7 @@ pub const ATTR_GROUP: &str = "group";
pub const ATTR_ID_VERIFICATION_ECKEY: &str = "id_verification_eckey";
pub const ATTR_IMAGE: &str = "image";
pub const ATTR_INDEX: &str = "index";
pub const ATTR_INDEXED: &str = "indexed";
pub const ATTR_IPANTHASH: &str = "ipanthash";
pub const ATTR_IPASSHPUBKEY: &str = "ipasshpubkey";
pub const ATTR_JWS_ES256_PRIVATE_KEY: &str = "jws_es256_private_key";

344
pykanidm/poetry.lock generated
View file

@ -14,93 +14,93 @@ files = [
[[package]]
name = "aiohttp"
version = "3.11.13"
version = "3.11.14"
description = "Async http client/server framework (asyncio)"
optional = false
python-versions = ">=3.9"
groups = ["main", "dev"]
files = [
{file = "aiohttp-3.11.13-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:a4fe27dbbeec445e6e1291e61d61eb212ee9fed6e47998b27de71d70d3e8777d"},
{file = "aiohttp-3.11.13-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:9e64ca2dbea28807f8484c13f684a2f761e69ba2640ec49dacd342763cc265ef"},
{file = "aiohttp-3.11.13-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9840be675de208d1f68f84d578eaa4d1a36eee70b16ae31ab933520c49ba1325"},
{file = "aiohttp-3.11.13-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28a772757c9067e2aee8a6b2b425d0efaa628c264d6416d283694c3d86da7689"},
{file = "aiohttp-3.11.13-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b88aca5adbf4625e11118df45acac29616b425833c3be7a05ef63a6a4017bfdb"},
{file = "aiohttp-3.11.13-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce10ddfbe26ed5856d6902162f71b8fe08545380570a885b4ab56aecfdcb07f4"},
{file = "aiohttp-3.11.13-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fa48dac27f41b36735c807d1ab093a8386701bbf00eb6b89a0f69d9fa26b3671"},
{file = "aiohttp-3.11.13-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:89ce611b1eac93ce2ade68f1470889e0173d606de20c85a012bfa24be96cf867"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:78e4dd9c34ec7b8b121854eb5342bac8b02aa03075ae8618b6210a06bbb8a115"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:66047eacbc73e6fe2462b77ce39fc170ab51235caf331e735eae91c95e6a11e4"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5ad8f1c19fe277eeb8bc45741c6d60ddd11d705c12a4d8ee17546acff98e0802"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:64815c6f02e8506b10113ddbc6b196f58dbef135751cc7c32136df27b736db09"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:967b93f21b426f23ca37329230d5bd122f25516ae2f24a9cea95a30023ff8283"},
{file = "aiohttp-3.11.13-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cf1f31f83d16ec344136359001c5e871915c6ab685a3d8dee38e2961b4c81730"},
{file = "aiohttp-3.11.13-cp310-cp310-win32.whl", hash = "sha256:00c8ac69e259c60976aa2edae3f13d9991cf079aaa4d3cd5a49168ae3748dee3"},
{file = "aiohttp-3.11.13-cp310-cp310-win_amd64.whl", hash = "sha256:90d571c98d19a8b6e793b34aa4df4cee1e8fe2862d65cc49185a3a3d0a1a3996"},
{file = "aiohttp-3.11.13-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6b35aab22419ba45f8fc290d0010898de7a6ad131e468ffa3922b1b0b24e9d2e"},
{file = "aiohttp-3.11.13-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f81cba651db8795f688c589dd11a4fbb834f2e59bbf9bb50908be36e416dc760"},
{file = "aiohttp-3.11.13-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f55d0f242c2d1fcdf802c8fabcff25a9d85550a4cf3a9cf5f2a6b5742c992839"},
{file = "aiohttp-3.11.13-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4bea08a6aad9195ac9b1be6b0c7e8a702a9cec57ce6b713698b4a5afa9c2e33"},
{file = "aiohttp-3.11.13-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6070bcf2173a7146bb9e4735b3c62b2accba459a6eae44deea0eb23e0035a23"},
{file = "aiohttp-3.11.13-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:718d5deb678bc4b9d575bfe83a59270861417da071ab44542d0fcb6faa686636"},
{file = "aiohttp-3.11.13-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f6b2c5b4a4d22b8fb2c92ac98e0747f5f195e8e9448bfb7404cd77e7bfa243f"},
{file = "aiohttp-3.11.13-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:747ec46290107a490d21fe1ff4183bef8022b848cf9516970cb31de6d9460088"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:01816f07c9cc9d80f858615b1365f8319d6a5fd079cd668cc58e15aafbc76a54"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:a08ad95fcbd595803e0c4280671d808eb170a64ca3f2980dd38e7a72ed8d1fea"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:c97be90d70f7db3aa041d720bfb95f4869d6063fcdf2bb8333764d97e319b7d0"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ab915a57c65f7a29353c8014ac4be685c8e4a19e792a79fe133a8e101111438e"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:35cda4e07f5e058a723436c4d2b7ba2124ab4e0aa49e6325aed5896507a8a42e"},
{file = "aiohttp-3.11.13-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:af55314407714fe77a68a9ccaab90fdb5deb57342585fd4a3a8102b6d4370080"},
{file = "aiohttp-3.11.13-cp311-cp311-win32.whl", hash = "sha256:42d689a5c0a0c357018993e471893e939f555e302313d5c61dfc566c2cad6185"},
{file = "aiohttp-3.11.13-cp311-cp311-win_amd64.whl", hash = "sha256:b73a2b139782a07658fbf170fe4bcdf70fc597fae5ffe75e5b67674c27434a9f"},
{file = "aiohttp-3.11.13-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2eabb269dc3852537d57589b36d7f7362e57d1ece308842ef44d9830d2dc3c90"},
{file = "aiohttp-3.11.13-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7b77ee42addbb1c36d35aca55e8cc6d0958f8419e458bb70888d8c69a4ca833d"},
{file = "aiohttp-3.11.13-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55789e93c5ed71832e7fac868167276beadf9877b85697020c46e9a75471f55f"},
{file = "aiohttp-3.11.13-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c929f9a7249a11e4aa5c157091cfad7f49cc6b13f4eecf9b747104befd9f56f2"},
{file = "aiohttp-3.11.13-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d33851d85537bbf0f6291ddc97926a754c8f041af759e0aa0230fe939168852b"},
{file = "aiohttp-3.11.13-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9229d8613bd8401182868fe95688f7581673e1c18ff78855671a4b8284f47bcb"},
{file = "aiohttp-3.11.13-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:669dd33f028e54fe4c96576f406ebb242ba534dd3a981ce009961bf49960f117"},
{file = "aiohttp-3.11.13-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c1b20a1ace54af7db1f95af85da530fe97407d9063b7aaf9ce6a32f44730778"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5724cc77f4e648362ebbb49bdecb9e2b86d9b172c68a295263fa072e679ee69d"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:aa36c35e94ecdb478246dd60db12aba57cfcd0abcad43c927a8876f25734d496"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9b5b37c863ad5b0892cc7a4ceb1e435e5e6acd3f2f8d3e11fa56f08d3c67b820"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e06cf4852ce8c4442a59bae5a3ea01162b8fcb49ab438d8548b8dc79375dad8a"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5194143927e494616e335d074e77a5dac7cd353a04755330c9adc984ac5a628e"},
{file = "aiohttp-3.11.13-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:afcb6b275c2d2ba5d8418bf30a9654fa978b4f819c2e8db6311b3525c86fe637"},
{file = "aiohttp-3.11.13-cp312-cp312-win32.whl", hash = "sha256:7104d5b3943c6351d1ad7027d90bdd0ea002903e9f610735ac99df3b81f102ee"},
{file = "aiohttp-3.11.13-cp312-cp312-win_amd64.whl", hash = "sha256:47dc018b1b220c48089b5b9382fbab94db35bef2fa192995be22cbad3c5730c8"},
{file = "aiohttp-3.11.13-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9862d077b9ffa015dbe3ce6c081bdf35135948cb89116e26667dd183550833d1"},
{file = "aiohttp-3.11.13-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:fbfef0666ae9e07abfa2c54c212ac18a1f63e13e0760a769f70b5717742f3ece"},
{file = "aiohttp-3.11.13-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:93a1f7d857c4fcf7cabb1178058182c789b30d85de379e04f64c15b7e88d66fb"},
{file = "aiohttp-3.11.13-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba40b7ae0f81c7029583a338853f6607b6d83a341a3dcde8bed1ea58a3af1df9"},
{file = "aiohttp-3.11.13-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b5b95787335c483cd5f29577f42bbe027a412c5431f2f80a749c80d040f7ca9f"},
{file = "aiohttp-3.11.13-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a7d474c5c1f0b9405c1565fafdc4429fa7d986ccbec7ce55bc6a330f36409cad"},
{file = "aiohttp-3.11.13-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e83fb1991e9d8982b3b36aea1e7ad27ea0ce18c14d054c7a404d68b0319eebb"},
{file = "aiohttp-3.11.13-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4586a68730bd2f2b04a83e83f79d271d8ed13763f64b75920f18a3a677b9a7f0"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fe4eb0e7f50cdb99b26250d9328faef30b1175a5dbcfd6d0578d18456bac567"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2a8a6bc19818ac3e5596310ace5aa50d918e1ebdcc204dc96e2f4d505d51740c"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7f27eec42f6c3c1df09cfc1f6786308f8b525b8efaaf6d6bd76c1f52c6511f6a"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:2a4a13dfbb23977a51853b419141cd0a9b9573ab8d3a1455c6e63561387b52ff"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:02876bf2f69b062584965507b07bc06903c2dc93c57a554b64e012d636952654"},
{file = "aiohttp-3.11.13-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b992778d95b60a21c4d8d4a5f15aaab2bd3c3e16466a72d7f9bfd86e8cea0d4b"},
{file = "aiohttp-3.11.13-cp313-cp313-win32.whl", hash = "sha256:507ab05d90586dacb4f26a001c3abf912eb719d05635cbfad930bdbeb469b36c"},
{file = "aiohttp-3.11.13-cp313-cp313-win_amd64.whl", hash = "sha256:5ceb81a4db2decdfa087381b5fc5847aa448244f973e5da232610304e199e7b2"},
{file = "aiohttp-3.11.13-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:51c3ff9c7a25f3cad5c09d9aacbc5aefb9267167c4652c1eb737989b554fe278"},
{file = "aiohttp-3.11.13-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e271beb2b1dabec5cd84eb488bdabf9758d22ad13471e9c356be07ad139b3012"},
{file = "aiohttp-3.11.13-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:0e9eb7e5764abcb49f0e2bd8f5731849b8728efbf26d0cac8e81384c95acec3f"},
{file = "aiohttp-3.11.13-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:baae005092e3f200de02699314ac8933ec20abf998ec0be39448f6605bce93df"},
{file = "aiohttp-3.11.13-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1982c98ac62c132d2b773d50e2fcc941eb0b8bad3ec078ce7e7877c4d5a2dce7"},
{file = "aiohttp-3.11.13-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2b25b2eeb35707113b2d570cadc7c612a57f1c5d3e7bb2b13870fe284e08fc0"},
{file = "aiohttp-3.11.13-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b27961d65639128336b7a7c3f0046dcc62a9443d5ef962e3c84170ac620cec47"},
{file = "aiohttp-3.11.13-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a01fe9f1e05025eacdd97590895e2737b9f851d0eb2e017ae9574d9a4f0b6252"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:fa1fb1b61881c8405829c50e9cc5c875bfdbf685edf57a76817dfb50643e4a1a"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:25de43bb3cf83ad83efc8295af7310219af6dbe4c543c2e74988d8e9c8a2a917"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:fe7065e2215e4bba63dc00db9ae654c1ba3950a5fff691475a32f511142fcddb"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:7836587eef675a17d835ec3d98a8c9acdbeb2c1d72b0556f0edf4e855a25e9c1"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:85fa0b18558eb1427090912bd456a01f71edab0872f4e0f9e4285571941e4090"},
{file = "aiohttp-3.11.13-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a86dc177eb4c286c19d1823ac296299f59ed8106c9536d2b559f65836e0fb2c6"},
{file = "aiohttp-3.11.13-cp39-cp39-win32.whl", hash = "sha256:684eea71ab6e8ade86b9021bb62af4bf0881f6be4e926b6b5455de74e420783a"},
{file = "aiohttp-3.11.13-cp39-cp39-win_amd64.whl", hash = "sha256:82c249f2bfa5ecbe4a1a7902c81c0fba52ed9ebd0176ab3047395d02ad96cfcb"},
{file = "aiohttp-3.11.13.tar.gz", hash = "sha256:8ce789231404ca8fff7f693cdce398abf6d90fd5dae2b1847477196c243b1fbb"},
{file = "aiohttp-3.11.14-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e2bc827c01f75803de77b134afdbf74fa74b62970eafdf190f3244931d7a5c0d"},
{file = "aiohttp-3.11.14-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e365034c5cf6cf74f57420b57682ea79e19eb29033399dd3f40de4d0171998fa"},
{file = "aiohttp-3.11.14-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c32593ead1a8c6aabd58f9d7ee706e48beac796bb0cb71d6b60f2c1056f0a65f"},
{file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b4e7c7ec4146a94a307ca4f112802a8e26d969018fabed526efc340d21d3e7d0"},
{file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8b2df9feac55043759aa89f722a967d977d80f8b5865a4153fc41c93b957efc"},
{file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c7571f99525c76a6280f5fe8e194eeb8cb4da55586c3c61c59c33a33f10cfce7"},
{file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b59d096b5537ec7c85954cb97d821aae35cfccce3357a2cafe85660cc6295628"},
{file = "aiohttp-3.11.14-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b42dbd097abb44b3f1156b4bf978ec5853840802d6eee2784857be11ee82c6a0"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:b05774864c87210c531b48dfeb2f7659407c2dda8643104fb4ae5e2c311d12d9"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_armv7l.whl", hash = "sha256:4e2e8ef37d4bc110917d038807ee3af82700a93ab2ba5687afae5271b8bc50ff"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e9faafa74dbb906b2b6f3eb9942352e9e9db8d583ffed4be618a89bd71a4e914"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:7e7abe865504f41b10777ac162c727af14e9f4db9262e3ed8254179053f63e6d"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:4848ae31ad44330b30f16c71e4f586cd5402a846b11264c412de99fa768f00f3"},
{file = "aiohttp-3.11.14-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2d0b46abee5b5737cb479cc9139b29f010a37b1875ee56d142aefc10686a390b"},
{file = "aiohttp-3.11.14-cp310-cp310-win32.whl", hash = "sha256:a0d2c04a623ab83963576548ce098baf711a18e2c32c542b62322a0b4584b990"},
{file = "aiohttp-3.11.14-cp310-cp310-win_amd64.whl", hash = "sha256:5409a59d5057f2386bb8b8f8bbcfb6e15505cedd8b2445db510563b5d7ea1186"},
{file = "aiohttp-3.11.14-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f296d637a50bb15fb6a229fbb0eb053080e703b53dbfe55b1e4bb1c5ed25d325"},
{file = "aiohttp-3.11.14-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ec6cd1954ca2bbf0970f531a628da1b1338f594bf5da7e361e19ba163ecc4f3b"},
{file = "aiohttp-3.11.14-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:572def4aad0a4775af66d5a2b5923c7de0820ecaeeb7987dcbccda2a735a993f"},
{file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c68e41c4d576cd6aa6c6d2eddfb32b2acfb07ebfbb4f9da991da26633a3db1a"},
{file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b8bbfc8111826aa8363442c0fc1f5751456b008737ff053570f06a151650b3"},
{file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4b0a200e85da5c966277a402736a96457b882360aa15416bf104ca81e6f5807b"},
{file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d173c0ac508a2175f7c9a115a50db5fd3e35190d96fdd1a17f9cb10a6ab09aa1"},
{file = "aiohttp-3.11.14-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:413fe39fd929329f697f41ad67936f379cba06fcd4c462b62e5b0f8061ee4a77"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:65c75b14ee74e8eeff2886321e76188cbe938d18c85cff349d948430179ad02c"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:321238a42ed463848f06e291c4bbfb3d15ba5a79221a82c502da3e23d7525d06"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:59a05cdc636431f7ce843c7c2f04772437dd816a5289f16440b19441be6511f1"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:daf20d9c3b12ae0fdf15ed92235e190f8284945563c4b8ad95b2d7a31f331cd3"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:05582cb2d156ac7506e68b5eac83179faedad74522ed88f88e5861b78740dc0e"},
{file = "aiohttp-3.11.14-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:12c5869e7ddf6b4b1f2109702b3cd7515667b437da90a5a4a50ba1354fe41881"},
{file = "aiohttp-3.11.14-cp311-cp311-win32.whl", hash = "sha256:92868f6512714efd4a6d6cb2bfc4903b997b36b97baea85f744229f18d12755e"},
{file = "aiohttp-3.11.14-cp311-cp311-win_amd64.whl", hash = "sha256:bccd2cb7aa5a3bfada72681bdb91637094d81639e116eac368f8b3874620a654"},
{file = "aiohttp-3.11.14-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:70ab0f61c1a73d3e0342cedd9a7321425c27a7067bebeeacd509f96695b875fc"},
{file = "aiohttp-3.11.14-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:602d4db80daf4497de93cb1ce00b8fc79969c0a7cf5b67bec96fa939268d806a"},
{file = "aiohttp-3.11.14-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3a8a0d127c10b8d89e69bbd3430da0f73946d839e65fec00ae48ca7916a31948"},
{file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca9f835cdfedcb3f5947304e85b8ca3ace31eef6346d8027a97f4de5fb687534"},
{file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8aa5c68e1e68fff7cd3142288101deb4316b51f03d50c92de6ea5ce646e6c71f"},
{file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b512f1de1c688f88dbe1b8bb1283f7fbeb7a2b2b26e743bb2193cbadfa6f307"},
{file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc9253069158d57e27d47a8453d8a2c5a370dc461374111b5184cf2f147a3cc3"},
{file = "aiohttp-3.11.14-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0b2501f1b981e70932b4a552fc9b3c942991c7ae429ea117e8fba57718cdeed0"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:28a3d083819741592685762d51d789e6155411277050d08066537c5edc4066e6"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:0df3788187559c262922846087e36228b75987f3ae31dd0a1e5ee1034090d42f"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e73fa341d8b308bb799cf0ab6f55fc0461d27a9fa3e4582755a3d81a6af8c09"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:51ba80d473eb780a329d73ac8afa44aa71dfb521693ccea1dea8b9b5c4df45ce"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:8d1dd75aa4d855c7debaf1ef830ff2dfcc33f893c7db0af2423ee761ebffd22b"},
{file = "aiohttp-3.11.14-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41cf0cefd9e7b5c646c2ef529c8335e7eafd326f444cc1cdb0c47b6bc836f9be"},
{file = "aiohttp-3.11.14-cp312-cp312-win32.whl", hash = "sha256:948abc8952aff63de7b2c83bfe3f211c727da3a33c3a5866a0e2cf1ee1aa950f"},
{file = "aiohttp-3.11.14-cp312-cp312-win_amd64.whl", hash = "sha256:3b420d076a46f41ea48e5fcccb996f517af0d406267e31e6716f480a3d50d65c"},
{file = "aiohttp-3.11.14-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8d14e274828561db91e4178f0057a915f3af1757b94c2ca283cb34cbb6e00b50"},
{file = "aiohttp-3.11.14-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f30fc72daf85486cdcdfc3f5e0aea9255493ef499e31582b34abadbfaafb0965"},
{file = "aiohttp-3.11.14-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4edcbe34e6dba0136e4cabf7568f5a434d89cc9de5d5155371acda275353d228"},
{file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a7169ded15505f55a87f8f0812c94c9412623c744227b9e51083a72a48b68a5"},
{file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad1f2fb9fe9b585ea4b436d6e998e71b50d2b087b694ab277b30e060c434e5db"},
{file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:20412c7cc3720e47a47e63c0005f78c0c2370020f9f4770d7fc0075f397a9fb0"},
{file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6dd9766da617855f7e85f27d2bf9a565ace04ba7c387323cd3e651ac4329db91"},
{file = "aiohttp-3.11.14-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:599b66582f7276ebefbaa38adf37585e636b6a7a73382eb412f7bc0fc55fb73d"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b41693b7388324b80f9acfabd479bd1c84f0bc7e8f17bab4ecd9675e9ff9c734"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:86135c32d06927339c8c5e64f96e4eee8825d928374b9b71a3c42379d7437058"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:04eb541ce1e03edc1e3be1917a0f45ac703e913c21a940111df73a2c2db11d73"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:dc311634f6f28661a76cbc1c28ecf3b3a70a8edd67b69288ab7ca91058eb5a33"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69bb252bfdca385ccabfd55f4cd740d421dd8c8ad438ded9637d81c228d0da49"},
{file = "aiohttp-3.11.14-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2b86efe23684b58a88e530c4ab5b20145f102916bbb2d82942cafec7bd36a647"},
{file = "aiohttp-3.11.14-cp313-cp313-win32.whl", hash = "sha256:b9c60d1de973ca94af02053d9b5111c4fbf97158e139b14f1be68337be267be6"},
{file = "aiohttp-3.11.14-cp313-cp313-win_amd64.whl", hash = "sha256:0a29be28e60e5610d2437b5b2fed61d6f3dcde898b57fb048aa5079271e7f6f3"},
{file = "aiohttp-3.11.14-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:14fc03508359334edc76d35b2821832f092c8f092e4b356e74e38419dfe7b6de"},
{file = "aiohttp-3.11.14-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:92007c89a8cb7be35befa2732b0b32bf3a394c1b22ef2dff0ef12537d98a7bda"},
{file = "aiohttp-3.11.14-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6d3986112e34eaa36e280dc8286b9dd4cc1a5bcf328a7f147453e188f6fe148f"},
{file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:749f1eb10e51dbbcdba9df2ef457ec060554842eea4d23874a3e26495f9e87b1"},
{file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:781c8bd423dcc4641298c8c5a2a125c8b1c31e11f828e8d35c1d3a722af4c15a"},
{file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:997b57e38aa7dc6caab843c5e042ab557bc83a2f91b7bd302e3c3aebbb9042a1"},
{file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a8b0321e40a833e381d127be993b7349d1564b756910b28b5f6588a159afef3"},
{file = "aiohttp-3.11.14-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8778620396e554b758b59773ab29c03b55047841d8894c5e335f12bfc45ebd28"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:e906da0f2bcbf9b26cc2b144929e88cb3bf943dd1942b4e5af066056875c7618"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_armv7l.whl", hash = "sha256:87f0e003fb4dd5810c7fbf47a1239eaa34cd929ef160e0a54c570883125c4831"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:7f2dadece8b85596ac3ab1ec04b00694bdd62abc31e5618f524648d18d9dd7fa"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:fe846f0a98aa9913c2852b630cd39b4098f296e0907dd05f6c7b30d911afa4c3"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:ced66c5c6ad5bcaf9be54560398654779ec1c3695f1a9cf0ae5e3606694a000a"},
{file = "aiohttp-3.11.14-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a40087b82f83bd671cbeb5f582c233d196e9653220404a798798bfc0ee189fff"},
{file = "aiohttp-3.11.14-cp39-cp39-win32.whl", hash = "sha256:95d7787f2bcbf7cb46823036a8d64ccfbc2ffc7d52016b4044d901abceeba3db"},
{file = "aiohttp-3.11.14-cp39-cp39-win_amd64.whl", hash = "sha256:22a8107896877212130c58f74e64b77f7007cb03cea8698be317272643602d45"},
{file = "aiohttp-3.11.14.tar.gz", hash = "sha256:d6edc538c7480fa0a3b2bdd705f8010062d74700198da55d16498e1b49549b9c"},
]
[package.dependencies]
@ -462,75 +462,75 @@ files = [
[[package]]
name = "coverage"
version = "7.7.0"
version = "7.7.1"
description = "Code coverage measurement for Python"
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "coverage-7.7.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a538a23119d1e2e2ce077e902d02ea3d8e0641786ef6e0faf11ce82324743944"},
{file = "coverage-7.7.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1586ad158523f4133499a4f322b230e2cfef9cc724820dbd58595a5a236186f4"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b6c96d69928a3a6767fab8dc1ce8a02cf0156836ccb1e820c7f45a423570d98"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f18d47641282664276977c604b5a261e51fefc2980f5271d547d706b06a837f"},
{file = "coverage-7.7.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f2a1e18a85bd066c7c556d85277a7adf4651f259b2579113844835ba1a74aafd"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:70f0925c4e2bfc965369f417e7cc72538fd1ba91639cf1e4ef4b1a6b50439b3b"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b0fac2088ec4aaeb5468b814bd3ff5e5978364bfbce5e567c44c9e2854469f6c"},
{file = "coverage-7.7.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b3e212a894d8ae07fde2ca8b43d666a6d49bbbddb10da0f6a74ca7bd31f20054"},
{file = "coverage-7.7.0-cp310-cp310-win32.whl", hash = "sha256:f32b165bf6dfea0846a9c9c38b7e1d68f313956d60a15cde5d1709fddcaf3bee"},
{file = "coverage-7.7.0-cp310-cp310-win_amd64.whl", hash = "sha256:a2454b12a3f12cc4698f3508912e6225ec63682e2ca5a96f80a2b93cef9e63f3"},
{file = "coverage-7.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a0a207c87a9f743c8072d059b4711f8d13c456eb42dac778a7d2e5d4f3c253a7"},
{file = "coverage-7.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2d673e3add00048215c2cc507f1228a7523fd8bf34f279ac98334c9b07bd2656"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f81fe93dc1b8e5673f33443c0786c14b77e36f1025973b85e07c70353e46882b"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d8c7524779003d59948c51b4fcbf1ca4e27c26a7d75984f63488f3625c328b9b"},
{file = "coverage-7.7.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c124025430249118d018dcedc8b7426f39373527c845093132196f2a483b6dd"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e7f559c36d5cdc448ee13e7e56ed7b6b5d44a40a511d584d388a0f5d940977ba"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:37cbc7b0d93dfd133e33c7ec01123fbb90401dce174c3b6661d8d36fb1e30608"},
{file = "coverage-7.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7d2a65876274acf544703e943c010b60bd79404e3623a1e5d52b64a6e2728de5"},
{file = "coverage-7.7.0-cp311-cp311-win32.whl", hash = "sha256:f5a2f71d6a91238e7628f23538c26aa464d390cbdedf12ee2a7a0fb92a24482a"},
{file = "coverage-7.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:ae8006772c6b0fa53c33747913473e064985dac4d65f77fd2fdc6474e7cd54e4"},
{file = "coverage-7.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:056d3017ed67e7ddf266e6f57378ece543755a4c9231e997789ab3bd11392c94"},
{file = "coverage-7.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:33c1394d8407e2771547583b66a85d07ed441ff8fae5a4adb4237ad39ece60db"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fbb7a0c3c21908520149d7751cf5b74eb9b38b54d62997b1e9b3ac19a8ee2fe"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bb356e7ae7c2da13f404bf8f75be90f743c6df8d4607022e759f5d7d89fe83f8"},
{file = "coverage-7.7.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bce730d484038e97f27ea2dbe5d392ec5c2261f28c319a3bb266f6b213650135"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:aa4dff57fc21a575672176d5ab0ef15a927199e775c5e8a3d75162ab2b0c7705"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b667b91f4f714b17af2a18e220015c941d1cf8b07c17f2160033dbe1e64149f0"},
{file = "coverage-7.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:693d921621a0c8043bfdc61f7d4df5ea6d22165fe8b807cac21eb80dd94e4bbd"},
{file = "coverage-7.7.0-cp312-cp312-win32.whl", hash = "sha256:52fc89602cde411a4196c8c6894afb384f2125f34c031774f82a4f2608c59d7d"},
{file = "coverage-7.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:0ce8cf59e09d31a4915ff4c3b94c6514af4c84b22c4cc8ad7c3c546a86150a92"},
{file = "coverage-7.7.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4545485fef7a8a2d8f30e6f79ce719eb154aab7e44217eb444c1d38239af2072"},
{file = "coverage-7.7.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1393e5aa9441dafb0162c36c8506c648b89aea9565b31f6bfa351e66c11bcd82"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:316f29cc3392fa3912493ee4c83afa4a0e2db04ff69600711f8c03997c39baaa"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e1ffde1d6bc2a92f9c9207d1ad808550873748ac2d4d923c815b866baa343b3f"},
{file = "coverage-7.7.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:416e2a8845eaff288f97eaf76ab40367deafb9073ffc47bf2a583f26b05e5265"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5efdeff5f353ed3352c04e6b318ab05c6ce9249c25ed3c2090c6e9cadda1e3b2"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:57f3bd0d29bf2bd9325c0ff9cc532a175110c4bf8f412c05b2405fd35745266d"},
{file = "coverage-7.7.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ab7090f04b12dc6469882ce81244572779d3a4b67eea1c96fb9ecc8c607ef39"},
{file = "coverage-7.7.0-cp313-cp313-win32.whl", hash = "sha256:180e3fc68ee4dc5af8b33b6ca4e3bb8aa1abe25eedcb958ba5cff7123071af68"},
{file = "coverage-7.7.0-cp313-cp313-win_amd64.whl", hash = "sha256:55143aa13c49491f5606f05b49ed88663446dce3a4d3c5d77baa4e36a16d3573"},
{file = "coverage-7.7.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:cc41374d2f27d81d6558f8a24e5c114580ffefc197fd43eabd7058182f743322"},
{file = "coverage-7.7.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:89078312f06237417adda7c021c33f80f7a6d2db8572a5f6c330d89b080061ce"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b2f144444879363ea8834cd7b6869d79ac796cb8f864b0cfdde50296cd95816"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:60e6347d1ed882b1159ffea172cb8466ee46c665af4ca397edbf10ff53e9ffaf"},
{file = "coverage-7.7.0-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb203c0afffaf1a8f5b9659a013f8f16a1b2cad3a80a8733ceedc968c0cf4c57"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:ad0edaa97cb983d9f2ff48cadddc3e1fb09f24aa558abeb4dc9a0dbacd12cbb4"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:c5f8a5364fc37b2f172c26a038bc7ec4885f429de4a05fc10fdcb53fb5834c5c"},
{file = "coverage-7.7.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4e09534037933bf6eb31d804e72c52ec23219b32c1730f9152feabbd7499463"},
{file = "coverage-7.7.0-cp313-cp313t-win32.whl", hash = "sha256:1b336d06af14f8da5b1f391e8dec03634daf54dfcb4d1c4fb6d04c09d83cef90"},
{file = "coverage-7.7.0-cp313-cp313t-win_amd64.whl", hash = "sha256:b54a1ee4c6f1905a436cbaa04b26626d27925a41cbc3a337e2d3ff7038187f07"},
{file = "coverage-7.7.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:1c8fbce80b2b8bf135d105aa8f5b36eae0c57d702a1cc3ebdea2a6f03f6cdde5"},
{file = "coverage-7.7.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d9710521f07f526de30ccdead67e6b236fe996d214e1a7fba8b36e2ba2cd8261"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7789e700f33f2b133adae582c9f437523cd5db8de845774988a58c360fc88253"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b8c36093aca722db73633cf2359026ed7782a239eb1c6db2abcff876012dc4cf"},
{file = "coverage-7.7.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c075d167a6ec99b798c1fdf6e391a1d5a2d054caffe9593ba0f97e3df2c04f0e"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:d013c07061751ae81861cae6ec3a4fe04e84781b11fd4b6b4201590234b25c7b"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:104bf640f408f4e115b85110047c7f27377e1a8b7ba86f7db4fa47aa49dc9a8e"},
{file = "coverage-7.7.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:39abcacd1ed54e2c33c54bdc488b310e8ef6705833f7148b6eb9a547199d375d"},
{file = "coverage-7.7.0-cp39-cp39-win32.whl", hash = "sha256:8e336b56301774ace6be0017ff85c3566c556d938359b61b840796a0202f805c"},
{file = "coverage-7.7.0-cp39-cp39-win_amd64.whl", hash = "sha256:8c938c6ae59be67ac19a7204e079efc94b38222cd7d0269f96e45e18cddeaa59"},
{file = "coverage-7.7.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:3b0e6e54591ae0d7427def8a4d40fca99df6b899d10354bab73cd5609807261c"},
{file = "coverage-7.7.0-py3-none-any.whl", hash = "sha256:708f0a1105ef2b11c79ed54ed31f17e6325ac936501fc373f24be3e6a578146a"},
{file = "coverage-7.7.0.tar.gz", hash = "sha256:cd879d4646055a573775a1cec863d00c9ff8c55860f8b17f6d8eee9140c06166"},
{file = "coverage-7.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:553ba93f8e3c70e1b0031e4dfea36aba4e2b51fe5770db35e99af8dc5c5a9dfe"},
{file = "coverage-7.7.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:44683f2556a56c9a6e673b583763096b8efbd2df022b02995609cf8e64fc8ae0"},
{file = "coverage-7.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02fad4f8faa4153db76f9246bc95c1d99f054f4e0a884175bff9155cf4f856cb"},
{file = "coverage-7.7.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4c181ceba2e6808ede1e964f7bdc77bd8c7eb62f202c63a48cc541e5ffffccb6"},
{file = "coverage-7.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b5b207a8b08c6a934b214e364cab2fa82663d4af18981a6c0a9e95f8df7602"},
{file = "coverage-7.7.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:25fe40967717bad0ce628a0223f08a10d54c9d739e88c9cbb0f77b5959367542"},
{file = "coverage-7.7.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:881cae0f9cbd928c9c001487bb3dcbfd0b0af3ef53ae92180878591053be0cb3"},
{file = "coverage-7.7.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c90e9141e9221dd6fbc16a2727a5703c19443a8d9bf7d634c792fa0287cee1ab"},
{file = "coverage-7.7.1-cp310-cp310-win32.whl", hash = "sha256:ae13ed5bf5542d7d4a0a42ff5160e07e84adc44eda65ddaa635c484ff8e55917"},
{file = "coverage-7.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:171e9977c6a5d2b2be9efc7df1126fd525ce7cad0eb9904fe692da007ba90d81"},
{file = "coverage-7.7.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1165490be0069e34e4f99d08e9c5209c463de11b471709dfae31e2a98cbd49fd"},
{file = "coverage-7.7.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:44af11c00fd3b19b8809487630f8a0039130d32363239dfd15238e6d37e41a48"},
{file = "coverage-7.7.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fbba59022e7c20124d2f520842b75904c7b9f16c854233fa46575c69949fb5b9"},
{file = "coverage-7.7.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:af94fb80e4f159f4d93fb411800448ad87b6039b0500849a403b73a0d36bb5ae"},
{file = "coverage-7.7.1-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eae79f8e3501133aa0e220bbc29573910d096795882a70e6f6e6637b09522133"},
{file = "coverage-7.7.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e33426a5e1dc7743dd54dfd11d3a6c02c5d127abfaa2edd80a6e352b58347d1a"},
{file = "coverage-7.7.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b559adc22486937786731dac69e57296cb9aede7e2687dfc0d2696dbd3b1eb6b"},
{file = "coverage-7.7.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b838a91e84e1773c3436f6cc6996e000ed3ca5721799e7789be18830fad009a2"},
{file = "coverage-7.7.1-cp311-cp311-win32.whl", hash = "sha256:2c492401bdb3a85824669d6a03f57b3dfadef0941b8541f035f83bbfc39d4282"},
{file = "coverage-7.7.1-cp311-cp311-win_amd64.whl", hash = "sha256:1e6f867379fd033a0eeabb1be0cffa2bd660582b8b0c9478895c509d875a9d9e"},
{file = "coverage-7.7.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:eff187177d8016ff6addf789dcc421c3db0d014e4946c1cc3fbf697f7852459d"},
{file = "coverage-7.7.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2444fbe1ba1889e0b29eb4d11931afa88f92dc507b7248f45be372775b3cef4f"},
{file = "coverage-7.7.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:177d837339883c541f8524683e227adcaea581eca6bb33823a2a1fdae4c988e1"},
{file = "coverage-7.7.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:15d54ecef1582b1d3ec6049b20d3c1a07d5e7f85335d8a3b617c9960b4f807e0"},
{file = "coverage-7.7.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75c82b27c56478d5e1391f2e7b2e7f588d093157fa40d53fd9453a471b1191f2"},
{file = "coverage-7.7.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:315ff74b585110ac3b7ab631e89e769d294f303c6d21302a816b3554ed4c81af"},
{file = "coverage-7.7.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:4dd532dac197d68c478480edde74fd4476c6823355987fd31d01ad9aa1e5fb59"},
{file = "coverage-7.7.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:385618003e3d608001676bb35dc67ae3ad44c75c0395d8de5780af7bb35be6b2"},
{file = "coverage-7.7.1-cp312-cp312-win32.whl", hash = "sha256:63306486fcb5a827449464f6211d2991f01dfa2965976018c9bab9d5e45a35c8"},
{file = "coverage-7.7.1-cp312-cp312-win_amd64.whl", hash = "sha256:37351dc8123c154fa05b7579fdb126b9f8b1cf42fd6f79ddf19121b7bdd4aa04"},
{file = "coverage-7.7.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:eebd927b86761a7068a06d3699fd6c20129becf15bb44282db085921ea0f1585"},
{file = "coverage-7.7.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2a79c4a09765d18311c35975ad2eb1ac613c0401afdd9cb1ca4110aeb5dd3c4c"},
{file = "coverage-7.7.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b1c65a739447c5ddce5b96c0a388fd82e4bbdff7251396a70182b1d83631019"},
{file = "coverage-7.7.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:392cc8fd2b1b010ca36840735e2a526fcbd76795a5d44006065e79868cc76ccf"},
{file = "coverage-7.7.1-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9bb47cc9f07a59a451361a850cb06d20633e77a9118d05fd0f77b1864439461b"},
{file = "coverage-7.7.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b4c144c129343416a49378e05c9451c34aae5ccf00221e4fa4f487db0816ee2f"},
{file = "coverage-7.7.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:bc96441c9d9ca12a790b5ae17d2fa6654da4b3962ea15e0eabb1b1caed094777"},
{file = "coverage-7.7.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3d03287eb03186256999539d98818c425c33546ab4901028c8fa933b62c35c3a"},
{file = "coverage-7.7.1-cp313-cp313-win32.whl", hash = "sha256:8fed429c26b99641dc1f3a79179860122b22745dd9af36f29b141e178925070a"},
{file = "coverage-7.7.1-cp313-cp313-win_amd64.whl", hash = "sha256:092b134129a8bb940c08b2d9ceb4459af5fb3faea77888af63182e17d89e1cf1"},
{file = "coverage-7.7.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:d3154b369141c3169b8133973ac00f63fcf8d6dbcc297d788d36afbb7811e511"},
{file = "coverage-7.7.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:264ff2bcce27a7f455b64ac0dfe097680b65d9a1a293ef902675fa8158d20b24"},
{file = "coverage-7.7.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba8480ebe401c2f094d10a8c4209b800a9b77215b6c796d16b6ecdf665048950"},
{file = "coverage-7.7.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:520af84febb6bb54453e7fbb730afa58c7178fd018c398a8fcd8e269a79bf96d"},
{file = "coverage-7.7.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88d96127ae01ff571d465d4b0be25c123789cef88ba0879194d673fdea52f54e"},
{file = "coverage-7.7.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:0ce92c5a9d7007d838456f4b77ea159cb628187a137e1895331e530973dcf862"},
{file = "coverage-7.7.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:0dab4ef76d7b14f432057fdb7a0477e8bffca0ad39ace308be6e74864e632271"},
{file = "coverage-7.7.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:7e688010581dbac9cab72800e9076e16f7cccd0d89af5785b70daa11174e94de"},
{file = "coverage-7.7.1-cp313-cp313t-win32.whl", hash = "sha256:e52eb31ae3afacdacfe50705a15b75ded67935770c460d88c215a9c0c40d0e9c"},
{file = "coverage-7.7.1-cp313-cp313t-win_amd64.whl", hash = "sha256:a6b6b3bd121ee2ec4bd35039319f3423d0be282b9752a5ae9f18724bc93ebe7c"},
{file = "coverage-7.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:34a3bf6b92e6621fc4dcdaab353e173ccb0ca9e4bfbcf7e49a0134c86c9cd303"},
{file = "coverage-7.7.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d6874929d624d3a670f676efafbbc747f519a6121b581dd41d012109e70a5ebd"},
{file = "coverage-7.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ba5ff236c87a7b7aa1441a216caf44baee14cbfbd2256d306f926d16b026578"},
{file = "coverage-7.7.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:452735fafe8ff5918236d5fe1feac322b359e57692269c75151f9b4ee4b7e1bc"},
{file = "coverage-7.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5f99a93cecf799738e211f9746dc83749b5693538fbfac279a61682ba309387"},
{file = "coverage-7.7.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:11dd6f52c2a7ce8bf0a5f3b6e4a8eb60e157ffedc3c4b4314a41c1dfbd26ce58"},
{file = "coverage-7.7.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:b52edb940d087e2a96e73c1523284a2e94a4e66fa2ea1e2e64dddc67173bad94"},
{file = "coverage-7.7.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d2e73e2ac468536197e6b3ab79bc4a5c9da0f078cd78cfcc7fe27cf5d1195ef0"},
{file = "coverage-7.7.1-cp39-cp39-win32.whl", hash = "sha256:18f544356bceef17cc55fcf859e5664f06946c1b68efcea6acdc50f8f6a6e776"},
{file = "coverage-7.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:d66ff48ab3bb6f762a153e29c0fc1eb5a62a260217bc64470d7ba602f5886d20"},
{file = "coverage-7.7.1-pp39.pp310.pp311-none-any.whl", hash = "sha256:5b7b02e50d54be6114cc4f6a3222fec83164f7c42772ba03b520138859b5fde1"},
{file = "coverage-7.7.1-py3-none-any.whl", hash = "sha256:822fa99dd1ac686061e1219b67868e25d9757989cf2259f735a4802497d6da31"},
{file = "coverage-7.7.1.tar.gz", hash = "sha256:199a1272e642266b90c9f40dec7fd3d307b51bf639fa0d15980dc0b3246c1393"},
]
[package.extras]
@ -1051,14 +1051,14 @@ pyyaml = ">=5.1"
[[package]]
name = "mkdocs-material"
version = "9.6.8"
version = "9.6.9"
description = "Documentation that simply works"
optional = false
python-versions = ">=3.8"
groups = ["dev"]
files = [
{file = "mkdocs_material-9.6.8-py3-none-any.whl", hash = "sha256:0a51532dd8aa80b232546c073fe3ef60dfaef1b1b12196ac7191ee01702d1cf8"},
{file = "mkdocs_material-9.6.8.tar.gz", hash = "sha256:8de31bb7566379802532b248bd56d9c4bc834afc4625884bf5769f9412c6a354"},
{file = "mkdocs_material-9.6.9-py3-none-any.whl", hash = "sha256:6e61b7fb623ce2aa4622056592b155a9eea56ff3487d0835075360be45a4c8d1"},
{file = "mkdocs_material-9.6.9.tar.gz", hash = "sha256:a4872139715a1f27b2aa3f3dc31a9794b7bbf36333c0ba4607cf04786c94f89c"},
]
[package.dependencies]
@ -1120,14 +1120,14 @@ python-legacy = ["mkdocstrings-python-legacy (>=0.2.1)"]
[[package]]
name = "mkdocstrings-python"
version = "1.16.5"
version = "1.16.7"
description = "A Python handler for mkdocstrings."
optional = false
python-versions = ">=3.9"
groups = ["dev"]
files = [
{file = "mkdocstrings_python-1.16.5-py3-none-any.whl", hash = "sha256:0899a12e356eab8e83720c63e15d0ff51cd96603216c837618de346e086b39ba"},
{file = "mkdocstrings_python-1.16.5.tar.gz", hash = "sha256:706b28dd0f59249a7c22cc5d517c9521e06c030b57e2a5478e1928a58f900abb"},
{file = "mkdocstrings_python-1.16.7-py3-none-any.whl", hash = "sha256:a5589a5be247a28ba651287f83630c69524042f8055d93b5c203d804a3409333"},
{file = "mkdocstrings_python-1.16.7.tar.gz", hash = "sha256:cdfc1a99fe5f6f0d90446a364ef7cac12014a4ef46114b2677a58cec84007117"},
]
[package.dependencies]
@ -2084,30 +2084,30 @@ files = [
[[package]]
name = "ruff"
version = "0.11.0"
version = "0.11.2"
description = "An extremely fast Python linter and code formatter, written in Rust."
optional = false
python-versions = ">=3.7"
groups = ["dev"]
files = [
{file = "ruff-0.11.0-py3-none-linux_armv6l.whl", hash = "sha256:dc67e32bc3b29557513eb7eeabb23efdb25753684b913bebb8a0c62495095acb"},
{file = "ruff-0.11.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:38c23fd9bdec4eb437b4c1e3595905a0a8edfccd63a790f818b28c78fe345639"},
{file = "ruff-0.11.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7c8661b0be91a38bd56db593e9331beaf9064a79028adee2d5f392674bbc5e88"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6c0e8d3d2db7e9f6efd884f44b8dc542d5b6b590fc4bb334fdbc624d93a29a2"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3c3156d3f4b42e57247275a0a7e15a851c165a4fc89c5e8fa30ea6da4f7407b8"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:490b1e147c1260545f6d041c4092483e3f6d8eba81dc2875eaebcf9140b53905"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:1bc09a7419e09662983b1312f6fa5dab829d6ab5d11f18c3760be7ca521c9329"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcfa478daf61ac8002214eb2ca5f3e9365048506a9d52b11bea3ecea822bb844"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6fbb2aed66fe742a6a3a0075ed467a459b7cedc5ae01008340075909d819df1e"},
{file = "ruff-0.11.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92c0c1ff014351c0b0cdfdb1e35fa83b780f1e065667167bb9502d47ca41e6db"},
{file = "ruff-0.11.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:e4fd5ff5de5f83e0458a138e8a869c7c5e907541aec32b707f57cf9a5e124445"},
{file = "ruff-0.11.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:96bc89a5c5fd21a04939773f9e0e276308be0935de06845110f43fd5c2e4ead7"},
{file = "ruff-0.11.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:a9352b9d767889ec5df1483f94870564e8102d4d7e99da52ebf564b882cdc2c7"},
{file = "ruff-0.11.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:049a191969a10897fe052ef9cc7491b3ef6de79acd7790af7d7897b7a9bfbcb6"},
{file = "ruff-0.11.0-py3-none-win32.whl", hash = "sha256:3191e9116b6b5bbe187447656f0c8526f0d36b6fd89ad78ccaad6bdc2fad7df2"},
{file = "ruff-0.11.0-py3-none-win_amd64.whl", hash = "sha256:c58bfa00e740ca0a6c43d41fb004cd22d165302f360aaa56f7126d544db31a21"},
{file = "ruff-0.11.0-py3-none-win_arm64.whl", hash = "sha256:868364fc23f5aa122b00c6f794211e85f7e78f5dffdf7c590ab90b8c4e69b657"},
{file = "ruff-0.11.0.tar.gz", hash = "sha256:e55c620690a4a7ee6f1cccb256ec2157dc597d109400ae75bbf944fc9d6462e2"},
{file = "ruff-0.11.2-py3-none-linux_armv6l.whl", hash = "sha256:c69e20ea49e973f3afec2c06376eb56045709f0212615c1adb0eda35e8a4e477"},
{file = "ruff-0.11.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2c5424cc1c4eb1d8ecabe6d4f1b70470b4f24a0c0171356290b1953ad8f0e272"},
{file = "ruff-0.11.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ecf20854cc73f42171eedb66f006a43d0a21bfb98a2523a809931cda569552d9"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0c543bf65d5d27240321604cee0633a70c6c25c9a2f2492efa9f6d4b8e4199bb"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:20967168cc21195db5830b9224be0e964cc9c8ecf3b5a9e3ce19876e8d3a96e3"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:955a9ce63483999d9f0b8f0b4a3ad669e53484232853054cc8b9d51ab4c5de74"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:86b3a27c38b8fce73bcd262b0de32e9a6801b76d52cdb3ae4c914515f0cef608"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a3b66a03b248c9fcd9d64d445bafdf1589326bee6fc5c8e92d7562e58883e30f"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0397c2672db015be5aa3d4dac54c69aa012429097ff219392c018e21f5085147"},
{file = "ruff-0.11.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:869bcf3f9abf6457fbe39b5a37333aa4eecc52a3b99c98827ccc371a8e5b6f1b"},
{file = "ruff-0.11.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:2a2b50ca35457ba785cd8c93ebbe529467594087b527a08d487cf0ee7b3087e9"},
{file = "ruff-0.11.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:7c69c74bf53ddcfbc22e6eb2f31211df7f65054bfc1f72288fc71e5f82db3eab"},
{file = "ruff-0.11.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6e8fb75e14560f7cf53b15bbc55baf5ecbe373dd5f3aab96ff7aa7777edd7630"},
{file = "ruff-0.11.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:842a472d7b4d6f5924e9297aa38149e5dcb1e628773b70e6387ae2c97a63c58f"},
{file = "ruff-0.11.2-py3-none-win32.whl", hash = "sha256:aca01ccd0eb5eb7156b324cfaa088586f06a86d9e5314b0eb330cb48415097cc"},
{file = "ruff-0.11.2-py3-none-win_amd64.whl", hash = "sha256:3170150172a8f994136c0c66f494edf199a0bbea7a409f649e4bc8f4d7084080"},
{file = "ruff-0.11.2-py3-none-win_arm64.whl", hash = "sha256:52933095158ff328f4c77af3d74f0379e34fd52f175144cefc1b192e7ccd32b4"},
{file = "ruff-0.11.2.tar.gz", hash = "sha256:ec47591497d5a1050175bdf4e1a4e6272cddff7da88a2ad595e1e326041d8d94"},
]
[[package]]
@ -2392,4 +2392,4 @@ type = ["pytest-mypy"]
[metadata]
lock-version = "2.1"
python-versions = "^3.9"
content-hash = "0eeac7b28f5df99e43389577f7d55f12f8f3ff3bd9df127a7d8676e297c53959"
content-hash = "ff06861c63e94fd59af8657d81f865f0e1f4130055b164952a75d739254014c3"

View file

@ -29,7 +29,7 @@ Authlib = "^1.2.0"
[tool.poetry.group.dev.dependencies]
ruff = ">=0.5.1,<0.11.1"
ruff = ">=0.5.1,<0.11.3"
pytest = "^8.3.4"
mypy = "^1.14.1"
types-requests = "^2.32.0.20241016"

View file

@ -21,7 +21,8 @@ sudo apt-get install -y \
libsystemd-dev \
libudev-dev \
pkg-config \
ripgrep
ripgrep \
lld
export PATH="$HOME/.cargo/bin:$PATH"
@ -36,7 +37,7 @@ sudo chgrp vscode ~/ -R
# shellcheck disable=SC1091
source scripts/devcontainer_poststart.sh
cargo install
cargo install \
cargo-audit \
mdbook-mermaid \
mdbook

View file

@ -191,7 +191,7 @@ impl QueryServerReadV1 {
pub async fn handle_online_backup(
&self,
msg: OnlineBackupEvent,
outpath: &str,
outpath: &Path,
versions: usize,
) -> Result<(), OperationError> {
trace!(eventid = ?msg.eventid, "Begin online backup event");
@ -200,12 +200,12 @@ impl QueryServerReadV1 {
#[allow(clippy::unwrap_used)]
let timestamp = now.format(&Rfc3339).unwrap();
let dest_file = format!("{}/backup-{}.json", outpath, timestamp);
let dest_file = outpath.join(format!("backup-{}.json", timestamp));
if Path::new(&dest_file).exists() {
if dest_file.exists() {
error!(
"Online backup file {} already exists, will not overwrite it.",
dest_file
dest_file.display()
);
return Err(OperationError::InvalidState);
}
@ -218,10 +218,14 @@ impl QueryServerReadV1 {
.get_be_txn()
.backup(&dest_file)
.map(|()| {
info!("Online backup created {} successfully", dest_file);
info!("Online backup created {} successfully", dest_file.display());
})
.map_err(|e| {
error!("Online backup failed to create {}: {:?}", dest_file, e);
error!(
"Online backup failed to create {}: {:?}",
dest_file.display(),
e
);
OperationError::InvalidState
})?;
}
@ -267,7 +271,11 @@ impl QueryServerReadV1 {
}
}
Err(e) => {
error!("Online backup cleanup error read dir {}: {}", outpath, e);
error!(
"Online backup cleanup error read dir {}: {}",
outpath.display(),
e
);
return Err(OperationError::InvalidState);
}
}

File diff suppressed because it is too large Load diff

View file

@ -112,19 +112,19 @@ impl IntervalActor {
if !op.exists() {
info!(
"Online backup output folder '{}' does not exist, trying to create it.",
outpath
outpath.display()
);
fs::create_dir_all(&outpath).map_err(|e| {
error!(
"Online backup failed to create output directory '{}': {}",
outpath.clone(),
outpath.display(),
e
)
})?;
}
if !op.is_dir() {
error!("Online backup output '{}' is not a directory or we are missing permissions to access it.", outpath);
error!("Online backup output '{}' is not a directory or we are missing permissions to access it.", outpath.display());
return Err(());
}
@ -148,7 +148,7 @@ impl IntervalActor {
if let Err(e) = server
.handle_online_backup(
OnlineBackupEvent::new(),
outpath.clone().as_str(),
&outpath,
versions,
)
.await

View file

@ -36,9 +36,10 @@ mod ldaps;
mod repl;
mod utils;
use std::fmt::{Display, Formatter};
use std::sync::Arc;
use crate::actors::{QueryServerReadV1, QueryServerWriteV1};
use crate::admin::AdminActor;
use crate::config::{Configuration, ServerRole};
use crate::interval::IntervalActor;
use crate::utils::touch_file_or_quit;
use compact_jwt::{JwsHs256Signer, JwsSigner};
use kanidm_proto::internal::OperationError;
@ -50,17 +51,14 @@ use kanidmd_lib::status::StatusActor;
use kanidmd_lib::value::CredentialType;
#[cfg(not(target_family = "windows"))]
use libc::umask;
use std::fmt::{Display, Formatter};
use std::path::Path;
use std::sync::Arc;
use tokio::sync::broadcast;
use tokio::sync::mpsc;
use tokio::sync::Notify;
use tokio::task;
use crate::actors::{QueryServerReadV1, QueryServerWriteV1};
use crate::admin::AdminActor;
use crate::config::{Configuration, ServerRole};
use crate::interval::IntervalActor;
use tokio::sync::mpsc;
// === internal setup helpers
fn setup_backend(config: &Configuration, schema: &Schema) -> Result<Backend, OperationError> {
@ -80,7 +78,7 @@ fn setup_backend_vacuum(
let pool_size: u32 = config.threads as u32;
let cfg = BackendConfig::new(
config.db_path.as_str(),
config.db_path.as_deref(),
pool_size,
config.db_fs_type.unwrap_or_default(),
config.db_arc_size,
@ -335,7 +333,7 @@ pub fn dbscan_restore_quarantined_core(config: &Configuration, id: u64) {
};
}
pub fn backup_server_core(config: &Configuration, dst_path: &str) {
pub fn backup_server_core(config: &Configuration, dst_path: &Path) {
let schema = match Schema::new() {
Ok(s) => s,
Err(e) => {
@ -371,8 +369,11 @@ pub fn backup_server_core(config: &Configuration, dst_path: &str) {
// Let the txn abort, even on success.
}
pub async fn restore_server_core(config: &Configuration, dst_path: &str) {
touch_file_or_quit(config.db_path.as_str());
pub async fn restore_server_core(config: &Configuration, dst_path: &Path) {
// If it's an in memory database, we don't need to touch anything
if let Some(db_path) = config.db_path.as_ref() {
touch_file_or_quit(db_path);
}
// First, we provide the in-memory schema so that core attrs are indexed correctly.
let schema = match Schema::new() {
@ -1011,7 +1012,7 @@ pub async fn create_server_core(
let tls_accepter_reload_task_notify = tls_acceptor_reload_notify.clone();
let tls_config = config.tls_config.clone();
let ldap_configured = config.ldapaddress.is_some();
let ldap_configured = config.ldapbindaddress.is_some();
let (ldap_tls_acceptor_reload_tx, ldap_tls_acceptor_reload_rx) = mpsc::channel(1);
let (http_tls_acceptor_reload_tx, http_tls_acceptor_reload_rx) = mpsc::channel(1);
@ -1076,7 +1077,7 @@ pub async fn create_server_core(
};
// If we have been requested to init LDAP, configure it now.
let maybe_ldap_acceptor_handle = match &config.ldapaddress {
let maybe_ldap_acceptor_handle = match &config.ldapbindaddress {
Some(la) => {
let opt_ldap_ssl_acceptor = maybe_tls_acceptor.clone();

View file

@ -1,32 +1,39 @@
use filetime::FileTime;
use std::fs::File;
use std::io::ErrorKind;
use std::path::PathBuf;
use std::path::Path;
use std::time::SystemTime;
pub fn touch_file_or_quit(file_path: &str) {
pub fn touch_file_or_quit<P: AsRef<Path>>(file_path: P) {
/*
Attempt to touch the file file_path, will quit the application if it fails for any reason.
Will also create a new file if it doesn't already exist.
*/
if PathBuf::from(file_path).exists() {
let file_path: &Path = file_path.as_ref();
if file_path.exists() {
let t = FileTime::from_system_time(SystemTime::now());
match filetime::set_file_times(file_path, t, t) {
Ok(_) => debug!(
"Successfully touched existing file {}, can continue",
file_path
file_path.display()
),
Err(e) => {
match e.kind() {
ErrorKind::PermissionDenied => {
// we bail here because you won't be able to write them back...
error!("Permission denied writing to {}, quitting.", file_path)
error!(
"Permission denied writing to {}, quitting.",
file_path.display()
)
}
_ => {
error!(
"Failed to write to {} due to error: {:?} ... quitting.",
file_path, e
file_path.display(),
e
)
}
}
@ -35,11 +42,12 @@ pub fn touch_file_or_quit(file_path: &str) {
}
} else {
match File::create(file_path) {
Ok(_) => debug!("Successfully touched new file {}", file_path),
Ok(_) => debug!("Successfully touched new file {}", file_path.display()),
Err(e) => {
error!(
"Failed to write to {} due to error: {:?} ... quitting.",
file_path, e
file_path.display(),
e
);
std::process::exit(1);
}

View file

@ -1,3 +1,4 @@
version = "2"
bindaddress = "[::]:8443"
ldapbindaddress = "127.0.0.1:3636"

View file

@ -22,14 +22,16 @@ fi
mkdir -p "${KANI_TMP}"/client_ca
CONFIG_FILE=${CONFIG_FILE:="${SCRIPT_DIR}/../../examples/insecure_server.toml"}
CONFIG_FILE=${CONFIG_FILE:="${SCRIPT_DIR}/insecure_server.toml"}
if [ ! -f "${CONFIG_FILE}" ]; then
echo "Couldn't find configuration file at ${CONFIG_FILE}, please ensure you're running this script from its base directory (${SCRIPT_DIR})."
exit 1
fi
pushd "${SCRIPT_DIR}" > /dev/null 2>&1
# Save current directory and change to script directory without pushd
OLD_DIR=$(pwd)
cd "${SCRIPT_DIR}" || exit 1
if [ -n "${1}" ]; then
COMMAND=$*
#shellcheck disable=SC2086
@ -40,4 +42,4 @@ else
#shellcheck disable=SC2086
cargo run ${KANI_CARGO_OPTS} --bin kanidmd -- server -c "${CONFIG_FILE}"
fi
popd > /dev/null 2>&1
cd "${OLD_DIR}" || exit 1

View file

@ -37,7 +37,7 @@ use kanidmd_core::admin::{
AdminTaskRequest, AdminTaskResponse, ClientCodec, ProtoDomainInfo,
ProtoDomainUpgradeCheckReport, ProtoDomainUpgradeCheckStatus,
};
use kanidmd_core::config::{Configuration, ServerConfig};
use kanidmd_core::config::{CliConfig, Configuration, EnvironmentConfig, ServerConfigUntagged};
use kanidmd_core::{
backup_server_core, cert_generate_core, create_server_core, dbscan_get_id2entry_core,
dbscan_list_id2entry_core, dbscan_list_index_analysis_core, dbscan_list_index_core,
@ -379,17 +379,13 @@ fn check_file_ownership(opt: &KanidmdParser) -> Result<(), ExitCode> {
}
// We have to do this because we can't use tracing until we've started the logging pipeline, and we can't start the logging pipeline until the tokio runtime's doing its thing.
async fn start_daemon(
opt: KanidmdParser,
mut config: Configuration,
sconfig: ServerConfig,
) -> ExitCode {
async fn start_daemon(opt: KanidmdParser, config: Configuration) -> ExitCode {
// if we have a server config and it has an OTEL URL, then we'll start the logging pipeline now.
// TODO: only send to stderr when we're not in a TTY
let sub = match sketching::otel::start_logging_pipeline(
&sconfig.otel_grpc_url,
sconfig.log_level.unwrap_or_default(),
&config.otel_grpc_url,
config.log_level,
"kanidmd",
) {
Err(err) => {
@ -423,8 +419,8 @@ async fn start_daemon(
return err;
};
if let Some(db_path) = sconfig.db_path.as_ref() {
let db_pathbuf = PathBuf::from(db_path.as_str());
if let Some(db_path) = config.db_path.as_ref() {
let db_pathbuf = db_path.to_path_buf();
// We can't check the db_path permissions because it may not exist yet!
if let Some(db_parent_path) = db_pathbuf.parent() {
if !db_parent_path.exists() {
@ -464,33 +460,11 @@ async fn start_daemon(
warn!("WARNING: DB folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", db_par_path_buf.to_str().unwrap_or("invalid file path"));
}
}
config.update_db_path(db_path);
} else {
error!("No db_path set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
if let Some(origin) = sconfig.origin.clone() {
config.update_origin(&origin);
} else {
error!("No origin set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
if let Some(domain) = sconfig.domain.clone() {
config.update_domain(&domain);
} else {
error!("No domain set in configuration, server startup will FAIL!");
return ExitCode::FAILURE;
}
config.update_db_arc_size(sconfig.get_db_arc_size());
config.update_role(sconfig.role);
config.update_output_mode(opt.commands.commonopt().output_mode.to_owned().into());
config.update_trust_x_forward_for(sconfig.trust_x_forward_for);
config.update_admin_bind_path(&sconfig.adminbindpath);
config.update_replication_config(sconfig.repl_config.clone());
match &opt.commands {
// we aren't going to touch the DB so we can carry on
KanidmdOpt::ShowReplicationCertificate { .. }
@ -501,19 +475,15 @@ async fn start_daemon(
_ => {
// Okay - Lets now create our lock and go.
#[allow(clippy::expect_used)]
let klock_path = match sconfig.db_path.clone() {
Some(val) => format!("{}.klock", val),
None => std::env::temp_dir()
.join("kanidmd.klock")
.to_str()
.expect("Unable to create klock path, this is a critical error!")
.to_string(),
let klock_path = match config.db_path.clone() {
Some(val) => val.with_extension("klock"),
None => std::env::temp_dir().join("kanidmd.klock"),
};
let flock = match File::create(&klock_path) {
Ok(flock) => flock,
Err(e) => {
error!("ERROR: Refusing to start - unable to create kanidmd exclusive lock at {} - {:?}", klock_path, e);
error!("ERROR: Refusing to start - unable to create kanidmd exclusive lock at {} - {:?}", klock_path.display(), e);
return ExitCode::FAILURE;
}
};
@ -521,7 +491,7 @@ async fn start_daemon(
match flock.try_lock_exclusive() {
Ok(()) => debug!("Acquired kanidm exclusive lock"),
Err(e) => {
error!("ERROR: Refusing to start - unable to lock kanidmd exclusive lock at {} - {:?}", klock_path, e);
error!("ERROR: Refusing to start - unable to lock kanidmd exclusive lock at {} - {:?}", klock_path.display(), e);
error!("Is another kanidmd process running?");
return ExitCode::FAILURE;
}
@ -529,7 +499,7 @@ async fn start_daemon(
}
}
kanidm_main(sconfig, config, opt).await
kanidm_main(config, opt).await
}
fn main() -> ExitCode {
@ -556,10 +526,6 @@ fn main() -> ExitCode {
return ExitCode::SUCCESS;
};
//we set up a list of these so we can set the log config THEN log out the errors.
let mut config_error: Vec<String> = Vec::new();
let mut config = Configuration::new();
if env!("KANIDM_SERVER_CONFIG_PATH").is_empty() {
println!("CRITICAL: Kanidmd was not built correctly and is missing a valid KANIDM_SERVER_CONFIG_PATH value");
return ExitCode::FAILURE;
@ -581,49 +547,56 @@ fn main() -> ExitCode {
}
};
let sconfig = match ServerConfig::new(maybe_config_path) {
Ok(c) => Some(c),
Err(e) => {
config_error.push(format!("Config Parse failure {:?}", e));
let maybe_sconfig = if let Some(config_path) = maybe_config_path {
match ServerConfigUntagged::new(config_path) {
Ok(c) => Some(c),
Err(err) => {
eprintln!("ERROR: Configuration Parse Failure: {:?}", err);
return ExitCode::FAILURE;
}
}
} else {
eprintln!("WARNING: No configuration path was provided, relying on environment variables.");
None
};
let envconfig = match EnvironmentConfig::new() {
Ok(ec) => ec,
Err(err) => {
eprintln!("ERROR: Environment Configuration Parse Failure: {:?}", err);
return ExitCode::FAILURE;
}
};
// Get information on the windows username
#[cfg(target_family = "windows")]
get_user_details_windows();
let cli_config = CliConfig {
output_mode: Some(opt.commands.commonopt().output_mode.to_owned().into()),
};
if !config_error.is_empty() {
println!("There were errors on startup, which prevent the server from starting:");
for e in config_error {
println!(" - {}", e);
}
let is_server = matches!(&opt.commands, KanidmdOpt::Server(_));
let config = Configuration::build()
.add_env_config(envconfig)
.add_opt_toml_config(maybe_sconfig)
// We always set threads to 1 unless it's the main server.
.add_cli_config(cli_config)
.is_server_mode(is_server)
.finish();
let Some(config) = config else {
eprintln!(
"ERROR: Unable to build server configuration from provided configuration inputs."
);
return ExitCode::FAILURE;
}
let sconfig = match sconfig {
Some(val) => val,
None => {
println!("Somehow you got an empty ServerConfig after error checking? Cannot start!");
return ExitCode::FAILURE;
}
};
// ===========================================================================
// Config ready
// We always set threads to 1 unless it's the main server.
if matches!(&opt.commands, KanidmdOpt::Server(_)) {
// If not updated, will default to maximum
if let Some(threads) = sconfig.thread_count {
config.update_threads_count(threads);
}
} else {
config.update_threads_count(1);
};
// Get information on the windows username
#[cfg(target_family = "windows")]
get_user_details_windows();
// Start the runtime
let maybe_rt = tokio::runtime::Builder::new_multi_thread()
.worker_threads(config.threads)
.enable_all()
@ -643,16 +616,12 @@ fn main() -> ExitCode {
}
};
rt.block_on(start_daemon(opt, config, sconfig))
rt.block_on(start_daemon(opt, config))
}
/// Build and execute the main server. The ServerConfig are the configuration options
/// that we are processing into the config for the main server.
async fn kanidm_main(
sconfig: ServerConfig,
mut config: Configuration,
opt: KanidmdParser,
) -> ExitCode {
async fn kanidm_main(config: Configuration, opt: KanidmdParser) -> ExitCode {
match &opt.commands {
KanidmdOpt::Server(_sopt) | KanidmdOpt::ConfigTest(_sopt) => {
let config_test = matches!(&opt.commands, KanidmdOpt::ConfigTest(_));
@ -662,88 +631,90 @@ async fn kanidm_main(
info!("Running in server mode ...");
};
// configuration options that only relate to server mode
config.update_config_for_server_mode(&sconfig);
if let Some(i_str) = &(sconfig.tls_chain) {
let i_path = PathBuf::from(i_str.as_str());
let i_meta = match metadata(&i_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for TLS chain file '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);
let diag = kanidm_lib_file_permissions::diagnose_path(&i_path);
info!(%diag);
return ExitCode::FAILURE;
// Verify the TLs configs.
if let Some(tls_config) = config.tls_config.as_ref() {
{
let i_meta = match metadata(&tls_config.chain) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for TLS chain file '{}' - {:?}",
tls_config.chain.display(),
e
);
let diag =
kanidm_lib_file_permissions::diagnose_path(&tls_config.chain);
info!(%diag);
return ExitCode::FAILURE;
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", tls_config.chain.display());
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
}
}
if let Some(i_str) = &(sconfig.tls_key) {
let i_path = PathBuf::from(i_str.as_str());
let i_meta = match metadata(&i_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for TLS key file '{}' - {:?}",
&i_path.to_str().unwrap_or("invalid file path"),
e
);
let diag = kanidm_lib_file_permissions::diagnose_path(&i_path);
info!(%diag);
return ExitCode::FAILURE;
{
let i_meta = match metadata(&tls_config.key) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for TLS key file '{}' - {:?}",
tls_config.key.display(),
e
);
let diag = kanidm_lib_file_permissions::diagnose_path(&tls_config.key);
info!(%diag);
return ExitCode::FAILURE;
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", tls_config.key.display());
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", tls_config.key.display());
}
};
if !kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("permissions on {} may not be secure. Should be readonly to running uid. This could be a security risk ...", i_str);
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
warn!("WARNING: {} has 'everyone' permission bits in the mode. This could be a security risk ...", i_str);
}
}
if let Some(ca_dir) = &(sconfig.tls_client_ca) {
// check that the TLS client CA config option is what we expect
let ca_dir_path = PathBuf::from(&ca_dir);
if !ca_dir_path.exists() {
error!(
"TLS CA folder {} does not exist, server startup will FAIL!",
ca_dir
);
let diag = kanidm_lib_file_permissions::diagnose_path(&ca_dir_path);
info!(%diag);
}
let i_meta = match metadata(&ca_dir_path) {
Ok(m) => m,
Err(e) => {
error!("Unable to read metadata for '{}' - {:?}", ca_dir, e);
if let Some(ca_dir) = tls_config.client_ca.as_ref() {
// check that the TLS client CA config option is what we expect
let ca_dir_path = PathBuf::from(&ca_dir);
if !ca_dir_path.exists() {
error!(
"TLS CA folder {} does not exist, server startup will FAIL!",
ca_dir.display()
);
let diag = kanidm_lib_file_permissions::diagnose_path(&ca_dir_path);
info!(%diag);
}
let i_meta = match metadata(&ca_dir_path) {
Ok(m) => m,
Err(e) => {
error!(
"Unable to read metadata for '{}' - {:?}",
ca_dir.display(),
e
);
let diag = kanidm_lib_file_permissions::diagnose_path(&ca_dir_path);
info!(%diag);
return ExitCode::FAILURE;
}
};
if !i_meta.is_dir() {
error!(
"ERROR: Refusing to run - TLS Client CA folder {} may not be a directory",
ca_dir.display()
);
return ExitCode::FAILURE;
}
};
if !i_meta.is_dir() {
error!(
"ERROR: Refusing to run - TLS Client CA folder {} may not be a directory",
ca_dir
);
return ExitCode::FAILURE;
}
if kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("WARNING: TLS Client CA folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", ca_dir);
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
warn!("WARNING: TLS Client CA folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", ca_dir);
if kanidm_lib_file_permissions::readonly(&i_meta) {
warn!("WARNING: TLS Client CA folder permissions on {} indicate it may not be RW. This could cause the server start up to fail!", ca_dir.display());
}
#[cfg(not(target_os = "windows"))]
if i_meta.mode() & 0o007 != 0 {
warn!("WARNING: TLS Client CA folder {} has 'everyone' permission bits in the mode. This could be a security risk ...", ca_dir.display());
}
}
}
@ -880,34 +851,19 @@ async fn kanidm_main(
}
KanidmdOpt::CertGenerate(_sopt) => {
info!("Running in certificate generate mode ...");
config.update_config_for_server_mode(&sconfig);
cert_generate_core(&config);
}
KanidmdOpt::Database {
commands: DbCommands::Backup(bopt),
} => {
info!("Running in backup mode ...");
let p = match bopt.path.to_str() {
Some(p) => p,
None => {
error!("Invalid backup path");
return ExitCode::FAILURE;
}
};
backup_server_core(&config, p);
backup_server_core(&config, &bopt.path);
}
KanidmdOpt::Database {
commands: DbCommands::Restore(ropt),
} => {
info!("Running in restore mode ...");
let p = match ropt.path.to_str() {
Some(p) => p,
None => {
error!("Invalid restore path");
return ExitCode::FAILURE;
}
};
restore_server_core(&config, p).await;
restore_server_core(&config, &ropt.path).await;
}
KanidmdOpt::Database {
commands: DbCommands::Verify(_vopt),
@ -1088,8 +1044,6 @@ async fn kanidm_main(
vacuum_server_core(&config);
}
KanidmdOpt::HealthCheck(sopt) => {
config.update_config_for_server_mode(&sconfig);
debug!("{sopt:?}");
let healthcheck_url = match &sopt.check_origin {
@ -1110,12 +1064,15 @@ async fn kanidm_main(
.danger_accept_invalid_hostnames(!sopt.verify_tls)
.https_only(true);
client = match &sconfig.tls_chain {
client = match &config.tls_config {
None => client,
Some(ca_cert) => {
debug!("Trying to load {} to build a CA cert path", ca_cert);
Some(tls_config) => {
debug!(
"Trying to load {} to build a CA cert path",
tls_config.chain.display()
);
// if the ca_cert file exists, then we'll use it
let ca_cert_path = PathBuf::from(ca_cert);
let ca_cert_path = tls_config.chain.clone();
match ca_cert_path.exists() {
true => {
let mut cert_buf = Vec::new();
@ -1148,7 +1105,10 @@ async fn kanidm_main(
client
}
false => {
warn!("Couldn't find ca cert {} but carrying on...", ca_cert);
warn!(
"Couldn't find ca cert {} but carrying on...",
tls_config.chain.display()
);
client
}
}

View file

@ -1,27 +1,22 @@
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::convert::{TryFrom, TryInto};
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration;
use super::keystorage::{KeyHandle, KeyHandleId};
// use crate::valueset;
use hashbrown::HashMap;
use idlset::v2::IDLBitRange;
use kanidm_proto::internal::{ConsistencyError, OperationError};
use rusqlite::vtab::array::Array;
use rusqlite::{Connection, OpenFlags, OptionalExtension};
use uuid::Uuid;
use crate::be::dbentry::DbIdentSpn;
use crate::be::dbvalue::DbCidV1;
use crate::be::{BackendConfig, IdList, IdRawEntry, IdxKey, IdxSlope};
use crate::entry::{Entry, EntryCommitted, EntrySealed};
use crate::prelude::*;
use crate::value::{IndexType, Value};
// use uuid::Uuid;
use hashbrown::HashMap;
use idlset::v2::IDLBitRange;
use kanidm_proto::internal::{ConsistencyError, OperationError};
use rusqlite::vtab::array::Array;
use rusqlite::{Connection, OpenFlags, OptionalExtension};
use std::collections::{BTreeMap, BTreeSet, VecDeque};
use std::convert::{TryFrom, TryInto};
use std::path::Path;
use std::sync::Arc;
use std::sync::Mutex;
use std::time::Duration;
use uuid::Uuid;
const DBV_ID2ENTRY: &str = "id2entry";
const DBV_INDEXV: &str = "indexv";
@ -1712,7 +1707,7 @@ impl IdlSqliteWriteTransaction {
impl IdlSqlite {
pub fn new(cfg: &BackendConfig, vacuum: bool) -> Result<Self, OperationError> {
if cfg.path.is_empty() {
if cfg.path == Path::new("") {
debug_assert_eq!(cfg.pool_size, 1);
}
// If provided, set the page size to match the tuning we want. By default we use 4096. The VACUUM
@ -1734,8 +1729,7 @@ impl IdlSqlite {
// Initial setup routines.
{
let vconn =
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error)?;
let vconn = Connection::open_with_flags(&cfg.path, flags).map_err(sqlite_error)?;
vconn
.execute_batch(
@ -1764,8 +1758,7 @@ impl IdlSqlite {
);
*/
let vconn =
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error)?;
let vconn = Connection::open_with_flags(&cfg.path, flags).map_err(sqlite_error)?;
vconn
.execute_batch("PRAGMA wal_checkpoint(TRUNCATE);")
@ -1786,8 +1779,7 @@ impl IdlSqlite {
OperationError::SqliteError
})?;
let vconn =
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error)?;
let vconn = Connection::open_with_flags(&cfg.path, flags).map_err(sqlite_error)?;
vconn
.pragma_update(None, "page_size", cfg.fstype as u32)
@ -1821,7 +1813,7 @@ impl IdlSqlite {
.map(|i| {
trace!("Opening Connection {}", i);
let conn =
Connection::open_with_flags(cfg.path.as_str(), flags).map_err(sqlite_error);
Connection::open_with_flags(&cfg.path, flags).map_err(sqlite_error);
match conn {
Ok(conn) => {
// We need to set the cachesize at this point as well.

View file

@ -4,20 +4,6 @@
//! is to persist content safely to disk, load that content, and execute queries
//! utilising indexes in the most effective way possible.
use std::collections::BTreeMap;
use std::fs;
use std::ops::DerefMut;
use std::sync::Arc;
use std::time::Duration;
use concread::cowcell::*;
use hashbrown::{HashMap as Map, HashSet};
use idlset::v2::IDLBitRange;
use idlset::AndNot;
use kanidm_proto::internal::{ConsistencyError, OperationError};
use tracing::{trace, trace_span};
use uuid::Uuid;
use crate::be::dbentry::{DbBackup, DbEntry};
use crate::be::dbrepl::DbReplMeta;
use crate::entry::Entry;
@ -31,6 +17,19 @@ use crate::repl::ruv::{
};
use crate::utils::trigraph_iter;
use crate::value::{IndexType, Value};
use concread::cowcell::*;
use hashbrown::{HashMap as Map, HashSet};
use idlset::v2::IDLBitRange;
use idlset::AndNot;
use kanidm_proto::internal::{ConsistencyError, OperationError};
use std::collections::BTreeMap;
use std::fs;
use std::ops::DerefMut;
use std::path::{Path, PathBuf};
use std::sync::Arc;
use std::time::Duration;
use tracing::{trace, trace_span};
use uuid::Uuid;
pub(crate) mod dbentry;
pub(crate) mod dbrepl;
@ -132,7 +131,7 @@ impl IdxMeta {
#[derive(Clone)]
pub struct BackendConfig {
path: String,
path: PathBuf,
pool_size: u32,
db_name: &'static str,
fstype: FsType,
@ -141,10 +140,16 @@ pub struct BackendConfig {
}
impl BackendConfig {
pub fn new(path: &str, pool_size: u32, fstype: FsType, arcsize: Option<usize>) -> Self {
pub fn new(
path: Option<&Path>,
pool_size: u32,
fstype: FsType,
arcsize: Option<usize>,
) -> Self {
BackendConfig {
pool_size,
path: path.to_string(),
// This means if path is None, that "" implies an sqlite in memory/ram only database.
path: path.unwrap_or_else(|| Path::new("")).to_path_buf(),
db_name: "main",
fstype,
arcsize,
@ -154,7 +159,7 @@ impl BackendConfig {
pub(crate) fn new_test(db_name: &'static str) -> Self {
BackendConfig {
pool_size: 1,
path: "".to_string(),
path: PathBuf::from(""),
db_name,
fstype: FsType::Generic,
arcsize: Some(2048),
@ -549,10 +554,11 @@ pub trait BackendTransaction {
}
(_, fp) => {
plan.push(fp);
filter_error!(
let setplan = FilterPlan::InclusionInvalid(plan);
error!(
?setplan,
"Inclusion is unable to proceed - all terms must be fully indexed!"
);
let setplan = FilterPlan::InclusionInvalid(plan);
return Ok((IdList::Partial(IDLBitRange::new()), setplan));
}
}
@ -935,7 +941,7 @@ pub trait BackendTransaction {
self.get_ruv().verify(&entries, results);
}
fn backup(&mut self, dst_path: &str) -> Result<(), OperationError> {
fn backup(&mut self, dst_path: &Path) -> Result<(), OperationError> {
let repl_meta = self.get_ruv().to_db_backup_ruv();
// load all entries into RAM, may need to change this later
@ -1427,20 +1433,16 @@ impl<'a> BackendWriteTransaction<'a> {
if self.is_idx_slopeyness_generated()? {
trace!("Indexing slopes available");
} else {
admin_warn!(
"No indexing slopes available. You should consider reindexing to generate these"
);
warn!("No indexing slopes available. You should consider reindexing to generate these");
};
// Setup idxkeys here. By default we set these all to "max slope" aka
// all indexes are "equal" but also worse case unless analysed. If they
// have been analysed, we can set the slope factor into here.
let idxkeys: Result<Map<_, _>, _> = idxkeys
let mut idxkeys = idxkeys
.into_iter()
.map(|k| self.get_idx_slope(&k).map(|slope| (k, slope)))
.collect();
let mut idxkeys = idxkeys?;
.collect::<Result<Map<_, _>, _>>()?;
std::mem::swap(&mut self.idxmeta_wr.deref_mut().idxkeys, &mut idxkeys);
Ok(())
@ -1811,7 +1813,7 @@ impl<'a> BackendWriteTransaction<'a> {
Ok(slope)
}
pub fn restore(&mut self, src_path: &str) -> Result<(), OperationError> {
pub fn restore(&mut self, src_path: &Path) -> Result<(), OperationError> {
let serialized_string = fs::read_to_string(src_path).map_err(|e| {
admin_error!("fs::read_to_string {:?}", e);
OperationError::FsError
@ -2124,7 +2126,7 @@ impl Backend {
debug!(db_tickets = ?cfg.pool_size, profile = %env!("KANIDM_PROFILE_NAME"), cpu_flags = %env!("KANIDM_CPU_FLAGS"));
// If in memory, reduce pool to 1
if cfg.path.is_empty() {
if cfg.path == Path::new("") {
cfg.pool_size = 1;
}
@ -2210,13 +2212,6 @@ impl Backend {
#[cfg(test)]
mod tests {
use std::fs;
use std::iter::FromIterator;
use std::sync::Arc;
use std::time::Duration;
use idlset::v2::IDLBitRange;
use super::super::entry::{Entry, EntryInit, EntryNew};
use super::Limits;
use super::{
@ -2226,6 +2221,12 @@ mod tests {
use crate::prelude::*;
use crate::repl::cid::Cid;
use crate::value::{IndexType, PartialValue, Value};
use idlset::v2::IDLBitRange;
use std::fs;
use std::iter::FromIterator;
use std::path::Path;
use std::sync::Arc;
use std::time::Duration;
lazy_static! {
static ref CID_ZERO: Cid = Cid::new_zero();
@ -2600,11 +2601,9 @@ mod tests {
#[test]
fn test_be_backup_restore() {
let db_backup_file_name = format!(
"{}/.backup_test.json",
option_env!("OUT_DIR").unwrap_or("/tmp")
);
eprintln!(" ⚠️ {db_backup_file_name}");
let db_backup_file_name =
Path::new(option_env!("OUT_DIR").unwrap_or("/tmp")).join(".backup_test.json");
eprintln!(" ⚠️ {}", db_backup_file_name.display());
run_test!(|be: &mut BackendWriteTransaction| {
// Important! Need db metadata setup!
be.reset_db_s_uuid().unwrap();
@ -2659,11 +2658,9 @@ mod tests {
#[test]
fn test_be_backup_restore_tampered() {
let db_backup_file_name = format!(
"{}/.backup2_test.json",
option_env!("OUT_DIR").unwrap_or("/tmp")
);
eprintln!(" ⚠️ {db_backup_file_name}");
let db_backup_file_name =
Path::new(option_env!("OUT_DIR").unwrap_or("/tmp")).join(".backup2_test.json");
eprintln!(" ⚠️ {}", db_backup_file_name.display());
run_test!(|be: &mut BackendWriteTransaction| {
// Important! Need db metadata setup!
be.reset_db_s_uuid().unwrap();

View file

@ -136,8 +136,6 @@ pub const UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL: Uuid = uuid!("00000000-0000-0000-
pub const UUID_SCHEMA_CLASS_PERSON: Uuid = uuid!("00000000-0000-0000-0000-ffff00000044");
pub const UUID_SCHEMA_CLASS_GROUP: Uuid = uuid!("00000000-0000-0000-0000-ffff00000045");
pub const UUID_SCHEMA_CLASS_ACCOUNT: Uuid = uuid!("00000000-0000-0000-0000-ffff00000046");
pub const UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000187");
pub const UUID_SCHEMA_ATTR_ATTRIBUTENAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000048");
pub const UUID_SCHEMA_ATTR_CLASSNAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000049");
pub const UUID_SCHEMA_ATTR_LEGALNAME: Uuid = uuid!("00000000-0000-0000-0000-ffff00000050");
@ -329,6 +327,9 @@ pub const UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000185");
pub const UUID_SCHEMA_ATTR_DOMAIN_ALLOW_EASTER_EGGS: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000186");
pub const UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: Uuid =
uuid!("00000000-0000-0000-0000-ffff00000187");
pub const UUID_SCHEMA_ATTR_INDEXED: Uuid = uuid!("00000000-0000-0000-0000-ffff00000188");
// System and domain infos
// I'd like to strongly criticise william of the past for making poor choices about these allocations.

View file

@ -492,6 +492,97 @@ impl Entry<EntryInit, EntryNew> {
}
}
impl From<SchemaAttribute> for EntryInitNew {
fn from(value: SchemaAttribute) -> Self {
EntryInitNew::from(&value)
}
}
impl From<&SchemaAttribute> for EntryInitNew {
fn from(s: &SchemaAttribute) -> Self {
// Build the Map of the attributes
let mut attrs = Eattrs::new();
attrs.insert(Attribute::AttributeName, vs_iutf8![s.name.as_str()]);
attrs.insert(Attribute::Description, vs_utf8![s.description.to_owned()]);
attrs.insert(Attribute::Uuid, vs_uuid![s.uuid]);
attrs.insert(Attribute::MultiValue, vs_bool![s.multivalue]);
attrs.insert(Attribute::Phantom, vs_bool![s.phantom]);
attrs.insert(Attribute::SyncAllowed, vs_bool![s.sync_allowed]);
attrs.insert(Attribute::Replicated, vs_bool![s.replicated.into()]);
attrs.insert(Attribute::Unique, vs_bool![s.unique]);
attrs.insert(Attribute::Indexed, vs_bool![s.indexed]);
attrs.insert(Attribute::Syntax, vs_syntax![s.syntax]);
attrs.insert(
Attribute::Class,
vs_iutf8![
EntryClass::Object.into(),
EntryClass::System.into(),
EntryClass::AttributeType.into()
],
);
// Insert stuff.
Entry {
valid: EntryInit,
state: EntryNew,
attrs,
}
}
}
impl From<SchemaClass> for EntryInitNew {
fn from(value: SchemaClass) -> Self {
EntryInitNew::from(&value)
}
}
impl From<&SchemaClass> for EntryInitNew {
fn from(s: &SchemaClass) -> Self {
let mut attrs = Eattrs::new();
attrs.insert(Attribute::ClassName, vs_iutf8![s.name.as_str()]);
attrs.insert(Attribute::Description, vs_utf8![s.description.to_owned()]);
attrs.insert(Attribute::SyncAllowed, vs_bool![s.sync_allowed]);
attrs.insert(Attribute::Uuid, vs_uuid![s.uuid]);
attrs.insert(
Attribute::Class,
vs_iutf8![
EntryClass::Object.into(),
EntryClass::System.into(),
EntryClass::ClassType.into()
],
);
let vs_systemmay = ValueSetIutf8::from_iter(s.systemmay.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemmay {
attrs.insert(Attribute::SystemMay, vs);
}
let vs_systemmust = ValueSetIutf8::from_iter(s.systemmust.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemmust {
attrs.insert(Attribute::SystemMust, vs);
}
let vs_systemexcludes =
ValueSetIutf8::from_iter(s.systemexcludes.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemexcludes {
attrs.insert(Attribute::SystemExcludes, vs);
}
let vs_systemsupplements =
ValueSetIutf8::from_iter(s.systemsupplements.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemsupplements {
attrs.insert(Attribute::SystemSupplements, vs);
}
Entry {
valid: EntryInit,
state: EntryNew,
attrs,
}
}
}
impl Entry<EntryRefresh, EntryNew> {
pub fn from_repl_entry_v1(repl_entry: ReplEntryV1) -> Result<Self, OperationError> {
// From the entry, we have to rebuild the ecstate and the attrs.
@ -1949,7 +2040,7 @@ impl<STATE> Entry<EntryValid, STATE> {
};
if !valid_supplements {
admin_warn!(
warn!(
"Validation error, the following possible supplement classes are missing - {:?}",
supplements_classes
);
@ -2633,21 +2724,6 @@ impl<VALID, STATE> Entry<VALID, STATE> {
// These are special types to allow returning typed values from
// an entry, if we "know" what we expect to receive.
/// This returns an array of IndexTypes, when the type is an Optional
/// multivalue in schema - IE this will *not* fail if the attribute is
/// empty, yielding and empty array instead.
///
/// However, the conversion to IndexType is fallible, so in case of a failure
/// to convert, an empty vec is returned
pub(crate) fn get_ava_opt_index<A: AsRef<Attribute>>(&self, attr: A) -> Option<Vec<IndexType>> {
if let Some(vs) = self.get_ava_set(attr) {
vs.as_indextype_iter().map(|i| i.collect())
} else {
// Empty, but consider as valid.
Some(vec![])
}
}
/// Return a single value of this attributes name, or `None` if it is NOT present, or
/// there are multiple values present (ambiguous).
pub fn get_ava_single<A: AsRef<Attribute>>(&self, attr: A) -> Option<Value> {
@ -3260,97 +3336,6 @@ impl<VALID, STATE> PartialEq for Entry<VALID, STATE> {
}
}
impl From<&SchemaAttribute> for Entry<EntryInit, EntryNew> {
fn from(s: &SchemaAttribute) -> Self {
// Convert an Attribute to an entry ... make it good!
let uuid_v = vs_uuid![s.uuid];
let name_v = vs_iutf8![s.name.as_str()];
let desc_v = vs_utf8![s.description.to_owned()];
let multivalue_v = vs_bool![s.multivalue];
let sync_allowed_v = vs_bool![s.sync_allowed];
let replicated_v = vs_bool![s.replicated];
let phantom_v = vs_bool![s.phantom];
let unique_v = vs_bool![s.unique];
let index_v = ValueSetIndex::from_iter(s.index.iter().copied());
let syntax_v = vs_syntax![s.syntax];
// Build the Map of the attributes relevant
// let mut attrs: Map<AttrString, Set<Value>> = Map::with_capacity(8);
let mut attrs: Map<Attribute, ValueSet> = Map::new();
attrs.insert(Attribute::AttributeName, name_v);
attrs.insert(Attribute::Description, desc_v);
attrs.insert(Attribute::Uuid, uuid_v);
attrs.insert(Attribute::MultiValue, multivalue_v);
attrs.insert(Attribute::Phantom, phantom_v);
attrs.insert(Attribute::SyncAllowed, sync_allowed_v);
attrs.insert(Attribute::Replicated, replicated_v);
attrs.insert(Attribute::Unique, unique_v);
if let Some(vs) = index_v {
attrs.insert(Attribute::Index, vs);
}
attrs.insert(Attribute::Syntax, syntax_v);
attrs.insert(
Attribute::Class,
vs_iutf8![
EntryClass::Object.into(),
EntryClass::System.into(),
EntryClass::AttributeType.into()
],
);
// Insert stuff.
Entry {
valid: EntryInit,
state: EntryNew,
attrs,
}
}
}
impl From<&SchemaClass> for Entry<EntryInit, EntryNew> {
fn from(s: &SchemaClass) -> Self {
let uuid_v = vs_uuid![s.uuid];
let name_v = vs_iutf8![s.name.as_str()];
let desc_v = vs_utf8![s.description.to_owned()];
let sync_allowed_v = vs_bool![s.sync_allowed];
let mut attrs: Map<Attribute, ValueSet> = Map::new();
attrs.insert(Attribute::ClassName, name_v);
attrs.insert(Attribute::Description, desc_v);
attrs.insert(Attribute::SyncAllowed, sync_allowed_v);
attrs.insert(Attribute::Uuid, uuid_v);
attrs.insert(
Attribute::Class,
vs_iutf8![
EntryClass::Object.into(),
EntryClass::System.into(),
EntryClass::ClassType.into()
],
);
let vs_systemmay = ValueSetIutf8::from_iter(s.systemmay.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemmay {
attrs.insert(Attribute::SystemMay, vs);
}
let vs_systemmust = ValueSetIutf8::from_iter(s.systemmust.iter().map(|sm| sm.as_str()));
if let Some(vs) = vs_systemmust {
attrs.insert(Attribute::SystemMust, vs);
}
Entry {
valid: EntryInit,
state: EntryNew,
attrs,
}
}
}
#[cfg(test)]
mod tests {
use crate::prelude::*;

View file

@ -527,7 +527,8 @@ impl Filter<FilterValid> {
// cases! The exception is *large* filters, especially from the memberof plugin. We
// want to skip these because they can really jam up the server.
let cacheable = FilterResolved::resolve_cacheable(&self.state.inner);
// Don't cache anything unless we have valid indexing metadata.
let cacheable = idxmeta.is_some() && FilterResolved::resolve_cacheable(&self.state.inner);
let cache_key = if cacheable {
// do we have a cache?
@ -536,6 +537,7 @@ impl Filter<FilterValid> {
let cache_key = (ev.get_event_origin_id(), Arc::new(self.clone()));
if let Some(f) = rcache.get(&cache_key) {
// Got it? Shortcut and return!
trace!("shortcut: a resolved filter already exists.");
return Ok(f.as_ref().clone());
};
// Not in cache? Set the cache_key.
@ -574,6 +576,7 @@ impl Filter<FilterValid> {
// if cacheable == false.
if let Some(cache_key) = cache_key {
if let Some(rcache) = rsv_cache.as_mut() {
trace!(?resolved_filt, "inserting filter to resolved cache");
rcache.insert(cache_key, Arc::new(resolved_filt.clone()));
}
}

View file

@ -124,8 +124,8 @@ pub mod prelude {
pub use kanidmd_lib_macros::*;
pub(crate) use crate::valueset::{
ValueSet, ValueSetBool, ValueSetCid, ValueSetIndex, ValueSetIutf8, ValueSetRefer,
ValueSetSyntax, ValueSetT, ValueSetUtf8, ValueSetUuid,
ValueSet, ValueSetBool, ValueSetCid, ValueSetIutf8, ValueSetRefer, ValueSetSyntax,
ValueSetT, ValueSetUtf8, ValueSetUuid,
};
pub(crate) use kanidm_proto::scim_v1::{

View file

@ -620,22 +620,6 @@ macro_rules! vs_syntax {
});
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! vs_index {
() => (
compile_error!("ValueSetIndex needs at least 1 element")
);
($e:expr) => ({
ValueSetIndex::new($e)
});
($e:expr, $($item:expr),*) => ({
let mut x = ValueSetIndex::new($e);
$(assert!(x.push($item));)*
x
});
}
#[allow(unused_macros)]
#[macro_export]
macro_rules! vs_cid {

View file

@ -69,7 +69,6 @@ pub fn phase_1_schema_attrs() -> Vec<EntryInitNew> {
SCHEMA_ATTR_SYNC_TOKEN_SESSION.clone().into(),
SCHEMA_ATTR_UNIX_PASSWORD.clone().into(),
SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION.clone().into(),
SCHEMA_ATTR_DENIED_NAME.clone().into(),
SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM.clone().into(),
SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST.clone().into(),
// DL4

View file

@ -2,52 +2,25 @@
use crate::constants::entries::{Attribute, EntryClass};
use crate::constants::uuids::*;
use crate::schema::{SchemaAttribute, SchemaClass};
use crate::value::IndexType;
use crate::value::SyntaxType;
lazy_static!(
pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
};
pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
indexed: true,
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
};
pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::EmailAddress,
..Default::default()
};
pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
indexed: true,
unique: true,
multivalue: true,
sync_allowed: true,
@ -59,8 +32,7 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
name: Attribute::IdVerificationEcKey,
description: "Account verification private key".to_string(),
index: vec![IndexType::Presence],
indexed: true,
unique: false,
sync_allowed: false,
syntax: SyntaxType::EcKeyPrivate,
@ -82,30 +54,17 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
name: Attribute::PrimaryCredential,
description: "Primary credential material of the account for authentication interactively".to_string(),
index: vec![IndexType::Presence],
indexed: true,
sync_allowed: true,
syntax: SyntaxType::Credential,
..Default::default()
};
pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
};
pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
indexed: true,
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -115,8 +74,7 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
name: Attribute::NameHistory,
description: "The history of names that a person has had".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AuditLogString,
@ -127,7 +85,6 @@ pub static ref SCHEMA_ATTR_RADIUS_SECRET: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_RADIUS_SECRET,
name: Attribute::RadiusSecret,
description: "The accounts generated radius secret for device network authentication".to_string(),
sync_allowed: true,
syntax: SyntaxType::SecretUtf8String,
..Default::default()
@ -137,8 +94,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
name: Attribute::DomainName,
description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
index: vec![IndexType::Equality, IndexType::Presence],
indexed: true,
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
@ -148,7 +104,6 @@ pub static ref SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_LDAP_ALLOW_UNIX_PW_BIND,
name: Attribute::LdapAllowUnixPwBind,
description: "Configuration to enable binds to LDAP objects using their UNIX password".to_string(),
unique: false,
syntax: SyntaxType::Boolean,
..Default::default()
@ -158,7 +113,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_LDAP_BASEDN: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_DOMAIN_LDAP_BASEDN,
name: Attribute::DomainLdapBasedn,
description: "The domain's optional ldap basedn. If unset defaults to domain components of domain name".to_string(),
unique: true,
syntax: SyntaxType::Utf8StringInsensitive,
..Default::default()
@ -168,7 +122,6 @@ pub static ref SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES: SchemaAttribute =
uuid: UUID_SCHEMA_ATTR_LDAP_MAXIMUM_QUERYABLE_ATTRIBUTES,
name: Attribute::LdapMaxQueryableAttrs,
description: "The maximum number of LDAP attributes that can be queried in one operation".to_string(),
multivalue: false,
sync_allowed: true,
syntax: SyntaxType::Uint32,
@ -179,8 +132,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
name: Attribute::DomainDisplayName,
description: "The user-facing display name of the Kanidm domain".to_string(),
index: vec![IndexType::Equality],
indexed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
};
@ -189,8 +141,7 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
name: Attribute::DomainUuid,
description: "The domain's uuid, used in CSN and trust relationships".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
syntax: SyntaxType::Uuid,
..Default::default()
@ -200,27 +151,16 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
name: Attribute::DomainSsid,
description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
syntax: SyntaxType::Utf8String,
..Default::default()
};
pub static ref SCHEMA_ATTR_DENIED_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DENIED_NAME,
name: Attribute::DeniedName,
description: "Iname values that are not allowed to be used in 'name'.".to_string(),
syntax: SyntaxType::Utf8StringIname,
..Default::default()
};
pub static ref SCHEMA_ATTR_DENIED_NAME_DL10: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DENIED_NAME,
name: Attribute::DeniedName,
description: "Iname values that are not allowed to be used in 'name'.".to_string(),
syntax: SyntaxType::Utf8StringIname,
multivalue: true,
..Default::default()
@ -230,7 +170,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_TOKEN_KEY: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_TOKEN_KEY,
name: Attribute::DomainTokenKey,
description: "The domain token encryption private key (NOT USED)".to_string(),
syntax: SyntaxType::SecretUtf8String,
..Default::default()
};
@ -248,8 +187,7 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
name: Attribute::GidNumber,
description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
sync_allowed: true,
syntax: SyntaxType::Uint32,
@ -260,7 +198,6 @@ pub static ref SCHEMA_ATTR_BADLIST_PASSWORD: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_BADLIST_PASSWORD,
name: Attribute::BadlistPassword,
description: "A password that is badlisted meaning that it can not be set as a valid password by any user account".to_string(),
multivalue: true,
syntax: SyntaxType::Utf8StringInsensitive,
..Default::default()
@ -270,7 +207,6 @@ pub static ref SCHEMA_ATTR_AUTH_SESSION_EXPIRY: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_AUTH_SESSION_EXPIRY,
name: Attribute::AuthSessionExpiry,
description: "An expiration time for an authentication session".to_string(),
syntax: SyntaxType::Uint32,
..Default::default()
};
@ -279,7 +215,6 @@ pub static ref SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_AUTH_PRIVILEGE_EXPIRY,
name: Attribute::PrivilegeExpiry,
description: "An expiration time for a privileged authentication session".to_string(),
syntax: SyntaxType::Uint32,
..Default::default()
};
@ -288,7 +223,6 @@ pub static ref SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH: SchemaAttribute = Schem
uuid: UUID_SCHEMA_ATTR_AUTH_PASSWORD_MINIMUM_LENGTH,
name: Attribute::AuthPasswordMinimumLength,
description: "Minimum length of passwords".to_string(),
syntax: SyntaxType::Uint32,
..Default::default()
};
@ -297,7 +231,6 @@ pub static ref SCHEMA_ATTR_LOGINSHELL: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LOGINSHELL,
name: Attribute::LoginShell,
description: "A POSIX user's UNIX login shell".to_string(),
sync_allowed: true,
syntax: SyntaxType::Utf8StringInsensitive,
..Default::default()
@ -307,8 +240,7 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
name: Attribute::UnixPassword,
description: "A POSIX user's UNIX login password".to_string(),
index: vec![IndexType::Presence],
indexed: true,
syntax: SyntaxType::Credential,
..Default::default()
};
@ -317,8 +249,7 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
name: Attribute::NsUniqueId,
description: "A unique id compatibility for 389-ds/dsee".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
sync_allowed: true,
syntax: SyntaxType::NsUniqueId,
@ -329,7 +260,6 @@ pub static ref SCHEMA_ATTR_ACCOUNT_EXPIRE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_ACCOUNT_EXPIRE,
name: Attribute::AccountExpire,
description: "The datetime after which this account no longer may authenticate".to_string(),
sync_allowed: true,
syntax: SyntaxType::DateTime,
..Default::default()
@ -339,7 +269,6 @@ pub static ref SCHEMA_ATTR_ACCOUNT_VALID_FROM: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_ACCOUNT_VALID_FROM,
name: Attribute::AccountValidFrom,
description: "The datetime after which this account may commence authenticating".to_string(),
sync_allowed: true,
syntax: SyntaxType::DateTime,
..Default::default()
@ -349,7 +278,6 @@ pub static ref SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST: SchemaAttribute = Schem
uuid: UUID_SCHEMA_ATTR_WEBAUTHN_ATTESTATION_CA_LIST,
name: Attribute::WebauthnAttestationCaList,
description: "A set of CA's that limit devices that can be used with webauthn".to_string(),
syntax: SyntaxType::WebauthnAttestationCaList,
multivalue: true,
..Default::default()
@ -359,27 +287,16 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
name: Attribute::OAuth2RsName,
description: "The unique name of an external Oauth2 resource".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
};
pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN,
name: Attribute::OAuth2RsOrigin,
description: "The origin domain of an oauth2 resource server".to_string(),
syntax: SyntaxType::Url,
..Default::default()
};
pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN,
name: Attribute::OAuth2RsOrigin,
description: "The origin domain of an OAuth2 client".to_string(),
syntax: SyntaxType::Url,
multivalue: true,
..Default::default()
@ -389,7 +306,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING: SchemaAttribute = SchemaAtt
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_ORIGIN_LANDING,
name: Attribute::OAuth2RsOriginLanding,
description: "The landing page of an RS, that will automatically trigger the auth process".to_string(),
syntax: SyntaxType::Url,
..Default::default()
};
@ -399,7 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT_DL4: SchemaAttribute
uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_LOCALHOST_REDIRECT,
name: Attribute::OAuth2AllowLocalhostRedirect,
description: "Allow public clients associated to this RS to redirect to localhost".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -408,8 +323,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
name: Attribute::OAuth2RsClaimMap,
description: "A set of custom claims mapped to group memberships of accounts".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
// CHANGE ME
syntax: SyntaxType::OauthClaimMap,
@ -420,8 +334,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
name: Attribute::OAuth2RsScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -431,8 +344,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
name: Attribute::OAuth2RsSupScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -442,7 +354,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET: SchemaAttribute = SchemaAttri
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_BASIC_SECRET,
name: Attribute::OAuth2RsBasicSecret,
description: "When using oauth2 basic authentication, the secret string of the resource server".to_string(),
syntax: SyntaxType::SecretUtf8String,
..Default::default()
};
@ -451,7 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_TOKEN_KEY,
name: Attribute::OAuth2RsTokenKey,
description: "An oauth2 resource servers unique token signing key".to_string(),
syntax: SyntaxType::SecretUtf8String,
..Default::default()
};
@ -460,7 +370,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES: SchemaAttribute = SchemaAt
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_IMPLICIT_SCOPES,
name: Attribute::OAuth2RsImplicitScopes,
description: "An oauth2 resource servers scopes that are implicitly granted to all users".to_string(),
multivalue: true,
syntax: SyntaxType::OauthScope,
..Default::default()
@ -470,8 +379,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
name: Attribute::OAuth2ConsentScopeMap,
description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -481,7 +389,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI_DL7: SchemaAttribute = Sch
uuid: UUID_SCHEMA_ATTR_OAUTH2_STRICT_REDIRECT_URI,
name: Attribute::OAuth2StrictRedirectUri,
description: "Represents if strict redirect uri enforcement is enabled.".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -491,7 +398,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE_DL9: SchemaAttribute = Sche
uuid: UUID_SCHEMA_ATTR_OAUTH2_DEVICE_FLOW_ENABLE,
name: Attribute::OAuth2DeviceFlowEnable,
description: "Represents if OAuth2 Device Flow is permitted on this client.".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -500,7 +406,6 @@ pub static ref SCHEMA_ATTR_ES256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_ES256_PRIVATE_KEY_DER,
name: Attribute::Es256PrivateKeyDer,
description: "An es256 private key".to_string(),
syntax: SyntaxType::PrivateBinary,
..Default::default()
};
@ -509,7 +414,6 @@ pub static ref SCHEMA_ATTR_RS256_PRIVATE_KEY_DER: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_RS256_PRIVATE_KEY_DER,
name: Attribute::Rs256PrivateKeyDer,
description: "An rs256 private key".to_string(),
syntax: SyntaxType::PrivateBinary,
..Default::default()
};
@ -518,8 +422,7 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
name: Attribute::JwsEs256PrivateKey,
description: "An es256 private key for jws".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
syntax: SyntaxType::JwsKeyEs256,
..Default::default()
@ -530,7 +433,6 @@ pub static ref SCHEMA_ATTR_PRIVATE_COOKIE_KEY: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_PRIVATE_COOKIE_KEY,
name: Attribute::PrivateCookieKey,
description: "An private cookie hmac key".to_string(),
syntax: SyntaxType::PrivateBinary,
..Default::default()
};
@ -539,7 +441,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE: SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_ALLOW_INSECURE_CLIENT_DISABLE_PKCE,
name: Attribute::OAuth2AllowInsecureClientDisablePkce,
description: "Allows disabling of PKCE for insecure OAuth2 clients".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -548,7 +449,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE: SchemaAttribute = Sc
uuid: UUID_SCHEMA_ATTR_OAUTH2_JWT_LEGACY_CRYPTO_ENABLE,
name: Attribute::OAuth2JwtLegacyCryptoEnable,
description: "Allows enabling legacy JWT cryptograhpy for clients".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -557,8 +457,7 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
name: Attribute::CredentialUpdateIntentToken,
description: "The status of a credential update intent token".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::IntentToken,
..Default::default()
@ -568,8 +467,7 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_PASSKEYS,
name: Attribute::PassKeys,
description: "A set of registered passkeys".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::Passkey,
@ -580,8 +478,7 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
name: Attribute::AttestedPasskeys,
description: "A set of registered device keys".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AttestedPasskey,
@ -592,7 +489,6 @@ pub static ref SCHEMA_ATTR_DYNGROUP_FILTER: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DYNGROUP_FILTER,
name: Attribute::DynGroupFilter,
description: "A filter describing the set of entries to add to a dynamic group".to_string(),
syntax: SyntaxType::JsonFilter,
..Default::default()
};
@ -601,7 +497,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME: SchemaAttribute = Schem
uuid: UUID_SCHEMA_ATTR_OAUTH2_PREFER_SHORT_USERNAME,
name: Attribute::OAuth2PreferShortUsername,
description: "Use 'name' instead of 'spn' in the preferred_username claim".to_string(),
syntax: SyntaxType::Boolean,
..Default::default()
};
@ -610,8 +505,7 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
name: Attribute::ApiTokenSession,
description: "A session entry related to an issued API token".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
multivalue: true,
syntax: SyntaxType::ApiToken,
@ -622,8 +516,7 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
name: Attribute::UserAuthTokenSession,
description: "A session entry related to an issued user auth token".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
multivalue: true,
syntax: SyntaxType::Session,
@ -634,8 +527,7 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
name: Attribute::OAuth2Session,
description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::Oauth2Session,
..Default::default()
@ -645,8 +537,7 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
name: Attribute::SyncTokenSession,
description: "A session entry related to an issued sync token".to_string(),
index: vec![IndexType::Equality],
indexed: true,
unique: true,
syntax: SyntaxType::ApiToken,
..Default::default()
@ -656,7 +547,6 @@ pub static ref SCHEMA_ATTR_SYNC_COOKIE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_SYNC_COOKIE,
name: Attribute::SyncCookie,
description: "A private sync cookie for a remote IDM source".to_string(),
syntax: SyntaxType::PrivateBinary,
..Default::default()
};
@ -665,8 +555,7 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
name: Attribute::GrantUiHint,
description: "A UI hint that is granted via membership to a group".to_string(),
index: vec![IndexType::Equality],
indexed: true,
multivalue: true,
syntax: SyntaxType::UiHint,
..Default::default()
@ -676,7 +565,6 @@ pub static ref SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL: SchemaAttribute = SchemaAttri
uuid: UUID_SCHEMA_ATTR_SYNC_CREDENTIAL_PORTAL,
name: Attribute::SyncCredentialPortal,
description: "The url of an external credential portal for synced accounts to visit to update their credentials".to_string(),
syntax: SyntaxType::Url,
..Default::default()
};
@ -685,7 +573,6 @@ pub static ref SCHEMA_ATTR_SYNC_YIELD_AUTHORITY: SchemaAttribute = SchemaAttribu
uuid: UUID_SCHEMA_ATTR_SYNC_YIELD_AUTHORITY,
name: Attribute::SyncYieldAuthority,
description: "A set of attributes that have their authority yielded to Kanidm in a sync agreement".to_string(),
multivalue: true,
syntax: SyntaxType::Utf8StringInsensitive,
..Default::default()
@ -695,7 +582,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_CREDENTIAL_TYPE_MINIMUM,
name: Attribute::CredentialTypeMinimum,
description: "The minimum level of credential type that can satisfy this policy".to_string(),
multivalue: false,
syntax: SyntaxType::CredentialType,
..Default::default()
@ -705,7 +591,6 @@ pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS_DL6: SchemaAttribute = Schem
uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_RESULTS,
name: Attribute::LimitSearchMaxResults,
description: "The maximum number of query results that may be returned in a single operation".to_string(),
multivalue: false,
syntax: SyntaxType::Uint32,
..Default::default()
@ -715,7 +600,6 @@ pub static ref SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST_DL6: SchemaAttribute = S
uuid: UUID_SCHEMA_ATTR_LIMIT_SEARCH_MAX_FILTER_TEST,
name: Attribute::LimitSearchMaxFilterTest,
description: "The maximum number of entries that may be examined in a partially indexed query".to_string(),
multivalue: false,
syntax: SyntaxType::Uint32,
..Default::default()
@ -735,6 +619,7 @@ pub static ref SCHEMA_ATTR_KEY_PROVIDER_DL6: SchemaAttribute = SchemaAttribute {
name: Attribute::KeyProvider,
description: "".to_string(),
multivalue: false,
indexed: true,
syntax: SyntaxType::ReferenceUuid,
..Default::default()
};
@ -800,6 +685,7 @@ pub static ref SCHEMA_ATTR_REFERS_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_REFERS,
name: Attribute::Refers,
description: "A reference to linked object".to_string(),
indexed: true,
multivalue: false,
syntax: SyntaxType::ReferenceUuid,
..Default::default()
@ -809,8 +695,8 @@ pub static ref SCHEMA_ATTR_LINKED_GROUP_DL8: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LINKED_GROUP,
name: Attribute::LinkedGroup,
description: "A reference linking a group to an entry".to_string(),
multivalue: false,
indexed: true,
syntax: SyntaxType::ReferenceUuid,
..Default::default()
};
@ -819,7 +705,6 @@ pub static ref SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK_DL8: SchemaAttribute = Sc
uuid: UUID_SCHEMA_ATTR_ALLOW_PRIMARY_CRED_FALLBACK,
name: Attribute::AllowPrimaryCredFallback,
description: "Allow fallback to primary password if no POSIX password exists".to_string(),
multivalue: false,
syntax: SyntaxType::Boolean,
..Default::default()
@ -838,57 +723,13 @@ pub static ref SCHEMA_ATTR_APPLICATION_PASSWORD_DL8: SchemaAttribute = SchemaAtt
uuid: UUID_SCHEMA_ATTR_APPLICATION_PASSWORD,
name: Attribute::ApplicationPassword,
description: "A set of application passwords".to_string(),
multivalue: true,
indexed: true,
syntax: SyntaxType::ApplicationPassword,
..Default::default()
};
// === classes ===
pub static ref SCHEMA_CLASS_PERSON: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_PERSON,
name: EntryClass::Person.into(),
description: "Object representation of a person".to_string(),
sync_allowed: true,
systemmay: vec![
Attribute::Mail,
Attribute::LegalName,
],
systemmust: vec![
Attribute::DisplayName,
Attribute::Name,
Attribute::IdVerificationEcKey],
..Default::default()
};
pub static ref SCHEMA_CLASS_PERSON_DL5: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_PERSON,
name: EntryClass::Person.into(),
description: "Object representation of a person".to_string(),
sync_allowed: true,
systemmay: vec![
Attribute::PrimaryCredential,
Attribute::PassKeys,
Attribute::AttestedPasskeys,
Attribute::CredentialUpdateIntentToken,
Attribute::SshPublicKey,
Attribute::RadiusSecret,
Attribute::OAuth2ConsentScopeMap,
Attribute::UserAuthTokenSession,
Attribute::OAuth2Session,
Attribute::Mail,
Attribute::LegalName,
],
systemmust: vec![
Attribute::IdVerificationEcKey
],
systemexcludes: vec![EntryClass::ServiceAccount.into(), EntryClass::Application.into()],
..Default::default()
};
pub static ref SCHEMA_CLASS_PERSON_DL8: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_PERSON,
name: EntryClass::Person.into(),
@ -961,24 +802,6 @@ pub static ref SCHEMA_CLASS_DYNGROUP: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL6: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY,
name: EntryClass::AccountPolicy.into(),
description: "Policies applied to accounts that are members of a group".to_string(),
systemmay: vec![
Attribute::AuthSessionExpiry,
Attribute::PrivilegeExpiry,
Attribute::AuthPasswordMinimumLength,
Attribute::CredentialTypeMinimum,
Attribute::WebauthnAttestationCaList,
Attribute::LimitSearchMaxResults,
Attribute::LimitSearchMaxFilterTest,
],
systemsupplements: vec![Attribute::Group.into()],
..Default::default()
};
pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_ACCOUNT_POLICY,
name: EntryClass::AccountPolicy.into(),
@ -998,40 +821,6 @@ pub static ref SCHEMA_CLASS_ACCOUNT_POLICY_DL8: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_ACCOUNT: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_ACCOUNT,
name: EntryClass::Account.into(),
description: "Object representation of an account".to_string(),
sync_allowed: true,
systemmay: vec![
Attribute::PrimaryCredential,
Attribute::PassKeys,
Attribute::AttestedPasskeys,
Attribute::CredentialUpdateIntentToken,
Attribute::SshPublicKey,
Attribute::RadiusSecret,
Attribute::AccountExpire,
Attribute::AccountValidFrom,
Attribute::Mail,
Attribute::OAuth2ConsentScopeMap,
Attribute::UserAuthTokenSession,
Attribute::OAuth2Session,
Attribute::Description,
Attribute::NameHistory,
],
systemmust: vec![
Attribute::DisplayName,
Attribute::Name,
Attribute::Spn
],
systemsupplements: vec![
EntryClass::Person.into(),
EntryClass::ServiceAccount.into(),
],
..Default::default()
};
pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_ACCOUNT,
name: EntryClass::Account.into(),
@ -1056,29 +845,6 @@ pub static ref SCHEMA_CLASS_ACCOUNT_DL5: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL6: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT,
name: EntryClass::ServiceAccount.into(),
description: "Object representation of service account".to_string(),
sync_allowed: true,
systemmay: vec![
Attribute::SshPublicKey,
Attribute::UserAuthTokenSession,
Attribute::OAuth2Session,
Attribute::OAuth2ConsentScopeMap,
Attribute::Description,
Attribute::Mail,
Attribute::PrimaryCredential,
Attribute::ApiTokenSession,
Attribute::JwsEs256PrivateKey,
],
systemexcludes: vec![EntryClass::Person.into()],
..Default::default()
};
pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_SERVICE_ACCOUNT,
name: EntryClass::ServiceAccount.into(),
@ -1100,23 +866,6 @@ pub static ref SCHEMA_CLASS_SERVICE_ACCOUNT_DL7: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL6: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT,
name: EntryClass::SyncAccount.into(),
description: "Object representation of sync account".to_string(),
systemmust: vec![Attribute::Name],
systemmay: vec![
Attribute::SyncTokenSession,
Attribute::SyncCookie,
Attribute::SyncCredentialPortal,
Attribute::SyncYieldAuthority,
Attribute::JwsEs256PrivateKey,
],
systemexcludes: vec![EntryClass::Account.into()],
..Default::default()
};
pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_SYNC_ACCOUNT,
name: EntryClass::SyncAccount.into(),
@ -1133,100 +882,6 @@ pub static ref SCHEMA_CLASS_SYNC_ACCOUNT_DL7: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL6: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
name: EntryClass::DomainInfo.into(),
description: "Local domain information and configuration".to_string(),
systemmay: vec![
Attribute::DomainSsid,
Attribute::DomainLdapBasedn,
Attribute::LdapAllowUnixPwBind,
Attribute::PrivateCookieKey,
Attribute::FernetPrivateKeyStr,
Attribute::Es256PrivateKeyDer,
Attribute::PatchLevel,
Attribute::DomainDevelopmentTaint,
],
systemmust: vec![
Attribute::Name,
Attribute::DomainUuid,
Attribute::DomainName,
Attribute::DomainDisplayName,
Attribute::Version,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL7: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
name: EntryClass::DomainInfo.into(),
description: "Local domain information and configuration".to_string(),
systemmay: vec![
Attribute::DomainSsid,
Attribute::DomainLdapBasedn,
Attribute::LdapAllowUnixPwBind,
Attribute::PatchLevel,
Attribute::DomainDevelopmentTaint,
],
systemmust: vec![
Attribute::Name,
Attribute::DomainUuid,
Attribute::DomainName,
Attribute::DomainDisplayName,
Attribute::Version,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL8: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
name: EntryClass::DomainInfo.into(),
description: "Local domain information and configuration".to_string(),
systemmay: vec![
Attribute::DomainSsid,
Attribute::DomainLdapBasedn,
Attribute::LdapAllowUnixPwBind,
Attribute::Image,
Attribute::PatchLevel,
Attribute::DomainDevelopmentTaint,
],
systemmust: vec![
Attribute::Name,
Attribute::DomainUuid,
Attribute::DomainName,
Attribute::DomainDisplayName,
Attribute::Version,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL9: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
name: EntryClass::DomainInfo.into(),
description: "Local domain information and configuration".to_string(),
systemmay: vec![
Attribute::DomainSsid,
Attribute::DomainLdapBasedn,
Attribute::LdapAllowUnixPwBind,
Attribute::Image,
Attribute::PatchLevel,
Attribute::DomainDevelopmentTaint,
Attribute::DomainAllowEasterEggs,
],
systemmust: vec![
Attribute::Name,
Attribute::DomainUuid,
Attribute::DomainName,
Attribute::DomainDisplayName,
Attribute::Version,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_DOMAIN_INFO_DL10: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_DOMAIN_INFO,
name: EntryClass::DomainInfo.into(),
@ -1290,83 +945,6 @@ pub static ref SCHEMA_CLASS_SYSTEM_CONFIG: SchemaClass = SchemaClass {
..Default::default()
};
pub static ref SCHEMA_CLASS_OAUTH2_RS_DL4: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
name: EntryClass::OAuth2ResourceServer.into(),
description: "The class representing a configured Oauth2 Resource Server".to_string(),
systemmay: vec![
Attribute::Description,
Attribute::OAuth2RsScopeMap,
Attribute::OAuth2RsSupScopeMap,
Attribute::Rs256PrivateKeyDer,
Attribute::OAuth2JwtLegacyCryptoEnable,
Attribute::OAuth2PreferShortUsername,
Attribute::OAuth2RsOriginLanding,
Attribute::Image,
Attribute::OAuth2RsClaimMap,
],
systemmust: vec![
Attribute::OAuth2RsName,
Attribute::DisplayName,
Attribute::OAuth2RsOrigin,
Attribute::OAuth2RsTokenKey,
Attribute::Es256PrivateKeyDer,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_OAUTH2_RS_DL5: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
name: EntryClass::OAuth2ResourceServer.into(),
description: "The class representing a configured Oauth2 Resource Server".to_string(),
systemmay: vec![
Attribute::Description,
Attribute::OAuth2RsScopeMap,
Attribute::OAuth2RsSupScopeMap,
Attribute::Rs256PrivateKeyDer,
Attribute::OAuth2JwtLegacyCryptoEnable,
Attribute::OAuth2PreferShortUsername,
Attribute::OAuth2RsOriginLanding,
Attribute::Image,
Attribute::OAuth2RsClaimMap,
Attribute::OAuth2Session,
],
systemmust: vec![
Attribute::OAuth2RsOrigin,
Attribute::OAuth2RsTokenKey,
Attribute::Es256PrivateKeyDer,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_OAUTH2_RS_DL7: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
name: EntryClass::OAuth2ResourceServer.into(),
description: "The class representing a configured OAuth2 Client".to_string(),
systemmay: vec![
Attribute::Description,
Attribute::OAuth2RsScopeMap,
Attribute::OAuth2RsSupScopeMap,
Attribute::Rs256PrivateKeyDer,
Attribute::OAuth2JwtLegacyCryptoEnable,
Attribute::OAuth2PreferShortUsername,
Attribute::Image,
Attribute::OAuth2RsClaimMap,
Attribute::OAuth2Session,
Attribute::OAuth2RsOrigin,
Attribute::OAuth2StrictRedirectUri,
],
systemmust: vec![
Attribute::OAuth2RsOriginLanding,
Attribute::OAuth2RsTokenKey,
Attribute::Es256PrivateKeyDer,
],
..Default::default()
};
pub static ref SCHEMA_CLASS_OAUTH2_RS_DL9: SchemaClass = SchemaClass {
uuid: UUID_SCHEMA_CLASS_OAUTH2_RS,
name: EntryClass::OAuth2ResourceServer.into(),

View file

@ -2,7 +2,6 @@
use crate::constants::entries::{Attribute, EntryClass};
use crate::constants::uuids::*;
use crate::schema::{SchemaAttribute, SchemaClass};
use crate::value::IndexType;
use crate::value::SyntaxType;
lazy_static!(
@ -11,8 +10,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -22,8 +19,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -33,8 +28,6 @@ pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
sync_allowed: true,
@ -46,8 +39,6 @@ pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
unique: true,
multivalue: true,
sync_allowed: true,
@ -59,8 +50,6 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
name: Attribute::IdVerificationEcKey,
description: "Account verification private key".to_string(),
index: vec![IndexType::Presence],
unique: false,
sync_allowed: false,
syntax: SyntaxType::EcKeyPrivate,
@ -82,8 +71,6 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
name: Attribute::PrimaryCredential,
description: "Primary credential material of the account for authentication interactively".to_string(),
index: vec![IndexType::Presence],
sync_allowed: true,
syntax: SyntaxType::Credential,
..Default::default()
@ -93,8 +80,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -104,8 +89,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -115,8 +98,6 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
name: Attribute::NameHistory,
description: "The history of names that a person has had".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AuditLogString,
@ -137,8 +118,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
name: Attribute::DomainName,
description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
index: vec![IndexType::Equality, IndexType::Presence],
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
@ -168,8 +147,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
name: Attribute::DomainDisplayName,
description: "The user-facing display name of the Kanidm domain".to_string(),
index: vec![IndexType::Equality],
syntax: SyntaxType::Utf8String,
..Default::default()
};
@ -178,8 +155,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
name: Attribute::DomainUuid,
description: "The domain's uuid, used in CSN and trust relationships".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Uuid,
..Default::default()
@ -189,8 +164,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
name: Attribute::DomainSsid,
description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -237,8 +210,6 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
name: Attribute::GidNumber,
description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
index: vec![IndexType::Equality],
unique: true,
sync_allowed: true,
syntax: SyntaxType::Uint32,
@ -296,8 +267,6 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
name: Attribute::UnixPassword,
description: "A POSIX user's UNIX login password".to_string(),
index: vec![IndexType::Presence],
syntax: SyntaxType::Credential,
..Default::default()
};
@ -306,8 +275,6 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
name: Attribute::NsUniqueId,
description: "A unique id compatibility for 389-ds/dsee".to_string(),
index: vec![IndexType::Equality],
unique: true,
sync_allowed: true,
syntax: SyntaxType::NsUniqueId,
@ -348,8 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
name: Attribute::OAuth2RsName,
description: "The unique name of an external Oauth2 resource".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
@ -397,8 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
name: Attribute::OAuth2RsClaimMap,
description: "A set of custom claims mapped to group memberships of accounts".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
// CHANGE ME
syntax: SyntaxType::OauthClaimMap,
@ -409,8 +372,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
name: Attribute::OAuth2RsScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -420,8 +381,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
name: Attribute::OAuth2RsSupScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -459,8 +418,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
name: Attribute::OAuth2ConsentScopeMap,
description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -507,8 +464,6 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
name: Attribute::JwsEs256PrivateKey,
description: "An es256 private key for jws".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::JwsKeyEs256,
..Default::default()
@ -546,8 +501,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
name: Attribute::CredentialUpdateIntentToken,
description: "The status of a credential update intent token".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::IntentToken,
..Default::default()
@ -557,8 +510,6 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_PASSKEYS,
name: Attribute::PassKeys,
description: "A set of registered passkeys".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::Passkey,
@ -569,8 +520,6 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
name: Attribute::AttestedPasskeys,
description: "A set of registered device keys".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AttestedPasskey,
@ -599,8 +548,6 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
name: Attribute::ApiTokenSession,
description: "A session entry related to an issued API token".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
syntax: SyntaxType::ApiToken,
@ -611,8 +558,6 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
name: Attribute::UserAuthTokenSession,
description: "A session entry related to an issued user auth token".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
syntax: SyntaxType::Session,
@ -623,8 +568,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
name: Attribute::OAuth2Session,
description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::Oauth2Session,
..Default::default()
@ -634,8 +577,6 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
name: Attribute::SyncTokenSession,
description: "A session entry related to an issued sync token".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::ApiToken,
..Default::default()
@ -654,8 +595,6 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
name: Attribute::GrantUiHint,
description: "A UI hint that is granted via membership to a group".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::UiHint,
..Default::default()

View file

@ -2,7 +2,6 @@
use crate::constants::entries::{Attribute, EntryClass};
use crate::constants::uuids::*;
use crate::schema::{SchemaAttribute, SchemaClass};
use crate::value::IndexType;
use crate::value::SyntaxType;
lazy_static!(
@ -11,8 +10,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -22,8 +19,6 @@ pub static ref SCHEMA_ATTR_DISPLAYNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DISPLAYNAME,
name: Attribute::DisplayName,
description: "The publicly visible display name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -33,8 +28,6 @@ pub static ref SCHEMA_ATTR_MAIL: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
sync_allowed: true,
@ -46,8 +39,6 @@ pub static ref SCHEMA_ATTR_MAIL_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_MAIL,
name: Attribute::Mail,
description: "Mail addresses of the object".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
unique: true,
multivalue: true,
sync_allowed: true,
@ -59,8 +50,6 @@ pub static ref SCHEMA_ATTR_EC_KEY_PRIVATE: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_EC_KEY_PRIVATE,
name: Attribute::IdVerificationEcKey,
description: "Account verification private key".to_string(),
index: vec![IndexType::Presence],
unique: false,
sync_allowed: false,
syntax: SyntaxType::EcKeyPrivate,
@ -82,8 +71,6 @@ pub static ref SCHEMA_ATTR_PRIMARY_CREDENTIAL: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_PRIMARY_CREDENTIAL,
name: Attribute::PrimaryCredential,
description: "Primary credential material of the account for authentication interactively".to_string(),
index: vec![IndexType::Presence],
sync_allowed: true,
syntax: SyntaxType::Credential,
..Default::default()
@ -93,8 +80,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -104,8 +89,6 @@ pub static ref SCHEMA_ATTR_LEGALNAME_DL7: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_LEGALNAME,
name: Attribute::LegalName,
description: "The private and sensitive legal name of this person".to_string(),
index: vec![IndexType::Equality, IndexType::SubString],
sync_allowed: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -115,8 +98,6 @@ pub static ref SCHEMA_ATTR_NAME_HISTORY: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NAME_HISTORY,
name: Attribute::NameHistory,
description: "The history of names that a person has had".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AuditLogString,
@ -137,8 +118,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_NAME,
name: Attribute::DomainName,
description: "The domain's DNS name for webauthn and SPN generation purposes".to_string(),
index: vec![IndexType::Equality, IndexType::Presence],
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
@ -168,8 +147,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_DISPLAY_NAME: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_DOMAIN_DISPLAY_NAME,
name: Attribute::DomainDisplayName,
description: "The user-facing display name of the Kanidm domain".to_string(),
index: vec![IndexType::Equality],
syntax: SyntaxType::Utf8String,
..Default::default()
};
@ -178,8 +155,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_UUID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_UUID,
name: Attribute::DomainUuid,
description: "The domain's uuid, used in CSN and trust relationships".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Uuid,
..Default::default()
@ -189,8 +164,6 @@ pub static ref SCHEMA_ATTR_DOMAIN_SSID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_DOMAIN_SSID,
name: Attribute::DomainSsid,
description: "The domains site-wide SSID for device autoconfiguration of wireless".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Utf8String,
..Default::default()
@ -237,8 +210,6 @@ pub static ref SCHEMA_ATTR_GIDNUMBER: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GIDNUMBER,
name: Attribute::GidNumber,
description: "The groupid (uid) number of a group or account.to_string(). This is the same value as the UID number on posix accounts for security reasons".to_string(),
index: vec![IndexType::Equality],
unique: true,
sync_allowed: true,
syntax: SyntaxType::Uint32,
@ -296,8 +267,6 @@ pub static ref SCHEMA_ATTR_UNIX_PASSWORD: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_UNIX_PASSWORD,
name: Attribute::UnixPassword,
description: "A POSIX user's UNIX login password".to_string(),
index: vec![IndexType::Presence],
syntax: SyntaxType::Credential,
..Default::default()
};
@ -306,8 +275,6 @@ pub static ref SCHEMA_ATTR_NSUNIQUEID: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_NSUNIQUEID,
name: Attribute::NsUniqueId,
description: "A unique id compatibility for 389-ds/dsee".to_string(),
index: vec![IndexType::Equality],
unique: true,
sync_allowed: true,
syntax: SyntaxType::NsUniqueId,
@ -348,8 +315,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_NAME: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_NAME,
name: Attribute::OAuth2RsName,
description: "The unique name of an external Oauth2 resource".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::Utf8StringIname,
..Default::default()
@ -397,8 +362,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP_DL4: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_CLAIM_MAP,
name: Attribute::OAuth2RsClaimMap,
description: "A set of custom claims mapped to group memberships of accounts".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
// CHANGE ME
syntax: SyntaxType::OauthClaimMap,
@ -409,8 +372,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP: SchemaAttribute = SchemaAttribut
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SCOPE_MAP,
name: Attribute::OAuth2RsScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -420,8 +381,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_OAUTH2_RS_SUP_SCOPE_MAP,
name: Attribute::OAuth2RsSupScopeMap,
description: "A reference to a group mapped to scopes for the associated oauth2 resource server".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -459,8 +418,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP: SchemaAttribute = SchemaAtt
uuid: UUID_SCHEMA_ATTR_OAUTH2_CONSENT_SCOPE_MAP,
name: Attribute::OAuth2ConsentScopeMap,
description: "A set of scopes mapped from a relying server to a user, where the user has previously consented to the following. If changed or deleted, consent will be re-sought".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::OauthScopeMap,
..Default::default()
@ -507,8 +464,6 @@ pub static ref SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY: SchemaAttribute = SchemaAttrib
uuid: UUID_SCHEMA_ATTR_JWS_ES256_PRIVATE_KEY,
name: Attribute::JwsEs256PrivateKey,
description: "An es256 private key for jws".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::JwsKeyEs256,
..Default::default()
@ -546,8 +501,6 @@ pub static ref SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN: SchemaAttribute = Sch
uuid: UUID_SCHEMA_ATTR_CREDENTIAL_UPDATE_INTENT_TOKEN,
name: Attribute::CredentialUpdateIntentToken,
description: "The status of a credential update intent token".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::IntentToken,
..Default::default()
@ -557,8 +510,6 @@ pub static ref SCHEMA_ATTR_PASSKEYS: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_PASSKEYS,
name: Attribute::PassKeys,
description: "A set of registered passkeys".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::Passkey,
@ -569,8 +520,6 @@ pub static ref SCHEMA_ATTR_ATTESTED_PASSKEYS: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_ATTESTED_PASSKEYS,
name: Attribute::AttestedPasskeys,
description: "A set of registered device keys".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
sync_allowed: true,
syntax: SyntaxType::AttestedPasskey,
@ -599,8 +548,6 @@ pub static ref SCHEMA_ATTR_API_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_API_TOKEN_SESSION,
name: Attribute::ApiTokenSession,
description: "A session entry related to an issued API token".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
syntax: SyntaxType::ApiToken,
@ -611,8 +558,6 @@ pub static ref SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION: SchemaAttribute = SchemaAttr
uuid: UUID_SCHEMA_ATTR_USER_AUTH_TOKEN_SESSION,
name: Attribute::UserAuthTokenSession,
description: "A session entry related to an issued user auth token".to_string(),
index: vec![IndexType::Equality],
unique: true,
multivalue: true,
syntax: SyntaxType::Session,
@ -623,8 +568,6 @@ pub static ref SCHEMA_ATTR_OAUTH2_SESSION: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_OAUTH2_SESSION,
name: Attribute::OAuth2Session,
description: "A session entry to an active oauth2 session, bound to a parent user auth token".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::Oauth2Session,
..Default::default()
@ -634,8 +577,6 @@ pub static ref SCHEMA_ATTR_SYNC_TOKEN_SESSION: SchemaAttribute = SchemaAttribute
uuid: UUID_SCHEMA_ATTR_SYNC_TOKEN_SESSION,
name: Attribute::SyncTokenSession,
description: "A session entry related to an issued sync token".to_string(),
index: vec![IndexType::Equality],
unique: true,
syntax: SyntaxType::ApiToken,
..Default::default()
@ -654,8 +595,6 @@ pub static ref SCHEMA_ATTR_GRANT_UI_HINT: SchemaAttribute = SchemaAttribute {
uuid: UUID_SCHEMA_ATTR_GRANT_UI_HINT,
name: Attribute::GrantUiHint,
description: "A UI hint that is granted via membership to a group".to_string(),
index: vec![IndexType::Equality],
multivalue: true,
syntax: SyntaxType::UiHint,
..Default::default()

View file

@ -109,7 +109,7 @@ impl DynGroup {
nd_group.purge_ava(Attribute::DynMember);
}
// Insert it to the dyngroup cache with the compiled/resolved filter for
// Insert it to the dyngroup cache with the parsed filter for
// fast matching in other paths.
if dyn_groups.insts.insert(uuid, scope_i).is_none() == expect {
error!("{} cache uuid conflict {}", Attribute::DynGroup, uuid);
@ -175,6 +175,11 @@ impl DynGroup {
) -> Result<BTreeSet<Uuid>, OperationError> {
let mut affected_uuids = BTreeSet::new();
if qs.get_phase() < ServerPhase::SchemaReady {
debug!("Server is not ready to apply dyngroups");
return Ok(affected_uuids);
}
let ident_internal = Identity::from_internal();
let (n_dyn_groups, entries): (Vec<&Entry<_, _>>, Vec<_>) = cand.iter().partition(|entry| {
@ -202,9 +207,7 @@ impl DynGroup {
let dg_filter_valid = dg_filter
.validate(qs.get_schema())
.map_err(OperationError::SchemaViolation)
.and_then(|f| {
f.resolve(&ident_internal, None, Some(qs.get_resolve_filter_cache()))
})?;
.and_then(|f| f.resolve(&ident_internal, None, qs.get_resolve_filter_cache()))?;
// Did any of our modified entries match our dyn group filter?
let matches: Vec<_> = entries
@ -291,6 +294,11 @@ impl DynGroup {
) -> Result<BTreeSet<Uuid>, OperationError> {
let mut affected_uuids = BTreeSet::new();
if qs.get_phase() < ServerPhase::SchemaReady {
debug!("Server is not ready to apply dyngroups");
return Ok(affected_uuids);
}
let ident_internal = Identity::from_internal();
// Probably should be filter here instead.
@ -338,9 +346,7 @@ impl DynGroup {
let dg_filter_valid = dg_filter
.validate(qs.get_schema())
.map_err(OperationError::SchemaViolation)
.and_then(|f| {
f.resolve(&ident_internal, None, Some(qs.get_resolve_filter_cache()))
})?;
.and_then(|f| f.resolve(&ident_internal, None, qs.get_resolve_filter_cache()))?;
let matches: Vec<_> = pre_entries
.iter()

View file

@ -1,7 +1,7 @@
use super::proto::*;
use crate::plugins::Plugins;
use crate::prelude::*;
use crate::server::ChangeFlag;
use crate::server::{ChangeFlag, ServerPhase};
use std::collections::{BTreeMap, BTreeSet};
use std::sync::Arc;
@ -343,7 +343,7 @@ impl QueryServerWriteTransaction<'_> {
}
}
#[instrument(level = "debug", skip_all)]
#[instrument(level = "info", skip_all)]
fn consumer_apply_changes_v1(
&mut self,
ctx_domain_version: DomainVersion,
@ -548,7 +548,7 @@ impl QueryServerWriteTransaction<'_> {
Ok(())
}
#[instrument(level = "debug", skip_all)]
#[instrument(level = "info", skip_all)]
fn consumer_apply_refresh_v1(
&mut self,
ctx_domain_version: DomainVersion,
@ -583,6 +583,7 @@ impl QueryServerWriteTransaction<'_> {
};
// == ⚠️ Below this point we begin to make changes! ==
self.set_phase_bootstrap();
// Update the d_uuid. This is what defines us as being part of this repl topology!
self.be_txn
@ -597,7 +598,6 @@ impl QueryServerWriteTransaction<'_> {
self.reset_server_uuid()?;
// Delete all entries - *proper delete, not just tombstone!*
self.be_txn
.danger_delete_all_db_content()
.inspect_err(|err| {
@ -609,6 +609,12 @@ impl QueryServerWriteTransaction<'_> {
error!(?err, "Failed to reset in memory schema to clean state");
})?;
// Reindex now to force some basic indexes to exist as we consume the schema
// from our replica.
self.reindex(false).inspect_err(|err| {
error!(?err, "Failed to reload schema");
})?;
// Apply the schema entries first. This is the foundation that everything
// else will build upon!
self.consumer_refresh_create_entries(ctx_schema_entries)
@ -621,6 +627,9 @@ impl QueryServerWriteTransaction<'_> {
error!(?err, "Failed to reload schema");
})?;
// Schema is now ready
self.set_phase(ServerPhase::SchemaReady);
// We have to reindex to force all the existing indexes to be dumped
// and recreated before we start to import.
self.reindex(false).inspect_err(|err| {
@ -652,7 +661,10 @@ impl QueryServerWriteTransaction<'_> {
| ChangeFlag::KEY_MATERIAL,
);
// That's it! We are GOOD to go!
// Domain info is now ready.
self.set_phase(ServerPhase::DomainInfoReady);
// ==== That's it! We are GOOD to go! ====
// Create all the entries. Note we don't hit plugins here beside post repl plugs.
self.consumer_refresh_create_entries(ctx_entries)
@ -672,6 +684,9 @@ impl QueryServerWriteTransaction<'_> {
error!(?err, "Unable to update RUV with supplier ranges.");
})?;
// Refresh complete
self.set_phase(ServerPhase::Running);
Ok(())
}
}

File diff suppressed because it is too large Load diff

View file

@ -31,7 +31,7 @@ use crate::value::{CredentialType, EXTRACT_VAL_DN};
use crate::valueset::uuid_to_proto_string;
use crate::valueset::ScimValueIntermediate;
use crate::valueset::*;
use concread::arcache::{ARCacheBuilder, ARCacheReadTxn};
use concread::arcache::{ARCacheBuilder, ARCacheReadTxn, ARCacheWriteTxn};
use concread::cowcell::*;
use hashbrown::{HashMap, HashSet};
use kanidm_proto::internal::{DomainInfo as ProtoDomainInfo, ImageValue, UiHint};
@ -205,6 +205,13 @@ pub struct QueryServerWriteTransaction<'a> {
pub(super) changed_uuid: HashSet<Uuid>,
_db_ticket: SemaphorePermit<'a>,
_write_ticket: SemaphorePermit<'a>,
resolve_filter_cache_clear: bool,
resolve_filter_cache_write: ARCacheWriteTxn<
'a,
(IdentityId, Arc<Filter<FilterValid>>),
Arc<Filter<FilterValidResolved>>,
(),
>,
resolve_filter_cache: ARCacheReadTxn<
'a,
(IdentityId, Arc<Filter<FilterValid>>),
@ -260,7 +267,7 @@ pub trait QueryServerTransaction<'a> {
fn get_domain_image_value(&self) -> Option<ImageValue>;
fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a>;
fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>>;
// Because of how borrowck in rust works, if we need to get two inner types we have to get them
// in a single fn.
@ -269,7 +276,7 @@ pub trait QueryServerTransaction<'a> {
&mut self,
) -> (
&mut Self::BackendTransactionType,
&mut ResolveFilterCacheReadTxn<'a>,
Option<&mut ResolveFilterCacheReadTxn<'a>>,
);
/// Conduct a search and apply access controls to yield a set of entries that
@ -326,11 +333,15 @@ pub trait QueryServerTransaction<'a> {
// NOTE: Filters are validated in event conversion.
let (be_txn, resolve_filter_cache) = self.get_resolve_filter_cache_and_be_txn();
let idxmeta = be_txn.get_idxmeta_ref();
trace!(resolve_filter_cache = %resolve_filter_cache.is_some());
// Now resolve all references and indexes.
let vfr = se
.filter
.resolve(&se.ident, Some(idxmeta), Some(resolve_filter_cache))
.resolve(&se.ident, Some(idxmeta), resolve_filter_cache)
.map_err(|e| {
admin_error!(?e, "search filter resolve failure");
e
@ -366,7 +377,7 @@ pub trait QueryServerTransaction<'a> {
let vfr = ee
.filter
.resolve(&ee.ident, Some(idxmeta), Some(resolve_filter_cache))
.resolve(&ee.ident, Some(idxmeta), resolve_filter_cache)
.map_err(|e| {
admin_error!(?e, "Failed to resolve filter");
e
@ -1444,17 +1455,17 @@ impl<'a> QueryServerTransaction<'a> for QueryServerReadTransaction<'a> {
&self.key_providers
}
fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a> {
&mut self.resolve_filter_cache
fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>> {
Some(&mut self.resolve_filter_cache)
}
fn get_resolve_filter_cache_and_be_txn(
&mut self,
) -> (
&mut BackendReadTransaction<'a>,
&mut ResolveFilterCacheReadTxn<'a>,
Option<&mut ResolveFilterCacheReadTxn<'a>>,
) {
(&mut self.be_txn, &mut self.resolve_filter_cache)
(&mut self.be_txn, Some(&mut self.resolve_filter_cache))
}
fn pw_badlist(&self) -> &HashSet<String> {
@ -1678,17 +1689,25 @@ impl<'a> QueryServerTransaction<'a> for QueryServerWriteTransaction<'a> {
&self.key_providers
}
fn get_resolve_filter_cache(&mut self) -> &mut ResolveFilterCacheReadTxn<'a> {
&mut self.resolve_filter_cache
fn get_resolve_filter_cache(&mut self) -> Option<&mut ResolveFilterCacheReadTxn<'a>> {
if self.resolve_filter_cache_clear || *self.phase < ServerPhase::SchemaReady {
None
} else {
Some(&mut self.resolve_filter_cache)
}
}
fn get_resolve_filter_cache_and_be_txn(
&mut self,
) -> (
&mut BackendWriteTransaction<'a>,
&mut ResolveFilterCacheReadTxn<'a>,
Option<&mut ResolveFilterCacheReadTxn<'a>>,
) {
(&mut self.be_txn, &mut self.resolve_filter_cache)
if self.resolve_filter_cache_clear || *self.phase < ServerPhase::SchemaReady {
(&mut self.be_txn, None)
} else {
(&mut self.be_txn, Some(&mut self.resolve_filter_cache))
}
}
fn pw_badlist(&self) -> &HashSet<String> {
@ -2003,6 +2022,8 @@ impl QueryServer {
_db_ticket: db_ticket,
_write_ticket: write_ticket,
resolve_filter_cache: self.resolve_filter_cache.read(),
resolve_filter_cache_clear: false,
resolve_filter_cache_write: self.resolve_filter_cache.write(),
dyngroup_cache: self.dyngroup_cache.write(),
key_providers: self.key_providers.write(),
})
@ -2152,16 +2173,13 @@ impl<'a> QueryServerWriteTransaction<'a> {
))
}?;
// TODO: Clear the filter resolve cache.
// currently we can't do this because of the limits of types with arccache txns. The only
// thing this impacts is if something in indexed though, and the backend does handle
// incorrectly indexed items correctly.
// Since we reloaded the schema, we need to reload the filter cache since it
// may have incorrect or outdated information about indexes now.
self.resolve_filter_cache_clear = true;
// Trigger reloads on services that require post-schema reloads.
// Mainly this is plugins.
if *self.phase >= ServerPhase::SchemaReady {
DynGroup::reload(self)?;
}
DynGroup::reload(self)?;
Ok(())
}
@ -2584,7 +2602,14 @@ impl<'a> QueryServerWriteTransaction<'a> {
self.changed_flags.remove(ChangeFlag::OAUTH2)
}
fn set_phase(&mut self, phase: ServerPhase) {
/// Indicate that we are about to re-bootstrap this server. You should ONLY
/// call this during a replication refresh!!!
pub(crate) fn set_phase_bootstrap(&mut self) {
*self.phase = ServerPhase::Bootstrap;
}
/// Raise the currently running server phase.
pub(crate) fn set_phase(&mut self, phase: ServerPhase) {
// Phase changes are one way
if phase > *self.phase {
*self.phase = phase
@ -2698,6 +2723,8 @@ impl<'a> QueryServerWriteTransaction<'a> {
changed_flags,
changed_uuid: _,
resolve_filter_cache: _,
resolve_filter_cache_clear,
mut resolve_filter_cache_write,
} = self;
debug_assert!(!committed);
@ -2711,6 +2738,12 @@ impl<'a> QueryServerWriteTransaction<'a> {
be_txn.set_db_ts_max(cid.ts)?;
cid.commit();
// We don't care if this passes/fails, committing this is fine.
if resolve_filter_cache_clear {
resolve_filter_cache_write.clear();
}
resolve_filter_cache_write.commit();
// Point of no return - everything has been validated and reloaded.
//
// = Lets commit =

View file

@ -388,6 +388,65 @@ impl fmt::Display for SyntaxType {
}
}
impl SyntaxType {
pub fn index_types(&self) -> &[IndexType] {
match self {
SyntaxType::Utf8String => &[IndexType::Equality, IndexType::Presence],
// Used by classes, needs to change ...
// Probably need an attrname syntax too
SyntaxType::Utf8StringInsensitive => &[IndexType::Equality, IndexType::Presence],
SyntaxType::Utf8StringIname => &[
IndexType::Equality,
IndexType::Presence,
IndexType::SubString,
],
SyntaxType::Uuid => &[IndexType::Equality, IndexType::Presence],
SyntaxType::Boolean => &[IndexType::Equality],
SyntaxType::SyntaxId => &[],
SyntaxType::IndexId => &[],
SyntaxType::ReferenceUuid => &[IndexType::Equality, IndexType::Presence],
SyntaxType::JsonFilter => &[],
SyntaxType::Credential => &[IndexType::Equality],
SyntaxType::SecretUtf8String => &[],
SyntaxType::SshKey => &[IndexType::Equality, IndexType::Presence],
SyntaxType::SecurityPrincipalName => &[
IndexType::Equality,
IndexType::Presence,
IndexType::SubString,
],
SyntaxType::Uint32 => &[IndexType::Equality, IndexType::Presence],
SyntaxType::Cid => &[],
SyntaxType::NsUniqueId => &[IndexType::Equality, IndexType::Presence],
SyntaxType::DateTime => &[],
SyntaxType::EmailAddress => &[IndexType::Equality, IndexType::SubString],
SyntaxType::Url => &[],
SyntaxType::OauthScope => &[],
SyntaxType::OauthScopeMap => &[IndexType::Equality],
SyntaxType::PrivateBinary => &[],
SyntaxType::IntentToken => &[IndexType::Equality],
SyntaxType::Passkey => &[IndexType::Equality],
SyntaxType::AttestedPasskey => &[IndexType::Equality],
SyntaxType::Session => &[IndexType::Equality],
SyntaxType::JwsKeyEs256 => &[],
SyntaxType::JwsKeyRs256 => &[],
SyntaxType::Oauth2Session => &[IndexType::Equality],
SyntaxType::UiHint => &[],
SyntaxType::TotpSecret => &[],
SyntaxType::ApiToken => &[IndexType::Equality],
SyntaxType::AuditLogString => &[],
SyntaxType::EcKeyPrivate => &[],
SyntaxType::Image => &[],
SyntaxType::CredentialType => &[],
SyntaxType::WebauthnAttestationCaList => &[],
SyntaxType::OauthClaimMap => &[IndexType::Equality],
SyntaxType::KeyInternal => &[],
SyntaxType::HexString => &[],
SyntaxType::Certificate => &[],
SyntaxType::ApplicationPassword => &[IndexType::Equality],
}
}
}
#[derive(
Hash,
Debug,

View file

@ -63,7 +63,7 @@ fn parse_attributes(
"ldap" => {
flags.ldap = true;
field_modifications.extend(quote! {
ldapaddress: Some("on".to_string()),})
ldapbindaddress: Some("on".to_string()),})
}
_ => {
let field_name = p.value().left.to_token_stream(); // here we can use to_token_stream as we know we're iterating over ExprAssigns

View file

@ -84,9 +84,9 @@ pub async fn setup_async_test(mut config: Configuration) -> AsyncTestEnvironment
let addr = format!("http://localhost:{}", port);
let ldap_url = if config.ldapaddress.is_some() {
let ldap_url = if config.ldapbindaddress.is_some() {
let ldapport = port_loop();
config.ldapaddress = Some(format!("127.0.0.1:{}", ldapport));
config.ldapbindaddress = Some(format!("127.0.0.1:{}", ldapport));
Url::parse(&format!("ldap://127.0.0.1:{}", ldapport))
.inspect_err(|err| error!(?err, "ldap address setup"))
.ok()

View file

@ -1,14 +1,13 @@
{ pkgs ? import <nixpkgs> {} }:
let
overrides = (builtins.fromTOML (builtins.readFile ./rust-toolchain.toml));
let
rust-overlay = (import (builtins.fetchTarball "https://github.com/oxalica/rust-overlay/archive/master.tar.gz"));
in
pkgs.mkShellNoCC rec {
{ pkgs ? import <nixpkgs> { overlays = [ rust-overlay ]; } }:
pkgs.mkShellNoCC {
# Kanidm dependencies
buildInputs = with pkgs; [
pkg-config
cargo
rustc
(rust-bin.fromRustupToolchainFile ./rust-toolchain.toml)
clang
llvmPackages.bintools
@ -19,7 +18,6 @@ pkgs.mkShellNoCC rec {
linux-pam
];
RUSTC_VERSION = overrides.toolchain.channel;
# https://github.com/rust-lang/rust-bindgen#environment-variables
LIBCLANG_PATH = pkgs.lib.makeLibraryPath [ pkgs.llvmPackages_latest.libclang.lib ];
}
}

View file

@ -998,7 +998,7 @@ async fn main() -> ExitCode {
let cachelayer = Arc::new(cl_inner);
// Setup the root-only socket. Take away all other access bits.
// Setup the root-only tasks socket. Take away all other access bits.
let before = unsafe { umask(0o0077) };
let task_listener = match UnixListener::bind(cfg.task_sock_path.as_str()) {
Ok(l) => l,
@ -1012,21 +1012,33 @@ async fn main() -> ExitCode {
// Undo umask changes.
let _ = unsafe { umask(before) };
// Setup the tasks socket first.
// The tasks ... well task. Tasks-task. Anyway, the tasks-task is bidirectional
// in its communication to the tasks-daemon. We submit tasks to the tasks-daemon
// via this channel here -\
// |
// v
let (task_channel_tx, mut task_channel_rx) = channel(16);
let task_channel_tx = Arc::new(task_channel_tx);
let task_channel_tx_cln = task_channel_tx.clone();
// Each submitted task contains a oneshot channel allowing the tasks-task to
// notify the submitter of the task that the task is completed.
// Start to build the worker tasks
// This channel is for the second case - the tasks-daemon can send us
// unsolicited dm's about system state, and when these occure we need to
// response to these notifications. Because each potential dm that the
// daemon can send us has a specific intent, we need a channel for each
// type of notification that we could get. This channel is for when
// the tasks daemon has a reloaded shadow database for us to process
// and cache:
let (notify_shadow_channel_tx, mut notify_shadow_channel_rx) = channel(16);
let notify_shadow_channel_tx = Arc::new(notify_shadow_channel_tx);
// Broadcast receivers so that the tasks-task can be shut down when we get
// signals etc.
let (broadcast_tx, mut broadcast_rx) = broadcast::channel(4);
let mut c_broadcast_rx = broadcast_tx.subscribe();
let mut d_broadcast_rx = broadcast_tx.subscribe();
// This channel allowss
let (notify_shadow_channel_tx, mut notify_shadow_channel_rx) = channel(16);
let notify_shadow_channel_tx = Arc::new(notify_shadow_channel_tx);
let task_b = tokio::spawn(async move {
loop {
tokio::select! {
@ -1037,7 +1049,9 @@ async fn main() -> ExitCode {
accept_res = task_listener.accept() => {
match accept_res {
Ok((socket, _addr)) => {
// Did it come from root?
// Did it come from root? If not, they don't have the needed
// permissions to actually be a task handler, and we wouldn't
// want to leak to anyone else anyway.
if let Ok(ucred) = socket.peer_cred() {
if ucred.uid() != 0 {
// move along.

View file

@ -70,7 +70,7 @@ async fn setup_test(fix_fn: Fixture) -> (Resolver, KanidmClient) {
});
// Setup the config ...
let mut config = Configuration::new();
let mut config = Configuration::new_for_test();
config.address = format!("127.0.0.1:{}", port);
config.integration_test_config = Some(int_config);
config.role = ServerRole::WriteReplicaNoUI;