Update OpenAPI schema gen to actually... be kinda sorta valid. ()

* updating lockfile

* OpenAPI validation issues
Fixes 

* clippy sez no

* adding another validator, more specs
This commit is contained in:
James Hodgkinson 2023-11-07 11:35:17 +10:00 committed by GitHub
parent 78dc936430
commit 12f1de8358
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
16 changed files with 318 additions and 329 deletions

192
Cargo.lock generated
View file

@ -37,6 +37,7 @@ dependencies = [
"cfg-if",
"getrandom",
"once_cell",
"serde",
"version_check",
"zerocopy",
]
@ -125,6 +126,12 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "anyhow"
version = "1.0.75"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6"
[[package]]
name = "anymap2"
version = "0.13.0"
@ -226,7 +233,7 @@ checksum = "5fd55a5ba1179988837d24ab4c7cc8ed6efdeff578ede0416b4225a5fca35bd0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -248,7 +255,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -259,7 +266,7 @@ checksum = "a66537f1bb974b254c98ed142ff995236e81b9d0fe4db0575f46612cb15eb0f9"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -383,7 +390,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -470,9 +477,9 @@ dependencies = [
[[package]]
name = "bindgen"
version = "0.66.1"
version = "0.68.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2b84e06fc203107bfbad243f4aba2af864eb7db3b1cf46ea0a023b0b433d2a7"
checksum = "726e4313eb6ec35d2730258ad4e15b547ee75d6afaa1361a922e78e59b7d8078"
dependencies = [
"bitflags 2.4.1",
"cexpr",
@ -487,7 +494,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.38",
"syn 2.0.39",
"which",
]
@ -601,6 +608,12 @@ version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e3b5ca7a04898ad4bcd41c90c5285445ff5b791899bb1b0abdd2a2aa791211d7"
[[package]]
name = "bytecount"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1e5f035d16fc623ae5f74981db80a439803888314e3a555fd6f04acd51a3205"
[[package]]
name = "bytemuck"
version = "1.14.0"
@ -749,7 +762,7 @@ dependencies = [
"heck",
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1173,7 +1186,7 @@ dependencies = [
"proc-macro2",
"quote",
"strsim",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1195,7 +1208,7 @@ checksum = "836a9bbc7ad63342d6d6e7b815ccab164bc77a2d95d84bc3117a8c0d5c98e2d5"
dependencies = [
"darling_core 0.20.3",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1335,7 +1348,7 @@ checksum = "487585f4d0c6655fe74905e2504d8ad6908e4db67f744eb140876906c2f3175d"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1394,7 +1407,7 @@ checksum = "eecf8589574ce9b895052fa12d69af7a233f99e6107f5cb8dd1044f2a17bfdcb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1414,7 +1427,7 @@ checksum = "04d0b288e3bb1d861c4403c1774a6f7a798781dfc519b3647df2a3dd4ae95f25"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1434,7 +1447,7 @@ checksum = "f95e2801cd355d4a1a3e3953ce6ee5ae9603a5c833455343a8bfe3f44d418246"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1455,7 +1468,7 @@ dependencies = [
"darling 0.20.3",
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -1640,6 +1653,16 @@ dependencies = [
"percent-encoding",
]
[[package]]
name = "fraction"
version = "0.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3027ae1df8d41b4bed2241c8fdad4acc1e7af60c8e17743534b545e77182d678"
dependencies = [
"lazy_static",
"num",
]
[[package]]
name = "fs2"
version = "0.4.3"
@ -1726,7 +1749,7 @@ checksum = "53b153fd91e4b0147f4aced87be237c98248656bb01050b96bf3ee89220a8ddb"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -2036,7 +2059,7 @@ checksum = "9d8acb5ee668d55f0f2d19a320a3f9ef67a6999ad483e11135abcc2464ed18b6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -2784,9 +2807,9 @@ dependencies = [
[[package]]
name = "indexmap"
version = "2.0.2"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8adf3ddd720272c6ea8bf59463c04e0f93d0bbf7c5439b691bca2987e0270897"
checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f"
dependencies = [
"equivalent",
"hashbrown 0.14.2",
@ -2839,6 +2862,15 @@ dependencies = [
"windows-sys 0.48.0",
]
[[package]]
name = "iso8601"
version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "924e5d73ea28f59011fec52a0d12185d496a9b075d360657aed2a5707f701153"
dependencies = [
"nom",
]
[[package]]
name = "itertools"
version = "0.10.5"
@ -2887,6 +2919,36 @@ dependencies = [
"wasm-bindgen",
]
[[package]]
name = "jsonschema"
version = "0.17.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a071f4f7efc9a9118dfb627a0a94ef247986e1ab8606a4c806ae2b3aa3b6978"
dependencies = [
"ahash 0.8.6",
"anyhow",
"base64 0.21.5",
"bytecount",
"clap",
"fancy-regex",
"fraction",
"getrandom",
"iso8601",
"itoa",
"memchr",
"num-cmp",
"once_cell",
"parking_lot 0.12.1",
"percent-encoding",
"regex",
"reqwest",
"serde",
"serde_json",
"time",
"url",
"uuid",
]
[[package]]
name = "kanidm-ipa-sync"
version = "1.1.0-rc.15-dev"
@ -3210,7 +3272,7 @@ version = "1.1.0-rc.15-dev"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -3224,6 +3286,7 @@ dependencies = [
"futures",
"http",
"hyper-tls",
"jsonschema",
"kanidm_build_profiles",
"kanidm_client",
"kanidm_lib_crypto",
@ -3449,6 +3512,17 @@ dependencies = [
"paste 0.1.18",
]
[[package]]
name = "libredox"
version = "0.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "85c833ca1e66078851dba29046874e38f08b2c883700aa29a03ddd3b23814ee8"
dependencies = [
"bitflags 2.4.1",
"libc",
"redox_syscall 0.4.1",
]
[[package]]
name = "libsqlite3-sys"
version = "0.25.2"
@ -3764,6 +3838,7 @@ version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b05180d69e3da0e530ba2a1dae5110317e49e3b7f3d41be227dc5f92e49ee7af"
dependencies = [
"num-bigint",
"num-complex",
"num-integer",
"num-iter",
@ -3782,6 +3857,12 @@ dependencies = [
"num-traits",
]
[[package]]
name = "num-cmp"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "63335b2e2c34fae2fb0aa2cecfd9f0832a1e24b3b32ecec612c3426d46dc8aaa"
[[package]]
name = "num-complex"
version = "0.4.4"
@ -3810,7 +3891,7 @@ checksum = "cfb77679af88f8b125209d354a202862602672222e7f2313fdd6dc349bad4712"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -3852,6 +3933,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0638a1c9d0a3c0914158145bc76cff373a75a627e6ecbfb71cbe6f453a5a19b0"
dependencies = [
"autocfg",
"num-bigint",
"num-integer",
"num-traits",
]
@ -3992,7 +4074,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -4209,7 +4291,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e1d3afd2628e69da2be385eb6f2fd57c8ac7977ceeff6dc166ff1657b0e386a9"
dependencies = [
"fixedbitset",
"indexmap 2.0.2",
"indexmap 2.1.0",
"serde",
"serde_derive",
]
@ -4266,7 +4348,7 @@ checksum = "4359fd9c9171ec6e8c62926d6faaf553a8dc3f64e1507e76da7911b4f6a04405"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -4383,7 +4465,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ae005bd773ab59b4725093fd7df83fd7892f7d8eafb48dbd7de6e024e4215f9d"
dependencies = [
"proc-macro2",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -4578,12 +4660,12 @@ dependencies = [
[[package]]
name = "redox_users"
version = "0.4.3"
version = "0.4.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b033d837a7cf162d7993aded9304e30a83213c648b6e389db233191f891e5c2b"
checksum = "a18479200779601e498ada4e8c1e1f50e3ee19deb0259c25825a98b5603b2cb4"
dependencies = [
"getrandom",
"redox_syscall 0.2.16",
"libredox",
"thiserror",
]
@ -4767,7 +4849,7 @@ dependencies = [
"quote",
"rust-embed-utils",
"shellexpand",
"syn 2.0.38",
"syn 2.0.39",
"walkdir",
]
@ -4928,9 +5010,9 @@ dependencies = [
[[package]]
name = "selinux-sys"
version = "0.6.6"
version = "0.6.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d56602385930248c57e45f6174a6a48e12b723d0cc2ae8f467fcbe80c0d06f41"
checksum = "90fc55e8a855264b2816b4c932a581aada4ab5c77d8ff618010021d5ad7c512b"
dependencies = [
"bindgen",
"cc",
@ -5024,7 +5106,7 @@ checksum = "67c5609f394e5c2bd7fc51efda478004ea80ef42fee983d5c67a65e34f32c0e3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5070,7 +5152,7 @@ dependencies = [
"chrono",
"hex",
"indexmap 1.9.3",
"indexmap 2.0.2",
"indexmap 2.1.0",
"serde",
"serde_json",
"serde_with_macros",
@ -5086,7 +5168,7 @@ dependencies = [
"darling 0.20.3",
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5340,9 +5422,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.38"
version = "2.0.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e96b79aaa137db8f61e26363a0c9b47d8b4ec75da28b7d1d614c2303e232408b"
checksum = "23e78b90f2fcf45d3e842032ce32e3f2d1545ba6636271dcbf24fa306d87be7a"
dependencies = [
"proc-macro2",
"quote",
@ -5419,7 +5501,7 @@ version = "0.1.0"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5439,7 +5521,7 @@ checksum = "266b2e40bc00e5a6c09c3584011e08b06f123c00362c92b975ba9843aaaa14b8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5554,7 +5636,7 @@ checksum = "630bdcf245f78637c13ec01ffae6187cca34625e8c63150d424b59e55af2675e"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5626,7 +5708,7 @@ version = "0.19.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421"
dependencies = [
"indexmap 2.0.2",
"indexmap 2.1.0",
"toml_datetime",
"winnow",
]
@ -5707,7 +5789,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -5911,7 +5993,7 @@ version = "4.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b208a50ff438dcdc887ea3f2db59530bd2f4bc3d2c70630e4d7ee7a281a1d1b"
dependencies = [
"indexmap 2.0.2",
"indexmap 2.1.0",
"serde",
"serde_json",
"utoipa-gen",
@ -5927,7 +6009,9 @@ dependencies = [
"proc-macro2",
"quote",
"regex",
"syn 2.0.38",
"syn 2.0.39",
"url",
"uuid",
]
[[package]]
@ -6031,7 +6115,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
"wasm-bindgen-shared",
]
@ -6065,7 +6149,7 @@ checksum = "c5353b8dab669f5e10f5bd76df26a9360c748f054f862ff5f3f8aae0c7fb3907"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@ -6098,7 +6182,7 @@ checksum = "493fcbab756bb764fa37e6bee8cec2dd709eb4273d06d0c282a5e74275ded735"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -6509,9 +6593,9 @@ checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
[[package]]
name = "winnow"
version = "0.5.18"
version = "0.5.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "176b6138793677221d420fd2f0aeeced263f197688b36484660da767bca2fa32"
checksum = "829846f3e3db426d4cee4510841b71a8e58aa2a76b1132579487ae430ccd9c7b"
dependencies = [
"memchr",
]
@ -6621,22 +6705,22 @@ dependencies = [
[[package]]
name = "zerocopy"
version = "0.7.20"
version = "0.7.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd66a62464e3ffd4e37bd09950c2b9dd6c4f8767380fabba0d523f9a775bc85a"
checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.20"
version = "0.7.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "255c4596d41e6916ced49cfafea18727b24d67878fa180ddfd69b9df34fd1726"
checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]
@ -6656,7 +6740,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.38",
"syn 2.0.39",
]
[[package]]

View file

@ -4,6 +4,7 @@ use crate::constants::{
use crate::v1::ApiTokenPurpose;
use serde::{Deserialize, Serialize};
use url::Url;
use utoipa::ToSchema;
use uuid::Uuid;
#[derive(Debug, Serialize, Deserialize, Clone)]
@ -31,7 +32,7 @@ pub struct ScimSyncToken {
}
// State machine states and transitions for the identity verification system feature!
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)]
#[derive(Serialize, Deserialize, Clone, Debug, PartialEq, ToSchema)]
pub enum IdentifyUserRequest {
Start,
SubmitCode { other_totp: u32 },

View file

@ -19,7 +19,7 @@ pub enum ScimSyncState {
Active { cookie: Base64UrlSafeData },
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, ToSchema)]
pub enum ScimSyncRetentionMode {
/// No actions are to be taken - only update or create entries in the
/// entries set.
@ -32,7 +32,7 @@ pub enum ScimSyncRetentionMode {
Delete(Vec<Uuid>),
}
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq)]
#[derive(Serialize, Deserialize, Debug, Clone, PartialEq, Eq, ToSchema)]
pub struct ScimSyncRequest {
pub from_state: ScimSyncState,
pub to_state: ScimSyncState,

View file

@ -235,6 +235,7 @@ pub enum OperationError {
NoMatchingAttributes,
CorruptedEntry(u64),
CorruptedIndex(String),
// TODO: this should just be a vec of the ConsistencyErrors, surely?
ConsistencyError(Vec<Result<(), ConsistencyError>>),
SchemaViolation(SchemaError),
Plugin(PluginError),
@ -368,7 +369,7 @@ impl FromStr for UiHint {
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum UatPurposeStatus {
ReadOnly,
@ -376,7 +377,7 @@ pub enum UatPurposeStatus {
PrivilegeCapable,
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum UatStatusState {
#[serde(with = "time::serde::timestamp")]
@ -421,7 +422,7 @@ impl fmt::Display for UatStatus {
}
}
#[derive(Debug, Serialize, Deserialize, Clone)]
#[derive(Debug, Serialize, Deserialize, Clone, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum UatPurpose {
ReadOnly,
@ -505,7 +506,7 @@ impl UserAuthToken {
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Default)]
#[derive(Debug, Serialize, Deserialize, Clone, Default, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum ApiTokenPurpose {
#[default]
@ -671,7 +672,7 @@ pub struct AccountOrgPersonExtend {
}
*/
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, ToSchema)]
pub enum CredentialDetailType {
Password,
GeneratedPassword,
@ -777,7 +778,7 @@ pub struct BackupCodesView {
// the in memory server core entry type, without affecting the protoEntry type
//
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default)]
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq, Default, ToSchema)]
pub struct Entry {
pub attrs: BTreeMap<String, Vec<String>>,
}
@ -811,7 +812,7 @@ pub enum Filter {
SelfUuid,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
#[derive(Serialize, Deserialize, Debug, Clone, ToSchema)]
#[serde(rename_all = "lowercase")]
pub enum Modify {
Present(String, String),

View file

@ -0,0 +1,41 @@
#!/bin/bash
set -e
cleanup() {
echo "Cleaning up ${1}"
rm -rf "$1"
}
if [ -f openapi.json ]; then
rm openapi.json
fi
WORKDIR="$(mktemp -d)"
echo "Trying to pull openapi.json to ${WORKDIR}"
curl -sfk https://localhost:8443/docs/v1/openapi.json > "${WORKDIR}/openapi.json" || echo "Failed download"
if [ ! -f "${WORKDIR}/openapi.json" ]; then
echo "Failed to download openapi.json"
cleanup "${WORKDIR}"
exit 1
fi
# if "${WORKDIR}/openapi.json" is empty, exit
if [ ! -s "${WORKDIR}/openapi.json" ]; then
echo "openapi.json is empty, cleaning up and exiting"
cleanup "${WORKDIR}"
exit 1
fi
docker run \
--mount "type=bind,src=${WORKDIR}/openapi.json,target=/openapi.json" \
--rm pythonopenapi/openapi-spec-validator /openapi.json && \
echo "openapi-spec-validator passed"
docker run --rm -it \
--mount "type=bind,src=${WORKDIR},target=/spec" \
openapitools/openapi-generator-cli generate \
-i /spec/openapi.json -g rust
cleanup "${WORKDIR}"

View file

@ -70,6 +70,9 @@ utoipa = { workspace = true, features = [
"axum_extras",
"openapi_extensions",
"preserve_order", # Preserve order of properties when serializing the schema for a component.
"time",
"url",
"uuid",
] }
utoipa-swagger-ui = { workspace = true, features = ["axum"] }

View file

@ -1,5 +1,5 @@
use axum::{middleware::from_fn, response::Redirect, routing::get, Router};
use kanidm_proto::{scim_v1::ScimSyncState, v1};
use kanidm_proto::{scim_v1, v1};
use utoipa::{
openapi::security::{HttpAuthScheme, HttpBuilder, SecurityScheme},
Modify, OpenApi,
@ -183,6 +183,9 @@ impl Modify for SecurityAddon {
),
components(
schemas(
scim_v1::ScimSyncState,
scim_v1::ScimSyncRequest,
scim_v1::ScimSyncRetentionMode,
// TODO: can't add Entry/ProtoEntry to schema as this was only recently supported utoipa v3.5.0 doesn't support it - ref <https://github.com/juhaku/utoipa/pull/756/files>
// v1::Entry,
v1::AccountUnixExtend,
@ -216,10 +219,46 @@ impl Modify for SecurityAddon {
v1::UnixUserToken,
v1::UserAuthToken,
v1::WhoamiResponse,
ScimSyncState,
v1::ApiTokenPurpose,
v1::AuthStep,
v1::AuthIssueSession,
v1::AuthMech,
v1::AuthCredential,
v1::AuthAllowed,
v1::CUExtPortal,
v1::CURegState,
v1::CredentialDetailType,
v1::Entry,
v1::Filter,
v1::Modify,
v1::UatStatusState,
v1::UatPurposeStatus,
v1::UatPurpose,
v1::OperationError,
v1::SchemaError,
v1::PluginError,
v1::PasswordFeedback,
kanidm_proto::internal::IdentifyUserRequest,
// terrible workaround for other things
response_schema::CreationChallengeResponse,
// terrible workaround for other things
response_schema::ProtoEntry,
// terrible workaround for other things
response_schema::PublicKeyCredential,
// terrible workaround for other things
response_schema::RequestChallengeResponse,
// terrible workaround for other things
response_schema::Base64UrlSafeData,
// terrible workaround for other things
response_schema::BTreeSet,
// terrible workaround for other things
response_schema::Result,
// terrible workaround for other things
response_schema::ScimEntry,
WebError,
)
),
modifiers(&SecurityAddon),

View file

@ -7,28 +7,3 @@ use utoipa::IntoParams;
pub(crate) struct UuidOrName {
id: String,
}
#[derive(IntoParams, Serialize, Deserialize, Debug)]
pub(crate) struct TokenId {
token_id: String,
}
#[derive(IntoParams, Serialize, Deserialize, Debug)]
pub(crate) struct Id {
id: String,
}
#[derive(IntoParams, Serialize, Deserialize, Debug)]
pub(crate) struct Attr {
attr: String,
}
#[derive(IntoParams, Serialize, Deserialize, Debug)]
pub(crate) struct RsName {
// The short name of the OAuth2 resource server to target
rs_name: String,
}
#[derive(IntoParams, Serialize, Deserialize, Debug)]
pub(crate) struct GroupName {
// The short name of the group to target
group: String,
}

View file

@ -6,7 +6,7 @@ use kanidm_proto::constants::APPLICATION_JSON;
use std::collections::BTreeMap;
use utoipa::{
openapi::{Content, RefOr, Response, ResponseBuilder, ResponsesBuilder},
IntoResponses,
IntoResponses, ToSchema,
};
#[allow(dead_code)] // because this is used for the OpenAPI schema gen
@ -59,3 +59,35 @@ impl IntoResponses for ApiResponseWithout200 {
.into()
}
}
/// Placeholder until we can handle a BTree in utipa
#[derive(Debug, Clone, ToSchema)]
pub(crate) struct ProtoEntry {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be `webauthn_rs_proto::auth::PublicKeyCredential``, but ... I don't know how to make it possible in utoipa
pub(crate) struct PublicKeyCredential {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be `webauthn_rs_proto::auth::RequestChallengeResponse``, but ... I don't know how to make it possible in utoipa
pub(crate) struct RequestChallengeResponse {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be `webauthn_rs_proto::auth::CreationChallengeResponse``, but ... I don't know how to make it possible in utoipa
pub(crate) struct CreationChallengeResponse {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be `Base64UrlSafeData`, but ... I don't know how to make it possible in utoipa
pub(crate) struct Base64UrlSafeData {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be handled elsewhere, but ... I don't know how to make it possible in utoipa
pub(crate) struct BTreeSet {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be handled elsewhere, but ... I don't know how to make it possible in utoipa
pub(crate) struct Result {}
#[derive(Debug, Clone, ToSchema)]
// TODO: this should be handled elsewhere, but ... I don't know how to make it possible in utoipa
pub(crate) struct ScimEntry {}

View file

@ -81,9 +81,6 @@ pub(crate) fn oauth2_id(rs_name: &str) -> Filter<FilterInvalid> {
#[utoipa::path(
get,
path = "/ui/images/oauth2/{rs_name}",
params(
super::apidocs::path_schema::RsName
),
responses(
(status = 200, description = "Ok", body=&[u8]),
(status = 403, description = "Authorization refused"),

View file

@ -1,7 +1,5 @@
//! The V1 API things!
use std::net::IpAddr;
use axum::extract::{Path, Query, State};
use axum::middleware::from_fn;
use axum::response::{IntoResponse, Response};
@ -11,6 +9,7 @@ use compact_jwt::Jws;
use http::{HeaderMap, HeaderValue};
use kanidm_proto::constants::uri::V1_AUTH_VALID;
use serde::{Deserialize, Serialize};
use std::net::IpAddr;
use uuid::Uuid;
use kanidm_proto::internal::{AppLink, IdentifyUserRequest, IdentifyUserResponse};
@ -27,7 +26,6 @@ use kanidmd_lib::prelude::*;
use kanidmd_lib::value::PartialValue;
use super::apidocs::path_schema;
use super::errors::WebError;
use super::middleware::caching::{cache_me, dont_cache_me};
use super::middleware::KOpId;
@ -566,7 +564,7 @@ pub async fn person_get(
responses(
DefaultApiResponse,
),
request_body=Json, // TODO: ProtoEntry can't be serialized, so we need to do this manually
// request_body=ProtoEntry, // TODO: ProtoEntry can't be serialized, so we need to do this manually
security(("token_jwt" = [])),
tag = "v1/person",
)]
@ -644,7 +642,7 @@ pub async fn service_account_get(
#[utoipa::path(
post,
path = "/v1/service_account",
request_body=Json, // TODO ProtoEntry can't be serialized, so we need to do this manually
// request_body=Json, // TODO ProtoEntry can't be serialized, so we need to do this manually
responses(
DefaultApiResponse,
),
@ -805,9 +803,6 @@ pub async fn service_account_api_token_get(
#[utoipa::path(
post,
path = "/v1/service_account/{id}/_spi_token",
params(
path_schema::Id,
),
request_body = ApiTokenGenerate,
responses(
(status=200), // TODO: define response
@ -840,10 +835,6 @@ pub async fn service_account_api_token_post(
#[utoipa::path(
delete,
path = "/v1/service_account/{id}/_spi_token/{token_id}",
params(
path_schema::Id,
path_schema::TokenId,
),
responses(
DefaultApiResponse,
),
@ -905,11 +896,7 @@ pub async fn service_account_id_get_attr(
#[utoipa::path(
post,
path = "/v1/person/{id}/_attr/{attr}",
params(
path_schema::Id,
path_schema::Attr,
),
request_body= Json<Vec<String>>,
request_body= Vec<String>,
responses(
DefaultApiResponse,
),
@ -929,7 +916,7 @@ pub async fn person_id_post_attr(
#[utoipa::path(
post,
path = "/v1/service_account/{id}/_attr/{attr}",
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -1075,7 +1062,7 @@ pub async fn person_id_credential_update_get(
get,
path = "/v1/person/{id}/_credential/_update_intent/?ttl={ttl}",
params(
("ttl" = u32, Query, description="The new TTL for the credential?") // TODO: this is a query param?
("ttl" = u64, description="The new TTL for the credential?")
),
responses(
(status=200), // TODO: define response
@ -1108,9 +1095,6 @@ pub async fn person_id_credential_update_intent_ttl_get(
#[utoipa::path(
get,
path = "/v1/person/{id}/_credential/_update_intent",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1135,9 +1119,6 @@ pub async fn person_id_credential_update_intent_get(
#[utoipa::path(
get,
path = "/v1/account/{id}/_user_auth_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1161,10 +1142,6 @@ pub async fn account_id_user_auth_token_get(
#[utoipa::path(
get,
path = "/v1/account/{id}/_user_auth_token/{token_id}",
params(
path_schema::Id,
path_schema::TokenId,
),
responses(
DefaultApiResponse,
),
@ -1236,7 +1213,7 @@ pub async fn credential_update_status(
post,
path = "/v1/credential/_update",
responses(
(status=200), // TODO: define response
(status=200, body=CUStatus), // TODO: define response
ApiResponseWithout200,
),
security(("token_jwt" = [])),
@ -1322,9 +1299,6 @@ pub async fn credential_update_cancel(
#[utoipa::path(
get,
path = "/v1/service_account/{id}/_credential/_status",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1358,9 +1332,6 @@ pub async fn service_account_id_credential_status_get(
#[utoipa::path(
delete,
path = "/v1/person/{id}/_credential/_status",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1394,9 +1365,6 @@ pub async fn person_get_id_credential_status(
#[utoipa::path(
get,
path = "/v1/person/{id}/_ssh_pubkeys",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1420,9 +1388,6 @@ pub async fn person_id_ssh_pubkeys_get(
#[utoipa::path(
get,
path = "/v1/account/{id}/_ssh_pubkeys",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1447,9 +1412,6 @@ pub async fn account_id_ssh_pubkeys_get(
#[utoipa::path(
get,
path = "/v1/service_account/{id}/_ssh_pubkeys",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1473,9 +1435,6 @@ pub async fn service_account_id_ssh_pubkeys_get(
#[utoipa::path(
post,
path = "/v1/person/{id}/_ssh_pubkeys",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -1502,9 +1461,6 @@ pub async fn person_id_ssh_pubkeys_post(
post,
path = "/v1/service_account/{id}/_ssh_pubkeys",
request_body = (String, String),
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -1530,10 +1486,6 @@ pub async fn service_account_id_ssh_pubkeys_post(
#[utoipa::path(
get,
path = "/v1/person/{id}/_ssh_pubkeys/{tag}",
params(
path_schema::Id,
("tag" = String, description="The tag of the SSH key"),
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1556,10 +1508,6 @@ pub async fn person_id_ssh_pubkeys_tag_get(
#[utoipa::path(
get,
path = "/v1/account/{id}/_ssh_pubkeys/{tag}",
params(
path_schema::Id,
("tag" = String, description="The tag of the SSH key"),
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1583,10 +1531,6 @@ pub async fn account_id_ssh_pubkeys_tag_get(
#[utoipa::path(
get,
path = "/v1/service_account/{id}/_ssh_pubkeys/{tag}",
params(
path_schema::Id,
("tag" = String, description="The tag of the SSH key"),
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1611,7 +1555,6 @@ pub async fn service_account_id_ssh_pubkeys_tag_get(
delete,
path = "/v1/person/{id}/_ssh_pubkeys/{tag}",
params(
path_schema::Id,
("tag" = String, description="The tag of the SSH key"),
),
responses(
@ -1646,7 +1589,6 @@ pub async fn person_id_ssh_pubkeys_tag_delete(
delete,
path = "/v1/service_account/{id}/_ssh_pubkeys/{tag}",
params(
path_schema::Id,
("tag" = String, description="The tag of the SSH key"),
),
responses(
@ -1680,9 +1622,6 @@ pub async fn service_account_id_ssh_pubkeys_tag_delete(
#[utoipa::path(
get,
path = "/v1/person/{id}/_radius",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1708,9 +1647,6 @@ pub async fn person_id_radius_get(
#[utoipa::path(
post,
path = "/v1/person/{id}/_radius",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1736,9 +1672,6 @@ pub async fn person_id_radius_post(
#[utoipa::path(
delete,
path = "/v1/person/{id}/_radius",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -1759,9 +1692,6 @@ pub async fn person_id_radius_delete(
#[utoipa::path(
get,
path = "/v1/person/{id}/_radius/_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1781,9 +1711,6 @@ pub async fn person_id_radius_token_get(
#[utoipa::path(
get,
path = "/v1/account/{id}/_radius/_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1802,9 +1729,6 @@ pub async fn account_id_radius_token_get(
#[utoipa::path(
post,
path = "/v1/account/{id}/_radius/_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1836,9 +1760,6 @@ async fn person_id_radius_handler(
#[utoipa::path(
post,
path = "/v1/person/{id}/_unix",
params(
path_schema::Id,
),
request_body=Jaon<AccountUnixExtend>,
responses(
DefaultApiResponse,
@ -1864,9 +1785,6 @@ pub async fn person_id_unix_post(
#[utoipa::path(
post,
path = "/v1/service_account/{id}/_unix",
params(
path_schema::Id,
),
request_body = AccountUnixExtend,
responses(
DefaultApiResponse,
@ -1893,9 +1811,6 @@ pub async fn service_account_id_unix_post(
#[utoipa::path(
post,
path = "/v1/account/{id}/_unix",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -1921,9 +1836,6 @@ pub async fn account_id_unix_post(
#[utoipa::path(
get,post,
path = "/v1/account/{id}/_unix/_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1964,9 +1876,6 @@ pub async fn account_id_unix_token(
#[utoipa::path(
post,
path = "/v1/account/{id}/_unix/_auth",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -1991,9 +1900,6 @@ pub async fn account_id_unix_auth_post(
#[utoipa::path(
post,
path = "/v1/person/{id}/_unix/_credential",
params(
path_schema::Id,
),
request_body = SingleStringRequest,
responses(
DefaultApiResponse,
@ -2018,9 +1924,6 @@ pub async fn person_id_unix_credential_put(
#[utoipa::path(
delete,
path = "/v1/person/{id}/_unix/_credential",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -2050,9 +1953,6 @@ pub async fn person_id_unix_credential_delete(
#[utoipa::path(
post,
path = "/v1/person/{id}/_identify/_user",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2097,7 +1997,7 @@ pub async fn group_get(
post,
path = "/v1/group/{id}",
params(
path_schema::Id,
path_schema::UuidOrName
),
responses(
DefaultApiResponse,
@ -2117,9 +2017,6 @@ pub async fn group_post(
#[utoipa::path(
get,
path = "/v1/group/{id}",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2139,9 +2036,6 @@ pub async fn group_id_get(
#[utoipa::path(
delete,
path = "/v1/group/{id}",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),
@ -2160,10 +2054,6 @@ pub async fn group_id_delete(
#[utoipa::path(
get,
path = "/v1/group/{id}/_attr/{attr}",
params(
path_schema::Id,
path_schema::Attr,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2183,11 +2073,7 @@ pub async fn group_id_attr_get(
#[utoipa::path(
post,
path = "/v1/group/{id}/_attr/{attr}",
params(
path_schema::Id,
path_schema::Attr,
),
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -2207,11 +2093,7 @@ pub async fn group_id_attr_post(
#[utoipa::path(
delete,
path = "/v1/group/{id}/_attr/{attr}",
params(
path_schema::Id,
path_schema::Attr,
),
request_body=Option<Json<Vec<String>>>,
request_body=Option<Vec<String>>,
responses(
DefaultApiResponse,
),
@ -2232,11 +2114,7 @@ pub async fn group_id_attr_delete(
#[utoipa::path(
put,
path = "/v1/group/{id}/_attr/{attr}",
params(
path_schema::Id,
path_schema::Attr,
),
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -2256,9 +2134,6 @@ pub async fn group_id_attr_put(
#[utoipa::path(
put,
path = "/v1/group/{id}/_unix",
params(
path_schema::Id,
),
request_body = GroupUnixExtend,
responses(
DefaultApiResponse,
@ -2283,9 +2158,6 @@ pub async fn group_id_unix_post(
#[utoipa::path(
get,
path = "/v1/group/{id}/_unix/_token",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2327,9 +2199,6 @@ pub async fn domain_get(
#[utoipa::path(
get,
path = "/v1/domain/_attr/{attr}",
params(
path_schema::Attr,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2349,10 +2218,7 @@ pub async fn domain_attr_get(
#[utoipa::path(
put,
path = "/v1/domain/_attr/{attr}",
params(
path_schema::Attr,
),
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -2380,10 +2246,7 @@ pub async fn domain_attr_put(
#[utoipa::path(
delete,
path = "/v1/domain/_attr/{attr}",
params(
path_schema::Attr,
),
request_body=Json<Option<Vec<String>>>,
request_body=Option<Vec<String>>,
responses(
DefaultApiResponse,
),
@ -2432,9 +2295,6 @@ pub async fn system_get(
#[utoipa::path(
get,
path = "/v1/system/_attr/{attr}",
params(
path_schema::Attr,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2454,10 +2314,7 @@ pub async fn system_attr_get(
#[utoipa::path(
post,
path = "/v1/system/_attr/{attr}",
params(
path_schema::Attr,
),
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -2485,10 +2342,7 @@ pub async fn system_attr_post(
#[utoipa::path(
delete,
path = "/v1/system/_attr/{attr}",
params(
path_schema::Attr,
),
request_body=Json<Option<Vec<String>>>,
request_body=Option<Vec<String>>,
responses(
DefaultApiResponse,
),
@ -2516,10 +2370,7 @@ pub async fn system_attr_delete(
#[utoipa::path(
put,
path = "/v1/system/_attr/{attr}",
params(
path_schema::Attr,
),
request_body=Json<Vec<String>>,
request_body=Vec<String>,
responses(
DefaultApiResponse,
),
@ -2571,9 +2422,6 @@ pub async fn recycle_bin_get(
#[utoipa::path(
get,
path = "/v1/recycle_bin/{id}",
params(
path_schema::Id,
),
responses(
(status=200), // TODO: define response
ApiResponseWithout200,
@ -2601,9 +2449,6 @@ pub async fn recycle_bin_id_get(
#[utoipa::path(
post,
path = "/v1/recycle_bin/{id}/_revive",
params(
path_schema::Id,
),
responses(
DefaultApiResponse,
),

View file

@ -1,4 +1,3 @@
use super::apidocs::path_schema;
use super::apidocs::response_schema::{ApiResponseWithout200, DefaultApiResponse};
use super::errors::WebError;
use super::middleware::KOpId;
@ -87,9 +86,6 @@ pub(crate) async fn oauth2_public_post(
#[utoipa::path(
get,
path = "/v1/oauth2/{rs_name}",
params(
path_schema::RsName
),
responses(
(status = 200, /* TODO response=Option<ProtoEntry>*/),
ApiResponseWithout200,
@ -116,9 +112,6 @@ pub(crate) async fn oauth2_id_get(
#[utoipa::path(
get,
path = "/v1/oauth2/{rs_name}/_basic_secret",
params(
path_schema::RsName,
),
responses(
(status = 200,content_type="application/json", body=Option<String>),
ApiResponseWithout200,
@ -145,9 +138,6 @@ pub(crate) async fn oauth2_id_get_basic_secret(
#[utoipa::path(
patch,
path = "/v1/oauth2/{rs_name}",
params(
path_schema::RsName,
),
request_body=ProtoEntry,
responses(
DefaultApiResponse,
@ -175,10 +165,6 @@ pub(crate) async fn oauth2_id_patch(
#[utoipa::path(
patch,
path = "/v1/oauth2/{rs_name}/_scopemap/{group}",
params(
path_schema::RsName,
path_schema::GroupName,
),
request_body=Vec<String>,
responses(
DefaultApiResponse,
@ -205,10 +191,6 @@ pub(crate) async fn oauth2_id_scopemap_post(
#[utoipa::path(
delete,
path = "/v1/oauth2/{rs_name}/_scopemap/{group}",
params(
path_schema::RsName,
path_schema::GroupName,
),
responses(
DefaultApiResponse,
),
@ -233,10 +215,6 @@ pub(crate) async fn oauth2_id_scopemap_delete(
#[utoipa::path(
post,
path = "/v1/oauth2/{rs_name}/_sup_scopemap/{group}",
params(
path_schema::RsName,
path_schema::GroupName,
),
responses(
DefaultApiResponse,
),
@ -262,10 +240,6 @@ pub(crate) async fn oauth2_id_sup_scopemap_post(
#[utoipa::path(
delete,
path = "/v1/oauth2/{rs_name}/_sup_scopemap/{group}",
params(
path_schema::RsName,
path_schema::GroupName,
),
responses(
DefaultApiResponse,
),
@ -290,9 +264,6 @@ pub(crate) async fn oauth2_id_sup_scopemap_delete(
#[utoipa::path(
delete,
path = "/v1/oauth2/{rs_name}",
params(
path_schema::RsName,
),
responses(
DefaultApiResponse,
(status = 404),
@ -318,9 +289,6 @@ pub(crate) async fn oauth2_id_delete(
#[utoipa::path(
delete,
path = "/v1/oauth2/{rs_name}/_image",
params(
path_schema::RsName,
),
responses(
DefaultApiResponse,
),
@ -344,9 +312,6 @@ pub(crate) async fn oauth2_id_image_delete(
#[utoipa::path(
post,
path = "/v1/oauth2/{rs_name}/_image",
params(
path_schema::RsName,
),
responses(
DefaultApiResponse,
),

View file

@ -1,4 +1,3 @@
use super::apidocs::path_schema;
use super::apidocs::response_schema::{ApiResponseWithout200, DefaultApiResponse};
use super::errors::WebError;
use super::middleware::KOpId;
@ -57,9 +56,6 @@ pub async fn sync_account_post(
#[utoipa::path(
get,
path = "/v1/sync_account/{id}",
params(
path_schema::Id
),
responses(
(status = 200,content_type="application/json", body=Option<ProtoEntry>),
ApiResponseWithout200,
@ -80,9 +76,6 @@ pub async fn sync_account_id_get(
#[utoipa::path(
patch,
path = "/v1/sync_account/{id}",
params(
path_schema::UuidOrName
),
request_body=ProtoEntry,
responses(
DefaultApiResponse,
@ -111,9 +104,6 @@ pub async fn sync_account_id_patch(
#[utoipa::path(
get,
path = "/v1/sync_account/{id}/_finalise",
params(
path_schema::UuidOrName
),
responses(
DefaultApiResponse,
),
@ -137,9 +127,6 @@ pub async fn sync_account_id_finalise_get(
#[utoipa::path(
get,
path = "/v1/sync_account/{id}/_terminate",
params(
path_schema::UuidOrName
),
responses(
DefaultApiResponse,
),
@ -163,9 +150,6 @@ pub async fn sync_account_id_terminate_get(
#[utoipa::path(
post,
path = "/v1/sync_account/{id}/_sync_token",
params(
path_schema::UuidOrName
),
responses(
(status = 200), // TODO: response content
ApiResponseWithout200,
@ -260,10 +244,6 @@ async fn scim_sync_get(
#[utoipa::path(
get,
path = "/v1/sync_account/{id}/_attr/{attr}",
params(
path_schema::UuidOrName,
path_schema::Attr,
),
responses(
(status = 200), // TODO: response content
ApiResponseWithout200,
@ -283,10 +263,6 @@ pub async fn sync_account_id_attr_get(
#[utoipa::path(
post,
path = "/v1/sync_account/{id}/_attr/{attr}",
params(
path_schema::UuidOrName,
path_schema::Attr,
),
request_body=Vec<String>,
responses(
DefaultApiResponse,

View file

@ -66,3 +66,4 @@ tokio-openssl = { workspace = true }
kanidm_lib_crypto = { workspace = true }
uuid = { workspace = true }
webauthn-authenticator-rs = { workspace = true }
jsonschema = "0.17.1"

View file

@ -1,3 +1,4 @@
use jsonschema::JSONSchema;
use serde::{Deserialize, Serialize};
use tracing::info;
@ -11,11 +12,32 @@ async fn check_that_the_swagger_api_loads(rsclient: kanidm_client::KanidmClient)
rsclient.set_token("".into()).await;
info!("Running test: check_that_the_swagger_api_loads");
let url = rsclient.make_url("/docs/v1/openapi.json");
let foo: OpenAPIResponse = reqwest::get(url)
let foo: OpenAPIResponse = reqwest::get(url.clone())
.await
.expect("Failed to get openapi.json")
.json()
.await
.unwrap();
assert!(foo.openapi != "1.2.3");
// this validates that it's valid JSON schema, but not that it's valid openapi... but it's a start.
let schema: serde_json::Value = reqwest::get(url)
.await
.expect("Failed to get openapi.json")
.json()
.await
.unwrap();
let instance = serde_json::json!("foo");
let compiled = JSONSchema::compile(&schema).expect("A valid schema");
assert!(jsonschema::is_valid(&schema, &instance));
let result = compiled.validate(&instance);
if let Err(errors) = result {
println!("ERRORS!");
for error in errors {
println!("Validation error: {}", error);
println!("Instance path: {}", error.instance_path);
}
panic!("Validation errors!");
}
}

View file

@ -23,13 +23,20 @@ impl ApiOpt {
&& std::io::stdin().is_terminal()
{
// validate with the user that it's OK to overwrite
let response = dialoguer::Confirm::new()
let response = match dialoguer::Confirm::new()
.with_prompt(format!(
"Output file {} already exists, overwrite?",
aopt.filename.display()
))
.interact()
.unwrap();
{
Ok(val) => val,
// if it throws an error just trigger false
Err(err) => {
eprintln!("Failed to get response from user: {:?}", err);
false
}
};
if !response {
bail = true;
}