From 884fc940017fcb6415d6c12b047a6a8a90f56efa Mon Sep 17 00:00:00 2001 From: GHOSCHT <31184695+GHOSCHT@users.noreply.github.com> Date: Thu, 30 May 2024 17:25:42 +0200 Subject: [PATCH] Integrate with OpenAPI contract Just the generated types will be used. The server stubs are unusable, since JWT auth isn't really supported in the generator (it says it does but nothing is generated...) --- .gitignore | 1 + .gitmodules | 3 + Cargo.lock | 359 ++++++++++++++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 1 + README.md | 11 ++ flake.nix | 116 +++++++++-------- justfile | 2 + openapi/api | 1 + src/main.rs | 4 +- 9 files changed, 429 insertions(+), 69 deletions(-) create mode 100644 .gitmodules create mode 100644 README.md create mode 100644 justfile create mode 160000 openapi/api diff --git a/.gitignore b/.gitignore index c7666b9..4a04e29 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ /result-lib .direnv .env +/openapi/module diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..046ca48 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "openapi/api"] + path = openapi/api + url = https://git.ghoscht.com/schnabu/api.git diff --git a/Cargo.lock b/Cargo.lock index 89060cf..b143a0b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -84,7 +84,7 @@ checksum = "d1eb7c4fcde1858a6796c18a729b661346d38e05a207e2d9028bce822fc20283" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -140,6 +140,21 @@ version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cb0a83a6b46ec05abd19fd19b2dfaa22c3555c390eeb66378ad60e81ee6edc5" +[[package]] +name = "android-tzdata" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" + +[[package]] +name = "android_system_properties" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" +dependencies = [ + "libc", +] + [[package]] name = "anyhow" version = "1.0.86" @@ -160,7 +175,7 @@ checksum = "c6fa2087f2753a7da8cc1c0dbfcf89579dd57458e36769de5ac750b4671737ca" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -224,6 +239,30 @@ dependencies = [ "tracing", ] +[[package]] +name = "axum-extra" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0be6ea09c9b96cb5076af0de2e383bd2bc0c18f827cf1967bdd353e0b910d733" +dependencies = [ + "axum", + "axum-core", + "bytes", + "cookie", + "futures-util", + "http", + "http-body", + "http-body-util", + "mime", + "multer", + "pin-project-lite", + "serde", + "tower", + "tower-layer", + "tower-service", + "tracing", +] + [[package]] name = "backtrace" version = "0.3.71" @@ -290,6 +329,21 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.38" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" +dependencies = [ + "android-tzdata", + "iana-time-zone", + "js-sys", + "num-traits", + "serde", + "wasm-bindgen", + "windows-targets 0.52.5", +] + [[package]] name = "compact_str" version = "0.7.1" @@ -304,6 +358,17 @@ dependencies = [ "static_assertions", ] +[[package]] +name = "cookie" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4ddef33a339a91ea89fb53151bd0a4689cfce27055c291dfa69945475d22c747" +dependencies = [ + "percent-encoding", + "time", + "version_check", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -320,6 +385,50 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "06ea2b9bc92be3c2baa9334a323ebca2d6f074ff852cd1d7b11064035cd3868f" +[[package]] +name = "darling" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83b2eb4d90d12bdda5ed17de686c2acb4c57914f8f921b8da7e112b5a36f3fe1" +dependencies = [ + "darling_core", + "darling_macro", +] + +[[package]] +name = "darling_core" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "622687fe0bac72a04e5599029151f5796111b90f1baaa9b544d807a5e31cd120" +dependencies = [ + "fnv", + "ident_case", + "proc-macro2", + "quote", + "strsim", + "syn 2.0.60", +] + +[[package]] +name = "darling_macro" +version = "0.20.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "733cabb43482b1a1b53eee8583c2b9e8684d592215ea83efd305dd31bc2f0178" +dependencies = [ + "darling_core", + "quote", + "syn 2.0.60", +] + +[[package]] +name = "deranged" +version = "0.3.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +dependencies = [ + "powerfmt", +] + [[package]] name = "diesel" version = "2.1.6" @@ -342,7 +451,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -354,7 +463,7 @@ dependencies = [ "diesel_table_macro_syntax", "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -363,7 +472,7 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc5557efc453706fed5e4fa85006fe9817c224c3f480a34c7e5959fd700921c5" dependencies = [ - "syn", + "syn 2.0.60", ] [[package]] @@ -372,6 +481,15 @@ version = "0.15.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" +[[package]] +name = "encoding_rs" +version = "0.8.34" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b45de904aa0b010bce2ab45264d0631681847fa7b6f2eaa7dab7619943bc4f59" +dependencies = [ + "cfg-if", +] + [[package]] name = "errno" version = "0.3.9" @@ -582,6 +700,35 @@ dependencies = [ "tracing", ] +[[package]] +name = "iana-time-zone" +version = "0.1.60" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e7ffbb5a1b541ea2561f8c41c087286cc091e21e556a4f09a8f6cbf17b69b141" +dependencies = [ + "android_system_properties", + "core-foundation-sys", + "iana-time-zone-haiku", + "js-sys", + "wasm-bindgen", + "windows-core", +] + +[[package]] +name = "iana-time-zone-haiku" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" +dependencies = [ + "cc", +] + +[[package]] +name = "ident_case" +version = "1.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" + [[package]] name = "idna" version = "0.5.0" @@ -685,6 +832,23 @@ dependencies = [ "windows-sys 0.48.0", ] +[[package]] +name = "multer" +version = "3.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "83e87776546dc87511aa5ee218730c92b666d7264ab6ed41f9d215af9cd5224b" +dependencies = [ + "bytes", + "encoding_rs", + "futures-util", + "http", + "httparse", + "memchr", + "mime", + "spin", + "version_check", +] + [[package]] name = "native-tls" version = "0.2.11" @@ -703,6 +867,21 @@ dependencies = [ "tempfile", ] +[[package]] +name = "num-conv" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" + +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "num_cpus" version = "1.16.0" @@ -728,6 +907,28 @@ version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +[[package]] +name = "openapi" +version = "0.0.1" +dependencies = [ + "async-trait", + "axum", + "axum-extra", + "base64", + "bytes", + "chrono", + "http", + "lazy_static", + "regex", + "serde", + "serde_json", + "serde_urlencoded", + "tokio", + "tracing", + "uuid", + "validator", +] + [[package]] name = "openssl" version = "0.10.64" @@ -751,7 +952,7 @@ checksum = "a948666b637a0f465e8564c73e89d4dde00d72d4d473cc972f390fc3dcee7d9c" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -818,7 +1019,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -850,6 +1051,12 @@ dependencies = [ "serde", ] +[[package]] +name = "powerfmt" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" + [[package]] name = "pq-sys" version = "0.4.8" @@ -859,6 +1066,30 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "proc-macro-error" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn 1.0.109", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869" +dependencies = [ + "proc-macro2", + "quote", + "version_check", +] + [[package]] name = "proc-macro2" version = "1.0.81" @@ -1039,6 +1270,7 @@ dependencies = [ "diesel-derive-enum", "dotenvy", "http", + "openapi", "postgis_diesel", "serde", "serde_json", @@ -1091,7 +1323,7 @@ checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1164,6 +1396,22 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a2eb9349b6444b326872e140eb1cf5e7c522154d69e7a0ffb0fb81c06b37543f" +[[package]] +name = "strsim" +version = "0.11.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7da8b5736845d9f2fcb837ea5d9e2628564b3b043a70948a3f0b778838c5fb4f" + +[[package]] +name = "syn" +version = "1.0.109" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +dependencies = [ + "proc-macro2", + "unicode-ident", +] + [[package]] name = "syn" version = "2.0.60" @@ -1216,7 +1464,38 @@ checksum = "46c3384250002a6d5af4d114f2845d37b57521033f30d5c3f46c4d70e1197533" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", +] + +[[package]] +name = "time" +version = "0.3.36" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +dependencies = [ + "deranged", + "itoa", + "num-conv", + "powerfmt", + "serde", + "time-core", + "time-macros", +] + +[[package]] +name = "time-core" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" + +[[package]] +name = "time-macros" +version = "0.2.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +dependencies = [ + "num-conv", + "time-core", ] [[package]] @@ -1261,7 +1540,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1339,7 +1618,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", ] [[package]] @@ -1395,12 +1674,57 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "uuid" +version = "1.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" +dependencies = [ + "serde", +] + +[[package]] +name = "validator" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db79c75af171630a3148bd3e6d7c4f42b6a9a014c2945bc5ed0020cbb8d9478e" +dependencies = [ + "idna", + "once_cell", + "regex", + "serde", + "serde_derive", + "serde_json", + "url", + "validator_derive", +] + +[[package]] +name = "validator_derive" +version = "0.18.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "55591299b7007f551ed1eb79a684af7672c19c3193fb9e0a31936987bb2438ec" +dependencies = [ + "darling", + "once_cell", + "proc-macro-error", + "proc-macro2", + "quote", + "syn 2.0.60", +] + [[package]] name = "vcpkg" version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426" +[[package]] +name = "version_check" +version = "0.9.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" + [[package]] name = "want" version = "0.3.1" @@ -1437,7 +1761,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-shared", ] @@ -1471,7 +1795,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7" dependencies = [ "proc-macro2", "quote", - "syn", + "syn 2.0.60", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -1492,6 +1816,15 @@ dependencies = [ "wasm-bindgen", ] +[[package]] +name = "windows-core" +version = "0.52.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "33ab640c8d7e35bf8ba19b884ba838ceb4fba93a4e8c65a9059d08afcfc683d9" +dependencies = [ + "windows-targets 0.52.5", +] + [[package]] name = "windows-sys" version = "0.48.0" diff --git a/Cargo.toml b/Cargo.toml index 17ceebd..7ffa5cf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,3 +20,4 @@ postgis_diesel = { version = "2.3.1", features = ["serde_geojson"] } serde = { version = "1.0.202", features = ["derive"] } serde_json = "1.0.117" tokio = {version = "1.37.0", features = ["full"]} +openapi = {path="./openapi/module"} diff --git a/README.md b/README.md new file mode 100644 index 0000000..8c88b8a --- /dev/null +++ b/README.md @@ -0,0 +1,11 @@ +# Schnabu Server + +## Getting Started + +The server's OpenAPI contract is added via Git submodules. OpenAPI generator cli can be called via `just` if the cli is installed globally or the nix shell is used. + +```sh +git clone +git submodule update --init --recursive #Update OpenAPI submodule +just openapi #Generate OpenAPI types +``` diff --git a/flake.nix b/flake.nix index 0996779..acb6bf4 100644 --- a/flake.nix +++ b/flake.nix @@ -9,67 +9,75 @@ }; outputs = inputs: - inputs.flake-parts.lib.mkFlake { inherit inputs; } { + inputs.flake-parts.lib.mkFlake {inherit inputs;} { systems = import inputs.systems; imports = [ inputs.treefmt-nix.flakeModule ]; - perSystem = - { config - , pkgs - , ... - }: - let - cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); - nonRustDeps = with pkgs; [ - libiconv - libudev-zero - pkg-config - postgresql - openssl + perSystem = { + config, + pkgs, + ... + }: let + cargoToml = builtins.fromTOML (builtins.readFile ./Cargo.toml); + openapi-generator-version = "7.6.0"; + openapi-generator = pkgs.openapi-generator-cli.overrideAttrs (prev: { + version = openapi-generator-version; + src = pkgs.fetchurl { + url = "mirror://maven/org/openapitools/${prev.pname}/${openapi-generator-version}/${prev.jarfilename}"; + sha256 = "sha256-NQdL3TzfxGvpqQLhGlSj+qPK4eNOtmy9lZ0cgHC719c="; + }; + }); + nonRustDeps = with pkgs; [ + libiconv + libudev-zero + pkg-config + postgresql + openssl + openapi-generator + just + ]; + rust-toolchain = pkgs.symlinkJoin { + name = "rust-toolchain"; + paths = with pkgs; [rustc cargo cargo-watch rust-analyzer rustPlatform.rustcSrc]; + }; + udev-rule = builtins.readFile ./heliox.udev; + in { + # Rust package + packages.default = pkgs.rustPlatform.buildRustPackage { + inherit (cargoToml.package) name version; + src = ./.; + cargoLock.lockFile = ./Cargo.lock; + nativeBuildInputs = with pkgs; [pkg-config udev libudev-zero libpqxx openssl]; + buildInputs = with pkgs; [udev libudev-zero libpqxx openssl]; + postInstall = '' + mkdir -p $out/etc/udev/rules.d + echo '${udev-rule}' > $out/etc/udev/rules.d/70-heliox.rules + ''; + }; + + # Rust dev environment + devShells.default = pkgs.mkShell { + inputsFrom = [ + config.treefmt.build.devShell ]; - rust-toolchain = pkgs.symlinkJoin { - name = "rust-toolchain"; - paths = with pkgs; [ rustc cargo cargo-watch rust-analyzer rustPlatform.rustcSrc ]; - }; - udev-rule = builtins.readFile ./heliox.udev; - in - { - # Rust package - packages.default = pkgs.rustPlatform.buildRustPackage { - inherit (cargoToml.package) name version; - src = ./.; - cargoLock.lockFile = ./Cargo.lock; - nativeBuildInputs = with pkgs; [ pkg-config udev libudev-zero libpqxx openssl ]; - buildInputs = with pkgs; [ udev libudev-zero libpqxx openssl ]; - postInstall = '' - mkdir -p $out/etc/udev/rules.d - echo '${udev-rule}' > $out/etc/udev/rules.d/70-heliox.rules - ''; - }; + buildInputs = nonRustDeps; + nativeBuildInputs = with pkgs; + [ + rust-toolchain + diesel-cli + ] + ++ nonRustDeps; + RUST_BACKTRACE = 1; + }; - # Rust dev environment - devShells.default = pkgs.mkShell { - inputsFrom = [ - config.treefmt.build.devShell - ]; - buildInputs = nonRustDeps; - nativeBuildInputs = with pkgs; - [ - rust-toolchain - diesel-cli - ] - ++ nonRustDeps; - RUST_BACKTRACE = 1; - }; - - treefmt.config = { - projectRootFile = "flake.nix"; - programs = { - nixpkgs-fmt.enable = true; - rustfmt.enable = true; - }; + treefmt.config = { + projectRootFile = "flake.nix"; + programs = { + nixpkgs-fmt.enable = true; + rustfmt.enable = true; }; }; + }; }; } diff --git a/justfile b/justfile new file mode 100644 index 0000000..2d6aaeb --- /dev/null +++ b/justfile @@ -0,0 +1,2 @@ +openapi: + openapi-generator-cli generate -i ./openapi/api/server.yaml -g rust-axum -o ./openapi/module diff --git a/openapi/api b/openapi/api new file mode 160000 index 0000000..5ccfdd4 --- /dev/null +++ b/openapi/api @@ -0,0 +1 @@ +Subproject commit 5ccfdd4c3619c7496691a2f0abb5eca2e60ee0bd diff --git a/src/main.rs b/src/main.rs index e2810c0..5f2bbcf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,8 +6,6 @@ mod models; mod ops; mod schema; -use std::time::Duration; - use aliri::{error::JwtVerifyError, jwa, jwt}; use aliri_oauth2::{Authority, HasScope, Scope}; use aliri_tower::Oauth2Authorizer; @@ -18,6 +16,8 @@ use axum::{ Extension, Router, }; use http::{request::Parts, Response}; +use openapi; +use std::time::Duration; #[tokio::main] async fn main() -> anyhow::Result<()> {