rest-http: add axum-based server
parent
243f4af198
commit
19860d2d87
|
@ -22,6 +22,21 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-no-stdlib"
|
||||||
|
version = "2.0.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "cc7bb162ec39d46ab1ca8c77bf72e890535becd1751bb45f64c597edb4c8c6b3"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "alloc-stdlib"
|
||||||
|
version = "0.2.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "94fb8275041c72129eb51b7d0322c29b8387a0386127718b096429201a5d6ece"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "android_system_properties"
|
name = "android_system_properties"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -55,6 +70,16 @@ version = "0.5.2"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "assert-json-diff"
|
||||||
|
version = "2.0.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "47e4f2b81832e72834d7518d8487a0396a28cc408186a2e8854c0f98011faf12"
|
||||||
|
dependencies = [
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "assert_cmd"
|
name = "assert_cmd"
|
||||||
version = "2.0.11"
|
version = "2.0.11"
|
||||||
|
@ -81,6 +106,19 @@ dependencies = [
|
||||||
"futures-core",
|
"futures-core",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "async-compression"
|
||||||
|
version = "0.3.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "942c7cd7ae39e91bde4820d74132e9862e62c2f386c3aa90ccf55949f5bad63a"
|
||||||
|
dependencies = [
|
||||||
|
"brotli",
|
||||||
|
"futures-core",
|
||||||
|
"memchr",
|
||||||
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "async-executor"
|
name = "async-executor"
|
||||||
version = "1.5.1"
|
version = "1.5.1"
|
||||||
|
@ -398,6 +436,19 @@ dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "bcrypt"
|
||||||
|
version = "0.14.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9df288bec72232f78c1ec5fe4e8f1d108aa0265476e93097593c803c8c02062a"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.21.0",
|
||||||
|
"blowfish",
|
||||||
|
"getrandom",
|
||||||
|
"subtle",
|
||||||
|
"zeroize",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bincode"
|
name = "bincode"
|
||||||
version = "1.3.3"
|
version = "1.3.3"
|
||||||
|
@ -461,6 +512,37 @@ dependencies = [
|
||||||
"log",
|
"log",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "blowfish"
|
||||||
|
version = "0.9.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e412e2cd0f2b2d93e02543ceae7917b3c70331573df19ee046bcbc35e45e87d7"
|
||||||
|
dependencies = [
|
||||||
|
"byteorder",
|
||||||
|
"cipher",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli"
|
||||||
|
version = "3.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a1a0b1dbcc8ae29329621f8d4f0d835787c1c38bb1401979b49d13b0b305ff68"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
"brotli-decompressor",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "brotli-decompressor"
|
||||||
|
version = "2.3.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "4b6561fd3f895a11e8f72af2cb7d22e08366bebc2b6b57f7744c4bda27034744"
|
||||||
|
dependencies = [
|
||||||
|
"alloc-no-stdlib",
|
||||||
|
"alloc-stdlib",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "bstr"
|
name = "bstr"
|
||||||
version = "1.4.0"
|
version = "1.4.0"
|
||||||
|
@ -631,6 +713,16 @@ dependencies = [
|
||||||
"winapi 0.3.9",
|
"winapi 0.3.9",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "cipher"
|
||||||
|
version = "0.4.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad"
|
||||||
|
dependencies = [
|
||||||
|
"crypto-common",
|
||||||
|
"inout",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "clap"
|
name = "clap"
|
||||||
version = "4.2.7"
|
version = "4.2.7"
|
||||||
|
@ -705,6 +797,25 @@ dependencies = [
|
||||||
"crossbeam-utils",
|
"crossbeam-utils",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "config"
|
||||||
|
version = "0.13.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d379af7f68bfc21714c6c7dea883544201741d2ce8274bb12fa54f89507f52a7"
|
||||||
|
dependencies = [
|
||||||
|
"async-trait",
|
||||||
|
"json5",
|
||||||
|
"lazy_static",
|
||||||
|
"nom",
|
||||||
|
"pathdiff",
|
||||||
|
"ron",
|
||||||
|
"rust-ini",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"toml",
|
||||||
|
"yaml-rust",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "constant_time_eq"
|
name = "constant_time_eq"
|
||||||
version = "0.1.5"
|
version = "0.1.5"
|
||||||
|
@ -902,6 +1013,12 @@ dependencies = [
|
||||||
"subtle",
|
"subtle",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dlv-list"
|
||||||
|
version = "0.3.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0688c2a7f92e427f44895cd63841bff7b29f8d7a1648b9e7e07a4a365b2e1257"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "doc-comment"
|
name = "doc-comment"
|
||||||
version = "0.3.3"
|
version = "0.3.3"
|
||||||
|
@ -1474,6 +1591,19 @@ dependencies = [
|
||||||
"want",
|
"want",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "hyper-tls"
|
||||||
|
version = "0.5.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d6183ddfa99b85da61a140bea0efc93fdf56ceaa041b37d553518030827f9905"
|
||||||
|
dependencies = [
|
||||||
|
"bytes",
|
||||||
|
"hyper",
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "iana-time-zone"
|
name = "iana-time-zone"
|
||||||
version = "0.1.56"
|
version = "0.1.56"
|
||||||
|
@ -1545,6 +1675,15 @@ dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "inout"
|
||||||
|
version = "0.1.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "a0c10553d664a4d0bcff9f4215d0aac67a639cc68ef660840afe309b807bc9f5"
|
||||||
|
dependencies = [
|
||||||
|
"generic-array",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "instant"
|
name = "instant"
|
||||||
version = "0.1.12"
|
version = "0.1.12"
|
||||||
|
@ -1613,6 +1752,17 @@ dependencies = [
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "json5"
|
||||||
|
version = "0.4.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "96b0db21af676c1ce64250b5f40f3ce2cf27e4e47cb91ed91eb6fe9350b430c1"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_derive",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "kernel32-sys"
|
name = "kernel32-sys"
|
||||||
version = "0.2.2"
|
version = "0.2.2"
|
||||||
|
@ -1695,6 +1845,12 @@ dependencies = [
|
||||||
"cc",
|
"cc",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "linked-hash-map"
|
||||||
|
version = "0.5.6"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "linux-raw-sys"
|
name = "linux-raw-sys"
|
||||||
version = "0.3.7"
|
version = "0.3.7"
|
||||||
|
@ -1816,8 +1972,23 @@ dependencies = [
|
||||||
name = "mailpot-http"
|
name = "mailpot-http"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"assert-json-diff",
|
||||||
|
"async-trait",
|
||||||
|
"axum",
|
||||||
|
"bcrypt",
|
||||||
|
"config",
|
||||||
|
"http",
|
||||||
|
"lazy_static",
|
||||||
|
"log",
|
||||||
"mailpot",
|
"mailpot",
|
||||||
|
"mailpot-web",
|
||||||
|
"reqwest",
|
||||||
|
"serde",
|
||||||
|
"serde_json",
|
||||||
|
"stderrlog",
|
||||||
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tower-http 0.4.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2168,6 +2339,16 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ordered-multimap"
|
||||||
|
version = "0.4.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "ccd746e37177e1711c20dd619a1620f34f5c8b569c53590a72dedd5344d8924a"
|
||||||
|
dependencies = [
|
||||||
|
"dlv-list",
|
||||||
|
"hashbrown",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "output_vt100"
|
name = "output_vt100"
|
||||||
version = "0.1.3"
|
version = "0.1.3"
|
||||||
|
@ -2206,12 +2387,62 @@ dependencies = [
|
||||||
"windows-sys 0.45.0",
|
"windows-sys 0.45.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pathdiff"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "percent-encoding"
|
name = "percent-encoding"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "e68e84bfb01f0507134eac1e9b410a12ba379d064eab48c50ba4ce329a527b70"
|
||||||
|
dependencies = [
|
||||||
|
"thiserror",
|
||||||
|
"ucd-trie",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_derive"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6b79d4c71c865a25a4322296122e3924d30bc8ee0834c8bfc8b95f7f054afbfb"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_generator",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_generator"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6c435bf1076437b851ebc8edc3a18442796b30f1728ffea6262d59bbe28b077e"
|
||||||
|
dependencies = [
|
||||||
|
"pest",
|
||||||
|
"pest_meta",
|
||||||
|
"proc-macro2",
|
||||||
|
"quote",
|
||||||
|
"syn 2.0.15",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "pest_meta"
|
||||||
|
version = "2.6.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "745a452f8eb71e39ffd8ee32b3c5f51d03845f99786fa9b68db6ff509c505411"
|
||||||
|
dependencies = [
|
||||||
|
"once_cell",
|
||||||
|
"pest",
|
||||||
|
"sha2 0.10.6",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pin-project"
|
name = "pin-project"
|
||||||
version = "1.0.12"
|
version = "1.0.12"
|
||||||
|
@ -2443,10 +2674,12 @@ dependencies = [
|
||||||
"http",
|
"http",
|
||||||
"http-body",
|
"http-body",
|
||||||
"hyper",
|
"hyper",
|
||||||
|
"hyper-tls",
|
||||||
"ipnet",
|
"ipnet",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"log",
|
"log",
|
||||||
"mime",
|
"mime",
|
||||||
|
"native-tls",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"percent-encoding",
|
"percent-encoding",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
@ -2454,6 +2687,7 @@ dependencies = [
|
||||||
"serde_json",
|
"serde_json",
|
||||||
"serde_urlencoded",
|
"serde_urlencoded",
|
||||||
"tokio",
|
"tokio",
|
||||||
|
"tokio-native-tls",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
"url",
|
"url",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
|
@ -2483,6 +2717,17 @@ version = "0.2.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
|
checksum = "b833d8d034ea094b1ea68aa6d5c740e0d04bad9d16568d08ba6f76823a114316"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ron"
|
||||||
|
version = "0.7.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "88073939a61e5b7680558e6be56b419e208420c2adb92be54921fa6b72283f1a"
|
||||||
|
dependencies = [
|
||||||
|
"base64 0.13.1",
|
||||||
|
"bitflags",
|
||||||
|
"serde",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rusqlite"
|
name = "rusqlite"
|
||||||
version = "0.28.0"
|
version = "0.28.0"
|
||||||
|
@ -2499,6 +2744,16 @@ dependencies = [
|
||||||
"smallvec",
|
"smallvec",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rust-ini"
|
||||||
|
version = "0.18.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "f6d5f2436026b4f6e79dc829837d467cc7e9a55ee40e750d716713540715a2df"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if 1.0.0",
|
||||||
|
"ordered-multimap",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rustc_version"
|
name = "rustc_version"
|
||||||
version = "0.4.0"
|
version = "0.4.0"
|
||||||
|
@ -3006,9 +3261,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio"
|
name = "tokio"
|
||||||
version = "1.28.0"
|
version = "1.28.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "c3c786bf8134e5a3a166db9b29ab8f48134739014a3eca7bc6bfa95d673b136f"
|
checksum = "0aa32867d44e6f2ce3385e89dceb990188b8bb0fb25b0cf576647a6f98ac5105"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"autocfg",
|
"autocfg",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -3034,6 +3289,16 @@ dependencies = [
|
||||||
"syn 2.0.15",
|
"syn 2.0.15",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tokio-native-tls"
|
||||||
|
version = "0.3.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "bbae76ab933c85776efabc971569dd6119c580d8f5d448769dec1764bf796ef2"
|
||||||
|
dependencies = [
|
||||||
|
"native-tls",
|
||||||
|
"tokio",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tokio-util"
|
name = "tokio-util"
|
||||||
version = "0.7.8"
|
version = "0.7.8"
|
||||||
|
@ -3098,6 +3363,7 @@ version = "0.4.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658"
|
checksum = "5d1d42a9b3f3ec46ba828e8d376aec14592ea199f70a06a548587ecd1c4ab658"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"async-compression",
|
||||||
"bitflags",
|
"bitflags",
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-core",
|
"futures-core",
|
||||||
|
@ -3106,8 +3372,11 @@ dependencies = [
|
||||||
"http-body",
|
"http-body",
|
||||||
"http-range-header",
|
"http-range-header",
|
||||||
"pin-project-lite",
|
"pin-project-lite",
|
||||||
|
"tokio",
|
||||||
|
"tokio-util",
|
||||||
"tower-layer",
|
"tower-layer",
|
||||||
"tower-service",
|
"tower-service",
|
||||||
|
"tracing",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3167,6 +3436,12 @@ version = "1.16.0"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "ucd-trie"
|
||||||
|
version = "0.1.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9e79c4d996edb816c91e4308506774452e55e95c3c9de07b6729e17e15a5ef81"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicase"
|
name = "unicase"
|
||||||
version = "2.6.0"
|
version = "2.6.0"
|
||||||
|
@ -3636,6 +3911,15 @@ dependencies = [
|
||||||
"lzma-sys",
|
"lzma-sys",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "yaml-rust"
|
||||||
|
version = "0.4.5"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
|
||||||
|
dependencies = [
|
||||||
|
"linked-hash-map",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "yansi"
|
name = "yansi"
|
||||||
version = "0.5.1"
|
version = "0.5.1"
|
||||||
|
|
|
@ -0,0 +1,2 @@
|
||||||
|
.env
|
||||||
|
config/local.json
|
|
@ -16,5 +16,29 @@ name = "mpot-http"
|
||||||
path = "src/main.rs"
|
path = "src/main.rs"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
async-trait = "0.1"
|
||||||
|
axum = { version = "0.6", features = ["headers"] }
|
||||||
|
#jsonwebtoken = "8.3"
|
||||||
|
bcrypt = "0.14"
|
||||||
|
config = "0.13"
|
||||||
|
http = "0.2"
|
||||||
|
lazy_static = "1.4"
|
||||||
|
log = "0.4"
|
||||||
mailpot = { version = "^0.1", path = "../core" }
|
mailpot = { version = "^0.1", path = "../core" }
|
||||||
tokio = { version = "^1", features = ["full"] }
|
mailpot-web = { version = "^0.1", path = "../web" }
|
||||||
|
serde = { version = "1", features = ["derive"] }
|
||||||
|
serde_json = "1"
|
||||||
|
stderrlog = "^0.5"
|
||||||
|
thiserror = "1"
|
||||||
|
tokio = { version = "1", features = ["full"] }
|
||||||
|
tower-http = { version = "0.4", features = [
|
||||||
|
"trace",
|
||||||
|
"compression-br",
|
||||||
|
"propagate-header",
|
||||||
|
"sensitive-headers",
|
||||||
|
"cors",
|
||||||
|
] }
|
||||||
|
|
||||||
|
[dev-dependencies]
|
||||||
|
assert-json-diff = "2"
|
||||||
|
reqwest = { version = "0.11", features = ["json"] }
|
||||||
|
|
|
@ -1,3 +1,2 @@
|
||||||
# mailpot REST http server
|
# mailpot REST http server
|
||||||
|
|
||||||
Not implemented.
|
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
{
|
||||||
|
"environment": "development",
|
||||||
|
"server": {
|
||||||
|
"port": 8080
|
||||||
|
},
|
||||||
|
"auth": {
|
||||||
|
"secret": "secret"
|
||||||
|
},
|
||||||
|
"logger": {
|
||||||
|
"level": "debug"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,6 @@
|
||||||
|
{
|
||||||
|
"environment": "production",
|
||||||
|
"logger": {
|
||||||
|
"level": "info"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,9 @@
|
||||||
|
{
|
||||||
|
"environment": "test",
|
||||||
|
"server": {
|
||||||
|
"port": 8088
|
||||||
|
},
|
||||||
|
"logger": {
|
||||||
|
"level": "error"
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,98 @@
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
response::{IntoResponse, Response},
|
||||||
|
Json,
|
||||||
|
};
|
||||||
|
use bcrypt::BcryptError;
|
||||||
|
use serde_json::json;
|
||||||
|
use tokio::task::JoinError;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error("...")]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Error parsing ObjectID {0}")]
|
||||||
|
ParseObjectID(String),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
Authenticate(#[from] AuthenticateError),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
BadRequest(#[from] BadRequest),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
NotFound(#[from] NotFound),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
RunSyncTask(#[from] JoinError),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
HashPassword(#[from] BcryptError),
|
||||||
|
|
||||||
|
#[error("{0}")]
|
||||||
|
System(#[from] mailpot::Error),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error {
|
||||||
|
fn get_codes(&self) -> (StatusCode, u16) {
|
||||||
|
match *self {
|
||||||
|
// 4XX Errors
|
||||||
|
Error::ParseObjectID(_) => (StatusCode::BAD_REQUEST, 40001),
|
||||||
|
Error::BadRequest(_) => (StatusCode::BAD_REQUEST, 40002),
|
||||||
|
Error::NotFound(_) => (StatusCode::NOT_FOUND, 40003),
|
||||||
|
Error::Authenticate(AuthenticateError::WrongCredentials) => {
|
||||||
|
(StatusCode::UNAUTHORIZED, 40004)
|
||||||
|
}
|
||||||
|
Error::Authenticate(AuthenticateError::InvalidToken) => {
|
||||||
|
(StatusCode::UNAUTHORIZED, 40005)
|
||||||
|
}
|
||||||
|
Error::Authenticate(AuthenticateError::Locked) => (StatusCode::LOCKED, 40006),
|
||||||
|
|
||||||
|
// 5XX Errors
|
||||||
|
Error::Authenticate(AuthenticateError::TokenCreation) => {
|
||||||
|
(StatusCode::INTERNAL_SERVER_ERROR, 5001)
|
||||||
|
}
|
||||||
|
Error::RunSyncTask(_) => (StatusCode::INTERNAL_SERVER_ERROR, 5005),
|
||||||
|
Error::HashPassword(_) => (StatusCode::INTERNAL_SERVER_ERROR, 5006),
|
||||||
|
Error::System(_) => (StatusCode::INTERNAL_SERVER_ERROR, 5007),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn bad_request() -> Self {
|
||||||
|
Error::BadRequest(BadRequest {})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn not_found() -> Self {
|
||||||
|
Error::NotFound(NotFound {})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl IntoResponse for Error {
|
||||||
|
fn into_response(self) -> Response {
|
||||||
|
let (status_code, code) = self.get_codes();
|
||||||
|
let message = self.to_string();
|
||||||
|
let body = Json(json!({ "code": code, "message": message }));
|
||||||
|
|
||||||
|
(status_code, body).into_response()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error("...")]
|
||||||
|
pub enum AuthenticateError {
|
||||||
|
#[error("Wrong authentication credentials")]
|
||||||
|
WrongCredentials,
|
||||||
|
#[error("Failed to create authentication token")]
|
||||||
|
TokenCreation,
|
||||||
|
#[error("Invalid authentication credentials")]
|
||||||
|
InvalidToken,
|
||||||
|
#[error("User is locked")]
|
||||||
|
Locked,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error("Bad Request")]
|
||||||
|
pub struct BadRequest {}
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
#[error("Not found")]
|
||||||
|
pub struct NotFound {}
|
|
@ -16,3 +16,13 @@
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
* You should have received a copy of the GNU Affero General Public License
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
pub use std::{net::SocketAddr, sync::Arc};
|
||||||
|
|
||||||
|
pub use axum::Router;
|
||||||
|
pub use http::header;
|
||||||
|
pub use log::{debug, info, trace};
|
||||||
|
pub use mailpot::{models::*, Configuration, Connection};
|
||||||
|
pub mod errors;
|
||||||
|
pub mod routes;
|
||||||
|
pub mod settings;
|
||||||
|
|
|
@ -1,20 +1,50 @@
|
||||||
/*
|
use mailpot_http::{settings::SETTINGS, *};
|
||||||
* This file is part of mailpot
|
use tower_http::{
|
||||||
*
|
compression::CompressionLayer, cors::CorsLayer, propagate_header::PropagateHeaderLayer,
|
||||||
* Copyright 2020 - Manos Pitsidianakis
|
sensitive_headers::SetSensitiveHeadersLayer,
|
||||||
*
|
};
|
||||||
* This program is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Affero General Public License as
|
|
||||||
* published by the Free Software Foundation, either version 3 of the
|
|
||||||
* License, or (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Affero General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Affero General Public License
|
|
||||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
fn main() {}
|
use crate::routes;
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() {
|
||||||
|
let app = create_app().await;
|
||||||
|
|
||||||
|
let port = SETTINGS.server.port;
|
||||||
|
let address = SocketAddr::from(([127, 0, 0, 1], port));
|
||||||
|
|
||||||
|
info!("Server listening on {}", &address);
|
||||||
|
axum::Server::bind(&address)
|
||||||
|
.serve(app.into_make_service())
|
||||||
|
.await
|
||||||
|
.expect("Failed to start server");
|
||||||
|
}
|
||||||
|
pub async fn create_app() -> Router {
|
||||||
|
let config_path = std::env::args()
|
||||||
|
.nth(1)
|
||||||
|
.expect("Expected configuration file path as first argument.");
|
||||||
|
stderrlog::new()
|
||||||
|
.quiet(false)
|
||||||
|
.verbosity(15)
|
||||||
|
.show_module_names(true)
|
||||||
|
.timestamp(stderrlog::Timestamp::Millisecond)
|
||||||
|
.init()
|
||||||
|
.unwrap();
|
||||||
|
let conf = Arc::new(Configuration::from_file(config_path).unwrap());
|
||||||
|
|
||||||
|
Router::new()
|
||||||
|
.with_state(conf.clone())
|
||||||
|
.merge(Router::new().nest("/v1", Router::new().merge(routes::list::create_route(conf))))
|
||||||
|
.layer(SetSensitiveHeadersLayer::new(std::iter::once(
|
||||||
|
header::AUTHORIZATION,
|
||||||
|
)))
|
||||||
|
// Compress responses
|
||||||
|
.layer(CompressionLayer::new())
|
||||||
|
// Propagate `X-Request-Id`s from requests to responses
|
||||||
|
.layer(PropagateHeaderLayer::new(header::HeaderName::from_static(
|
||||||
|
"x-request-id",
|
||||||
|
)))
|
||||||
|
// CORS configuration. This should probably be more restrictive in
|
||||||
|
// production.
|
||||||
|
.layer(CorsLayer::permissive())
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,107 @@
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
pub use axum::extract::{Path, Query, State};
|
||||||
|
use axum::{
|
||||||
|
http::StatusCode,
|
||||||
|
routing::{get, post},
|
||||||
|
Json, Router,
|
||||||
|
};
|
||||||
|
use mailpot_web::{typed_paths::*, ResponseError, RouterExt};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
|
|
||||||
|
use crate::*;
|
||||||
|
|
||||||
|
pub fn create_route(conf: Arc<Configuration>) -> Router {
|
||||||
|
Router::new()
|
||||||
|
.route("/list/", get(all_lists))
|
||||||
|
.route("/list/", post(post_list))
|
||||||
|
.typed_get(get_list)
|
||||||
|
.with_state(conf)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn get_list(
|
||||||
|
ListPath(id): ListPath,
|
||||||
|
State(state): State<Arc<Configuration>>,
|
||||||
|
) -> Result<Json<DbVal<MailingList>>, ResponseError> {
|
||||||
|
let db = Connection::open_db(Configuration::clone(&state))?;
|
||||||
|
let Some(list) = (match id {
|
||||||
|
ListPathIdentifier::Pk(id) => db.list(id)?,
|
||||||
|
ListPathIdentifier::Id(id) => db.list_by_id(id)?,
|
||||||
|
}) else {
|
||||||
|
return Err(mailpot_web::ResponseError::new(
|
||||||
|
"Not found".to_string(),
|
||||||
|
StatusCode::NOT_FOUND,
|
||||||
|
));
|
||||||
|
};
|
||||||
|
Ok(Json(list))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn all_lists(
|
||||||
|
Query(GetRequest {
|
||||||
|
filter: _,
|
||||||
|
count,
|
||||||
|
page,
|
||||||
|
}): Query<GetRequest>,
|
||||||
|
State(state): State<Arc<Configuration>>,
|
||||||
|
) -> Result<Json<GetResponse>, ResponseError> {
|
||||||
|
let db = Connection::open_db(Configuration::clone(&state))?;
|
||||||
|
let lists_values = db.lists()?;
|
||||||
|
let page = page.unwrap_or(0);
|
||||||
|
let Some(count) = count else {
|
||||||
|
let mut stmt = db
|
||||||
|
.connection
|
||||||
|
.prepare("SELECT count(*) FROM list;")?;
|
||||||
|
return Ok(Json(GetResponse {
|
||||||
|
entries: vec![],
|
||||||
|
total: stmt.query_row([], |row| {
|
||||||
|
let count: usize = row.get(0)?;
|
||||||
|
Ok(count)
|
||||||
|
})?,
|
||||||
|
start: 0,
|
||||||
|
}));
|
||||||
|
};
|
||||||
|
let offset = page * count;
|
||||||
|
let res: Vec<_> = lists_values.into_iter().skip(offset).take(count).collect();
|
||||||
|
|
||||||
|
Ok(Json(GetResponse {
|
||||||
|
total: res.len(),
|
||||||
|
start: offset,
|
||||||
|
entries: res,
|
||||||
|
}))
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn post_list(
|
||||||
|
State(state): State<Arc<Configuration>>,
|
||||||
|
Json(_body): Json<GetRequest>,
|
||||||
|
) -> Result<Json<()>, ResponseError> {
|
||||||
|
let _db = Connection::open_db(Configuration::clone(&state))?;
|
||||||
|
// let password_hash = list::hash_password(body.password).await?;
|
||||||
|
// let list = list::new(body.name, body.email, password_hash);
|
||||||
|
// let list = list::create(list).await?;
|
||||||
|
// let res = Publiclist::from(list);
|
||||||
|
//
|
||||||
|
|
||||||
|
Ok(Json(()))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
enum GetFilter {
|
||||||
|
Pk(i64),
|
||||||
|
Address(String),
|
||||||
|
Id(String),
|
||||||
|
Name(String),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct GetRequest {
|
||||||
|
filter: Option<GetFilter>,
|
||||||
|
count: Option<usize>,
|
||||||
|
page: Option<usize>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Serialize, Deserialize)]
|
||||||
|
struct GetResponse {
|
||||||
|
entries: Vec<DbVal<MailingList>>,
|
||||||
|
total: usize,
|
||||||
|
start: usize,
|
||||||
|
}
|
|
@ -0,0 +1 @@
|
||||||
|
pub mod list;
|
|
@ -0,0 +1,61 @@
|
||||||
|
use std::{env, fmt};
|
||||||
|
|
||||||
|
use config::{Config, ConfigError, Environment, File};
|
||||||
|
use lazy_static::lazy_static;
|
||||||
|
use serde::Deserialize;
|
||||||
|
|
||||||
|
lazy_static! {
|
||||||
|
pub static ref SETTINGS: Settings = Settings::new().expect("Failed to setup settings");
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct Server {
|
||||||
|
pub port: u16,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct Logger {
|
||||||
|
pub level: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct Auth {
|
||||||
|
pub secret: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, Deserialize)]
|
||||||
|
pub struct Settings {
|
||||||
|
pub environment: String,
|
||||||
|
pub server: Server,
|
||||||
|
pub logger: Logger,
|
||||||
|
pub auth: Auth,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Settings {
|
||||||
|
pub fn new() -> Result<Self, ConfigError> {
|
||||||
|
let run_mode = env::var("RUN_MODE").unwrap_or_else(|_| "development".into());
|
||||||
|
|
||||||
|
let mut builder = Config::builder()
|
||||||
|
.add_source(File::with_name("config/default"))
|
||||||
|
.add_source(File::with_name(&format!("config/{run_mode}")).required(false))
|
||||||
|
.add_source(File::with_name("config/local").required(false))
|
||||||
|
.add_source(Environment::default().separator("__"));
|
||||||
|
|
||||||
|
// Some cloud services like Heroku exposes a randomly assigned port in
|
||||||
|
// the PORT env var and there is no way to change the env var name.
|
||||||
|
if let Ok(port) = env::var("PORT") {
|
||||||
|
builder = builder.set_override("server.port", port)?;
|
||||||
|
}
|
||||||
|
|
||||||
|
builder
|
||||||
|
.build()?
|
||||||
|
// Deserialize (and thus freeze) the entire configuration.
|
||||||
|
.try_deserialize()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for Server {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
|
write!(f, "http://localhost:{}", &self.port)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue