From da8281636a6ebabf32d510207bf60a3019600049 Mon Sep 17 00:00:00 2001 From: Savanni D'Gerinel Date: Tue, 3 Oct 2023 11:10:37 -0400 Subject: [PATCH] Set up authentication routes --- Cargo.lock | 753 +++++++++++++++++++++++++--------- file-service/Cargo.toml | 51 ++- file-service/src/handlers.rs | 113 +++++ file-service/src/main.rs | 414 ++++--------------- file-service/src/pages.rs | 17 +- file-service/src/store/mod.rs | 137 ++++++- 6 files changed, 929 insertions(+), 556 deletions(-) create mode 100644 file-service/src/handlers.rs diff --git a/Cargo.lock b/Cargo.lock index 4c86352..41a60d5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -23,15 +23,33 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aae1277d39aeec15cb388266ecc24b11c80469deae6067e17a1a7aa9e5c1f234" +[[package]] +name = "ahash" +version = "0.8.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2c99f64d1e06488f620f932677e24bc6e2897582980441ae90a671415bd7ec2f" +dependencies = [ + "cfg-if", + "getrandom", + "once_cell", + "version_check 0.9.4", +] + [[package]] name = "aho-corasick" version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea5d730647d4fadd988536d06fecce94b7b4f2a7efdae548f1cf4b63205518ab" dependencies = [ - "memchr 2.6.4", + "memchr", ] +[[package]] +name = "allocator-api2" +version = "0.2.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0942ffc6dcaadf03badf6e6a2d0228460359d5e34b57ccdc720b7382dfbd5ec5" + [[package]] name = "android-tzdata" version = "0.1.1" @@ -62,6 +80,15 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" +[[package]] +name = "atoi" +version = "2.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f28d99ec8bfea296261ca1af174f24225171fea9664ba9003cbebee704810528" +dependencies = [ + "num-traits", +] + [[package]] name = "atty" version = "0.2.14" @@ -110,7 +137,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643" dependencies = [ "byteorder", - "safemem 0.3.3", + "safemem", ] [[package]] @@ -119,6 +146,12 @@ version = "0.21.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +[[package]] +name = "base64ct" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" + [[package]] name = "bit-set" version = "0.5.3" @@ -151,6 +184,9 @@ name = "bitflags" version = "2.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4682ae6287fcf752ecaabbfcc7b6f9b72aa33933dc23a554d853aea8eea8635" +dependencies = [ + "serde 1.0.188", +] [[package]] name = "block-buffer" @@ -161,29 +197,6 @@ dependencies = [ "generic-array 0.14.7", ] -[[package]] -name = "bodyparser" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f023abfa58aad6f6bc4ae0630799e24d5ee0ab8bb2e49f651d9b1f9aa4f52f30" -dependencies = [ - "iron", - "persistent", - "plugin", - "serde 1.0.188", - "serde_json", -] - -[[package]] -name = "buf_redux" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9279646319ff816b05fb5897883ece50d7d854d12b59992683d4f8a71b0f949" -dependencies = [ - "memchr 1.0.2", - "safemem 0.2.0", -] - [[package]] name = "build_html" version = "2.4.0" @@ -358,6 +371,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "const-oid" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "28c122c3980598d243d63d9a704629a2d748d101f278052ff068be5a4423ab6f" + [[package]] name = "cool_asserts" version = "2.0.3" @@ -401,6 +420,21 @@ dependencies = [ "libc", ] +[[package]] +name = "crc" +version = "3.0.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "86ec7a15cbe22e59248fc7eadb1907dab5ba09372595da4d73dd805ed4417dfe" +dependencies = [ + "crc-catalog", +] + +[[package]] +name = "crc-catalog" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9cace84e55f07e7301bae1c519df89cdad8cc3cd868413d3fdbdeca9ff3db484" + [[package]] name = "crc32fast" version = "1.3.2" @@ -434,6 +468,16 @@ dependencies = [ "scopeguard", ] +[[package]] +name = "crossbeam-queue" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d1cfb3ea8a53f37c40dea2c7bedcbd88bdfae54f5e2175d6ecaff1c988353add" +dependencies = [ + "cfg-if", + "crossbeam-utils", +] + [[package]] name = "crossbeam-utils" version = "0.8.16" @@ -512,6 +556,17 @@ dependencies = [ "byteorder", ] +[[package]] +name = "der" +version = "0.7.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fffa369a668c8af7dbf8b5e56c9f744fbd399949ed171606040001947de40b1c" +dependencies = [ + "const-oid", + "pem-rfc7468", + "zeroize", +] + [[package]] name = "digest" version = "0.10.7" @@ -519,7 +574,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer", + "const-oid", "crypto-common", + "subtle", ] [[package]] @@ -545,11 +602,20 @@ dependencies = [ "syn 2.0.37", ] +[[package]] +name = "dotenvy" +version = "0.15.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b" + [[package]] name = "either" version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a26ae43d7bcc3b814de94796a5e736d4029efb0ee900c12e2d54c993ad1a1e07" +dependencies = [ + "serde 1.0.188", +] [[package]] name = "emseries" @@ -615,6 +681,23 @@ dependencies = [ "libc", ] +[[package]] +name = "etcetera" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" +dependencies = [ + "cfg-if", + "home", + "windows-sys", +] + +[[package]] +name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + [[package]] name = "exr" version = "1.71.0" @@ -668,19 +751,15 @@ dependencies = [ "hex-string", "http", "image 0.23.14", - "iron", "log 0.4.20", "logger", "mime 0.3.17", "mime_guess 2.0.4", - "mustache", - "orizentic", - "params", "pretty_env_logger", - "router", "serde 1.0.188", "serde_json", "sha2", + "sqlx", "tempdir", "thiserror", "tokio", @@ -688,6 +767,12 @@ dependencies = [ "warp", ] +[[package]] +name = "finl_unicode" +version = "1.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8fcfdc7a0362c9f4444381a9e697c79d435fe65b52a37466fc2c1184cee9edc6" + [[package]] name = "flate2" version = "1.0.27" @@ -765,7 +850,9 @@ version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "55ac459de2512911e4b674ce33cf20befaba382d05b62b008afc1c8b57cbf181" dependencies = [ - "spin", + "futures-core", + "futures-sink", + "spin 0.9.8", ] [[package]] @@ -846,6 +933,17 @@ dependencies = [ "futures-util", ] +[[package]] +name = "futures-intrusive" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d930c203dd0b6ff06e0201a4a2fe9149b43c684fd4420555b26d21b1a02956f" +dependencies = [ + "futures-core", + "lock_api", + "parking_lot", +] + [[package]] name = "futures-io" version = "0.3.28" @@ -887,7 +985,7 @@ dependencies = [ "futures-macro", "futures-sink", "futures-task", - "memchr 2.6.4", + "memchr", "pin-project-lite", "pin-utils", "slab", @@ -1095,7 +1193,7 @@ dependencies = [ "glib-sys 0.17.10", "gobject-sys 0.17.10", "libc", - "memchr 2.6.4", + "memchr", "once_cell", "smallvec", "thiserror", @@ -1118,7 +1216,7 @@ dependencies = [ "glib-sys 0.18.1", "gobject-sys 0.18.0", "libc", - "memchr 2.6.4", + "memchr", "once_cell", "smallvec", "thiserror", @@ -1384,6 +1482,19 @@ name = "hashbrown" version = "0.14.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7dfda62a12f55daeae5015f81b0baea145391cb4520f86c248fc615d72640d12" +dependencies = [ + "ahash", + "allocator-api2", +] + +[[package]] +name = "hashlink" +version = "0.8.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8094feaf31ff591f651a2664fb9cfd92bba7a60ce3197265e9482ebe753c8f7" +dependencies = [ + "hashbrown 0.14.1", +] [[package]] name = "headers" @@ -1414,6 +1525,9 @@ name = "heck" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +dependencies = [ + "unicode-segmentation", +] [[package]] name = "hermit-abi" @@ -1430,6 +1544,12 @@ version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d77f7ec81a6d05a3abb01ab6eb7590f6083d08449fe5a1c8b1e620283546ccb7" +[[package]] +name = "hex" +version = "0.4.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" + [[package]] name = "hex-grid" version = "0.1.0" @@ -1449,6 +1569,33 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "848ec2dd093df965a34b434580d94852197fc83feac5b2c1962399bbf2cb4f0b" +[[package]] +name = "hkdf" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "791a029f6b9fc27657f6f188ec6e5e43f6911f6f878e0dc5501396e09809d437" +dependencies = [ + "hmac", +] + +[[package]] +name = "hmac" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" +dependencies = [ + "digest", +] + +[[package]] +name = "home" +version = "0.5.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5444c27eef6923071f7ebcc33e3444508466a76f7a2b93da00ed6e19f30c1ddb" +dependencies = [ + "windows-sys", +] + [[package]] name = "http" version = "0.2.9" @@ -1709,7 +1856,7 @@ version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cb0889898416213fab133e1d33a0e5858a48177452750691bde3666d0fdbaf8b" dependencies = [ - "hermit-abi 0.3.2", + "hermit-abi 0.3.3", "rustix", "windows-sys", ] @@ -1723,6 +1870,15 @@ dependencies = [ "either", ] +[[package]] +name = "itertools" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1c173a5686ce8bfa551b3563d0c2170bf24ca44da99c7ca4bfdab5418c3fe57" +dependencies = [ + "either", +] + [[package]] name = "itoa" version = "1.0.9" @@ -1815,6 +1971,9 @@ name = "lazy_static" version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" +dependencies = [ + "spin 0.5.2", +] [[package]] name = "lebe" @@ -1867,6 +2026,17 @@ version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f7012b1bbb0719e1097c47611d3898568c546d597c2e74d66f6087edd5233ff4" +[[package]] +name = "libsqlite3-sys" +version = "0.26.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "afc22eff61b133b115c6e8c74e818c628d6d5e7a502afea6f64dee076dd94326" +dependencies = [ + "cc", + "pkg-config", + "vcpkg", +] + [[package]] name = "linked-hash-map" version = "0.5.6" @@ -1922,12 +2092,13 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2532096657941c2fea9c289d370a250971c689d4f143798ff67113ec042024a5" [[package]] -name = "memchr" -version = "1.0.2" +name = "md-5" +version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "148fab2e51b4f1cfc66da2a7c32981d1d3c083a803978268bb11fe4b86925e7a" +checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "libc", + "cfg-if", + "digest", ] [[package]] @@ -2057,39 +2228,12 @@ dependencies = [ "http", "httparse", "log 0.4.20", - "memchr 2.6.4", + "memchr", "mime 0.3.17", - "spin", + "spin 0.9.8", "version_check 0.9.4", ] -[[package]] -name = "multipart" -version = "0.13.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92f54eb45230c3aa20864ccf0c277eeaeadcf5e437e91731db498dbf7fbe0ec6" -dependencies = [ - "buf_redux", - "httparse", - "log 0.3.9", - "mime 0.2.6", - "mime_guess 1.8.8", - "rand 0.3.23", - "safemem 0.2.0", - "tempdir", - "twoway", -] - -[[package]] -name = "mustache" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "51956ef1c5d20a1384524d91e616fb44dfc7d8f249bf696d49c97dd3289ecab5" -dependencies = [ - "log 0.3.9", - "serde 1.0.188", -] - [[package]] name = "native-tls" version = "0.2.11" @@ -2120,7 +2264,7 @@ version = "7.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a" dependencies = [ - "memchr 2.6.4", + "memchr", "minimal-lexical", ] @@ -2133,39 +2277,20 @@ dependencies = [ ] [[package]] -name = "num" -version = "0.1.42" +name = "num-bigint-dig" +version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4703ad64153382334aa8db57c637364c322d3372e097840c72000dabdcf6156e" +checksum = "dc84195820f291c7697304f3cbdadd1cb7199c0efc917ff5eafd71225c136151" dependencies = [ - "num-bigint", - "num-complex", + "byteorder", + "lazy_static", + "libm", "num-integer", "num-iter", - "num-rational 0.1.42", "num-traits", -] - -[[package]] -name = "num-bigint" -version = "0.1.44" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e63899ad0da84ce718c14936262a41cee2c79c981fc0a0e7c7beb47d5a07e8c1" -dependencies = [ - "num-integer", - "num-traits", - "rand 0.4.6", - "rustc-serialize", -] - -[[package]] -name = "num-complex" -version = "0.1.43" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b288631d7878aaf59442cffd36910ea604ecd7745c36054328595114001c9656" -dependencies = [ - "num-traits", - "rustc-serialize", + "rand 0.8.5", + "smallvec", + "zeroize", ] [[package]] @@ -2189,18 +2314,6 @@ dependencies = [ "num-traits", ] -[[package]] -name = "num-rational" -version = "0.1.42" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee314c74bd753fc86b4780aa9475da469155f3848473a261d2d18e35245a784e" -dependencies = [ - "num-bigint", - "num-integer", - "num-traits", - "rustc-serialize", -] - [[package]] name = "num-rational" version = "0.3.2" @@ -2249,7 +2362,7 @@ version = "0.32.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9cf5f9dd3933bd50a9e1f149ec995f39ae2c496d31fd772c1fd45ebc27e902b0" dependencies = [ - "memchr 2.6.4", + "memchr", ] [[package]] @@ -2308,7 +2421,7 @@ version = "1.0.1" dependencies = [ "chrono", "clap", - "itertools", + "itertools 0.10.5", "jsonwebtoken", "serde 1.0.188", "serde_derive", @@ -2370,22 +2483,6 @@ dependencies = [ "system-deps", ] -[[package]] -name = "params" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c789fdad2cfdaa551ea0e3a9eadb74c5d634968a9fb3a8c767d89be470d21589" -dependencies = [ - "bodyparser", - "iron", - "multipart", - "num", - "plugin", - "serde_json", - "tempdir", - "urlencoded", -] - [[package]] name = "parking_lot" version = "0.12.1" @@ -2418,6 +2515,21 @@ dependencies = [ "regex", ] +[[package]] +name = "paste" +version = "1.0.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "de3145af08024dea9fa9914f381a17b8fc6034dfb00f3a84013f7ff43f29ed4c" + +[[package]] +name = "pem-rfc7468" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "88b39c9bfcfc231068454382784bb460aae594343fb030d46e9f50a645418412" +dependencies = [ + "base64ct", +] + [[package]] name = "percent-encoding" version = "1.0.1" @@ -2430,16 +2542,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b2a4787296e9989611394c33f193f676704af1686e70b8f8033ab5ba9a35a94" -[[package]] -name = "persistent" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e8fa0009c4f3d350281309909c618abddf10bb7e3145f28410782f6a5ec74c5" -dependencies = [ - "iron", - "plugin", -] - [[package]] name = "phf" version = "0.7.24" @@ -2549,6 +2651,27 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" +[[package]] +name = "pkcs1" +version = "0.7.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c8ffb9f10fa047879315e6625af03c164b16962a5368d724ed16323b68ace47f" +dependencies = [ + "der", + "pkcs8", + "spki", +] + +[[package]] +name = "pkcs8" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f950b2377845cebe5cf8b5165cb3cc1a5e0fa5cfa3e1f7f55707d8fd82e0a7b7" +dependencies = [ + "der", + "spki", +] + [[package]] name = "pkg-config" version = "0.3.27" @@ -2905,7 +3028,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ebee201405406dbf528b8b672104ae6d6d63e6d118cb10e4d51abbc7b58044ff" dependencies = [ "aho-corasick", - "memchr 2.6.4", + "memchr", "regex-automata", "regex-syntax", ] @@ -2917,7 +3040,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" dependencies = [ "aho-corasick", - "memchr 2.6.4", + "memchr", "regex-syntax", ] @@ -2987,20 +3110,25 @@ dependencies = [ ] [[package]] -name = "route-recognizer" -version = "0.1.13" +name = "rsa" +version = "0.9.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea509065eb0b3c446acdd0102f0d46567dc30902dc0be91d6552035d92b0f4f8" - -[[package]] -name = "router" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc63b6f3b8895b0d04e816b2b1aa58fdba2d5acca3cbb8f0ab8e017347d57397" +checksum = "6ab43bb47d23c1a631b4b680199a45255dce26fa9ab2fa902581f624ff13e6a8" dependencies = [ - "iron", - "route-recognizer", - "url 1.7.2", + "byteorder", + "const-oid", + "digest", + "num-bigint-dig", + "num-integer", + "num-iter", + "num-traits", + "pkcs1", + "pkcs8", + "rand_core 0.6.4", + "signature", + "spki", + "subtle", + "zeroize", ] [[package]] @@ -3015,12 +3143,6 @@ version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" -[[package]] -name = "rustc-serialize" -version = "0.3.24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda" - [[package]] name = "rustc_version" version = "0.4.0" @@ -3070,12 +3192,6 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1ad4cc8da4ef723ed60bced201181d83791ad433213d8c24efffda1eec85d741" -[[package]] -name = "safemem" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f" - [[package]] name = "safemem" version = "0.3.3" @@ -3234,9 +3350,9 @@ dependencies = [ [[package]] name = "sha2" -version = "0.10.7" +version = "0.10.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "479fb9d862239e610720565ca91403019f2f00410f1864c5aa7479b950a76ed8" +checksum = "793db75ad2bcafc3ffa7c68b215fee268f537982cd901d132f89c6343f3a3dc8" dependencies = [ "cfg-if", "cpufeatures", @@ -3252,6 +3368,16 @@ dependencies = [ "libc", ] +[[package]] +name = "signature" +version = "2.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500" +dependencies = [ + "digest", + "rand_core 0.6.4", +] + [[package]] name = "simd-adler32" version = "0.3.7" @@ -3305,6 +3431,12 @@ dependencies = [ "windows-sys", ] +[[package]] +name = "spin" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" + [[package]] name = "spin" version = "0.9.8" @@ -3314,12 +3446,244 @@ dependencies = [ "lock_api", ] +[[package]] +name = "spki" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9d1e996ef02c474957d681f1b05213dfb0abab947b446a62d37770b23500184a" +dependencies = [ + "base64ct", + "der", +] + +[[package]] +name = "sqlformat" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b7b278788e7be4d0d29c0f39497a0eef3fba6bbc8e70d8bf7fde46edeaa9e85" +dependencies = [ + "itertools 0.11.0", + "nom", + "unicode_categories", +] + +[[package]] +name = "sqlx" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0e50c216e3624ec8e7ecd14c6a6a6370aad6ee5d8cfc3ab30b5162eeeef2ed33" +dependencies = [ + "sqlx-core", + "sqlx-macros", + "sqlx-mysql", + "sqlx-postgres", + "sqlx-sqlite", +] + +[[package]] +name = "sqlx-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d6753e460c998bbd4cd8c6f0ed9a64346fcca0723d6e75e52fdc351c5d2169d" +dependencies = [ + "ahash", + "atoi", + "byteorder", + "bytes", + "crc", + "crossbeam-queue", + "dotenvy", + "either", + "event-listener", + "futures-channel", + "futures-core", + "futures-intrusive", + "futures-io", + "futures-util", + "hashlink", + "hex", + "indexmap 2.0.2", + "log 0.4.20", + "memchr", + "once_cell", + "paste", + "percent-encoding 2.3.0", + "serde 1.0.188", + "serde_json", + "sha2", + "smallvec", + "sqlformat", + "thiserror", + "tokio", + "tokio-stream", + "tracing", + "url 2.4.1", +] + +[[package]] +name = "sqlx-macros" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9a793bb3ba331ec8359c1853bd39eed32cdd7baaf22c35ccf5c92a7e8d1189ec" +dependencies = [ + "proc-macro2", + "quote", + "sqlx-core", + "sqlx-macros-core", + "syn 1.0.109", +] + +[[package]] +name = "sqlx-macros-core" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a4ee1e104e00dedb6aa5ffdd1343107b0a4702e862a84320ee7cc74782d96fc" +dependencies = [ + "dotenvy", + "either", + "heck", + "hex", + "once_cell", + "proc-macro2", + "quote", + "serde 1.0.188", + "serde_json", + "sha2", + "sqlx-core", + "sqlx-mysql", + "sqlx-sqlite", + "syn 1.0.109", + "tempfile", + "tokio", + "url 2.4.1", +] + +[[package]] +name = "sqlx-mysql" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "864b869fdf56263f4c95c45483191ea0af340f9f3e3e7b4d57a61c7c87a970db" +dependencies = [ + "atoi", + "base64 0.21.4", + "bitflags 2.4.0", + "byteorder", + "bytes", + "crc", + "digest", + "dotenvy", + "either", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "generic-array 0.14.7", + "hex", + "hkdf", + "hmac", + "itoa", + "log 0.4.20", + "md-5", + "memchr", + "once_cell", + "percent-encoding 2.3.0", + "rand 0.8.5", + "rsa", + "serde 1.0.188", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-postgres" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eb7ae0e6a97fb3ba33b23ac2671a5ce6e3cabe003f451abd5a56e7951d975624" +dependencies = [ + "atoi", + "base64 0.21.4", + "bitflags 2.4.0", + "byteorder", + "crc", + "dotenvy", + "etcetera", + "futures-channel", + "futures-core", + "futures-io", + "futures-util", + "hex", + "hkdf", + "hmac", + "home", + "itoa", + "log 0.4.20", + "md-5", + "memchr", + "once_cell", + "rand 0.8.5", + "serde 1.0.188", + "serde_json", + "sha1", + "sha2", + "smallvec", + "sqlx-core", + "stringprep", + "thiserror", + "tracing", + "whoami", +] + +[[package]] +name = "sqlx-sqlite" +version = "0.7.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d59dc83cf45d89c555a577694534fcd1b55c545a816c816ce51f20bbe56a4f3f" +dependencies = [ + "atoi", + "flume", + "futures-channel", + "futures-core", + "futures-executor", + "futures-intrusive", + "futures-util", + "libsqlite3-sys", + "log 0.4.20", + "percent-encoding 2.3.0", + "serde 1.0.188", + "sqlx-core", + "tracing", + "url 2.4.1", +] + +[[package]] +name = "stringprep" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb41d74e231a107a1b4ee36bd1214b11285b77768d2e3824aedafa988fd36ee6" +dependencies = [ + "finl_unicode", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "strsim" version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" +[[package]] +name = "subtle" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "81cdd64d312baedb58e21336b31bc043b77e01cc99033ce76ef539f78e965ebc" + [[package]] name = "syn" version = "1.0.109" @@ -3637,9 +4001,21 @@ dependencies = [ "cfg-if", "log 0.4.20", "pin-project-lite", + "tracing-attributes", "tracing-core", ] +[[package]] +name = "tracing-attributes" +version = "0.1.26" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5f4f31f56159e98206da9efd823404b79b6ef3143b4a7ab76e67b1751b25a4ab" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + [[package]] name = "tracing-core" version = "0.1.31" @@ -3680,15 +4056,6 @@ dependencies = [ "utf-8", ] -[[package]] -name = "twoway" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59b11b2b5241ba34be09c3cc85a36e56e48f9888862e19cedf23336d35316ed1" -dependencies = [ - "memchr 2.6.4", -] - [[package]] name = "type-map" version = "0.4.0" @@ -3804,12 +4171,24 @@ dependencies = [ "tinyvec", ] +[[package]] +name = "unicode-segmentation" +version = "1.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1dd624098567895118886609431a7c3b8f516e41d30e0643f03d94592a147e36" + [[package]] name = "unicode-width" version = "0.1.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85" +[[package]] +name = "unicode_categories" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "39ec24b3121d976906ece63c9daad25b85969647682eee313cb5779fdd69e14e" + [[package]] name = "unsafe-any" version = "0.4.2" @@ -3847,18 +4226,6 @@ dependencies = [ "percent-encoding 2.3.0", ] -[[package]] -name = "urlencoded" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a52f50139118b60ae91af08bf15ed158817d34b91b9d24c11ffbe21195d33e3" -dependencies = [ - "bodyparser", - "iron", - "plugin", - "url 1.7.2", -] - [[package]] name = "utf-8" version = "0.7.6" @@ -4067,6 +4434,12 @@ version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9193164d4de03a926d909d3bc7c30543cecb35400c02114792c2cae20d5e2dbb" +[[package]] +name = "whoami" +version = "1.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22fc3756b8a9133049b26c7f61ab35416c130e8c09b660f5b3958b446f52cc50" + [[package]] name = "winapi" version = "0.3.9" @@ -4179,7 +4552,7 @@ version = "0.5.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c2e3184b9c4e92ad5167ca73039d0c42476302ab603e2fec4487511f38ccefc" dependencies = [ - "memchr 2.6.4", + "memchr", ] [[package]] @@ -4201,6 +4574,12 @@ dependencies = [ "linked-hash-map", ] +[[package]] +name = "zeroize" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9" + [[package]] name = "zune-inflate" version = "0.2.54" diff --git a/file-service/Cargo.toml b/file-service/Cargo.toml index f080ffe..c1571fb 100644 --- a/file-service/Cargo.toml +++ b/file-service/Cargo.toml @@ -7,29 +7,28 @@ edition = "2018" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -build_html = { version = "2" } -chrono = { version = "0.4", features = ["serde"] } -hex-string = "0.1.0" -http = { version = "0.2" } -image = "0.23.5" -iron = "0.6.1" -logger = "*" -mime = "0.3.16" -mime_guess = "2.0.3" -mustache = "0.9.0" -orizentic = { path = "../orizentic" } -params = "*" -router = "*" -serde_json = "*" -serde = { version = "1.0", features = ["derive"] } -sha2 = "0.10" -thiserror = "1.0.20" -tokio = { version = "1", features = [ "full" ] } -uuid = { version = "0.4", features = [ "serde", "v4" ] } -warp = { version = "0.3" } -pretty_env_logger = { version = "0.5" } -log = { version = "0.4" } -bytes = { version = "1" } -futures-util = { version = "0.3" } -cool_asserts = { version = "2" } -tempdir = { version = "0.3" } +build_html = { version = "2" } +bytes = { version = "1" } +chrono = { version = "0.4", features = ["serde"] } +futures-util = { version = "0.3" } +hex-string = "0.1.0" +http = { version = "0.2" } +image = "0.23.5" +logger = "*" +log = { version = "0.4" } +mime = "0.3.16" +mime_guess = "2.0.3" +pretty_env_logger = { version = "0.5" } +serde_json = "*" +serde = { version = "1.0", features = ["derive"] } +sha2 = "0.10" +sqlx = { version = "0.7", features = [ "runtime-tokio", "sqlite" ] } +thiserror = "1.0.20" +tokio = { version = "1", features = [ "full" ] } +uuid = { version = "0.4", features = [ "serde", "v4" ] } +warp = { version = "0.3" } + +[dev-dependencies] +cool_asserts = { version = "2" } +tempdir = { version = "0.3" } + diff --git a/file-service/src/handlers.rs b/file-service/src/handlers.rs new file mode 100644 index 0000000..cb6d926 --- /dev/null +++ b/file-service/src/handlers.rs @@ -0,0 +1,113 @@ +use build_html::Html; +use http::{Error, StatusCode}; +use std::{collections::HashMap, future::Future}; +use warp::http::Response; + +use crate::{pages, App, FileHandle, FileId, FileInfo, ReadFileError, SessionToken}; + +pub async fn handle_index( + app: App, + token: Option, +) -> Result, Error> { + match token { + Some(token) => match app.auth_session(token).await { + Ok(_) => render_gallery_page(app).await, + Err(err) => render_auth_page(Some(format!("authentication refused: {:?}", err))), + }, + None => render_auth_page(None), + } +} + +pub fn render_auth_page(message: Option) -> Result, Error> { + Response::builder() + .status(StatusCode::OK) + .body(pages::auth(message).to_html_string()) +} + +pub async fn render_gallery_page(app: App) -> Result, Error> { + match app.list_files().await { + Ok(ids) => { + let mut files = vec![]; + for id in ids.into_iter() { + let file = app.get_file(&id).await; + files.push(file); + } + Response::builder() + .header("content-type", "text/html") + .status(StatusCode::OK) + .body(pages::gallery(files).to_html_string()) + } + Err(_) => Response::builder() + .header("content-type", "text/html") + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body("".to_owned()), + } +} + +pub async fn thumbnail( + app: App, + id: String, + old_etags: Option, +) -> Result>, Error> { + match app.get_file(&FileId::from(id)).await { + Ok(file) => serve_file(file.info.clone(), || file.thumbnail(), old_etags), + Err(_err) => Response::builder() + .status(StatusCode::NOT_FOUND) + .body(vec![]), + } +} + +pub async fn file( + app: App, + id: String, + old_etags: Option, +) -> Result>, Error> { + match app.get_file(&FileId::from(id)).await { + Ok(file) => serve_file(file.info.clone(), || file.thumbnail(), old_etags), + Err(_err) => Response::builder() + .status(StatusCode::NOT_FOUND) + .body(vec![]), + } +} + +pub async fn handle_auth(_form: HashMap) -> Result, Error> { + Response::builder() + .status(StatusCode::NOT_IMPLEMENTED) + .body("".to_owned()) +} + +pub async fn handle_upload( + _app: App, + _token: SessionToken, +) -> Result, Error> { + println!("handle_upload"); + Response::builder() + .status(StatusCode::NOT_IMPLEMENTED) + .body("".to_owned()) +} + +fn serve_file( + info: FileInfo, + file: F, + old_etags: Option, +) -> http::Result>> +where + F: FnOnce() -> Result, ReadFileError>, +{ + match old_etags { + Some(old_etags) if old_etags != info.hash => Response::builder() + .header("content-type", info.file_type) + .status(StatusCode::NOT_MODIFIED) + .body(vec![]), + _ => match file() { + Ok(content) => Response::builder() + .header("content-type", info.file_type) + .header("etag", info.hash) + .status(StatusCode::OK) + .body(content), + Err(_) => Response::builder() + .status(StatusCode::INTERNAL_SERVER_ERROR) + .body(vec![]), + }, + } +} diff --git a/file-service/src/main.rs b/file-service/src/main.rs index 2a2a000..191db78 100644 --- a/file-service/src/main.rs +++ b/file-service/src/main.rs @@ -1,250 +1,44 @@ #[macro_use] extern crate log; +use handlers::{file, handle_auth, handle_upload, thumbnail}; use http::status::StatusCode; // use mustache::{compile_path, Template}; // use orizentic::{Permissions, ResourceName, Secret}; -use build_html::Html; use bytes::Buf; use futures_util::StreamExt; use std::{ collections::HashMap, + convert::Infallible, io::Read, net::{IpAddr, Ipv4Addr, SocketAddr}, path::PathBuf, sync::{Arc, RwLock}, }; -use warp::{filters::multipart::Part, Filter}; +use store::Username; +use warp::{filters::multipart::Part, Filter, Rejection}; -// mod cookies; +mod handlers; mod html; -// mod middleware; mod pages; mod store; -pub use store::{FileHandle, FileId, FileInfo, ReadFileError, Store}; +pub use handlers::handle_index; +pub use store::{App, AuthDB, FileHandle, FileId, FileInfo, ReadFileError, SessionToken, Store}; /* -fn is_admin(resource: &ResourceName, permissions: &Permissions) -> bool { - let Permissions(perms) = permissions; - ResourceName(String::from( - "https://savanni.luminescent-dreams.com/file-service/", - )) == *resource - && perms.contains(&String::from("admin")) -} - -pub fn compare_etags(info: FileInfo, etag_list: &headers::IfNoneMatch) -> bool { - let current_etag = headers::EntityTag::new(false, info.hash); - match etag_list { - headers::IfNoneMatch::Any => false, - headers::IfNoneMatch::Items(lst) => lst.iter().any(|etag| etag.weak_eq(¤t_etag)), +async fn authenticate_user(app: App, auth_token: String) -> Result { + match app.auth_session(SessionToken::from(auth_token)).await { + Ok(username) => Ok(username), + Err(_) => Err(warp::reject::not_found()), } } - -mod files { - use super::*; - - pub struct GetHandler { - pub app: Arc>, - } - - impl Handler for GetHandler { - fn handle(&self, req: &mut Request) -> IronResult { - let app = self.app.read().unwrap(); - let capture = req.extensions.get::().unwrap().clone(); - let old_etags = req.headers.get::(); - match capture.find("id") { - Some(id) => { - let info = app.get_metadata(String::from(id)); - match (info, old_etags) { - (Ok(info_), Some(if_none_match)) => { - if compare_etags(info_, if_none_match) { - return Ok(Response::with(status::NotModified)); - } - } - _ => (), - } - match app.get_file(String::from(id)) { - Ok((info, stream)) => Ok(Response::with(( - status::Ok, - Header(headers::ContentType( - info.file_type.parse::().unwrap(), - )), - Header(headers::ETag(headers::EntityTag::new(false, info.hash))), - BodyReader(stream), - ))), - Err(_err) => Ok(Response::with(status::NotFound)), - } - } - _ => Ok(Response::with(status::BadRequest)), - } - } - } - - pub struct GetThumbnailHandler { - pub app: Arc>, - } - - impl Handler for GetThumbnailHandler { - fn handle(&self, req: &mut Request) -> IronResult { - let app = self.app.read().unwrap(); - let capture = req.extensions.get::().unwrap().clone(); - let old_etags = req.headers.get::(); - match capture.find("id") { - Some(id) => { - let info = app.get_metadata(String::from(id)); - match (info, old_etags) { - (Ok(info_), Some(if_none_match)) => { - if compare_etags(info_, if_none_match) { - return Ok(Response::with(status::NotModified)); - } - } - _ => (), - } - match app.get_thumbnail(id) { - Ok((info, stream)) => Ok(Response::with(( - status::Ok, - Header(headers::ContentType( - info.file_type.parse::().unwrap(), - )), - Header(headers::ETag(headers::EntityTag::new(false, info.hash))), - BodyReader(stream), - ))), - Err(_err) => Ok(Response::with(status::NotFound)), - } - } - _ => Ok(Response::with(status::BadRequest)), - } - } - } - pub struct PostHandler { - pub app: Arc>, - } - - impl Handler for PostHandler { - fn handle(&self, req: &mut Request) -> IronResult { - let mut app = self.app.write().unwrap(); - let m_token = req.extensions.get::(); - match m_token { - Some(token) => { - if token.check_authorizations(is_admin) { - let params = req.get_ref::().unwrap(); - if let Value::File(f_info) = params.get("file").unwrap() { - match app.add_file( - &f_info.path, - &f_info.filename.clone().map(|fname| PathBuf::from(fname)), - ) { - Ok(_) => Ok(Response::with(( - status::MovedPermanently, - Redirect(router::url_for(req, "index", HashMap::new())), - ))), - Err(_) => Ok(Response::with(status::InternalServerError)), - } - } else { - Ok(Response::with(status::BadRequest)) - } - } else { - Ok(Response::with(status::Forbidden)) - } - } - None => Ok(Response::with(status::Forbidden)), - } - } - } - - pub struct DeleteHandler { - pub app: Arc>, - } - - impl Handler for DeleteHandler { - fn handle(&self, req: &mut Request) -> IronResult { - let mut app = self.app.write().unwrap(); - let capture = req.extensions.get::().unwrap().clone(); - let m_token = req.extensions.get::(); - match m_token { - Some(token) => { - if token.check_authorizations(is_admin) { - match capture.find("id") { - Some(id) => match app.delete_file(String::from(id)) { - Ok(()) => Ok(Response::with(( - status::MovedPermanently, - Redirect(router::url_for(req, "index", HashMap::new())), - ))), - Err(_) => Ok(Response::with(status::InternalServerError)), - }, - None => Ok(Response::with(status::BadRequest)), - } - } else { - Ok(Response::with(status::Forbidden)) - } - } - None => Ok(Response::with(status::Forbidden)), - } - } - } -} - -fn css(_: &mut Request) -> IronResult { - let mut css: String = String::from(""); - File::open("templates/style.css") - .unwrap() - .read_to_string(&mut css) - .unwrap(); - Ok(Response::with(( - status::Ok, - Header(headers::ContentType(iron::mime::Mime( - iron::mime::TopLevel::Text, - iron::mime::SubLevel::Css, - vec![], - ))), - css, - ))) -} - -fn script(_: &mut Request) -> IronResult { - let mut js: String = String::from(""); - File::open("templates/script.js") - .unwrap() - .read_to_string(&mut js) - .unwrap(); - Ok(Response::with(( - status::Ok, - Header(headers::ContentType(iron::mime::Mime( - iron::mime::TopLevel::Text, - iron::mime::SubLevel::Javascript, - vec![], - ))), - js, - ))) -} */ -fn serve_file( - info: FileInfo, - file: F, - old_etags: Option, -) -> http::Result>> -where - F: FnOnce() -> Result, ReadFileError>, -{ - match old_etags { - Some(old_etags) if old_etags != info.hash => warp::http::Response::builder() - .header("content-type", info.file_type) - .status(StatusCode::NOT_MODIFIED) - .body(vec![]), - _ => match file() { - Ok(content) => warp::http::Response::builder() - .header("content-type", info.file_type) - .header("etag", info.hash) - .status(StatusCode::OK) - .body(content), - Err(_) => warp::http::Response::builder() - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body(vec![]), - }, - } -} +/* +*/ +/* async fn collect_content( mut part: Part, ) -> Result<(Option, Option, Vec), String> { @@ -261,7 +55,9 @@ async fn collect_content( content, )) } +*/ +/* async fn collect_multipart( mut stream: warp::filters::multipart::FormData, ) -> Result, Option, Vec)>, warp::Error> { @@ -276,10 +72,12 @@ async fn collect_multipart( Ok(content) } +*/ +/* async fn handle_upload( form: warp::filters::multipart::FormData, - app: Arc>, + app: App, ) -> warp::http::Result> { let files = collect_multipart(form).await; match files { @@ -287,7 +85,7 @@ async fn handle_upload( for (_, filename, content) in files { match filename { Some(filename) => { - app.write().unwrap().add_file(filename, content).unwrap(); + app.add_file(filename, content).unwrap(); } None => { return warp::http::Response::builder() @@ -310,150 +108,84 @@ async fn handle_upload( .status(StatusCode::SEE_OTHER) .body("".to_owned()) } +*/ + +fn with_app(app: App) -> impl Filter + Clone { + warp::any().map(move || app.clone()) +} + +fn maybe_with_session() -> impl Filter,), Error = Rejection> + Copy +{ + warp::any() + .and(warp::header::optional::("cookie")) + .map(|cookies| { + println!("cookies retrieved: {:?}", cookies); + None + }) +} + +fn with_session() -> impl Filter + Copy { + warp::any() + .and(warp::header::("cookie")) + .map(|token: String| SessionToken::from(token)) +} #[tokio::main] pub async fn main() { - /* - let auth_db_path = std::env::var("ORIZENTIC_DB").unwrap(); - let secret = Secret(Vec::from( - std::env::var("ORIZENTIC_SECRET").unwrap().as_bytes(), - )); - let auth_middleware = Authentication::new(secret, auth_db_path); - - let mut router = Router::new(); - - router.post("/", files::PostHandler { app: app.clone() }, "upload-file"); - - router.delete( - "/:id", - files::DeleteHandler { app: app.clone() }, - "delete-file", - ); - router.get("/css", css, "styles"); - router.get("/script", script, "script"); - - let mut chain = Chain::new(router); - chain.link_before(auth_middleware); - chain.link_before(RestForm {}); - - Iron::new(chain).http("0.0.0.0:3000").unwrap(); - */ - - /* - let root = warp::path!().and(warp::get()).map({ - || { - warp::http::Response::builder() - .header("content-type", "text/html") - .status(StatusCode::NOT_MODIFIED) - .body(()) - } - }); - let server = warp::serve(root); - server - .run(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8002)) - .await; - */ - pretty_env_logger::init(); - let app = Arc::new(RwLock::new(Store::new(PathBuf::from( - &std::env::var("FILE_SHARE_DIR").unwrap(), - )))); + let authdb = AuthDB::new(PathBuf::from(":memory:")).await.unwrap(); + let store = Store::new(PathBuf::from(&std::env::var("FILE_SHARE_DIR").unwrap())); - let app_filter = { + let app = App::new(authdb, store); + + /* + let with_app = { let app = app.clone(); warp::any().map(move || app.clone()) }; + */ let log = warp::log("file_service"); + let root = warp::path!() + .and(warp::get()) + .and(with_app(app.clone())) + .and(maybe_with_session()) + .then(handle_index); - let root = warp::path!().and(warp::get()).and(app_filter.clone()).map({ - move |app: Arc>| { - info!("root handler"); - let app = app.read().unwrap(); - match app.list_files() { - Ok(ids) => { - let files = ids - .into_iter() - .map(|id| app.get_file(&id)) - .collect::>>(); - warp::http::Response::builder() - .header("content-type", "text/html") - .status(StatusCode::OK) - .body(pages::index(files).to_html_string()) - } - Err(_) => warp::http::Response::builder() - .header("content-type", "text/html") - .status(StatusCode::INTERNAL_SERVER_ERROR) - .body("".to_owned()), - } - } - }); - - let post_upload_handler = warp::path!("upload") - .and(warp::post()) - .and(warp::filters::multipart::form().max_length(1024 * 1024 * 32)) - .and(app_filter.clone()) - .then( - |form: warp::filters::multipart::FormData, app: Arc>| { - handle_upload(form, app) - }, - ); - - /* - let post_delete_handler = warp::path!(String) + let auth = warp::path!("auth") .and(warp::post()) .and(warp::filters::body::form()) - .map(|id: String, form: HashMap| { - info!("post_delete {}", id); - info!("form: {:?}", form); - warp::http::Response::builder() - .header("location", "/") - .status(StatusCode::SEE_OTHER) - .body(vec![]) - }); - */ + .then(handle_auth); + + let upload_handler = warp::path!("upload") + .and(warp::post()) + .and(with_app(app.clone())) + .and(with_session()) + .then(handle_upload); let thumbnail = warp::path!(String / "tn") .and(warp::get()) .and(warp::header::optional::("if-none-match")) - .map({ - let app = app.clone(); - move |id: String, old_etags: Option| match app - .read() - .unwrap() - .get_file(&FileId::from(id)) - { - Ok(file) => serve_file(file.info.clone(), || file.thumbnail(), old_etags), - Err(_err) => warp::http::Response::builder() - .status(StatusCode::NOT_FOUND) - .body(vec![]), - } - }); + .and(with_app(app.clone())) + .then(move |id, old_etags, app: App| thumbnail(app, id, old_etags)); let file = warp::path!(String) .and(warp::get()) .and(warp::header::optional::("if-none-match")) - .map({ - let app = app.clone(); - move |id: String, old_etags: Option| match app - .read() - .unwrap() - .get_file(&FileId::from(id)) - { - Ok(file) => serve_file(file.info.clone(), || file.content(), old_etags), - Err(_err) => warp::http::Response::builder() - .status(StatusCode::NOT_FOUND) - .body(vec![]), - } - }); + .and(with_app(app.clone())) + .then(move |id, old_etags, app: App| file(app, id, old_etags)); let server = warp::serve( - root.or(post_upload_handler) - .or(thumbnail) - .or(file) - .with(log), + root.or(auth).with(log), /* + root.or(auth) + .or(thumbnail) + .or(file) + .or(upload_handler) + .with(log), + */ ); + server .run(SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 8002)) .await; diff --git a/file-service/src/pages.rs b/file-service/src/pages.rs index 3dfbc5e..45d5fdf 100644 --- a/file-service/src/pages.rs +++ b/file-service/src/pages.rs @@ -4,7 +4,22 @@ use crate::{ }; use build_html::{self, Container, ContainerType, Html, HtmlContainer}; -pub fn index(handles: Vec>) -> build_html::HtmlPage { +pub fn auth(_message: Option) -> build_html::HtmlPage { + build_html::HtmlPage::new() + .with_title("Authentication") + .with_html( + Form::new() + .with_path("/auth") + .with_method("post") + .with_container( + Container::new(ContainerType::Div) + .with_html(Input::new("token", "token").with_id("for-token-input")) + .with_html(Label::new("for-token-input", "Authentication Token")), + ), + ) +} + +pub fn gallery(handles: Vec>) -> build_html::HtmlPage { let mut page = build_html::HtmlPage::new() .with_title("Admin list of files") .with_header(1, "Admin list of files") diff --git a/file-service/src/store/mod.rs b/file-service/src/store/mod.rs index c023673..e757643 100644 --- a/file-service/src/store/mod.rs +++ b/file-service/src/store/mod.rs @@ -1,7 +1,9 @@ use serde::{Deserialize, Serialize}; +use sqlx::sqlite::SqlitePool; use std::collections::HashSet; -use std::{ops::Deref, path::PathBuf}; +use std::{ops::Deref, path::PathBuf, sync::Arc}; use thiserror::Error; +use tokio::sync::RwLock; mod filehandle; mod fileinfo; @@ -57,6 +59,82 @@ pub enum ReadFileError { IOError(#[from] std::io::Error), } +#[derive(Debug, Error)] +pub enum AuthError { + #[error("database failed")] + SqlError, +} + +#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)] +pub struct Username(String); + +impl From for Username { + fn from(s: String) -> Self { + Self(s) + } +} + +impl From<&str> for Username { + fn from(s: &str) -> Self { + Self(s.to_owned()) + } +} + +impl From for PathBuf { + fn from(s: Username) -> Self { + Self::from(&s) + } +} + +impl From<&Username> for PathBuf { + fn from(s: &Username) -> Self { + let Username(s) = s; + Self::from(s) + } +} + +impl Deref for Username { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)] +pub struct SessionToken(String); + +impl From for SessionToken { + fn from(s: String) -> Self { + Self(s) + } +} + +impl From<&str> for SessionToken { + fn from(s: &str) -> Self { + Self(s.to_owned()) + } +} + +impl From for PathBuf { + fn from(s: SessionToken) -> Self { + Self::from(&s) + } +} + +impl From<&SessionToken> for PathBuf { + fn from(s: &SessionToken) -> Self { + let SessionToken(s) = s; + Self::from(s) + } +} + +impl Deref for SessionToken { + type Target = String; + fn deref(&self) -> &Self::Target { + &self.0 + } +} + #[derive(Clone, Debug, Serialize, Deserialize, Hash, PartialEq, Eq)] pub struct FileId(String); @@ -104,6 +182,63 @@ impl FileRoot for Context { } } +#[derive(Clone)] +pub struct App { + authdb: Arc>, + store: Arc>, +} + +impl App { + pub fn new(authdb: AuthDB, store: Store) -> Self { + Self { + authdb: Arc::new(RwLock::new(authdb)), + store: Arc::new(RwLock::new(store)), + } + } + + pub async fn auth_session(&self, token: SessionToken) -> Result { + let authdb = self.authdb.read(); + // authdb.auth_session(token).await + unimplemented!() + } + + pub async fn list_files(&self) -> Result, ReadFileError> { + self.store.read().await.list_files() + } + + pub async fn get_file(&self, id: &FileId) -> Result { + self.store.read().await.get_file(id) + } + + pub async fn add_file( + &self, + filename: String, + content: Vec, + ) -> Result { + self.store.write().await.add_file(filename, content) + } +} + +#[derive(Clone)] +pub struct AuthDB { + pool: SqlitePool, +} + +impl AuthDB { + pub async fn new(path: PathBuf) -> Result { + let pool = SqlitePool::connect(&format!("sqlite://{}", path.to_str().unwrap())).await?; + Ok(Self { pool }) + } + + pub async fn auth_session(&self, _token: SessionToken) -> Result { + /* + let conn = self.pool.acquire().await.map_err(|_| AuthError::SqlError)?; + conn.transaction(|tr| {}) + */ + unimplemented!() + } +} + pub struct Store { files_root: PathBuf, }